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