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