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