Lines Matching +full:codec +full:- +full:0

1 // SPDX-License-Identifier: GPL-2.0
3 * sysfs support for HD-audio core device
24 struct hdac_device *codec = dev_to_hdac_dev(dev); \
25 return sysfs_emit(buf, "0x%x\n", codec->type); \
34 struct hdac_device *codec = dev_to_hdac_dev(dev); \
36 codec->type ? codec->type : ""); \
89 ssize_t (*show)(struct hdac_device *codec, hda_nid_t nid,
91 ssize_t (*store)(struct hdac_device *codec, hda_nid_t nid,
98 struct device *dev = kobj_to_dev(kobj->parent->parent); in get_codec_nid()
102 ret = kstrtoint(kobj->name, 16, &nid); in get_codec_nid()
103 if (ret < 0) in get_codec_nid()
114 struct hdac_device *codec; in widget_attr_show() local
117 if (!wid_attr->show) in widget_attr_show()
118 return -EIO; in widget_attr_show()
119 nid = get_codec_nid(kobj, &codec); in widget_attr_show()
120 if (nid < 0) in widget_attr_show()
122 return wid_attr->show(codec, nid, wid_attr, buf); in widget_attr_show()
130 struct hdac_device *codec; in widget_attr_store() local
133 if (!wid_attr->store) in widget_attr_store()
134 return -EIO; in widget_attr_store()
135 nid = get_codec_nid(kobj, &codec); in widget_attr_store()
136 if (nid < 0) in widget_attr_store()
138 return wid_attr->store(codec, nid, wid_attr, buf, count); in widget_attr_store()
161 static ssize_t caps_show(struct hdac_device *codec, hda_nid_t nid, in caps_show() argument
164 return sysfs_emit(buf, "0x%08x\n", get_wcaps(codec, nid)); in caps_show()
167 static ssize_t pin_caps_show(struct hdac_device *codec, hda_nid_t nid, in pin_caps_show() argument
170 if (get_wcaps_type(get_wcaps(codec, nid)) != AC_WID_PIN) in pin_caps_show()
171 return 0; in pin_caps_show()
172 return sysfs_emit(buf, "0x%08x\n", in pin_caps_show()
173 snd_hdac_read_parm(codec, nid, AC_PAR_PIN_CAP)); in pin_caps_show()
176 static ssize_t pin_cfg_show(struct hdac_device *codec, hda_nid_t nid, in pin_cfg_show() argument
181 if (get_wcaps_type(get_wcaps(codec, nid)) != AC_WID_PIN) in pin_cfg_show()
182 return 0; in pin_cfg_show()
183 if (snd_hdac_read(codec, nid, AC_VERB_GET_CONFIG_DEFAULT, 0, &val)) in pin_cfg_show()
184 return 0; in pin_cfg_show()
185 return sysfs_emit(buf, "0x%08x\n", val); in pin_cfg_show()
188 static bool has_pcm_cap(struct hdac_device *codec, hda_nid_t nid) in has_pcm_cap() argument
190 if (nid == codec->afg || nid == codec->mfg) in has_pcm_cap()
192 switch (get_wcaps_type(get_wcaps(codec, nid))) { in has_pcm_cap()
201 static ssize_t pcm_caps_show(struct hdac_device *codec, hda_nid_t nid, in pcm_caps_show() argument
204 if (!has_pcm_cap(codec, nid)) in pcm_caps_show()
205 return 0; in pcm_caps_show()
206 return sysfs_emit(buf, "0x%08x\n", in pcm_caps_show()
207 snd_hdac_read_parm(codec, nid, AC_PAR_PCM)); in pcm_caps_show()
210 static ssize_t pcm_formats_show(struct hdac_device *codec, hda_nid_t nid, in pcm_formats_show() argument
213 if (!has_pcm_cap(codec, nid)) in pcm_formats_show()
214 return 0; in pcm_formats_show()
215 return sysfs_emit(buf, "0x%08x\n", in pcm_formats_show()
216 snd_hdac_read_parm(codec, nid, AC_PAR_STREAM)); in pcm_formats_show()
219 static ssize_t amp_in_caps_show(struct hdac_device *codec, hda_nid_t nid, in amp_in_caps_show() argument
222 if (nid != codec->afg && !(get_wcaps(codec, nid) & AC_WCAP_IN_AMP)) in amp_in_caps_show()
223 return 0; in amp_in_caps_show()
224 return sysfs_emit(buf, "0x%08x\n", in amp_in_caps_show()
225 snd_hdac_read_parm(codec, nid, AC_PAR_AMP_IN_CAP)); in amp_in_caps_show()
228 static ssize_t amp_out_caps_show(struct hdac_device *codec, hda_nid_t nid, in amp_out_caps_show() argument
231 if (nid != codec->afg && !(get_wcaps(codec, nid) & AC_WCAP_OUT_AMP)) in amp_out_caps_show()
232 return 0; in amp_out_caps_show()
233 return sysfs_emit(buf, "0x%08x\n", in amp_out_caps_show()
234 snd_hdac_read_parm(codec, nid, AC_PAR_AMP_OUT_CAP)); in amp_out_caps_show()
237 static ssize_t power_caps_show(struct hdac_device *codec, hda_nid_t nid, in power_caps_show() argument
240 if (nid != codec->afg && !(get_wcaps(codec, nid) & AC_WCAP_POWER)) in power_caps_show()
241 return 0; in power_caps_show()
242 return sysfs_emit(buf, "0x%08x\n", in power_caps_show()
243 snd_hdac_read_parm(codec, nid, AC_PAR_POWER_STATE)); in power_caps_show()
246 static ssize_t gpio_caps_show(struct hdac_device *codec, hda_nid_t nid, in gpio_caps_show() argument
249 return sysfs_emit(buf, "0x%08x\n", in gpio_caps_show()
250 snd_hdac_read_parm(codec, nid, AC_PAR_GPIO_CAP)); in gpio_caps_show()
253 static ssize_t connections_show(struct hdac_device *codec, hda_nid_t nid, in connections_show() argument
258 ssize_t ret = 0; in connections_show()
260 nconns = snd_hdac_get_connections(codec, nid, list, ARRAY_SIZE(list)); in connections_show()
261 if (nconns <= 0) in connections_show()
263 for (i = 0; i < nconns; i++) in connections_show()
320 static void widget_tree_free(struct hdac_device *codec) in widget_tree_free() argument
322 struct hdac_widget_tree *tree = codec->widgets; in widget_tree_free()
327 free_widget_node(tree->afg, &widget_afg_group); in widget_tree_free()
328 if (tree->nodes) { in widget_tree_free()
329 for (p = tree->nodes; *p; p++) in widget_tree_free()
331 kfree(tree->nodes); in widget_tree_free()
333 kobject_put(tree->root); in widget_tree_free()
335 codec->widgets = NULL; in widget_tree_free()
346 return -ENOMEM; in add_widget_node()
349 if (err < 0) { in add_widget_node()
354 if (err < 0) { in add_widget_node()
360 return 0; in add_widget_node()
363 static int widget_tree_create(struct hdac_device *codec) in widget_tree_create() argument
369 tree = codec->widgets = kzalloc(sizeof(*tree), GFP_KERNEL); in widget_tree_create()
371 return -ENOMEM; in widget_tree_create()
373 tree->root = kobject_create_and_add("widgets", &codec->dev.kobj); in widget_tree_create()
374 if (!tree->root) in widget_tree_create()
375 return -ENOMEM; in widget_tree_create()
377 tree->nodes = kcalloc(codec->num_nodes + 1, sizeof(*tree->nodes), in widget_tree_create()
379 if (!tree->nodes) in widget_tree_create()
380 return -ENOMEM; in widget_tree_create()
382 for (i = 0, nid = codec->start_nid; i < codec->num_nodes; i++, nid++) { in widget_tree_create()
383 err = add_widget_node(tree->root, nid, &widget_node_group, in widget_tree_create()
384 &tree->nodes[i]); in widget_tree_create()
385 if (err < 0) in widget_tree_create()
389 if (codec->afg) { in widget_tree_create()
390 err = add_widget_node(tree->root, codec->afg, in widget_tree_create()
391 &widget_afg_group, &tree->afg); in widget_tree_create()
392 if (err < 0) in widget_tree_create()
396 kobject_uevent(tree->root, KOBJ_CHANGE); in widget_tree_create()
397 return 0; in widget_tree_create()
400 /* call with codec->widget_lock held */
401 int hda_widget_sysfs_init(struct hdac_device *codec) in hda_widget_sysfs_init() argument
405 if (codec->widgets) in hda_widget_sysfs_init()
406 return 0; /* already created */ in hda_widget_sysfs_init()
408 err = widget_tree_create(codec); in hda_widget_sysfs_init()
409 if (err < 0) { in hda_widget_sysfs_init()
410 widget_tree_free(codec); in hda_widget_sysfs_init()
414 return 0; in hda_widget_sysfs_init()
417 /* call with codec->widget_lock held */
418 void hda_widget_sysfs_exit(struct hdac_device *codec) in hda_widget_sysfs_exit() argument
420 widget_tree_free(codec); in hda_widget_sysfs_exit()
423 /* call with codec->widget_lock held */
424 int hda_widget_sysfs_reinit(struct hdac_device *codec, in hda_widget_sysfs_reinit() argument
432 if (!codec->widgets) in hda_widget_sysfs_reinit()
433 return 0; in hda_widget_sysfs_reinit()
435 tree = kmemdup(codec->widgets, sizeof(*tree), GFP_KERNEL); in hda_widget_sysfs_reinit()
437 return -ENOMEM; in hda_widget_sysfs_reinit()
439 tree->nodes = kcalloc(num_nodes + 1, sizeof(*tree->nodes), GFP_KERNEL); in hda_widget_sysfs_reinit()
440 if (!tree->nodes) { in hda_widget_sysfs_reinit()
442 return -ENOMEM; in hda_widget_sysfs_reinit()
445 /* prune non-existing nodes */ in hda_widget_sysfs_reinit()
446 for (i = 0, nid = codec->start_nid; i < codec->num_nodes; i++, nid++) { in hda_widget_sysfs_reinit()
448 free_widget_node(codec->widgets->nodes[i], in hda_widget_sysfs_reinit()
453 for (i = 0, nid = start_nid; i < num_nodes; i++, nid++) { in hda_widget_sysfs_reinit()
454 if (nid < codec->start_nid || nid >= codec->end_nid) in hda_widget_sysfs_reinit()
455 add_widget_node(tree->root, nid, &widget_node_group, in hda_widget_sysfs_reinit()
456 &tree->nodes[i]); in hda_widget_sysfs_reinit()
458 tree->nodes[i] = in hda_widget_sysfs_reinit()
459 codec->widgets->nodes[nid - codec->start_nid]; in hda_widget_sysfs_reinit()
463 kfree(codec->widgets->nodes); in hda_widget_sysfs_reinit()
464 kfree(codec->widgets); in hda_widget_sysfs_reinit()
465 codec->widgets = tree; in hda_widget_sysfs_reinit()
467 kobject_uevent(tree->root, KOBJ_CHANGE); in hda_widget_sysfs_reinit()
468 return 0; in hda_widget_sysfs_reinit()