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