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