1 /* 2 * HWDEP Interface for HD-audio codec 3 * 4 * Copyright (c) 2007 Takashi Iwai <tiwai@suse.de> 5 * 6 * This driver is free software; you can redistribute it and/or modify 7 * it under the terms of the GNU General Public License as published by 8 * the Free Software Foundation; either version 2 of the License, or 9 * (at your option) any later version. 10 * 11 * This driver is distributed in the hope that it will be useful, 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 * GNU General Public License for more details. 15 * 16 * You should have received a copy of the GNU General Public License 17 * along with this program; if not, write to the Free Software 18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 19 */ 20 21 #include <linux/init.h> 22 #include <linux/slab.h> 23 #include <linux/pci.h> 24 #include <linux/compat.h> 25 #include <linux/mutex.h> 26 #include <linux/ctype.h> 27 #include <linux/firmware.h> 28 #include <sound/core.h> 29 #include "hda_codec.h" 30 #include "hda_local.h" 31 #include <sound/hda_hwdep.h> 32 #include <sound/minors.h> 33 34 /* hint string pair */ 35 struct hda_hint { 36 const char *key; 37 const char *val; /* contained in the same alloc as key */ 38 }; 39 40 /* 41 * write/read an out-of-bound verb 42 */ 43 static int verb_write_ioctl(struct hda_codec *codec, 44 struct hda_verb_ioctl __user *arg) 45 { 46 u32 verb, res; 47 48 if (get_user(verb, &arg->verb)) 49 return -EFAULT; 50 res = snd_hda_codec_read(codec, verb >> 24, 0, 51 (verb >> 8) & 0xffff, verb & 0xff); 52 if (put_user(res, &arg->res)) 53 return -EFAULT; 54 return 0; 55 } 56 57 static int get_wcap_ioctl(struct hda_codec *codec, 58 struct hda_verb_ioctl __user *arg) 59 { 60 u32 verb, res; 61 62 if (get_user(verb, &arg->verb)) 63 return -EFAULT; 64 res = get_wcaps(codec, verb >> 24); 65 if (put_user(res, &arg->res)) 66 return -EFAULT; 67 return 0; 68 } 69 70 71 /* 72 */ 73 static int hda_hwdep_ioctl(struct snd_hwdep *hw, struct file *file, 74 unsigned int cmd, unsigned long arg) 75 { 76 struct hda_codec *codec = hw->private_data; 77 void __user *argp = (void __user *)arg; 78 79 switch (cmd) { 80 case HDA_IOCTL_PVERSION: 81 return put_user(HDA_HWDEP_VERSION, (int __user *)argp); 82 case HDA_IOCTL_VERB_WRITE: 83 return verb_write_ioctl(codec, argp); 84 case HDA_IOCTL_GET_WCAP: 85 return get_wcap_ioctl(codec, argp); 86 } 87 return -ENOIOCTLCMD; 88 } 89 90 #ifdef CONFIG_COMPAT 91 static int hda_hwdep_ioctl_compat(struct snd_hwdep *hw, struct file *file, 92 unsigned int cmd, unsigned long arg) 93 { 94 return hda_hwdep_ioctl(hw, file, cmd, (unsigned long)compat_ptr(arg)); 95 } 96 #endif 97 98 static int hda_hwdep_open(struct snd_hwdep *hw, struct file *file) 99 { 100 #ifndef CONFIG_SND_DEBUG_VERBOSE 101 if (!capable(CAP_SYS_RAWIO)) 102 return -EACCES; 103 #endif 104 return 0; 105 } 106 107 static void clear_hwdep_elements(struct hda_codec *codec) 108 { 109 int i; 110 111 /* clear init verbs */ 112 snd_array_free(&codec->init_verbs); 113 /* clear hints */ 114 for (i = 0; i < codec->hints.used; i++) { 115 struct hda_hint *hint = snd_array_elem(&codec->hints, i); 116 kfree(hint->key); /* we don't need to free hint->val */ 117 } 118 snd_array_free(&codec->hints); 119 snd_array_free(&codec->user_pins); 120 } 121 122 static void hwdep_free(struct snd_hwdep *hwdep) 123 { 124 clear_hwdep_elements(hwdep->private_data); 125 } 126 127 int /*__devinit*/ snd_hda_create_hwdep(struct hda_codec *codec) 128 { 129 char hwname[16]; 130 struct snd_hwdep *hwdep; 131 int err; 132 133 sprintf(hwname, "HDA Codec %d", codec->addr); 134 err = snd_hwdep_new(codec->bus->card, hwname, codec->addr, &hwdep); 135 if (err < 0) 136 return err; 137 codec->hwdep = hwdep; 138 sprintf(hwdep->name, "HDA Codec %d", codec->addr); 139 hwdep->iface = SNDRV_HWDEP_IFACE_HDA; 140 hwdep->private_data = codec; 141 hwdep->private_free = hwdep_free; 142 hwdep->exclusive = 1; 143 144 hwdep->ops.open = hda_hwdep_open; 145 hwdep->ops.ioctl = hda_hwdep_ioctl; 146 #ifdef CONFIG_COMPAT 147 hwdep->ops.ioctl_compat = hda_hwdep_ioctl_compat; 148 #endif 149 150 snd_array_init(&codec->init_verbs, sizeof(struct hda_verb), 32); 151 snd_array_init(&codec->hints, sizeof(struct hda_hint), 32); 152 snd_array_init(&codec->user_pins, sizeof(struct hda_pincfg), 16); 153 154 return 0; 155 } 156 157 #ifdef CONFIG_SND_HDA_RECONFIG 158 159 /* 160 * sysfs interface 161 */ 162 163 static int clear_codec(struct hda_codec *codec) 164 { 165 int err; 166 167 err = snd_hda_codec_reset(codec); 168 if (err < 0) { 169 snd_printk(KERN_ERR "The codec is being used, can't free.\n"); 170 return err; 171 } 172 clear_hwdep_elements(codec); 173 return 0; 174 } 175 176 static int reconfig_codec(struct hda_codec *codec) 177 { 178 int err; 179 180 snd_hda_power_up(codec); 181 snd_printk(KERN_INFO "hda-codec: reconfiguring\n"); 182 err = snd_hda_codec_reset(codec); 183 if (err < 0) { 184 snd_printk(KERN_ERR 185 "The codec is being used, can't reconfigure.\n"); 186 goto error; 187 } 188 err = snd_hda_codec_configure(codec); 189 if (err < 0) 190 goto error; 191 /* rebuild PCMs */ 192 err = snd_hda_codec_build_pcms(codec); 193 if (err < 0) 194 goto error; 195 /* rebuild mixers */ 196 err = snd_hda_codec_build_controls(codec); 197 if (err < 0) 198 goto error; 199 err = snd_card_register(codec->bus->card); 200 error: 201 snd_hda_power_down(codec); 202 return err; 203 } 204 205 /* 206 * allocate a string at most len chars, and remove the trailing EOL 207 */ 208 static char *kstrndup_noeol(const char *src, size_t len) 209 { 210 char *s = kstrndup(src, len, GFP_KERNEL); 211 char *p; 212 if (!s) 213 return NULL; 214 p = strchr(s, '\n'); 215 if (p) 216 *p = 0; 217 return s; 218 } 219 220 #define CODEC_INFO_SHOW(type) \ 221 static ssize_t type##_show(struct device *dev, \ 222 struct device_attribute *attr, \ 223 char *buf) \ 224 { \ 225 struct snd_hwdep *hwdep = dev_get_drvdata(dev); \ 226 struct hda_codec *codec = hwdep->private_data; \ 227 return sprintf(buf, "0x%x\n", codec->type); \ 228 } 229 230 #define CODEC_INFO_STR_SHOW(type) \ 231 static ssize_t type##_show(struct device *dev, \ 232 struct device_attribute *attr, \ 233 char *buf) \ 234 { \ 235 struct snd_hwdep *hwdep = dev_get_drvdata(dev); \ 236 struct hda_codec *codec = hwdep->private_data; \ 237 return sprintf(buf, "%s\n", \ 238 codec->type ? codec->type : ""); \ 239 } 240 241 CODEC_INFO_SHOW(vendor_id); 242 CODEC_INFO_SHOW(subsystem_id); 243 CODEC_INFO_SHOW(revision_id); 244 CODEC_INFO_SHOW(afg); 245 CODEC_INFO_SHOW(mfg); 246 CODEC_INFO_STR_SHOW(vendor_name); 247 CODEC_INFO_STR_SHOW(chip_name); 248 CODEC_INFO_STR_SHOW(modelname); 249 250 #define CODEC_INFO_STORE(type) \ 251 static ssize_t type##_store(struct device *dev, \ 252 struct device_attribute *attr, \ 253 const char *buf, size_t count) \ 254 { \ 255 struct snd_hwdep *hwdep = dev_get_drvdata(dev); \ 256 struct hda_codec *codec = hwdep->private_data; \ 257 char *after; \ 258 codec->type = simple_strtoul(buf, &after, 0); \ 259 return count; \ 260 } 261 262 #define CODEC_INFO_STR_STORE(type) \ 263 static ssize_t type##_store(struct device *dev, \ 264 struct device_attribute *attr, \ 265 const char *buf, size_t count) \ 266 { \ 267 struct snd_hwdep *hwdep = dev_get_drvdata(dev); \ 268 struct hda_codec *codec = hwdep->private_data; \ 269 char *s = kstrndup_noeol(buf, 64); \ 270 if (!s) \ 271 return -ENOMEM; \ 272 kfree(codec->type); \ 273 codec->type = s; \ 274 return count; \ 275 } 276 277 CODEC_INFO_STORE(vendor_id); 278 CODEC_INFO_STORE(subsystem_id); 279 CODEC_INFO_STORE(revision_id); 280 CODEC_INFO_STR_STORE(vendor_name); 281 CODEC_INFO_STR_STORE(chip_name); 282 CODEC_INFO_STR_STORE(modelname); 283 284 #define CODEC_ACTION_STORE(type) \ 285 static ssize_t type##_store(struct device *dev, \ 286 struct device_attribute *attr, \ 287 const char *buf, size_t count) \ 288 { \ 289 struct snd_hwdep *hwdep = dev_get_drvdata(dev); \ 290 struct hda_codec *codec = hwdep->private_data; \ 291 int err = 0; \ 292 if (*buf) \ 293 err = type##_codec(codec); \ 294 return err < 0 ? err : count; \ 295 } 296 297 CODEC_ACTION_STORE(reconfig); 298 CODEC_ACTION_STORE(clear); 299 300 static ssize_t init_verbs_show(struct device *dev, 301 struct device_attribute *attr, 302 char *buf) 303 { 304 struct snd_hwdep *hwdep = dev_get_drvdata(dev); 305 struct hda_codec *codec = hwdep->private_data; 306 int i, len = 0; 307 for (i = 0; i < codec->init_verbs.used; i++) { 308 struct hda_verb *v = snd_array_elem(&codec->init_verbs, i); 309 len += snprintf(buf + len, PAGE_SIZE - len, 310 "0x%02x 0x%03x 0x%04x\n", 311 v->nid, v->verb, v->param); 312 } 313 return len; 314 } 315 316 static int parse_init_verbs(struct hda_codec *codec, const char *buf) 317 { 318 struct hda_verb *v; 319 int nid, verb, param; 320 321 if (sscanf(buf, "%i %i %i", &nid, &verb, ¶m) != 3) 322 return -EINVAL; 323 if (!nid || !verb) 324 return -EINVAL; 325 v = snd_array_new(&codec->init_verbs); 326 if (!v) 327 return -ENOMEM; 328 v->nid = nid; 329 v->verb = verb; 330 v->param = param; 331 return 0; 332 } 333 334 static ssize_t init_verbs_store(struct device *dev, 335 struct device_attribute *attr, 336 const char *buf, size_t count) 337 { 338 struct snd_hwdep *hwdep = dev_get_drvdata(dev); 339 struct hda_codec *codec = hwdep->private_data; 340 int err = parse_init_verbs(codec, buf); 341 if (err < 0) 342 return err; 343 return count; 344 } 345 346 static ssize_t hints_show(struct device *dev, 347 struct device_attribute *attr, 348 char *buf) 349 { 350 struct snd_hwdep *hwdep = dev_get_drvdata(dev); 351 struct hda_codec *codec = hwdep->private_data; 352 int i, len = 0; 353 for (i = 0; i < codec->hints.used; i++) { 354 struct hda_hint *hint = snd_array_elem(&codec->hints, i); 355 len += snprintf(buf + len, PAGE_SIZE - len, 356 "%s = %s\n", hint->key, hint->val); 357 } 358 return len; 359 } 360 361 static struct hda_hint *get_hint(struct hda_codec *codec, const char *key) 362 { 363 int i; 364 365 for (i = 0; i < codec->hints.used; i++) { 366 struct hda_hint *hint = snd_array_elem(&codec->hints, i); 367 if (!strcmp(hint->key, key)) 368 return hint; 369 } 370 return NULL; 371 } 372 373 static void remove_trail_spaces(char *str) 374 { 375 char *p; 376 if (!*str) 377 return; 378 p = str + strlen(str) - 1; 379 for (; isspace(*p); p--) { 380 *p = 0; 381 if (p == str) 382 return; 383 } 384 } 385 386 #define MAX_HINTS 1024 387 388 static int parse_hints(struct hda_codec *codec, const char *buf) 389 { 390 char *key, *val; 391 struct hda_hint *hint; 392 393 while (isspace(*buf)) 394 buf++; 395 if (!*buf || *buf == '#' || *buf == '\n') 396 return 0; 397 if (*buf == '=') 398 return -EINVAL; 399 key = kstrndup_noeol(buf, 1024); 400 if (!key) 401 return -ENOMEM; 402 /* extract key and val */ 403 val = strchr(key, '='); 404 if (!val) { 405 kfree(key); 406 return -EINVAL; 407 } 408 *val++ = 0; 409 while (isspace(*val)) 410 val++; 411 remove_trail_spaces(key); 412 remove_trail_spaces(val); 413 hint = get_hint(codec, key); 414 if (hint) { 415 /* replace */ 416 kfree(hint->key); 417 hint->key = key; 418 hint->val = val; 419 return 0; 420 } 421 /* allocate a new hint entry */ 422 if (codec->hints.used >= MAX_HINTS) 423 hint = NULL; 424 else 425 hint = snd_array_new(&codec->hints); 426 if (!hint) { 427 kfree(key); 428 return -ENOMEM; 429 } 430 hint->key = key; 431 hint->val = val; 432 return 0; 433 } 434 435 static ssize_t hints_store(struct device *dev, 436 struct device_attribute *attr, 437 const char *buf, size_t count) 438 { 439 struct snd_hwdep *hwdep = dev_get_drvdata(dev); 440 struct hda_codec *codec = hwdep->private_data; 441 int err = parse_hints(codec, buf); 442 if (err < 0) 443 return err; 444 return count; 445 } 446 447 static ssize_t pin_configs_show(struct hda_codec *codec, 448 struct snd_array *list, 449 char *buf) 450 { 451 int i, len = 0; 452 for (i = 0; i < list->used; i++) { 453 struct hda_pincfg *pin = snd_array_elem(list, i); 454 len += sprintf(buf + len, "0x%02x 0x%08x\n", 455 pin->nid, pin->cfg); 456 } 457 return len; 458 } 459 460 static ssize_t init_pin_configs_show(struct device *dev, 461 struct device_attribute *attr, 462 char *buf) 463 { 464 struct snd_hwdep *hwdep = dev_get_drvdata(dev); 465 struct hda_codec *codec = hwdep->private_data; 466 return pin_configs_show(codec, &codec->init_pins, buf); 467 } 468 469 static ssize_t user_pin_configs_show(struct device *dev, 470 struct device_attribute *attr, 471 char *buf) 472 { 473 struct snd_hwdep *hwdep = dev_get_drvdata(dev); 474 struct hda_codec *codec = hwdep->private_data; 475 return pin_configs_show(codec, &codec->user_pins, buf); 476 } 477 478 static ssize_t driver_pin_configs_show(struct device *dev, 479 struct device_attribute *attr, 480 char *buf) 481 { 482 struct snd_hwdep *hwdep = dev_get_drvdata(dev); 483 struct hda_codec *codec = hwdep->private_data; 484 return pin_configs_show(codec, &codec->driver_pins, buf); 485 } 486 487 #define MAX_PIN_CONFIGS 32 488 489 static int parse_user_pin_configs(struct hda_codec *codec, const char *buf) 490 { 491 int nid, cfg; 492 493 if (sscanf(buf, "%i %i", &nid, &cfg) != 2) 494 return -EINVAL; 495 if (!nid) 496 return -EINVAL; 497 return snd_hda_add_pincfg(codec, &codec->user_pins, nid, cfg); 498 } 499 500 static ssize_t user_pin_configs_store(struct device *dev, 501 struct device_attribute *attr, 502 const char *buf, size_t count) 503 { 504 struct snd_hwdep *hwdep = dev_get_drvdata(dev); 505 struct hda_codec *codec = hwdep->private_data; 506 int err = parse_user_pin_configs(codec, buf); 507 if (err < 0) 508 return err; 509 return count; 510 } 511 512 #define CODEC_ATTR_RW(type) \ 513 __ATTR(type, 0644, type##_show, type##_store) 514 #define CODEC_ATTR_RO(type) \ 515 __ATTR_RO(type) 516 #define CODEC_ATTR_WO(type) \ 517 __ATTR(type, 0200, NULL, type##_store) 518 519 static struct device_attribute codec_attrs[] = { 520 CODEC_ATTR_RW(vendor_id), 521 CODEC_ATTR_RW(subsystem_id), 522 CODEC_ATTR_RW(revision_id), 523 CODEC_ATTR_RO(afg), 524 CODEC_ATTR_RO(mfg), 525 CODEC_ATTR_RW(vendor_name), 526 CODEC_ATTR_RW(chip_name), 527 CODEC_ATTR_RW(modelname), 528 CODEC_ATTR_RW(init_verbs), 529 CODEC_ATTR_RW(hints), 530 CODEC_ATTR_RO(init_pin_configs), 531 CODEC_ATTR_RW(user_pin_configs), 532 CODEC_ATTR_RO(driver_pin_configs), 533 CODEC_ATTR_WO(reconfig), 534 CODEC_ATTR_WO(clear), 535 }; 536 537 /* 538 * create sysfs files on hwdep directory 539 */ 540 int snd_hda_hwdep_add_sysfs(struct hda_codec *codec) 541 { 542 struct snd_hwdep *hwdep = codec->hwdep; 543 int i; 544 545 for (i = 0; i < ARRAY_SIZE(codec_attrs); i++) 546 snd_add_device_sysfs_file(SNDRV_DEVICE_TYPE_HWDEP, hwdep->card, 547 hwdep->device, &codec_attrs[i]); 548 return 0; 549 } 550 551 /* 552 * Look for hint string 553 */ 554 const char *snd_hda_get_hint(struct hda_codec *codec, const char *key) 555 { 556 struct hda_hint *hint = get_hint(codec, key); 557 return hint ? hint->val : NULL; 558 } 559 EXPORT_SYMBOL_HDA(snd_hda_get_hint); 560 561 int snd_hda_get_bool_hint(struct hda_codec *codec, const char *key) 562 { 563 const char *p = snd_hda_get_hint(codec, key); 564 if (!p || !*p) 565 return -ENOENT; 566 switch (toupper(*p)) { 567 case 'T': /* true */ 568 case 'Y': /* yes */ 569 case '1': 570 return 1; 571 } 572 return 0; 573 } 574 EXPORT_SYMBOL_HDA(snd_hda_get_bool_hint); 575 576 #endif /* CONFIG_SND_HDA_RECONFIG */ 577 578 #ifdef CONFIG_SND_HDA_PATCH_LOADER 579 580 /* parser mode */ 581 enum { 582 LINE_MODE_NONE, 583 LINE_MODE_CODEC, 584 LINE_MODE_MODEL, 585 LINE_MODE_PINCFG, 586 LINE_MODE_VERB, 587 LINE_MODE_HINT, 588 NUM_LINE_MODES, 589 }; 590 591 static inline int strmatch(const char *a, const char *b) 592 { 593 return strnicmp(a, b, strlen(b)) == 0; 594 } 595 596 /* parse the contents after the line "[codec]" 597 * accept only the line with three numbers, and assign the current codec 598 */ 599 static void parse_codec_mode(char *buf, struct hda_bus *bus, 600 struct hda_codec **codecp) 601 { 602 unsigned int vendorid, subid, caddr; 603 struct hda_codec *codec; 604 605 *codecp = NULL; 606 if (sscanf(buf, "%i %i %i", &vendorid, &subid, &caddr) == 3) { 607 list_for_each_entry(codec, &bus->codec_list, list) { 608 if (codec->addr == caddr) { 609 *codecp = codec; 610 break; 611 } 612 } 613 } 614 } 615 616 /* parse the contents after the other command tags, [pincfg], [verb], 617 * [hint] and [model] 618 * just pass to the sysfs helper (only when any codec was specified) 619 */ 620 static void parse_pincfg_mode(char *buf, struct hda_bus *bus, 621 struct hda_codec **codecp) 622 { 623 if (!*codecp) 624 return; 625 parse_user_pin_configs(*codecp, buf); 626 } 627 628 static void parse_verb_mode(char *buf, struct hda_bus *bus, 629 struct hda_codec **codecp) 630 { 631 if (!*codecp) 632 return; 633 parse_init_verbs(*codecp, buf); 634 } 635 636 static void parse_hint_mode(char *buf, struct hda_bus *bus, 637 struct hda_codec **codecp) 638 { 639 if (!*codecp) 640 return; 641 parse_hints(*codecp, buf); 642 } 643 644 static void parse_model_mode(char *buf, struct hda_bus *bus, 645 struct hda_codec **codecp) 646 { 647 if (!*codecp) 648 return; 649 kfree((*codecp)->modelname); 650 (*codecp)->modelname = kstrdup(buf, GFP_KERNEL); 651 } 652 653 struct hda_patch_item { 654 const char *tag; 655 void (*parser)(char *buf, struct hda_bus *bus, struct hda_codec **retc); 656 }; 657 658 static struct hda_patch_item patch_items[NUM_LINE_MODES] = { 659 [LINE_MODE_CODEC] = { "[codec]", parse_codec_mode }, 660 [LINE_MODE_MODEL] = { "[model]", parse_model_mode }, 661 [LINE_MODE_VERB] = { "[verb]", parse_verb_mode }, 662 [LINE_MODE_PINCFG] = { "[pincfg]", parse_pincfg_mode }, 663 [LINE_MODE_HINT] = { "[hint]", parse_hint_mode }, 664 }; 665 666 /* check the line starting with '[' -- change the parser mode accodingly */ 667 static int parse_line_mode(char *buf, struct hda_bus *bus) 668 { 669 int i; 670 for (i = 0; i < ARRAY_SIZE(patch_items); i++) { 671 if (!patch_items[i].tag) 672 continue; 673 if (strmatch(buf, patch_items[i].tag)) 674 return i; 675 } 676 return LINE_MODE_NONE; 677 } 678 679 /* copy one line from the buffer in fw, and update the fields in fw 680 * return zero if it reaches to the end of the buffer, or non-zero 681 * if successfully copied a line 682 * 683 * the spaces at the beginning and the end of the line are stripped 684 */ 685 static int get_line_from_fw(char *buf, int size, struct firmware *fw) 686 { 687 int len; 688 const char *p = fw->data; 689 while (isspace(*p) && fw->size) { 690 p++; 691 fw->size--; 692 } 693 if (!fw->size) 694 return 0; 695 if (size < fw->size) 696 size = fw->size; 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 -= len; 711 fw->data = p; 712 remove_trail_spaces(buf); 713 return 1; 714 } 715 716 /* 717 * load a "patch" firmware file and parse it 718 */ 719 int snd_hda_load_patch(struct hda_bus *bus, const char *patch) 720 { 721 int err; 722 const struct firmware *fw; 723 struct firmware tmp; 724 char buf[128]; 725 struct hda_codec *codec; 726 int line_mode; 727 struct device *dev = bus->card->dev; 728 729 if (snd_BUG_ON(!dev)) 730 return -ENODEV; 731 err = request_firmware(&fw, patch, dev); 732 if (err < 0) { 733 printk(KERN_ERR "hda-codec: Cannot load the patch '%s'\n", 734 patch); 735 return err; 736 } 737 738 tmp = *fw; 739 line_mode = LINE_MODE_NONE; 740 codec = NULL; 741 while (get_line_from_fw(buf, sizeof(buf) - 1, &tmp)) { 742 if (!*buf || *buf == '#' || *buf == '\n') 743 continue; 744 if (*buf == '[') 745 line_mode = parse_line_mode(buf, bus); 746 else if (patch_items[line_mode].parser) 747 patch_items[line_mode].parser(buf, bus, &codec); 748 } 749 release_firmware(fw); 750 return 0; 751 } 752 EXPORT_SYMBOL_HDA(snd_hda_load_patch); 753 #endif /* CONFIG_SND_HDA_PATCH_LOADER */ 754