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 */ 23 struct hda_hint { 24 const char *key; 25 const char *val; /* contained in the same alloc as key */ 26 }; 27 28 #ifdef CONFIG_PM 29 static 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 38 static 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 47 static DEVICE_ATTR_RO(power_on_acct); 48 static DEVICE_ATTR_RO(power_off_acct); 49 #endif /* CONFIG_PM */ 50 51 #define CODEC_INFO_SHOW(type, field) \ 52 static 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) \ 61 static 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 70 CODEC_INFO_SHOW(vendor_id, core.vendor_id); 71 CODEC_INFO_SHOW(subsystem_id, core.subsystem_id); 72 CODEC_INFO_SHOW(revision_id, core.revision_id); 73 CODEC_INFO_SHOW(afg, core.afg); 74 CODEC_INFO_SHOW(mfg, core.mfg); 75 CODEC_INFO_STR_SHOW(vendor_name, core.vendor_name); 76 CODEC_INFO_STR_SHOW(chip_name, core.chip_name); 77 CODEC_INFO_STR_SHOW(modelname, modelname); 78 79 static 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 94 static 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 102 static 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 116 static 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 129 static 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 */ 153 static 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) \ 166 static 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) \ 180 static 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 193 CODEC_INFO_STORE(vendor_id, core.vendor_id); 194 CODEC_INFO_STORE(subsystem_id, core.subsystem_id); 195 CODEC_INFO_STORE(revision_id, core.revision_id); 196 CODEC_INFO_STR_STORE(vendor_name, core.vendor_name); 197 CODEC_INFO_STR_STORE(chip_name, core.chip_name); 198 CODEC_INFO_STR_STORE(modelname, modelname); 199 200 #define CODEC_ACTION_STORE(type) \ 201 static 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 212 CODEC_ACTION_STORE(reconfig); 213 CODEC_ACTION_STORE(clear); 214 215 static 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 232 static 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, ¶m) != 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 254 static 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 265 static 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 281 static 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 293 static 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 308 static 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 359 static 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 370 static 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 380 static 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 394 static 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 */ 406 static DEVICE_ATTR_RW(init_verbs); 407 static DEVICE_ATTR_RW(hints); 408 static DEVICE_ATTR_RW(user_pin_configs); 409 static DEVICE_ATTR_WO(reconfig); 410 static 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 */ 420 const 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 } 425 EXPORT_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 */ 436 int 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 } 460 EXPORT_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 */ 472 int 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 } 491 EXPORT_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 502 static RECONFIG_DEVICE_ATTR(vendor_id); 503 static RECONFIG_DEVICE_ATTR(subsystem_id); 504 static RECONFIG_DEVICE_ATTR(revision_id); 505 static DEVICE_ATTR_RO(afg); 506 static DEVICE_ATTR_RO(mfg); 507 static RECONFIG_DEVICE_ATTR(vendor_name); 508 static RECONFIG_DEVICE_ATTR(chip_name); 509 static RECONFIG_DEVICE_ATTR(modelname); 510 static DEVICE_ATTR_RO(init_pin_configs); 511 static DEVICE_ATTR_RO(driver_pin_configs); 512 513 514 #ifdef CONFIG_SND_HDA_PATCH_LOADER 515 516 /* parser mode */ 517 enum { 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 531 static 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 */ 539 static 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 */ 562 static 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 568 static void parse_verb_mode(char *buf, struct hda_bus *bus, 569 struct hda_codec **codecp) 570 { 571 parse_init_verbs(*codecp, buf); 572 } 573 574 static void parse_hint_mode(char *buf, struct hda_bus *bus, 575 struct hda_codec **codecp) 576 { 577 parse_hints(*codecp, buf); 578 } 579 580 static 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 587 static 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) \ 594 static 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 602 DEFINE_PARSE_ID_MODE(vendor_id); 603 DEFINE_PARSE_ID_MODE(subsystem_id); 604 DEFINE_PARSE_ID_MODE(revision_id); 605 606 607 struct 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 613 static 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 */ 656 static 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 */ 676 static 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 */ 714 int 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 } 733 EXPORT_SYMBOL_GPL(snd_hda_load_patch); 734 #endif /* CONFIG_SND_HDA_PATCH_LOADER */ 735 736 /* 737 * sysfs entries 738 */ 739 static 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 764 static struct attribute_group hda_dev_attr_group = { 765 .attrs = hda_dev_attrs, 766 }; 767 768 const struct attribute_group *snd_hda_dev_attr_groups[] = { 769 &hda_dev_attr_group, 770 NULL 771 }; 772 773 void 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 783 void 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