1
2
3
4
5
6
7
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
24struct hda_hint {
25 const char *key;
26 const char *val;
27};
28
29#ifdef CONFIG_PM
30static 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 sprintf(buf, "%u\n", jiffies_to_msecs(codec->power_on_acct));
37}
38
39static 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 sprintf(buf, "%u\n", jiffies_to_msecs(codec->power_off_acct));
46}
47
48static DEVICE_ATTR_RO(power_on_acct);
49static DEVICE_ATTR_RO(power_off_acct);
50#endif
51
52#define CODEC_INFO_SHOW(type, field) \
53static 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 sprintf(buf, "0x%x\n", codec->field); \
59}
60
61#define CODEC_INFO_STR_SHOW(type, field) \
62static 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 sprintf(buf, "%s\n", \
68 codec->field ? codec->field : ""); \
69}
70
71CODEC_INFO_SHOW(vendor_id, core.vendor_id);
72CODEC_INFO_SHOW(subsystem_id, core.subsystem_id);
73CODEC_INFO_SHOW(revision_id, core.revision_id);
74CODEC_INFO_SHOW(afg, core.afg);
75CODEC_INFO_SHOW(mfg, core.mfg);
76CODEC_INFO_STR_SHOW(vendor_name, core.vendor_name);
77CODEC_INFO_STR_SHOW(chip_name, core.chip_name);
78CODEC_INFO_STR_SHOW(modelname, modelname);
79
80static 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 += sprintf(buf + len, "0x%02x 0x%08x\n",
89 pin->nid, pin->cfg);
90 }
91 mutex_unlock(&codec->user_mutex);
92 return len;
93}
94
95static 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
103static 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
115
116
117static 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
130static 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
153
154static 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) \
167static 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) \
181static 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
194CODEC_INFO_STORE(vendor_id, core.vendor_id);
195CODEC_INFO_STORE(subsystem_id, core.subsystem_id);
196CODEC_INFO_STORE(revision_id, core.revision_id);
197CODEC_INFO_STR_STORE(vendor_name, core.vendor_name);
198CODEC_INFO_STR_STORE(chip_name, core.chip_name);
199CODEC_INFO_STR_STORE(modelname, modelname);
200
201#define CODEC_ACTION_STORE(type) \
202static 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
213CODEC_ACTION_STORE(reconfig);
214CODEC_ACTION_STORE(clear);
215
216static 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 += scnprintf(buf + len, PAGE_SIZE - len,
226 "0x%02x 0x%03x 0x%04x\n",
227 v->nid, v->verb, v->param);
228 }
229 mutex_unlock(&codec->user_mutex);
230 return len;
231}
232
233static int parse_init_verbs(struct hda_codec *codec, const char *buf)
234{
235 struct hda_verb *v;
236 int nid, verb, param;
237
238 if (sscanf(buf, "%i %i %i", &nid, &verb, ¶m) != 3)
239 return -EINVAL;
240 if (!nid || !verb)
241 return -EINVAL;
242 mutex_lock(&codec->user_mutex);
243 v = snd_array_new(&codec->init_verbs);
244 if (!v) {
245 mutex_unlock(&codec->user_mutex);
246 return -ENOMEM;
247 }
248 v->nid = nid;
249 v->verb = verb;
250 v->param = param;
251 mutex_unlock(&codec->user_mutex);
252 return 0;
253}
254
255static ssize_t init_verbs_store(struct device *dev,
256 struct device_attribute *attr,
257 const char *buf, size_t count)
258{
259 struct hda_codec *codec = dev_get_drvdata(dev);
260 int err = parse_init_verbs(codec, buf);
261 if (err < 0)
262 return err;
263 return count;
264}
265
266static ssize_t hints_show(struct device *dev,
267 struct device_attribute *attr,
268 char *buf)
269{
270 struct hda_codec *codec = dev_get_drvdata(dev);
271 const struct hda_hint *hint;
272 int i, len = 0;
273 mutex_lock(&codec->user_mutex);
274 snd_array_for_each(&codec->hints, i, hint) {
275 len += scnprintf(buf + len, PAGE_SIZE - len,
276 "%s = %s\n", hint->key, hint->val);
277 }
278 mutex_unlock(&codec->user_mutex);
279 return len;
280}
281
282static struct hda_hint *get_hint(struct hda_codec *codec, const char *key)
283{
284 struct hda_hint *hint;
285 int i;
286
287 snd_array_for_each(&codec->hints, i, hint) {
288 if (!strcmp(hint->key, key))
289 return hint;
290 }
291 return NULL;
292}
293
294static void remove_trail_spaces(char *str)
295{
296 char *p;
297 if (!*str)
298 return;
299 p = str + strlen(str) - 1;
300 for (; isspace(*p); p--) {
301 *p = 0;
302 if (p == str)
303 return;
304 }
305}
306
307#define MAX_HINTS 1024
308
309static int parse_hints(struct hda_codec *codec, const char *buf)
310{
311 char *key, *val;
312 struct hda_hint *hint;
313 int err = 0;
314
315 buf = skip_spaces(buf);
316 if (!*buf || *buf == '#' || *buf == '\n')
317 return 0;
318 if (*buf == '=')
319 return -EINVAL;
320 key = kstrndup_noeol(buf, 1024);
321 if (!key)
322 return -ENOMEM;
323
324 val = strchr(key, '=');
325 if (!val) {
326 kfree(key);
327 return -EINVAL;
328 }
329 *val++ = 0;
330 val = skip_spaces(val);
331 remove_trail_spaces(key);
332 remove_trail_spaces(val);
333 mutex_lock(&codec->user_mutex);
334 hint = get_hint(codec, key);
335 if (hint) {
336
337 kfree(hint->key);
338 hint->key = key;
339 hint->val = val;
340 goto unlock;
341 }
342
343 if (codec->hints.used >= MAX_HINTS)
344 hint = NULL;
345 else
346 hint = snd_array_new(&codec->hints);
347 if (hint) {
348 hint->key = key;
349 hint->val = val;
350 } else {
351 err = -ENOMEM;
352 }
353 unlock:
354 mutex_unlock(&codec->user_mutex);
355 if (err)
356 kfree(key);
357 return err;
358}
359
360static ssize_t hints_store(struct device *dev,
361 struct device_attribute *attr,
362 const char *buf, size_t count)
363{
364 struct hda_codec *codec = dev_get_drvdata(dev);
365 int err = parse_hints(codec, buf);
366 if (err < 0)
367 return err;
368 return count;
369}
370
371static ssize_t user_pin_configs_show(struct device *dev,
372 struct device_attribute *attr,
373 char *buf)
374{
375 struct hda_codec *codec = dev_get_drvdata(dev);
376 return pin_configs_show(codec, &codec->user_pins, buf);
377}
378
379#define MAX_PIN_CONFIGS 32
380
381static int parse_user_pin_configs(struct hda_codec *codec, const char *buf)
382{
383 int nid, cfg, err;
384
385 if (sscanf(buf, "%i %i", &nid, &cfg) != 2)
386 return -EINVAL;
387 if (!nid)
388 return -EINVAL;
389 mutex_lock(&codec->user_mutex);
390 err = snd_hda_add_pincfg(codec, &codec->user_pins, nid, cfg);
391 mutex_unlock(&codec->user_mutex);
392 return err;
393}
394
395static ssize_t user_pin_configs_store(struct device *dev,
396 struct device_attribute *attr,
397 const char *buf, size_t count)
398{
399 struct hda_codec *codec = dev_get_drvdata(dev);
400 int err = parse_user_pin_configs(codec, buf);
401 if (err < 0)
402 return err;
403 return count;
404}
405
406
407static DEVICE_ATTR_RW(init_verbs);
408static DEVICE_ATTR_RW(hints);
409static DEVICE_ATTR_RW(user_pin_configs);
410static DEVICE_ATTR_WO(reconfig);
411static DEVICE_ATTR_WO(clear);
412
413
414
415
416
417
418
419
420
421const char *snd_hda_get_hint(struct hda_codec *codec, const char *key)
422{
423 struct hda_hint *hint = get_hint(codec, key);
424 return hint ? hint->val : NULL;
425}
426EXPORT_SYMBOL_GPL(snd_hda_get_hint);
427
428
429
430
431
432
433
434
435
436
437int snd_hda_get_bool_hint(struct hda_codec *codec, const char *key)
438{
439 const char *p;
440 int ret;
441
442 mutex_lock(&codec->user_mutex);
443 p = snd_hda_get_hint(codec, key);
444 if (!p || !*p)
445 ret = -ENOENT;
446 else {
447 switch (toupper(*p)) {
448 case 'T':
449 case 'Y':
450 case '1':
451 ret = 1;
452 break;
453 default:
454 ret = 0;
455 break;
456 }
457 }
458 mutex_unlock(&codec->user_mutex);
459 return ret;
460}
461EXPORT_SYMBOL_GPL(snd_hda_get_bool_hint);
462
463
464
465
466
467
468
469
470
471
472
473int snd_hda_get_int_hint(struct hda_codec *codec, const char *key, int *valp)
474{
475 const char *p;
476 unsigned long val;
477 int ret;
478
479 mutex_lock(&codec->user_mutex);
480 p = snd_hda_get_hint(codec, key);
481 if (!p)
482 ret = -ENOENT;
483 else if (kstrtoul(p, 0, &val))
484 ret = -EINVAL;
485 else {
486 *valp = val;
487 ret = 0;
488 }
489 mutex_unlock(&codec->user_mutex);
490 return ret;
491}
492EXPORT_SYMBOL_GPL(snd_hda_get_int_hint);
493#endif
494
495
496
497
498#ifdef CONFIG_SND_HDA_RECONFIG
499#define RECONFIG_DEVICE_ATTR(name) DEVICE_ATTR_RW(name)
500#else
501#define RECONFIG_DEVICE_ATTR(name) DEVICE_ATTR_RO(name)
502#endif
503static RECONFIG_DEVICE_ATTR(vendor_id);
504static RECONFIG_DEVICE_ATTR(subsystem_id);
505static RECONFIG_DEVICE_ATTR(revision_id);
506static DEVICE_ATTR_RO(afg);
507static DEVICE_ATTR_RO(mfg);
508static RECONFIG_DEVICE_ATTR(vendor_name);
509static RECONFIG_DEVICE_ATTR(chip_name);
510static RECONFIG_DEVICE_ATTR(modelname);
511static DEVICE_ATTR_RO(init_pin_configs);
512static DEVICE_ATTR_RO(driver_pin_configs);
513
514
515#ifdef CONFIG_SND_HDA_PATCH_LOADER
516
517
518enum {
519 LINE_MODE_NONE,
520 LINE_MODE_CODEC,
521 LINE_MODE_MODEL,
522 LINE_MODE_PINCFG,
523 LINE_MODE_VERB,
524 LINE_MODE_HINT,
525 LINE_MODE_VENDOR_ID,
526 LINE_MODE_SUBSYSTEM_ID,
527 LINE_MODE_REVISION_ID,
528 LINE_MODE_CHIP_NAME,
529 NUM_LINE_MODES,
530};
531
532static inline int strmatch(const char *a, const char *b)
533{
534 return strncasecmp(a, b, strlen(b)) == 0;
535}
536
537
538
539
540static void parse_codec_mode(char *buf, struct hda_bus *bus,
541 struct hda_codec **codecp)
542{
543 int vendorid, subid, caddr;
544 struct hda_codec *codec;
545
546 *codecp = NULL;
547 if (sscanf(buf, "%i %i %i", &vendorid, &subid, &caddr) == 3) {
548 list_for_each_codec(codec, bus) {
549 if ((vendorid <= 0 || codec->core.vendor_id == vendorid) &&
550 (subid <= 0 || codec->core.subsystem_id == subid) &&
551 codec->core.addr == caddr) {
552 *codecp = codec;
553 break;
554 }
555 }
556 }
557}
558
559
560
561
562
563static void parse_pincfg_mode(char *buf, struct hda_bus *bus,
564 struct hda_codec **codecp)
565{
566 parse_user_pin_configs(*codecp, buf);
567}
568
569static void parse_verb_mode(char *buf, struct hda_bus *bus,
570 struct hda_codec **codecp)
571{
572 parse_init_verbs(*codecp, buf);
573}
574
575static void parse_hint_mode(char *buf, struct hda_bus *bus,
576 struct hda_codec **codecp)
577{
578 parse_hints(*codecp, buf);
579}
580
581static void parse_model_mode(char *buf, struct hda_bus *bus,
582 struct hda_codec **codecp)
583{
584 kfree((*codecp)->modelname);
585 (*codecp)->modelname = kstrdup(buf, GFP_KERNEL);
586}
587
588static void parse_chip_name_mode(char *buf, struct hda_bus *bus,
589 struct hda_codec **codecp)
590{
591 snd_hda_codec_set_name(*codecp, buf);
592}
593
594#define DEFINE_PARSE_ID_MODE(name) \
595static void parse_##name##_mode(char *buf, struct hda_bus *bus, \
596 struct hda_codec **codecp) \
597{ \
598 unsigned long val; \
599 if (!kstrtoul(buf, 0, &val)) \
600 (*codecp)->core.name = val; \
601}
602
603DEFINE_PARSE_ID_MODE(vendor_id);
604DEFINE_PARSE_ID_MODE(subsystem_id);
605DEFINE_PARSE_ID_MODE(revision_id);
606
607
608struct hda_patch_item {
609 const char *tag;
610 const char *alias;
611 void (*parser)(char *buf, struct hda_bus *bus, struct hda_codec **retc);
612};
613
614static const struct hda_patch_item patch_items[NUM_LINE_MODES] = {
615 [LINE_MODE_CODEC] = {
616 .tag = "[codec]",
617 .parser = parse_codec_mode,
618 },
619 [LINE_MODE_MODEL] = {
620 .tag = "[model]",
621 .parser = parse_model_mode,
622 },
623 [LINE_MODE_VERB] = {
624 .tag = "[verb]",
625 .alias = "[init_verbs]",
626 .parser = parse_verb_mode,
627 },
628 [LINE_MODE_PINCFG] = {
629 .tag = "[pincfg]",
630 .alias = "[user_pin_configs]",
631 .parser = parse_pincfg_mode,
632 },
633 [LINE_MODE_HINT] = {
634 .tag = "[hint]",
635 .alias = "[hints]",
636 .parser = parse_hint_mode
637 },
638 [LINE_MODE_VENDOR_ID] = {
639 .tag = "[vendor_id]",
640 .parser = parse_vendor_id_mode,
641 },
642 [LINE_MODE_SUBSYSTEM_ID] = {
643 .tag = "[subsystem_id]",
644 .parser = parse_subsystem_id_mode,
645 },
646 [LINE_MODE_REVISION_ID] = {
647 .tag = "[revision_id]",
648 .parser = parse_revision_id_mode,
649 },
650 [LINE_MODE_CHIP_NAME] = {
651 .tag = "[chip_name]",
652 .parser = parse_chip_name_mode,
653 },
654};
655
656
657static int parse_line_mode(char *buf, struct hda_bus *bus)
658{
659 int i;
660 for (i = 0; i < ARRAY_SIZE(patch_items); i++) {
661 if (!patch_items[i].tag)
662 continue;
663 if (strmatch(buf, patch_items[i].tag))
664 return i;
665 if (patch_items[i].alias && strmatch(buf, patch_items[i].alias))
666 return i;
667 }
668 return LINE_MODE_NONE;
669}
670
671
672
673
674
675
676
677static int get_line_from_fw(char *buf, int size, size_t *fw_size_p,
678 const void **fw_data_p)
679{
680 int len;
681 size_t fw_size = *fw_size_p;
682 const char *p = *fw_data_p;
683
684 while (isspace(*p) && fw_size) {
685 p++;
686 fw_size--;
687 }
688 if (!fw_size)
689 return 0;
690
691 for (len = 0; len < fw_size; len++) {
692 if (!*p)
693 break;
694 if (*p == '\n') {
695 p++;
696 len++;
697 break;
698 }
699 if (len < size)
700 *buf++ = *p++;
701 }
702 *buf = 0;
703 *fw_size_p = fw_size - len;
704 *fw_data_p = p;
705 remove_trail_spaces(buf);
706 return 1;
707}
708
709
710
711
712
713
714
715int snd_hda_load_patch(struct hda_bus *bus, size_t fw_size, const void *fw_buf)
716{
717 char buf[128];
718 struct hda_codec *codec;
719 int line_mode;
720
721 line_mode = LINE_MODE_NONE;
722 codec = NULL;
723 while (get_line_from_fw(buf, sizeof(buf) - 1, &fw_size, &fw_buf)) {
724 if (!*buf || *buf == '#' || *buf == '\n')
725 continue;
726 if (*buf == '[')
727 line_mode = parse_line_mode(buf, bus);
728 else if (patch_items[line_mode].parser &&
729 (codec || line_mode <= LINE_MODE_CODEC))
730 patch_items[line_mode].parser(buf, bus, &codec);
731 }
732 return 0;
733}
734EXPORT_SYMBOL_GPL(snd_hda_load_patch);
735#endif
736
737
738
739
740static struct attribute *hda_dev_attrs[] = {
741 &dev_attr_vendor_id.attr,
742 &dev_attr_subsystem_id.attr,
743 &dev_attr_revision_id.attr,
744 &dev_attr_afg.attr,
745 &dev_attr_mfg.attr,
746 &dev_attr_vendor_name.attr,
747 &dev_attr_chip_name.attr,
748 &dev_attr_modelname.attr,
749 &dev_attr_init_pin_configs.attr,
750 &dev_attr_driver_pin_configs.attr,
751#ifdef CONFIG_PM
752 &dev_attr_power_on_acct.attr,
753 &dev_attr_power_off_acct.attr,
754#endif
755#ifdef CONFIG_SND_HDA_RECONFIG
756 &dev_attr_init_verbs.attr,
757 &dev_attr_hints.attr,
758 &dev_attr_user_pin_configs.attr,
759 &dev_attr_reconfig.attr,
760 &dev_attr_clear.attr,
761#endif
762 NULL
763};
764
765static const struct attribute_group hda_dev_attr_group = {
766 .attrs = hda_dev_attrs,
767};
768
769const struct attribute_group *snd_hda_dev_attr_groups[] = {
770 &hda_dev_attr_group,
771 NULL
772};
773
774void snd_hda_sysfs_init(struct hda_codec *codec)
775{
776 mutex_init(&codec->user_mutex);
777#ifdef CONFIG_SND_HDA_RECONFIG
778 snd_array_init(&codec->init_verbs, sizeof(struct hda_verb), 32);
779 snd_array_init(&codec->hints, sizeof(struct hda_hint), 32);
780 snd_array_init(&codec->user_pins, sizeof(struct hda_pincfg), 16);
781#endif
782}
783
784void snd_hda_sysfs_clear(struct hda_codec *codec)
785{
786#ifdef CONFIG_SND_HDA_RECONFIG
787 struct hda_hint *hint;
788 int i;
789
790
791 snd_array_free(&codec->init_verbs);
792
793 snd_array_for_each(&codec->hints, i, hint) {
794 kfree(hint->key);
795 }
796 snd_array_free(&codec->hints);
797 snd_array_free(&codec->user_pins);
798#endif
799}
800