Merge branch 'irq-threaded-for-linus' of git://git.kernel.org/pub/scm/linux/kernel...
[pandora-kernel.git] / sound / pci / hda / hda_hwdep.c
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, &param) != 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 */