linux/sound/pci/hda/hda_sysfs.c
<<
>>
Prefs
   1/*
   2 * sysfs interface for HD-audio codec
   3 *
   4 * Copyright (c) 2014 Takashi Iwai <tiwai@suse.de>
   5 *
   6 * split from hda_hwdep.c
   7 */
   8
   9#include <linux/init.h>
  10#include <linux/slab.h>
  11#include <linux/compat.h>
  12#include <linux/mutex.h>
  13#include <linux/ctype.h>
  14#include <linux/string.h>
  15#include <linux/export.h>
  16#include <sound/core.h>
  17#include "hda_codec.h"
  18#include "hda_local.h"
  19#include <sound/hda_hwdep.h>
  20#include <sound/minors.h>
  21
  22/* hint string pair */
  23struct hda_hint {
  24        const char *key;
  25        const char *val;        /* contained in the same alloc as key */
  26};
  27
  28#ifdef CONFIG_PM
  29static ssize_t power_on_acct_show(struct device *dev,
  30                                  struct device_attribute *attr,
  31                                  char *buf)
  32{
  33        struct hda_codec *codec = dev_get_drvdata(dev);
  34        snd_hda_update_power_acct(codec);
  35        return sprintf(buf, "%u\n", jiffies_to_msecs(codec->power_on_acct));
  36}
  37
  38static ssize_t power_off_acct_show(struct device *dev,
  39                                   struct device_attribute *attr,
  40                                   char *buf)
  41{
  42        struct hda_codec *codec = dev_get_drvdata(dev);
  43        snd_hda_update_power_acct(codec);
  44        return sprintf(buf, "%u\n", jiffies_to_msecs(codec->power_off_acct));
  45}
  46
  47static DEVICE_ATTR_RO(power_on_acct);
  48static DEVICE_ATTR_RO(power_off_acct);
  49#endif /* CONFIG_PM */
  50
  51#define CODEC_INFO_SHOW(type, field)                            \
  52static ssize_t type##_show(struct device *dev,                  \
  53                           struct device_attribute *attr,       \
  54                           char *buf)                           \
  55{                                                               \
  56        struct hda_codec *codec = dev_get_drvdata(dev);         \
  57        return sprintf(buf, "0x%x\n", codec->field);            \
  58}
  59
  60#define CODEC_INFO_STR_SHOW(type, field)                        \
  61static ssize_t type##_show(struct device *dev,                  \
  62                             struct device_attribute *attr,     \
  63                                        char *buf)              \
  64{                                                               \
  65        struct hda_codec *codec = dev_get_drvdata(dev);         \
  66        return sprintf(buf, "%s\n",                             \
  67                       codec->field ? codec->field : "");       \
  68}
  69
  70CODEC_INFO_SHOW(vendor_id, core.vendor_id);
  71CODEC_INFO_SHOW(subsystem_id, core.subsystem_id);
  72CODEC_INFO_SHOW(revision_id, core.revision_id);
  73CODEC_INFO_SHOW(afg, core.afg);
  74CODEC_INFO_SHOW(mfg, core.mfg);
  75CODEC_INFO_STR_SHOW(vendor_name, core.vendor_name);
  76CODEC_INFO_STR_SHOW(chip_name, core.chip_name);
  77CODEC_INFO_STR_SHOW(modelname, modelname);
  78
  79static ssize_t pin_configs_show(struct hda_codec *codec,
  80                                struct snd_array *list,
  81                                char *buf)
  82{
  83        int i, len = 0;
  84        mutex_lock(&codec->user_mutex);
  85        for (i = 0; i < list->used; i++) {
  86                struct hda_pincfg *pin = snd_array_elem(list, i);
  87                len += sprintf(buf + len, "0x%02x 0x%08x\n",
  88                               pin->nid, pin->cfg);
  89        }
  90        mutex_unlock(&codec->user_mutex);
  91        return len;
  92}
  93
  94static ssize_t init_pin_configs_show(struct device *dev,
  95                                     struct device_attribute *attr,
  96                                     char *buf)
  97{
  98        struct hda_codec *codec = dev_get_drvdata(dev);
  99        return pin_configs_show(codec, &codec->init_pins, buf);
 100}
 101
 102static ssize_t driver_pin_configs_show(struct device *dev,
 103                                       struct device_attribute *attr,
 104                                       char *buf)
 105{
 106        struct hda_codec *codec = dev_get_drvdata(dev);
 107        return pin_configs_show(codec, &codec->driver_pins, buf);
 108}
 109
 110#ifdef CONFIG_SND_HDA_RECONFIG
 111
 112/*
 113 * sysfs interface
 114 */
 115
 116static int clear_codec(struct hda_codec *codec)
 117{
 118        int err;
 119
 120        err = snd_hda_codec_reset(codec);
 121        if (err < 0) {
 122                codec_err(codec, "The codec is being used, can't free.\n");
 123                return err;
 124        }
 125        snd_hda_sysfs_clear(codec);
 126        return 0;
 127}
 128
 129static int reconfig_codec(struct hda_codec *codec)
 130{
 131        int err;
 132
 133        snd_hda_power_up(codec);
 134        codec_info(codec, "hda-codec: reconfiguring\n");
 135        err = snd_hda_codec_reset(codec);
 136        if (err < 0) {
 137                codec_err(codec,
 138                           "The codec is being used, can't reconfigure.\n");
 139                goto error;
 140        }
 141        err = snd_hda_codec_configure(codec);
 142        if (err < 0)
 143                goto error;
 144        /* rebuild PCMs */
 145        err = snd_hda_codec_build_pcms(codec);
 146        if (err < 0)
 147                goto error;
 148        /* rebuild mixers */
 149        err = snd_hda_codec_build_controls(codec);
 150        if (err < 0)
 151                goto error;
 152        err = snd_card_register(codec->card);
 153 error:
 154        snd_hda_power_down(codec);
 155        return err;
 156}
 157
 158/*
 159 * allocate a string at most len chars, and remove the trailing EOL
 160 */
 161static char *kstrndup_noeol(const char *src, size_t len)
 162{
 163        char *s = kstrndup(src, len, GFP_KERNEL);
 164        char *p;
 165        if (!s)
 166                return NULL;
 167        p = strchr(s, '\n');
 168        if (p)
 169                *p = 0;
 170        return s;
 171}
 172
 173#define CODEC_INFO_STORE(type, field)                           \
 174static ssize_t type##_store(struct device *dev,                 \
 175                            struct device_attribute *attr,      \
 176                            const char *buf, size_t count)      \
 177{                                                               \
 178        struct hda_codec *codec = dev_get_drvdata(dev);         \
 179        unsigned long val;                                      \
 180        int err = kstrtoul(buf, 0, &val);                       \
 181        if (err < 0)                                            \
 182                return err;                                     \
 183        codec->field = val;                                     \
 184        return count;                                           \
 185}
 186
 187#define CODEC_INFO_STR_STORE(type, field)                       \
 188static ssize_t type##_store(struct device *dev,                 \
 189                            struct device_attribute *attr,      \
 190                            const char *buf, size_t count)      \
 191{                                                               \
 192        struct hda_codec *codec = dev_get_drvdata(dev);         \
 193        char *s = kstrndup_noeol(buf, 64);                      \
 194        if (!s)                                                 \
 195                return -ENOMEM;                                 \
 196        kfree(codec->field);                                    \
 197        codec->field = s;                                       \
 198        return count;                                           \
 199}
 200
 201CODEC_INFO_STORE(vendor_id, core.vendor_id);
 202CODEC_INFO_STORE(subsystem_id, core.subsystem_id);
 203CODEC_INFO_STORE(revision_id, core.revision_id);
 204CODEC_INFO_STR_STORE(vendor_name, core.vendor_name);
 205CODEC_INFO_STR_STORE(chip_name, core.chip_name);
 206CODEC_INFO_STR_STORE(modelname, modelname);
 207
 208#define CODEC_ACTION_STORE(type)                                \
 209static ssize_t type##_store(struct device *dev,                 \
 210                            struct device_attribute *attr,      \
 211                            const char *buf, size_t count)      \
 212{                                                               \
 213        struct hda_codec *codec = dev_get_drvdata(dev);         \
 214        int err = 0;                                            \
 215        if (*buf)                                               \
 216                err = type##_codec(codec);                      \
 217        return err < 0 ? err : count;                           \
 218}
 219
 220CODEC_ACTION_STORE(reconfig);
 221CODEC_ACTION_STORE(clear);
 222
 223static ssize_t init_verbs_show(struct device *dev,
 224                               struct device_attribute *attr,
 225                               char *buf)
 226{
 227        struct hda_codec *codec = dev_get_drvdata(dev);
 228        int i, len = 0;
 229        mutex_lock(&codec->user_mutex);
 230        for (i = 0; i < codec->init_verbs.used; i++) {
 231                struct hda_verb *v = snd_array_elem(&codec->init_verbs, i);
 232                len += snprintf(buf + len, PAGE_SIZE - len,
 233                                "0x%02x 0x%03x 0x%04x\n",
 234                                v->nid, v->verb, v->param);
 235        }
 236        mutex_unlock(&codec->user_mutex);
 237        return len;
 238}
 239
 240static int parse_init_verbs(struct hda_codec *codec, const char *buf)
 241{
 242        struct hda_verb *v;
 243        int nid, verb, param;
 244
 245        if (sscanf(buf, "%i %i %i", &nid, &verb, &param) != 3)
 246                return -EINVAL;
 247        if (!nid || !verb)
 248                return -EINVAL;
 249        mutex_lock(&codec->user_mutex);
 250        v = snd_array_new(&codec->init_verbs);
 251        if (!v) {
 252                mutex_unlock(&codec->user_mutex);
 253                return -ENOMEM;
 254        }
 255        v->nid = nid;
 256        v->verb = verb;
 257        v->param = param;
 258        mutex_unlock(&codec->user_mutex);
 259        return 0;
 260}
 261
 262static ssize_t init_verbs_store(struct device *dev,
 263                                struct device_attribute *attr,
 264                                const char *buf, size_t count)
 265{
 266        struct hda_codec *codec = dev_get_drvdata(dev);
 267        int err = parse_init_verbs(codec, buf);
 268        if (err < 0)
 269                return err;
 270        return count;
 271}
 272
 273static ssize_t hints_show(struct device *dev,
 274                          struct device_attribute *attr,
 275                          char *buf)
 276{
 277        struct hda_codec *codec = dev_get_drvdata(dev);
 278        int i, len = 0;
 279        mutex_lock(&codec->user_mutex);
 280        for (i = 0; i < codec->hints.used; i++) {
 281                struct hda_hint *hint = snd_array_elem(&codec->hints, i);
 282                len += snprintf(buf + len, PAGE_SIZE - len,
 283                                "%s = %s\n", hint->key, hint->val);
 284        }
 285        mutex_unlock(&codec->user_mutex);
 286        return len;
 287}
 288
 289static struct hda_hint *get_hint(struct hda_codec *codec, const char *key)
 290{
 291        int i;
 292
 293        for (i = 0; i < codec->hints.used; i++) {
 294                struct hda_hint *hint = snd_array_elem(&codec->hints, i);
 295                if (!strcmp(hint->key, key))
 296                        return hint;
 297        }
 298        return NULL;
 299}
 300
 301static void remove_trail_spaces(char *str)
 302{
 303        char *p;
 304        if (!*str)
 305                return;
 306        p = str + strlen(str) - 1;
 307        for (; isspace(*p); p--) {
 308                *p = 0;
 309                if (p == str)
 310                        return;
 311        }
 312}
 313
 314#define MAX_HINTS       1024
 315
 316static int parse_hints(struct hda_codec *codec, const char *buf)
 317{
 318        char *key, *val;
 319        struct hda_hint *hint;
 320        int err = 0;
 321
 322        buf = skip_spaces(buf);
 323        if (!*buf || *buf == '#' || *buf == '\n')
 324                return 0;
 325        if (*buf == '=')
 326                return -EINVAL;
 327        key = kstrndup_noeol(buf, 1024);
 328        if (!key)
 329                return -ENOMEM;
 330        /* extract key and val */
 331        val = strchr(key, '=');
 332        if (!val) {
 333                kfree(key);
 334                return -EINVAL;
 335        }
 336        *val++ = 0;
 337        val = skip_spaces(val);
 338        remove_trail_spaces(key);
 339        remove_trail_spaces(val);
 340        mutex_lock(&codec->user_mutex);
 341        hint = get_hint(codec, key);
 342        if (hint) {
 343                /* replace */
 344                kfree(hint->key);
 345                hint->key = key;
 346                hint->val = val;
 347                goto unlock;
 348        }
 349        /* allocate a new hint entry */
 350        if (codec->hints.used >= MAX_HINTS)
 351                hint = NULL;
 352        else
 353                hint = snd_array_new(&codec->hints);
 354        if (hint) {
 355                hint->key = key;
 356                hint->val = val;
 357        } else {
 358                err = -ENOMEM;
 359        }
 360 unlock:
 361        mutex_unlock(&codec->user_mutex);
 362        if (err)
 363                kfree(key);
 364        return err;
 365}
 366
 367static ssize_t hints_store(struct device *dev,
 368                           struct device_attribute *attr,
 369                           const char *buf, size_t count)
 370{
 371        struct hda_codec *codec = dev_get_drvdata(dev);
 372        int err = parse_hints(codec, buf);
 373        if (err < 0)
 374                return err;
 375        return count;
 376}
 377
 378static ssize_t user_pin_configs_show(struct device *dev,
 379                                     struct device_attribute *attr,
 380                                     char *buf)
 381{
 382        struct hda_codec *codec = dev_get_drvdata(dev);
 383        return pin_configs_show(codec, &codec->user_pins, buf);
 384}
 385
 386#define MAX_PIN_CONFIGS         32
 387
 388static int parse_user_pin_configs(struct hda_codec *codec, const char *buf)
 389{
 390        int nid, cfg, err;
 391
 392        if (sscanf(buf, "%i %i", &nid, &cfg) != 2)
 393                return -EINVAL;
 394        if (!nid)
 395                return -EINVAL;
 396        mutex_lock(&codec->user_mutex);
 397        err = snd_hda_add_pincfg(codec, &codec->user_pins, nid, cfg);
 398        mutex_unlock(&codec->user_mutex);
 399        return err;
 400}
 401
 402static ssize_t user_pin_configs_store(struct device *dev,
 403                                      struct device_attribute *attr,
 404                                      const char *buf, size_t count)
 405{
 406        struct hda_codec *codec = dev_get_drvdata(dev);
 407        int err = parse_user_pin_configs(codec, buf);
 408        if (err < 0)
 409                return err;
 410        return count;
 411}
 412
 413/* sysfs attributes exposed only when CONFIG_SND_HDA_RECONFIG=y */
 414static DEVICE_ATTR_RW(init_verbs);
 415static DEVICE_ATTR_RW(hints);
 416static DEVICE_ATTR_RW(user_pin_configs);
 417static DEVICE_ATTR_WO(reconfig);
 418static DEVICE_ATTR_WO(clear);
 419
 420/**
 421 * snd_hda_get_hint - Look for hint string
 422 * @codec: the HDA codec
 423 * @key: the hint key string
 424 *
 425 * Look for a hint key/value pair matching with the given key string
 426 * and returns the value string.  If nothing found, returns NULL.
 427 */
 428const char *snd_hda_get_hint(struct hda_codec *codec, const char *key)
 429{
 430        struct hda_hint *hint = get_hint(codec, key);
 431        return hint ? hint->val : NULL;
 432}
 433EXPORT_SYMBOL_GPL(snd_hda_get_hint);
 434
 435/**
 436 * snd_hda_get_bool_hint - Get a boolean hint value
 437 * @codec: the HDA codec
 438 * @key: the hint key string
 439 *
 440 * Look for a hint key/value pair matching with the given key string
 441 * and returns a boolean value parsed from the value.  If no matching
 442 * key is found, return a negative value.
 443 */
 444int snd_hda_get_bool_hint(struct hda_codec *codec, const char *key)
 445{
 446        const char *p;
 447        int ret;
 448
 449        mutex_lock(&codec->user_mutex);
 450        p = snd_hda_get_hint(codec, key);
 451        if (!p || !*p)
 452                ret = -ENOENT;
 453        else {
 454                switch (toupper(*p)) {
 455                case 'T': /* true */
 456                case 'Y': /* yes */
 457                case '1':
 458                        ret = 1;
 459                        break;
 460                default:
 461                        ret = 0;
 462                        break;
 463                }
 464        }
 465        mutex_unlock(&codec->user_mutex);
 466        return ret;
 467}
 468EXPORT_SYMBOL_GPL(snd_hda_get_bool_hint);
 469
 470/**
 471 * snd_hda_get_int_hint - Get an integer hint value
 472 * @codec: the HDA codec
 473 * @key: the hint key string
 474 * @valp: pointer to store a value
 475 *
 476 * Look for a hint key/value pair matching with the given key string
 477 * and stores the integer value to @valp.  If no matching key is found,
 478 * return a negative error code.  Otherwise it returns zero.
 479 */
 480int snd_hda_get_int_hint(struct hda_codec *codec, const char *key, int *valp)
 481{
 482        const char *p;
 483        unsigned long val;
 484        int ret;
 485
 486        mutex_lock(&codec->user_mutex);
 487        p = snd_hda_get_hint(codec, key);
 488        if (!p)
 489                ret = -ENOENT;
 490        else if (kstrtoul(p, 0, &val))
 491                ret = -EINVAL;
 492        else {
 493                *valp = val;
 494                ret = 0;
 495        }
 496        mutex_unlock(&codec->user_mutex);
 497        return ret;
 498}
 499EXPORT_SYMBOL_GPL(snd_hda_get_int_hint);
 500#endif /* CONFIG_SND_HDA_RECONFIG */
 501
 502/*
 503 * common sysfs attributes
 504 */
 505#ifdef CONFIG_SND_HDA_RECONFIG
 506#define RECONFIG_DEVICE_ATTR(name)      DEVICE_ATTR_RW(name)
 507#else
 508#define RECONFIG_DEVICE_ATTR(name)      DEVICE_ATTR_RO(name)
 509#endif
 510static RECONFIG_DEVICE_ATTR(vendor_id);
 511static RECONFIG_DEVICE_ATTR(subsystem_id);
 512static RECONFIG_DEVICE_ATTR(revision_id);
 513static DEVICE_ATTR_RO(afg);
 514static DEVICE_ATTR_RO(mfg);
 515static RECONFIG_DEVICE_ATTR(vendor_name);
 516static RECONFIG_DEVICE_ATTR(chip_name);
 517static RECONFIG_DEVICE_ATTR(modelname);
 518static DEVICE_ATTR_RO(init_pin_configs);
 519static DEVICE_ATTR_RO(driver_pin_configs);
 520
 521
 522#ifdef CONFIG_SND_HDA_PATCH_LOADER
 523
 524/* parser mode */
 525enum {
 526        LINE_MODE_NONE,
 527        LINE_MODE_CODEC,
 528        LINE_MODE_MODEL,
 529        LINE_MODE_PINCFG,
 530        LINE_MODE_VERB,
 531        LINE_MODE_HINT,
 532        LINE_MODE_VENDOR_ID,
 533        LINE_MODE_SUBSYSTEM_ID,
 534        LINE_MODE_REVISION_ID,
 535        LINE_MODE_CHIP_NAME,
 536        NUM_LINE_MODES,
 537};
 538
 539static inline int strmatch(const char *a, const char *b)
 540{
 541        return strncasecmp(a, b, strlen(b)) == 0;
 542}
 543
 544/* parse the contents after the line "[codec]"
 545 * accept only the line with three numbers, and assign the current codec
 546 */
 547static void parse_codec_mode(char *buf, struct hda_bus *bus,
 548                             struct hda_codec **codecp)
 549{
 550        int vendorid, subid, caddr;
 551        struct hda_codec *codec;
 552
 553        *codecp = NULL;
 554        if (sscanf(buf, "%i %i %i", &vendorid, &subid, &caddr) == 3) {
 555                list_for_each_codec(codec, bus) {
 556                        if ((vendorid <= 0 || codec->core.vendor_id == vendorid) &&
 557                            (subid <= 0 || codec->core.subsystem_id == subid) &&
 558                            codec->core.addr == caddr) {
 559                                *codecp = codec;
 560                                break;
 561                        }
 562                }
 563        }
 564}
 565
 566/* parse the contents after the other command tags, [pincfg], [verb],
 567 * [vendor_id], [subsystem_id], [revision_id], [chip_name], [hint] and [model]
 568 * just pass to the sysfs helper (only when any codec was specified)
 569 */
 570static void parse_pincfg_mode(char *buf, struct hda_bus *bus,
 571                              struct hda_codec **codecp)
 572{
 573        parse_user_pin_configs(*codecp, buf);
 574}
 575
 576static void parse_verb_mode(char *buf, struct hda_bus *bus,
 577                            struct hda_codec **codecp)
 578{
 579        parse_init_verbs(*codecp, buf);
 580}
 581
 582static void parse_hint_mode(char *buf, struct hda_bus *bus,
 583                            struct hda_codec **codecp)
 584{
 585        parse_hints(*codecp, buf);
 586}
 587
 588static void parse_model_mode(char *buf, struct hda_bus *bus,
 589                             struct hda_codec **codecp)
 590{
 591        kfree((*codecp)->modelname);
 592        (*codecp)->modelname = kstrdup(buf, GFP_KERNEL);
 593}
 594
 595static void parse_chip_name_mode(char *buf, struct hda_bus *bus,
 596                                 struct hda_codec **codecp)
 597{
 598        snd_hda_codec_set_name(*codecp, buf);
 599}
 600
 601#define DEFINE_PARSE_ID_MODE(name) \
 602static void parse_##name##_mode(char *buf, struct hda_bus *bus, \
 603                                 struct hda_codec **codecp) \
 604{ \
 605        unsigned long val; \
 606        if (!kstrtoul(buf, 0, &val)) \
 607                (*codecp)->core.name = val; \
 608}
 609
 610DEFINE_PARSE_ID_MODE(vendor_id);
 611DEFINE_PARSE_ID_MODE(subsystem_id);
 612DEFINE_PARSE_ID_MODE(revision_id);
 613
 614
 615struct hda_patch_item {
 616        const char *tag;
 617        const char *alias;
 618        void (*parser)(char *buf, struct hda_bus *bus, struct hda_codec **retc);
 619};
 620
 621static struct hda_patch_item patch_items[NUM_LINE_MODES] = {
 622        [LINE_MODE_CODEC] = {
 623                .tag = "[codec]",
 624                .parser = parse_codec_mode,
 625        },
 626        [LINE_MODE_MODEL] = {
 627                .tag = "[model]",
 628                .parser = parse_model_mode,
 629        },
 630        [LINE_MODE_VERB] = {
 631                .tag = "[verb]",
 632                .alias = "[init_verbs]",
 633                .parser = parse_verb_mode,
 634        },
 635        [LINE_MODE_PINCFG] = {
 636                .tag = "[pincfg]",
 637                .alias = "[user_pin_configs]",
 638                .parser = parse_pincfg_mode,
 639        },
 640        [LINE_MODE_HINT] = {
 641                .tag = "[hint]",
 642                .alias = "[hints]",
 643                .parser = parse_hint_mode
 644        },
 645        [LINE_MODE_VENDOR_ID] = {
 646                .tag = "[vendor_id]",
 647                .parser = parse_vendor_id_mode,
 648        },
 649        [LINE_MODE_SUBSYSTEM_ID] = {
 650                .tag = "[subsystem_id]",
 651                .parser = parse_subsystem_id_mode,
 652        },
 653        [LINE_MODE_REVISION_ID] = {
 654                .tag = "[revision_id]",
 655                .parser = parse_revision_id_mode,
 656        },
 657        [LINE_MODE_CHIP_NAME] = {
 658                .tag = "[chip_name]",
 659                .parser = parse_chip_name_mode,
 660        },
 661};
 662
 663/* check the line starting with '[' -- change the parser mode accodingly */
 664static int parse_line_mode(char *buf, struct hda_bus *bus)
 665{
 666        int i;
 667        for (i = 0; i < ARRAY_SIZE(patch_items); i++) {
 668                if (!patch_items[i].tag)
 669                        continue;
 670                if (strmatch(buf, patch_items[i].tag))
 671                        return i;
 672                if (patch_items[i].alias && strmatch(buf, patch_items[i].alias))
 673                        return i;
 674        }
 675        return LINE_MODE_NONE;
 676}
 677
 678/* copy one line from the buffer in fw, and update the fields in fw
 679 * return zero if it reaches to the end of the buffer, or non-zero
 680 * if successfully copied a line
 681 *
 682 * the spaces at the beginning and the end of the line are stripped
 683 */
 684static int get_line_from_fw(char *buf, int size, size_t *fw_size_p,
 685                            const void **fw_data_p)
 686{
 687        int len;
 688        size_t fw_size = *fw_size_p;
 689        const char *p = *fw_data_p;
 690
 691        while (isspace(*p) && fw_size) {
 692                p++;
 693                fw_size--;
 694        }
 695        if (!fw_size)
 696                return 0;
 697
 698        for (len = 0; len < fw_size; len++) {
 699                if (!*p)
 700                        break;
 701                if (*p == '\n') {
 702                        p++;
 703                        len++;
 704                        break;
 705                }
 706                if (len < size)
 707                        *buf++ = *p++;
 708        }
 709        *buf = 0;
 710        *fw_size_p = fw_size - len;
 711        *fw_data_p = p;
 712        remove_trail_spaces(buf);
 713        return 1;
 714}
 715
 716/**
 717 * snd_hda_load_patch - load a "patch" firmware file and parse it
 718 * @bus: HD-audio bus
 719 * @fw_size: the firmware byte size
 720 * @fw_buf: the firmware data
 721 */
 722int snd_hda_load_patch(struct hda_bus *bus, size_t fw_size, const void *fw_buf)
 723{
 724        char buf[128];
 725        struct hda_codec *codec;
 726        int line_mode;
 727
 728        line_mode = LINE_MODE_NONE;
 729        codec = NULL;
 730        while (get_line_from_fw(buf, sizeof(buf) - 1, &fw_size, &fw_buf)) {
 731                if (!*buf || *buf == '#' || *buf == '\n')
 732                        continue;
 733                if (*buf == '[')
 734                        line_mode = parse_line_mode(buf, bus);
 735                else if (patch_items[line_mode].parser &&
 736                         (codec || line_mode <= LINE_MODE_CODEC))
 737                        patch_items[line_mode].parser(buf, bus, &codec);
 738        }
 739        return 0;
 740}
 741EXPORT_SYMBOL_GPL(snd_hda_load_patch);
 742#endif /* CONFIG_SND_HDA_PATCH_LOADER */
 743
 744/*
 745 * sysfs entries
 746 */
 747static struct attribute *hda_dev_attrs[] = {
 748        &dev_attr_vendor_id.attr,
 749        &dev_attr_subsystem_id.attr,
 750        &dev_attr_revision_id.attr,
 751        &dev_attr_afg.attr,
 752        &dev_attr_mfg.attr,
 753        &dev_attr_vendor_name.attr,
 754        &dev_attr_chip_name.attr,
 755        &dev_attr_modelname.attr,
 756        &dev_attr_init_pin_configs.attr,
 757        &dev_attr_driver_pin_configs.attr,
 758#ifdef CONFIG_PM
 759        &dev_attr_power_on_acct.attr,
 760        &dev_attr_power_off_acct.attr,
 761#endif
 762#ifdef CONFIG_SND_HDA_RECONFIG
 763        &dev_attr_init_verbs.attr,
 764        &dev_attr_hints.attr,
 765        &dev_attr_user_pin_configs.attr,
 766        &dev_attr_reconfig.attr,
 767        &dev_attr_clear.attr,
 768#endif
 769        NULL
 770};
 771
 772static struct attribute_group hda_dev_attr_group = {
 773        .attrs  = hda_dev_attrs,
 774};
 775
 776const struct attribute_group *snd_hda_dev_attr_groups[] = {
 777        &hda_dev_attr_group,
 778        NULL
 779};
 780
 781void snd_hda_sysfs_init(struct hda_codec *codec)
 782{
 783        mutex_init(&codec->user_mutex);
 784#ifdef CONFIG_SND_HDA_RECONFIG
 785        snd_array_init(&codec->init_verbs, sizeof(struct hda_verb), 32);
 786        snd_array_init(&codec->hints, sizeof(struct hda_hint), 32);
 787        snd_array_init(&codec->user_pins, sizeof(struct hda_pincfg), 16);
 788#endif
 789}
 790
 791void snd_hda_sysfs_clear(struct hda_codec *codec)
 792{
 793#ifdef CONFIG_SND_HDA_RECONFIG
 794        int i;
 795
 796        /* clear init verbs */
 797        snd_array_free(&codec->init_verbs);
 798        /* clear hints */
 799        for (i = 0; i < codec->hints.used; i++) {
 800                struct hda_hint *hint = snd_array_elem(&codec->hints, i);
 801                kfree(hint->key); /* we don't need to free hint->val */
 802        }
 803        snd_array_free(&codec->hints);
 804        snd_array_free(&codec->user_pins);
 805#endif
 806}
 807