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