Lines Matching +full:adc +full:- +full:channel +full:- +full:clk +full:- +full:src

1 // SPDX-License-Identifier: GPL-2.0+
3 // soc-dapm.c -- ALSA SoC Dynamic Audio Power Management
12 // o Platform power domain - can support external components i.e. amps and
15 // o Jack insertion power event initiation - e.g. hp insertion will enable
32 #include <linux/clk.h>
42 #define DAPM_UPDATE_STAT(widget, val) widget->dapm->card->dapm_stats.val++;
65 /* dapm power sequences - make this per codec in the future */
150 if (dapm->card && dapm->card->instantiated) in dapm_assert_locked()
151 lockdep_assert_held(&dapm->card->dapm_mutex); in dapm_assert_locked()
183 return !list_empty(&w->dirty); in dapm_dirty_widget()
188 dapm_assert_locked(w->dapm); in dapm_mark_dirty()
191 dev_vdbg(w->dapm->dev, "Marking %s dirty due to %s\n", in dapm_mark_dirty()
192 w->name, reason); in dapm_mark_dirty()
193 list_add_tail(&w->dirty, &w->dapm->card->dapm_dirty); in dapm_mark_dirty()
212 dapm_assert_locked(w->dapm); in dapm_widget_invalidate_paths()
214 if (w->endpoints[dir] == -1) in dapm_widget_invalidate_paths()
217 list_add_tail(&w->work_list, &list); in dapm_widget_invalidate_paths()
218 w->endpoints[dir] = -1; in dapm_widget_invalidate_paths()
222 if (p->is_supply || p->weak || !p->connect) in dapm_widget_invalidate_paths()
224 node = p->node[rdir]; in dapm_widget_invalidate_paths()
225 if (node->endpoints[dir] != -1) { in dapm_widget_invalidate_paths()
226 node->endpoints[dir] = -1; in dapm_widget_invalidate_paths()
227 list_add_tail(&node->work_list, &list); in dapm_widget_invalidate_paths()
234 * dapm_widget_invalidate_input_paths() - Invalidate the cached number of
251 * dapm_widget_invalidate_output_paths() - Invalidate the cached number of
268 * dapm_path_invalidate() - Invalidates the cached number of inputs and outputs
284 if (p->weak || p->is_supply) in dapm_path_invalidate()
291 * so there is no need to re-check the path. in dapm_path_invalidate()
293 if (p->source->endpoints[SND_SOC_DAPM_DIR_IN] != 0) in dapm_path_invalidate()
294 dapm_widget_invalidate_input_paths(p->sink); in dapm_path_invalidate()
295 if (p->sink->endpoints[SND_SOC_DAPM_DIR_OUT] != 0) in dapm_path_invalidate()
296 dapm_widget_invalidate_output_paths(p->source); in dapm_path_invalidate()
303 mutex_lock(&card->dapm_mutex); in dapm_mark_endpoints_dirty()
306 if (w->is_ep) { in dapm_mark_endpoints_dirty()
308 if (w->is_ep & SND_SOC_DAPM_EP_SINK) in dapm_mark_endpoints_dirty()
310 if (w->is_ep & SND_SOC_DAPM_EP_SOURCE) in dapm_mark_endpoints_dirty()
315 mutex_unlock(&card->dapm_mutex); in dapm_mark_endpoints_dirty()
330 * w->name is duplicated in caller, but w->sname isn't. in dapm_cnew_widget()
333 if (_widget->sname) { in dapm_cnew_widget()
334 w->sname = kstrdup_const(_widget->sname, GFP_KERNEL); in dapm_cnew_widget()
335 if (!w->sname) { in dapm_cnew_widget()
361 return -ENOMEM; in dapm_kcontrol_data_alloc()
363 INIT_LIST_HEAD(&data->paths); in dapm_kcontrol_data_alloc()
365 switch (widget->id) { in dapm_kcontrol_data_alloc()
369 mc = (struct soc_mixer_control *)kcontrol->private_value; in dapm_kcontrol_data_alloc()
371 if (mc->autodisable && snd_soc_volsw_is_stereo(mc)) in dapm_kcontrol_data_alloc()
372 dev_warn(widget->dapm->dev, in dapm_kcontrol_data_alloc()
376 if (mc->autodisable) { in dapm_kcontrol_data_alloc()
382 ret = -ENOMEM; in dapm_kcontrol_data_alloc()
387 template.reg = mc->reg; in dapm_kcontrol_data_alloc()
388 template.mask = (1 << fls(mc->max)) - 1; in dapm_kcontrol_data_alloc()
389 template.shift = mc->shift; in dapm_kcontrol_data_alloc()
390 if (mc->invert) in dapm_kcontrol_data_alloc()
391 template.off_val = mc->max; in dapm_kcontrol_data_alloc()
398 data->value = template.on_val; in dapm_kcontrol_data_alloc()
400 data->widget = in dapm_kcontrol_data_alloc()
401 snd_soc_dapm_new_control_unlocked(widget->dapm, in dapm_kcontrol_data_alloc()
404 if (IS_ERR(data->widget)) { in dapm_kcontrol_data_alloc()
405 ret = PTR_ERR(data->widget); in dapm_kcontrol_data_alloc()
412 e = (struct soc_enum *)kcontrol->private_value; in dapm_kcontrol_data_alloc()
414 if (e->autodisable) { in dapm_kcontrol_data_alloc()
420 ret = -ENOMEM; in dapm_kcontrol_data_alloc()
425 template.reg = e->reg; in dapm_kcontrol_data_alloc()
426 template.mask = e->mask; in dapm_kcontrol_data_alloc()
427 template.shift = e->shift_l; in dapm_kcontrol_data_alloc()
433 data->value = template.on_val; in dapm_kcontrol_data_alloc()
435 data->widget = snd_soc_dapm_new_control_unlocked( in dapm_kcontrol_data_alloc()
436 widget->dapm, &template); in dapm_kcontrol_data_alloc()
438 if (IS_ERR(data->widget)) { in dapm_kcontrol_data_alloc()
439 ret = PTR_ERR(data->widget); in dapm_kcontrol_data_alloc()
443 snd_soc_dapm_add_path(widget->dapm, data->widget, in dapm_kcontrol_data_alloc()
451 kcontrol->private_data = data; in dapm_kcontrol_data_alloc()
464 list_del(&data->paths); in dapm_kcontrol_free()
465 kfree(data->wlist); in dapm_kcontrol_free()
474 return data->wlist; in dapm_kcontrol_get_wlist()
484 if (data->wlist) in dapm_kcontrol_add_widget()
485 n = data->wlist->num_widgets + 1; in dapm_kcontrol_add_widget()
489 new_wlist = krealloc(data->wlist, in dapm_kcontrol_add_widget()
493 return -ENOMEM; in dapm_kcontrol_add_widget()
495 new_wlist->widgets[n - 1] = widget; in dapm_kcontrol_add_widget()
496 new_wlist->num_widgets = n; in dapm_kcontrol_add_widget()
498 data->wlist = new_wlist; in dapm_kcontrol_add_widget()
508 list_add_tail(&path->list_kcontrol, &data->paths); in dapm_kcontrol_add_path()
515 if (!data->widget) in dapm_kcontrol_is_powered()
518 return data->widget->power; in dapm_kcontrol_is_powered()
526 return &data->paths; in dapm_kcontrol_get_path_list()
537 return data->value; in dapm_kcontrol_get_value()
546 if (data->value == value) in dapm_kcontrol_set_value()
549 if (data->widget) { in dapm_kcontrol_set_value()
550 switch (dapm_kcontrol_get_wlist(kcontrol)->widgets[0]->id) { in dapm_kcontrol_set_value()
554 data->widget->on_val = value & data->widget->mask; in dapm_kcontrol_set_value()
558 data->widget->on_val = value >> data->widget->shift; in dapm_kcontrol_set_value()
561 data->widget->on_val = value; in dapm_kcontrol_set_value()
566 data->value = value; in dapm_kcontrol_set_value()
572 * snd_soc_dapm_kcontrol_widget() - Returns the widget associated to a
579 return dapm_kcontrol_get_wlist(kcontrol)->widgets[0]; in snd_soc_dapm_kcontrol_widget()
584 * snd_soc_dapm_kcontrol_dapm() - Returns the dapm context associated to a
594 return dapm_kcontrol_get_wlist(kcontrol)->widgets[0]->dapm; in snd_soc_dapm_kcontrol_dapm()
602 lockdep_assert_held(&card->dapm_mutex); in dapm_reset()
604 memset(&card->dapm_stats, 0, sizeof(card->dapm_stats)); in dapm_reset()
607 w->new_power = w->power; in dapm_reset()
608 w->power_checked = false; in dapm_reset()
614 if (!dapm->component) in soc_dapm_prefix()
616 return dapm->component->name_prefix; in soc_dapm_prefix()
621 if (!dapm->component) in soc_dapm_read()
622 return -EIO; in soc_dapm_read()
623 return snd_soc_component_read(dapm->component, reg); in soc_dapm_read()
629 if (!dapm->component) in soc_dapm_update_bits()
630 return -EIO; in soc_dapm_update_bits()
631 return snd_soc_component_update_bits(dapm->component, reg, in soc_dapm_update_bits()
638 if (!dapm->component) in soc_dapm_test_bits()
639 return -EIO; in soc_dapm_test_bits()
640 return snd_soc_component_test_bits(dapm->component, reg, mask, value); in soc_dapm_test_bits()
645 if (dapm->component) in soc_dapm_async_complete()
646 snd_soc_component_async_complete(dapm->component); in soc_dapm_async_complete()
652 struct snd_soc_dapm_widget *w = wcache->widget; in dapm_wcache_lookup()
658 wlist = &w->dapm->card->widgets; in dapm_wcache_lookup()
661 if (!strcmp(name, w->name)) in dapm_wcache_lookup()
675 wcache->widget = w; in dapm_wcache_update()
679 * snd_soc_dapm_force_bias_level() - Sets the DAPM bias level
700 if (dapm->component) in snd_soc_dapm_force_bias_level()
701 ret = snd_soc_component_set_bias_level(dapm->component, level); in snd_soc_dapm_force_bias_level()
704 dapm->bias_level = level; in snd_soc_dapm_force_bias_level()
711 * snd_soc_dapm_set_bias_level - set the bias level for the system
722 struct snd_soc_card *card = dapm->card; in snd_soc_dapm_set_bias_level()
731 if (!card || dapm != &card->dapm) in snd_soc_dapm_set_bias_level()
749 const struct snd_kcontrol_new *kcontrol = &w->kcontrol_news[0]; in dapm_connect_mux()
750 struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; in dapm_connect_mux()
754 if (e->reg != SND_SOC_NOPM) { in dapm_connect_mux()
755 val = soc_dapm_read(dapm, e->reg); in dapm_connect_mux()
756 val = (val >> e->shift_l) & e->mask; in dapm_connect_mux()
768 i = match_string(e->texts, e->items, control_name); in dapm_connect_mux()
770 return -ENODEV; in dapm_connect_mux()
772 path->name = e->texts[i]; in dapm_connect_mux()
773 path->connect = (i == item); in dapm_connect_mux()
783 p->sink->kcontrol_news[i].private_value; in dapm_set_mixer_path_status()
784 unsigned int reg = mc->reg; in dapm_set_mixer_path_status()
785 unsigned int shift = mc->shift; in dapm_set_mixer_path_status()
786 unsigned int max = mc->max; in dapm_set_mixer_path_status()
787 unsigned int mask = (1 << fls(max)) - 1; in dapm_set_mixer_path_status()
788 unsigned int invert = mc->invert; in dapm_set_mixer_path_status()
792 val = soc_dapm_read(p->sink->dapm, reg); in dapm_set_mixer_path_status()
802 * first path is the left channel, and all remaining in dapm_set_mixer_path_status()
803 * paths are the right channel. in dapm_set_mixer_path_status()
806 if (reg != mc->rreg) in dapm_set_mixer_path_status()
807 val = soc_dapm_read(p->sink->dapm, mc->rreg); in dapm_set_mixer_path_status()
808 val = (val >> mc->rshift) & mask; in dapm_set_mixer_path_status()
813 val = max - val; in dapm_set_mixer_path_status()
814 p->connect = !!val; in dapm_set_mixer_path_status()
822 p->connect = invert; in dapm_set_mixer_path_status()
833 for (i = 0; i < path->sink->num_kcontrols; i++) { in dapm_connect_mixer()
834 if (!strcmp(control_name, path->sink->kcontrol_news[i].name)) { in dapm_connect_mixer()
835 path->name = path->sink->kcontrol_news[i].name; in dapm_connect_mixer()
840 return -ENODEV; in dapm_connect_mixer()
853 for_each_card_widgets(dapm->card, w) { in dapm_is_shared_kcontrol()
854 if (w == kcontrolw || w->dapm != kcontrolw->dapm) in dapm_is_shared_kcontrol()
856 for (i = 0; i < w->num_kcontrols; i++) { in dapm_is_shared_kcontrol()
857 if (&w->kcontrol_news[i] == kcontrol_new) { in dapm_is_shared_kcontrol()
858 if (w->kcontrols) in dapm_is_shared_kcontrol()
859 *kcontrol = w->kcontrols[i]; in dapm_is_shared_kcontrol()
875 struct snd_soc_dapm_context *dapm = w->dapm; in dapm_create_or_share_kcontrol()
876 struct snd_card *card = dapm->card->snd_card; in dapm_create_or_share_kcontrol()
892 shared = dapm_is_shared_kcontrol(dapm, w, &w->kcontrol_news[kci], in dapm_create_or_share_kcontrol()
900 switch (w->id) { in dapm_create_or_share_kcontrol()
919 return -EINVAL; in dapm_create_or_share_kcontrol()
931 w->name + prefix_len, in dapm_create_or_share_kcontrol()
932 w->kcontrol_news[kci].name); in dapm_create_or_share_kcontrol()
934 return -ENOMEM; in dapm_create_or_share_kcontrol()
939 name = w->name + prefix_len; in dapm_create_or_share_kcontrol()
942 name = w->kcontrol_news[kci].name; in dapm_create_or_share_kcontrol()
945 kcontrol = snd_soc_cnew(&w->kcontrol_news[kci], NULL, name, in dapm_create_or_share_kcontrol()
948 ret = -ENOMEM; in dapm_create_or_share_kcontrol()
952 kcontrol->private_free = dapm_kcontrol_free; in dapm_create_or_share_kcontrol()
962 dev_err(dapm->dev, in dapm_create_or_share_kcontrol()
964 w->name, name, ret); in dapm_create_or_share_kcontrol()
971 w->kcontrols[kci] = kcontrol; in dapm_create_or_share_kcontrol()
987 for (i = 0; i < w->num_kcontrols; i++) { in dapm_new_mixer()
991 if (path->name != (char *)w->kcontrol_news[i].name) in dapm_new_mixer()
994 if (!w->kcontrols[i]) { in dapm_new_mixer()
1000 dapm_kcontrol_add_path(w->kcontrols[i], path); in dapm_new_mixer()
1002 data = snd_kcontrol_chip(w->kcontrols[i]); in dapm_new_mixer()
1003 if (data->widget) in dapm_new_mixer()
1004 snd_soc_dapm_add_path(data->widget->dapm, in dapm_new_mixer()
1005 data->widget, in dapm_new_mixer()
1006 path->source, in dapm_new_mixer()
1017 struct snd_soc_dapm_context *dapm = w->dapm; in dapm_new_mux()
1023 switch (w->id) { in dapm_new_mux()
1033 return -EINVAL; in dapm_new_mux()
1036 if (w->num_kcontrols != 1) { in dapm_new_mux()
1037 dev_err(dapm->dev, in dapm_new_mux()
1039 w->name); in dapm_new_mux()
1040 return -EINVAL; in dapm_new_mux()
1043 if (list_empty(&w->edges[dir])) { in dapm_new_mux()
1044 dev_err(dapm->dev, "ASoC: %s %s has no paths\n", type, w->name); in dapm_new_mux()
1045 return -EINVAL; in dapm_new_mux()
1053 if (path->name) in dapm_new_mux()
1054 dapm_kcontrol_add_path(w->kcontrols[0], path); in dapm_new_mux()
1065 for (i = 0; i < w->num_kcontrols; i++) { in dapm_new_pga()
1079 struct snd_soc_dapm_context *dapm = w->dapm; in dapm_new_dai_link()
1080 struct snd_card *card = dapm->card->snd_card; in dapm_new_dai_link()
1081 struct snd_soc_pcm_runtime *rtd = w->priv; in dapm_new_dai_link()
1084 if (rtd->dai_link->num_params <= 1) in dapm_new_dai_link()
1088 for (i = 0; i < w->num_kcontrols; i++) { in dapm_new_dai_link()
1089 kcontrol = snd_soc_cnew(&w->kcontrol_news[i], w, in dapm_new_dai_link()
1090 w->name, NULL); in dapm_new_dai_link()
1093 dev_err(dapm->dev, in dapm_new_dai_link()
1095 w->name, w->kcontrol_news[i].name, ret); in dapm_new_dai_link()
1098 kcontrol->private_data = w; in dapm_new_dai_link()
1099 w->kcontrols[i] = kcontrol; in dapm_new_dai_link()
1106 * the ALSA card - when we are suspending the ALSA state for the card
1111 int level = snd_power_get_state(widget->dapm->card->snd_card); in snd_soc_dapm_suspend_check()
1116 if (widget->ignore_suspend) in snd_soc_dapm_suspend_check()
1117 dev_dbg(widget->dapm->dev, "ASoC: %s ignoring suspend\n", in snd_soc_dapm_suspend_check()
1118 widget->name); in snd_soc_dapm_suspend_check()
1119 return widget->ignore_suspend; in snd_soc_dapm_suspend_check()
1143 return -ENOMEM; in dapm_widget_list_create()
1146 (*list)->widgets[i++] = w; in dapm_widget_list_create()
1148 (*list)->num_widgets = i; in dapm_widget_list_create()
1164 widget->endpoints[dir] = -1; in invalidate_paths_ep()
1167 if (path->weak || path->is_supply) in invalidate_paths_ep()
1170 if (path->walking) in invalidate_paths_ep()
1173 if (path->connect) { in invalidate_paths_ep()
1174 path->walking = 1; in invalidate_paths_ep()
1175 invalidate_paths_ep(path->node[dir], dir); in invalidate_paths_ep()
1176 path->walking = 0; in invalidate_paths_ep()
1200 if (widget->endpoints[dir] >= 0) in is_connected_ep()
1201 return widget->endpoints[dir]; in is_connected_ep()
1207 list_add_tail(&widget->work_list, list); in is_connected_ep()
1214 if ((widget->is_ep & SND_SOC_DAPM_DIR_TO_EP(dir)) && widget->connected) { in is_connected_ep()
1215 widget->endpoints[dir] = snd_soc_dapm_suspend_check(widget); in is_connected_ep()
1216 return widget->endpoints[dir]; in is_connected_ep()
1222 if (path->weak || path->is_supply) in is_connected_ep()
1225 if (path->walking) in is_connected_ep()
1230 if (path->connect) { in is_connected_ep()
1231 path->walking = 1; in is_connected_ep()
1232 con += fn(path->node[dir], list, custom_stop_condition); in is_connected_ep()
1233 path->walking = 0; in is_connected_ep()
1237 widget->endpoints[dir] = con; in is_connected_ep()
1279 * snd_soc_dapm_dai_get_connected_widgets - query audio path and it's widgets.
1302 struct snd_soc_card *card = dai->component->card; in snd_soc_dapm_dai_get_connected_widgets()
1308 mutex_lock_nested(&card->dapm_mutex, SND_SOC_DAPM_CLASS_RUNTIME); in snd_soc_dapm_dai_get_connected_widgets()
1311 w = dai->playback_widget; in snd_soc_dapm_dai_get_connected_widgets()
1316 w = dai->capture_widget; in snd_soc_dapm_dai_get_connected_widgets()
1330 mutex_unlock(&card->dapm_mutex); in snd_soc_dapm_dai_get_connected_widgets()
1348 soc_dapm_async_complete(w->dapm); in dapm_regulator_event()
1351 if (w->on_val & SND_SOC_DAPM_REGULATOR_BYPASS) { in dapm_regulator_event()
1352 ret = regulator_allow_bypass(w->regulator, false); in dapm_regulator_event()
1354 dev_warn(w->dapm->dev, in dapm_regulator_event()
1356 w->name, ret); in dapm_regulator_event()
1359 return regulator_enable(w->regulator); in dapm_regulator_event()
1361 if (w->on_val & SND_SOC_DAPM_REGULATOR_BYPASS) { in dapm_regulator_event()
1362 ret = regulator_allow_bypass(w->regulator, true); in dapm_regulator_event()
1364 dev_warn(w->dapm->dev, in dapm_regulator_event()
1366 w->name, ret); in dapm_regulator_event()
1369 return regulator_disable_deferred(w->regulator, w->shift); in dapm_regulator_event()
1380 struct snd_soc_dapm_pinctrl_priv *priv = w->priv; in dapm_pinctrl_event()
1381 struct pinctrl *p = w->pinctrl; in dapm_pinctrl_event()
1385 return -EIO; in dapm_pinctrl_event()
1388 s = pinctrl_lookup_state(p, priv->active_state); in dapm_pinctrl_event()
1390 s = pinctrl_lookup_state(p, priv->sleep_state); in dapm_pinctrl_event()
1405 if (!w->clk) in dapm_clock_event()
1406 return -EIO; in dapm_clock_event()
1408 soc_dapm_async_complete(w->dapm); in dapm_clock_event()
1411 return clk_prepare_enable(w->clk); in dapm_clock_event()
1413 clk_disable_unprepare(w->clk); in dapm_clock_event()
1423 if (w->power_checked) in dapm_widget_power_check()
1424 return w->new_power; in dapm_widget_power_check()
1426 if (w->force) in dapm_widget_power_check()
1427 w->new_power = 1; in dapm_widget_power_check()
1429 w->new_power = w->power_check(w); in dapm_widget_power_check()
1431 w->power_checked = true; in dapm_widget_power_check()
1433 return w->new_power; in dapm_widget_power_check()
1459 if (path->weak) in dapm_supply_check_power()
1462 if (path->connected && in dapm_supply_check_power()
1463 !path->connected(path->source, path->sink)) in dapm_supply_check_power()
1466 if (dapm_widget_power_check(path->sink)) in dapm_supply_check_power()
1475 return w->connected; in dapm_always_on_check_power()
1492 WARN_ONCE(sort[a->id] == 0, "offset a->id %d not initialized\n", a->id); in dapm_seq_compare()
1493 WARN_ONCE(sort[b->id] == 0, "offset b->id %d not initialized\n", b->id); in dapm_seq_compare()
1495 if (sort[a->id] != sort[b->id]) in dapm_seq_compare()
1496 return sort[a->id] - sort[b->id]; in dapm_seq_compare()
1497 if (a->subseq != b->subseq) { in dapm_seq_compare()
1499 return a->subseq - b->subseq; in dapm_seq_compare()
1501 return b->subseq - a->subseq; in dapm_seq_compare()
1503 if (a->reg != b->reg) in dapm_seq_compare()
1504 return a->reg - b->reg; in dapm_seq_compare()
1505 if (a->dapm != b->dapm) in dapm_seq_compare()
1506 return (unsigned long)a->dapm - (unsigned long)b->dapm; in dapm_seq_compare()
1520 list_add_tail(&new_widget->power_list, &w->power_list); in dapm_seq_insert()
1524 list_add_tail(&new_widget->power_list, list); in dapm_seq_insert()
1563 if (w->new_power != power) in dapm_seq_check_event()
1566 if (w->event && (w->event_flags & event)) { in dapm_seq_check_event()
1567 pop_dbg(w->dapm->dev, card->pop_time, "pop test : %s %s\n", in dapm_seq_check_event()
1568 w->name, ev_name); in dapm_seq_check_event()
1569 soc_dapm_async_complete(w->dapm); in dapm_seq_check_event()
1571 ret = w->event(w, NULL, event); in dapm_seq_check_event()
1574 dev_err(w->dapm->dev, "ASoC: %s: %s event failed: %d\n", in dapm_seq_check_event()
1575 ev_name, w->name, ret); in dapm_seq_check_event()
1590 reg = w->reg; in dapm_seq_run_coalesced()
1591 dapm = w->dapm; in dapm_seq_run_coalesced()
1594 WARN_ON(reg != w->reg || dapm != w->dapm); in dapm_seq_run_coalesced()
1595 w->power = w->new_power; in dapm_seq_run_coalesced()
1597 mask |= w->mask << w->shift; in dapm_seq_run_coalesced()
1598 if (w->power) in dapm_seq_run_coalesced()
1599 value |= w->on_val << w->shift; in dapm_seq_run_coalesced()
1601 value |= w->off_val << w->shift; in dapm_seq_run_coalesced()
1603 pop_dbg(dapm->dev, card->pop_time, in dapm_seq_run_coalesced()
1605 w->name, reg, value, mask); in dapm_seq_run_coalesced()
1617 pop_dbg(dapm->dev, card->pop_time, in dapm_seq_run_coalesced()
1619 value, mask, reg, card->pop_time); in dapm_seq_run_coalesced()
1620 pop_wait(card->pop_time); in dapm_seq_run_coalesced()
1632 * We walk over a pre-sorted list of widgets to apply power to. In
1644 int cur_sort = -1; in dapm_seq_run()
1645 int cur_subseq = -1; in dapm_seq_run()
1660 if (sort[w->id] != cur_sort || w->reg != cur_reg || in dapm_seq_run()
1661 w->dapm != cur_dapm || w->subseq != cur_subseq) { in dapm_seq_run()
1665 if (cur_dapm && cur_dapm->component) { in dapm_seq_run()
1669 cur_dapm->component, in dapm_seq_run()
1673 if (cur_dapm && w->dapm != cur_dapm) in dapm_seq_run()
1677 cur_sort = -1; in dapm_seq_run()
1683 switch (w->id) { in dapm_seq_run()
1685 if (!w->event) in dapm_seq_run()
1690 ret = w->event(w, in dapm_seq_run()
1693 ret = w->event(w, in dapm_seq_run()
1698 if (!w->event) in dapm_seq_run()
1703 ret = w->event(w, in dapm_seq_run()
1706 ret = w->event(w, in dapm_seq_run()
1712 cur_sort = sort[w->id]; in dapm_seq_run()
1713 cur_subseq = w->subseq; in dapm_seq_run()
1714 cur_reg = w->reg; in dapm_seq_run()
1715 cur_dapm = w->dapm; in dapm_seq_run()
1716 list_move(&w->power_list, &pending); in dapm_seq_run()
1721 dev_err(w->dapm->dev, in dapm_seq_run()
1728 if (cur_dapm && cur_dapm->component) { in dapm_seq_run()
1732 cur_dapm->component, in dapm_seq_run()
1742 struct snd_soc_dapm_update *update = card->update; in dapm_widget_update()
1748 if (!update || !dapm_kcontrol_is_powered(update->kcontrol)) in dapm_widget_update()
1751 wlist = dapm_kcontrol_get_wlist(update->kcontrol); in dapm_widget_update()
1754 if (w->event && (w->event_flags & SND_SOC_DAPM_PRE_REG)) { in dapm_widget_update()
1755 ret = w->event(w, update->kcontrol, SND_SOC_DAPM_PRE_REG); in dapm_widget_update()
1757 dev_err(w->dapm->dev, "ASoC: %s DAPM pre-event failed: %d\n", in dapm_widget_update()
1758 w->name, ret); in dapm_widget_update()
1765 ret = soc_dapm_update_bits(w->dapm, update->reg, update->mask, in dapm_widget_update()
1766 update->val); in dapm_widget_update()
1768 dev_err(w->dapm->dev, "ASoC: %s DAPM update failed: %d\n", in dapm_widget_update()
1769 w->name, ret); in dapm_widget_update()
1771 if (update->has_second_set) { in dapm_widget_update()
1772 ret = soc_dapm_update_bits(w->dapm, update->reg2, in dapm_widget_update()
1773 update->mask2, update->val2); in dapm_widget_update()
1775 dev_err(w->dapm->dev, in dapm_widget_update()
1777 w->name, ret); in dapm_widget_update()
1781 if (w->event && (w->event_flags & SND_SOC_DAPM_POST_REG)) { in dapm_widget_update()
1782 ret = w->event(w, update->kcontrol, SND_SOC_DAPM_POST_REG); in dapm_widget_update()
1784 dev_err(w->dapm->dev, "ASoC: %s DAPM post-event failed: %d\n", in dapm_widget_update()
1785 w->name, ret); in dapm_widget_update()
1790 /* Async callback run prior to DAPM sequences - brings to _PREPARE if
1799 if (d->bias_level == SND_SOC_BIAS_OFF && in dapm_pre_sequence_async()
1800 d->target_bias_level != SND_SOC_BIAS_OFF) { in dapm_pre_sequence_async()
1801 if (d->dev && cookie) in dapm_pre_sequence_async()
1802 pm_runtime_get_sync(d->dev); in dapm_pre_sequence_async()
1806 dev_err(d->dev, in dapm_pre_sequence_async()
1811 if ((d->target_bias_level == SND_SOC_BIAS_ON && in dapm_pre_sequence_async()
1812 d->bias_level != SND_SOC_BIAS_ON) || in dapm_pre_sequence_async()
1813 (d->target_bias_level != SND_SOC_BIAS_ON && in dapm_pre_sequence_async()
1814 d->bias_level == SND_SOC_BIAS_ON)) { in dapm_pre_sequence_async()
1817 dev_err(d->dev, in dapm_pre_sequence_async()
1822 /* Async callback run prior to DAPM sequences - brings to their final
1831 if (d->bias_level == SND_SOC_BIAS_PREPARE && in dapm_post_sequence_async()
1832 (d->target_bias_level == SND_SOC_BIAS_STANDBY || in dapm_post_sequence_async()
1833 d->target_bias_level == SND_SOC_BIAS_OFF)) { in dapm_post_sequence_async()
1836 dev_err(d->dev, "ASoC: Failed to apply standby bias: %d\n", in dapm_post_sequence_async()
1841 if (d->bias_level == SND_SOC_BIAS_STANDBY && in dapm_post_sequence_async()
1842 d->target_bias_level == SND_SOC_BIAS_OFF) { in dapm_post_sequence_async()
1845 dev_err(d->dev, "ASoC: Failed to turn off bias: %d\n", in dapm_post_sequence_async()
1848 if (d->dev && cookie) in dapm_post_sequence_async()
1849 pm_runtime_put(d->dev); in dapm_post_sequence_async()
1853 if (d->bias_level == SND_SOC_BIAS_PREPARE && in dapm_post_sequence_async()
1854 d->target_bias_level == SND_SOC_BIAS_ON) { in dapm_post_sequence_async()
1857 dev_err(d->dev, "ASoC: Failed to apply active bias: %d\n", in dapm_post_sequence_async()
1873 if (power != peer->power) in dapm_widget_set_peer_power()
1883 if (w->power == power) in dapm_widget_set_power()
1892 dapm_widget_set_peer_power(path->source, power, path->connect); in dapm_widget_set_power()
1895 if (!w->is_supply) { in dapm_widget_set_power()
1897 dapm_widget_set_peer_power(path->sink, power, in dapm_widget_set_power()
1898 path->connect); in dapm_widget_set_power()
1913 switch (w->id) { in dapm_power_one_widget()
1931 if (dapm->idle_bias_off) in dapm_idle_bias_off()
1934 switch (snd_power_get_state(dapm->card->snd_card)) { in dapm_idle_bias_off()
1937 return dapm->suspend_bias_off; in dapm_idle_bias_off()
1947 * A complete path is a route that has valid endpoints i.e.:-
1950 * o Input pin to ADC.
1952 * o DAC to ADC (loopback).
1964 lockdep_assert_held(&card->dapm_mutex); in dapm_power_widgets()
1970 d->target_bias_level = SND_SOC_BIAS_OFF; in dapm_power_widgets()
1972 d->target_bias_level = SND_SOC_BIAS_STANDBY; in dapm_power_widgets()
1983 list_for_each_entry(w, &card->dapm_dirty, dirty) { in dapm_power_widgets()
1988 switch (w->id) { in dapm_power_widgets()
1994 list_del_init(&w->dirty); in dapm_power_widgets()
1998 if (w->new_power) { in dapm_power_widgets()
1999 d = w->dapm; in dapm_power_widgets()
2008 switch (w->id) { in dapm_power_widgets()
2017 if (d->target_bias_level < SND_SOC_BIAS_STANDBY) in dapm_power_widgets()
2018 d->target_bias_level = SND_SOC_BIAS_STANDBY; in dapm_power_widgets()
2021 d->target_bias_level = SND_SOC_BIAS_ON; in dapm_power_widgets()
2033 if (d->target_bias_level > bias) in dapm_power_widgets()
2034 bias = d->target_bias_level; in dapm_power_widgets()
2037 d->target_bias_level = bias; in dapm_power_widgets()
2042 dapm_pre_sequence_async(&card->dapm, 0); in dapm_power_widgets()
2045 if (d != &card->dapm && d->bias_level != d->target_bias_level) in dapm_power_widgets()
2069 if (d != &card->dapm && d->bias_level != d->target_bias_level) in dapm_power_widgets()
2075 dapm_post_sequence_async(&card->dapm, 0); in dapm_power_widgets()
2079 if (!d->component) in dapm_power_widgets()
2082 ret = snd_soc_component_stream_event(d->component, event); in dapm_power_widgets()
2087 pop_dbg(card->dev, card->pop_time, in dapm_power_widgets()
2088 "DAPM sequencing finished, waiting %dms\n", card->pop_time); in dapm_power_widgets()
2089 pop_wait(card->pop_time); in dapm_power_widgets()
2101 struct snd_soc_dapm_widget *w = file->private_data; in dapm_widget_power_read_file()
2102 struct snd_soc_card *card = w->dapm->card; in dapm_widget_power_read_file()
2111 return -ENOMEM; in dapm_widget_power_read_file()
2113 mutex_lock(&card->dapm_mutex); in dapm_widget_power_read_file()
2116 if (w->is_supply) { in dapm_widget_power_read_file()
2125 w->name, w->power ? "On" : "Off", in dapm_widget_power_read_file()
2126 w->force ? " (forced)" : "", in, out); in dapm_widget_power_read_file()
2128 if (w->reg >= 0) in dapm_widget_power_read_file()
2129 ret += scnprintf(buf + ret, PAGE_SIZE - ret, in dapm_widget_power_read_file()
2130 " - R%d(0x%x) mask 0x%x", in dapm_widget_power_read_file()
2131 w->reg, w->reg, w->mask << w->shift); in dapm_widget_power_read_file()
2133 ret += scnprintf(buf + ret, PAGE_SIZE - ret, "\n"); in dapm_widget_power_read_file()
2135 if (w->sname) in dapm_widget_power_read_file()
2136 ret += scnprintf(buf + ret, PAGE_SIZE - ret, " stream %s %s\n", in dapm_widget_power_read_file()
2137 w->sname, in dapm_widget_power_read_file()
2138 w->active ? "active" : "inactive"); in dapm_widget_power_read_file()
2143 if (p->connected && !p->connected(p->source, p->sink)) in dapm_widget_power_read_file()
2146 if (!p->connect) in dapm_widget_power_read_file()
2149 ret += scnprintf(buf + ret, PAGE_SIZE - ret, in dapm_widget_power_read_file()
2152 p->name ? p->name : "static", in dapm_widget_power_read_file()
2153 p->node[rdir]->name); in dapm_widget_power_read_file()
2157 mutex_unlock(&card->dapm_mutex); in dapm_widget_power_read_file()
2174 struct snd_soc_dapm_context *dapm = file->private_data; in dapm_bias_read_file()
2177 switch (dapm->bias_level) { in dapm_bias_read_file()
2191 WARN(1, "Unknown bias_level %d\n", dapm->bias_level); in dapm_bias_read_file()
2212 dapm->debugfs_dapm = debugfs_create_dir("dapm", parent); in snd_soc_dapm_debugfs_init()
2214 debugfs_create_file("bias_level", 0444, dapm->debugfs_dapm, dapm, in snd_soc_dapm_debugfs_init()
2220 struct snd_soc_dapm_context *dapm = w->dapm; in dapm_debugfs_add_widget()
2222 if (!dapm->debugfs_dapm || !w->name) in dapm_debugfs_add_widget()
2225 debugfs_create_file(w->name, 0444, dapm->debugfs_dapm, w, in dapm_debugfs_add_widget()
2231 debugfs_remove_recursive(dapm->debugfs_dapm); in dapm_debugfs_cleanup()
2232 dapm->debugfs_dapm = NULL; in dapm_debugfs_cleanup()
2252 * soc_dapm_connect_path() - Connects or disconnects a path
2261 if (path->connect == connect) in soc_dapm_connect_path()
2264 path->connect = connect; in soc_dapm_connect_path()
2265 dapm_mark_dirty(path->source, reason); in soc_dapm_connect_path()
2266 dapm_mark_dirty(path->sink, reason); in soc_dapm_connect_path()
2278 lockdep_assert_held(&card->dapm_mutex); in soc_dapm_mux_update_power()
2284 if (e && !(strcmp(path->name, e->texts[mux]))) in soc_dapm_mux_update_power()
2302 struct snd_soc_card *card = dapm->card; in snd_soc_dapm_mux_update_power()
2305 mutex_lock_nested(&card->dapm_mutex, SND_SOC_DAPM_CLASS_RUNTIME); in snd_soc_dapm_mux_update_power()
2306 card->update = update; in snd_soc_dapm_mux_update_power()
2308 card->update = NULL; in snd_soc_dapm_mux_update_power()
2309 mutex_unlock(&card->dapm_mutex); in snd_soc_dapm_mux_update_power()
2324 lockdep_assert_held(&card->dapm_mutex); in soc_dapm_mixer_update_power()
2335 * first path (when 'found == 0') is the left channel, in soc_dapm_mixer_update_power()
2337 * right channel. in soc_dapm_mixer_update_power()
2347 * the left channel, and 'rconnect' for the right in soc_dapm_mixer_update_power()
2348 * channel. in soc_dapm_mixer_update_power()
2367 struct snd_soc_card *card = dapm->card; in snd_soc_dapm_mixer_update_power()
2370 mutex_lock_nested(&card->dapm_mutex, SND_SOC_DAPM_CLASS_RUNTIME); in snd_soc_dapm_mixer_update_power()
2371 card->update = update; in snd_soc_dapm_mixer_update_power()
2372 ret = soc_dapm_mixer_update_power(card, kcontrol, connect, -1); in snd_soc_dapm_mixer_update_power()
2373 card->update = NULL; in snd_soc_dapm_mixer_update_power()
2374 mutex_unlock(&card->dapm_mutex); in snd_soc_dapm_mixer_update_power()
2393 if (!cmpnt->card) in dapm_widget_show_component()
2396 for_each_card_widgets(cmpnt->card, w) { in dapm_widget_show_component()
2397 if (w->dapm != dapm) in dapm_widget_show_component()
2401 switch (w->id) { in dapm_widget_show_component()
2418 if (w->name) in dapm_widget_show_component()
2420 w->name, w->power ? "On":"Off"); in dapm_widget_show_component()
2454 mutex_lock(&rtd->card->dapm_mutex); in dapm_widget_show()
2457 struct snd_soc_component *cmpnt = codec_dai->component; in dapm_widget_show()
2462 mutex_unlock(&rtd->card->dapm_mutex); in dapm_widget_show()
2476 list_del(&path->list_node[SND_SOC_DAPM_DIR_IN]); in dapm_free_path()
2477 list_del(&path->list_node[SND_SOC_DAPM_DIR_OUT]); in dapm_free_path()
2478 list_del(&path->list_kcontrol); in dapm_free_path()
2479 list_del(&path->list); in dapm_free_path()
2488 list_del(&w->list); in snd_soc_dapm_free_widget()
2499 kfree(w->kcontrols); in snd_soc_dapm_free_widget()
2500 kfree_const(w->name); in snd_soc_dapm_free_widget()
2501 kfree_const(w->sname); in snd_soc_dapm_free_widget()
2507 dapm->path_sink_cache.widget = NULL; in snd_soc_dapm_reset_cache()
2508 dapm->path_source_cache.widget = NULL; in snd_soc_dapm_reset_cache()
2516 for_each_card_widgets_safe(dapm->card, w, next_w) { in dapm_free_widgets()
2517 if (w->dapm != dapm) in dapm_free_widgets()
2531 for_each_card_widgets(dapm->card, w) { in dapm_find_widget()
2532 if (!strcmp(w->name, pin)) { in dapm_find_widget()
2533 if (w->dapm == dapm) in dapm_find_widget()
2554 dev_err(dapm->dev, "ASoC: DAPM unknown pin %s\n", pin); in snd_soc_dapm_set_pin()
2555 return -EINVAL; in snd_soc_dapm_set_pin()
2558 if (w->connected != status) { in snd_soc_dapm_set_pin()
2564 w->connected = status; in snd_soc_dapm_set_pin()
2566 w->force = 0; in snd_soc_dapm_set_pin()
2572 * snd_soc_dapm_sync_unlocked - scan and power dapm paths
2588 if (!dapm->card || !dapm->card->instantiated) in snd_soc_dapm_sync_unlocked()
2591 return dapm_power_widgets(dapm->card, SND_SOC_DAPM_STREAM_NOP); in snd_soc_dapm_sync_unlocked()
2596 * snd_soc_dapm_sync - scan and power dapm paths
2608 mutex_lock_nested(&dapm->card->dapm_mutex, SND_SOC_DAPM_CLASS_RUNTIME); in snd_soc_dapm_sync()
2610 mutex_unlock(&dapm->card->dapm_mutex); in snd_soc_dapm_sync()
2619 switch (w->id) { in dapm_update_dai_chan()
2627 dev_dbg(w->dapm->dev, "%s DAI route %s -> %s\n", in dapm_update_dai_chan()
2628 w->channel < channels ? "Connecting" : "Disconnecting", in dapm_update_dai_chan()
2629 p->source->name, p->sink->name); in dapm_update_dai_chan()
2631 if (w->channel < channels) in dapm_update_dai_chan()
2643 int dir = substream->stream; in dapm_update_dai_unlocked()
2654 dev_dbg(dai->dev, "Update DAI routes for %s %s\n", dai->name, in dapm_update_dai_unlocked()
2658 ret = dapm_update_dai_chan(p, p->sink, channels); in dapm_update_dai_unlocked()
2664 ret = dapm_update_dai_chan(p, p->source, channels); in dapm_update_dai_unlocked()
2679 mutex_lock_nested(&rtd->card->dapm_mutex, SND_SOC_DAPM_CLASS_RUNTIME); in snd_soc_dapm_update_dai()
2681 mutex_unlock(&rtd->card->dapm_mutex); in snd_soc_dapm_update_dai()
2688 * dapm_update_widget_flags() - Re-compute widget sink and source flags
2702 switch (w->id) { in dapm_update_widget_flags()
2705 if (w->dapm->card->fully_routed) in dapm_update_widget_flags()
2709 if (p->source->id == snd_soc_dapm_micbias || in dapm_update_widget_flags()
2710 p->source->id == snd_soc_dapm_mic || in dapm_update_widget_flags()
2711 p->source->id == snd_soc_dapm_line || in dapm_update_widget_flags()
2712 p->source->id == snd_soc_dapm_output) { in dapm_update_widget_flags()
2720 if (w->dapm->card->fully_routed) in dapm_update_widget_flags()
2724 if (p->sink->id == snd_soc_dapm_spk || in dapm_update_widget_flags()
2725 p->sink->id == snd_soc_dapm_hp || in dapm_update_widget_flags()
2726 p->sink->id == snd_soc_dapm_line || in dapm_update_widget_flags()
2727 p->sink->id == snd_soc_dapm_input) { in dapm_update_widget_flags()
2736 if (!list_empty(&w->edges[dir])) in dapm_update_widget_flags()
2744 w->is_ep = ep; in dapm_update_widget_flags()
2757 switch (source->id) { in snd_soc_dapm_check_dynamic_path()
2765 switch (sink->id) { in snd_soc_dapm_check_dynamic_path()
2777 dev_err(dapm->dev, in snd_soc_dapm_check_dynamic_path()
2778 "Direct connection between demux and mixer/mux not supported for path %s -> [%s] -> %s\n", in snd_soc_dapm_check_dynamic_path()
2779 source->name, control, sink->name); in snd_soc_dapm_check_dynamic_path()
2780 return -EINVAL; in snd_soc_dapm_check_dynamic_path()
2782 dev_err(dapm->dev, in snd_soc_dapm_check_dynamic_path()
2783 "Control not supported for path %s -> [%s] -> %s\n", in snd_soc_dapm_check_dynamic_path()
2784 source->name, control, sink->name); in snd_soc_dapm_check_dynamic_path()
2785 return -EINVAL; in snd_soc_dapm_check_dynamic_path()
2802 if (wsink->is_supply && !wsource->is_supply) { in snd_soc_dapm_add_path()
2803 dev_err(dapm->dev, in snd_soc_dapm_add_path()
2804 "Connecting non-supply widget to supply widget is not supported (%s -> %s)\n", in snd_soc_dapm_add_path()
2805 wsource->name, wsink->name); in snd_soc_dapm_add_path()
2806 return -EINVAL; in snd_soc_dapm_add_path()
2809 if (connected && !wsource->is_supply) { in snd_soc_dapm_add_path()
2810 dev_err(dapm->dev, in snd_soc_dapm_add_path()
2811 "connected() callback only supported for supply widgets (%s -> %s)\n", in snd_soc_dapm_add_path()
2812 wsource->name, wsink->name); in snd_soc_dapm_add_path()
2813 return -EINVAL; in snd_soc_dapm_add_path()
2816 if (wsource->is_supply && control) { in snd_soc_dapm_add_path()
2817 dev_err(dapm->dev, in snd_soc_dapm_add_path()
2818 "Conditional paths are not supported for supply widgets (%s -> [%s] -> %s)\n", in snd_soc_dapm_add_path()
2819 wsource->name, control, wsink->name); in snd_soc_dapm_add_path()
2820 return -EINVAL; in snd_soc_dapm_add_path()
2829 return -ENOMEM; in snd_soc_dapm_add_path()
2831 path->node[SND_SOC_DAPM_DIR_IN] = wsource; in snd_soc_dapm_add_path()
2832 path->node[SND_SOC_DAPM_DIR_OUT] = wsink; in snd_soc_dapm_add_path()
2836 path->connected = connected; in snd_soc_dapm_add_path()
2837 INIT_LIST_HEAD(&path->list); in snd_soc_dapm_add_path()
2838 INIT_LIST_HEAD(&path->list_kcontrol); in snd_soc_dapm_add_path()
2840 if (wsource->is_supply || wsink->is_supply) in snd_soc_dapm_add_path()
2841 path->is_supply = 1; in snd_soc_dapm_add_path()
2845 path->connect = 1; in snd_soc_dapm_add_path()
2847 switch (wsource->id) { in snd_soc_dapm_add_path()
2857 switch (wsink->id) { in snd_soc_dapm_add_path()
2875 list_add(&path->list, &dapm->card->paths); in snd_soc_dapm_add_path()
2877 list_add(&path->list_node[dir], &widgets[dir]->edges[dir]); in snd_soc_dapm_add_path()
2884 if (dapm->card->instantiated && path->connect) in snd_soc_dapm_add_path()
2910 prefix, route->sink); in snd_soc_dapm_add_route()
2913 prefix, route->source); in snd_soc_dapm_add_route()
2916 sink = route->sink; in snd_soc_dapm_add_route()
2917 source = route->source; in snd_soc_dapm_add_route()
2920 wsource = dapm_wcache_lookup(&dapm->path_source_cache, source); in snd_soc_dapm_add_route()
2921 wsink = dapm_wcache_lookup(&dapm->path_sink_cache, sink); in snd_soc_dapm_add_route()
2927 * find src and dest widgets over all widgets but favor a widget from in snd_soc_dapm_add_route()
2930 for_each_card_widgets(dapm->card, w) { in snd_soc_dapm_add_route()
2931 if (!wsink && !(strcmp(w->name, sink))) { in snd_soc_dapm_add_route()
2933 if (w->dapm == dapm) { in snd_soc_dapm_add_route()
2940 dev_warn(dapm->dev, in snd_soc_dapm_add_route()
2942 w->name); in snd_soc_dapm_add_route()
2945 if (!wsource && !(strcmp(w->name, source))) { in snd_soc_dapm_add_route()
2947 if (w->dapm == dapm) { in snd_soc_dapm_add_route()
2954 dev_warn(dapm->dev, in snd_soc_dapm_add_route()
2956 w->name); in snd_soc_dapm_add_route()
2966 dev_err(dapm->dev, "ASoC: no source widget found for %s\n", in snd_soc_dapm_add_route()
2967 route->source); in snd_soc_dapm_add_route()
2968 return -ENODEV; in snd_soc_dapm_add_route()
2971 dev_err(dapm->dev, "ASoC: no sink widget found for %s\n", in snd_soc_dapm_add_route()
2972 route->sink); in snd_soc_dapm_add_route()
2973 return -ENODEV; in snd_soc_dapm_add_route()
2977 dapm_wcache_update(&dapm->path_sink_cache, wsink); in snd_soc_dapm_add_route()
2978 dapm_wcache_update(&dapm->path_source_cache, wsource); in snd_soc_dapm_add_route()
2980 ret = snd_soc_dapm_add_path(dapm, wsource, wsink, route->control, in snd_soc_dapm_add_route()
2981 route->connected); in snd_soc_dapm_add_route()
2987 dev_warn(dapm->dev, "ASoC: no dapm match for %s --> %s --> %s\n", in snd_soc_dapm_add_route()
2988 source, route->control, sink); in snd_soc_dapm_add_route()
3003 if (route->control) { in snd_soc_dapm_del_route()
3004 dev_err(dapm->dev, in snd_soc_dapm_del_route()
3006 return -EINVAL; in snd_soc_dapm_del_route()
3012 prefix, route->sink); in snd_soc_dapm_del_route()
3015 prefix, route->source); in snd_soc_dapm_del_route()
3018 sink = route->sink; in snd_soc_dapm_del_route()
3019 source = route->source; in snd_soc_dapm_del_route()
3023 list_for_each_entry(p, &dapm->card->paths, list) { in snd_soc_dapm_del_route()
3024 if (strcmp(p->source->name, source) != 0) in snd_soc_dapm_del_route()
3026 if (strcmp(p->sink->name, sink) != 0) in snd_soc_dapm_del_route()
3033 wsource = path->source; in snd_soc_dapm_del_route()
3034 wsink = path->sink; in snd_soc_dapm_del_route()
3038 if (path->connect) in snd_soc_dapm_del_route()
3047 dev_warn(dapm->dev, "ASoC: Route %s->%s does not exist\n", in snd_soc_dapm_del_route()
3055 * snd_soc_dapm_add_routes - Add routes between DAPM widgets
3072 mutex_lock_nested(&dapm->card->dapm_mutex, SND_SOC_DAPM_CLASS_RUNTIME); in snd_soc_dapm_add_routes()
3076 dev_err(dapm->dev, "ASoC: Failed to add route %s -> %s -> %s\n", in snd_soc_dapm_add_routes()
3077 route->source, in snd_soc_dapm_add_routes()
3078 route->control ? route->control : "direct", in snd_soc_dapm_add_routes()
3079 route->sink); in snd_soc_dapm_add_routes()
3084 mutex_unlock(&dapm->card->dapm_mutex); in snd_soc_dapm_add_routes()
3091 * snd_soc_dapm_del_routes - Remove routes between DAPM widgets
3103 mutex_lock_nested(&dapm->card->dapm_mutex, SND_SOC_DAPM_CLASS_RUNTIME); in snd_soc_dapm_del_routes()
3108 mutex_unlock(&dapm->card->dapm_mutex); in snd_soc_dapm_del_routes()
3118 route->source, in snd_soc_dapm_weak_route()
3121 route->sink, in snd_soc_dapm_weak_route()
3127 dev_err(dapm->dev, "ASoC: Unable to find source %s for weak route\n", in snd_soc_dapm_weak_route()
3128 route->source); in snd_soc_dapm_weak_route()
3129 return -ENODEV; in snd_soc_dapm_weak_route()
3133 dev_err(dapm->dev, "ASoC: Unable to find sink %s for weak route\n", in snd_soc_dapm_weak_route()
3134 route->sink); in snd_soc_dapm_weak_route()
3135 return -ENODEV; in snd_soc_dapm_weak_route()
3138 if (route->control || route->connected) in snd_soc_dapm_weak_route()
3139 dev_warn(dapm->dev, "ASoC: Ignoring control for weak route %s->%s\n", in snd_soc_dapm_weak_route()
3140 route->source, route->sink); in snd_soc_dapm_weak_route()
3143 if (path->sink == sink) { in snd_soc_dapm_weak_route()
3144 path->weak = 1; in snd_soc_dapm_weak_route()
3150 dev_err(dapm->dev, "ASoC: No path found for weak route %s->%s\n", in snd_soc_dapm_weak_route()
3151 route->source, route->sink); in snd_soc_dapm_weak_route()
3153 dev_warn(dapm->dev, "ASoC: %d paths found for weak route %s->%s\n", in snd_soc_dapm_weak_route()
3154 count, route->source, route->sink); in snd_soc_dapm_weak_route()
3160 * snd_soc_dapm_weak_routes - Mark routes between DAPM widgets as weak
3181 mutex_lock_nested(&dapm->card->dapm_mutex, SND_SOC_DAPM_CLASS_INIT); in snd_soc_dapm_weak_routes()
3188 mutex_unlock(&dapm->card->dapm_mutex); in snd_soc_dapm_weak_routes()
3195 * snd_soc_dapm_new_widgets - add new dapm widgets
3207 mutex_lock_nested(&card->dapm_mutex, SND_SOC_DAPM_CLASS_INIT); in snd_soc_dapm_new_widgets()
3211 if (w->new) in snd_soc_dapm_new_widgets()
3214 if (w->num_kcontrols) { in snd_soc_dapm_new_widgets()
3215 w->kcontrols = kcalloc(w->num_kcontrols, in snd_soc_dapm_new_widgets()
3218 if (!w->kcontrols) { in snd_soc_dapm_new_widgets()
3219 mutex_unlock(&card->dapm_mutex); in snd_soc_dapm_new_widgets()
3220 return -ENOMEM; in snd_soc_dapm_new_widgets()
3224 switch(w->id) { in snd_soc_dapm_new_widgets()
3247 if (w->reg >= 0) { in snd_soc_dapm_new_widgets()
3248 val = soc_dapm_read(w->dapm, w->reg); in snd_soc_dapm_new_widgets()
3249 val = val >> w->shift; in snd_soc_dapm_new_widgets()
3250 val &= w->mask; in snd_soc_dapm_new_widgets()
3251 if (val == w->on_val) in snd_soc_dapm_new_widgets()
3252 w->power = 1; in snd_soc_dapm_new_widgets()
3255 w->new = 1; in snd_soc_dapm_new_widgets()
3262 mutex_unlock(&card->dapm_mutex); in snd_soc_dapm_new_widgets()
3268 * snd_soc_dapm_get_volsw - dapm mixer get callback
3280 struct snd_soc_card *card = dapm->card; in snd_soc_dapm_get_volsw()
3282 (struct soc_mixer_control *)kcontrol->private_value; in snd_soc_dapm_get_volsw()
3283 int reg = mc->reg; in snd_soc_dapm_get_volsw()
3284 unsigned int shift = mc->shift; in snd_soc_dapm_get_volsw()
3285 int max = mc->max; in snd_soc_dapm_get_volsw()
3287 unsigned int mask = (1 << fls(max)) - 1; in snd_soc_dapm_get_volsw()
3288 unsigned int invert = mc->invert; in snd_soc_dapm_get_volsw()
3291 mutex_lock_nested(&card->dapm_mutex, SND_SOC_DAPM_CLASS_RUNTIME); in snd_soc_dapm_get_volsw()
3296 if (reg != mc->rreg) in snd_soc_dapm_get_volsw()
3297 reg_val = soc_dapm_read(dapm, mc->rreg); in snd_soc_dapm_get_volsw()
3300 rval = (reg_val >> mc->rshift) & mask; in snd_soc_dapm_get_volsw()
3308 mutex_unlock(&card->dapm_mutex); in snd_soc_dapm_get_volsw()
3311 ucontrol->value.integer.value[0] = max - val; in snd_soc_dapm_get_volsw()
3313 ucontrol->value.integer.value[0] = val; in snd_soc_dapm_get_volsw()
3317 ucontrol->value.integer.value[1] = max - rval; in snd_soc_dapm_get_volsw()
3319 ucontrol->value.integer.value[1] = rval; in snd_soc_dapm_get_volsw()
3327 * snd_soc_dapm_put_volsw - dapm mixer set callback
3339 struct snd_soc_card *card = dapm->card; in snd_soc_dapm_put_volsw()
3341 (struct soc_mixer_control *)kcontrol->private_value; in snd_soc_dapm_put_volsw()
3342 int reg = mc->reg; in snd_soc_dapm_put_volsw()
3343 unsigned int shift = mc->shift; in snd_soc_dapm_put_volsw()
3344 int max = mc->max; in snd_soc_dapm_put_volsw()
3346 unsigned int mask = (1 << width) - 1; in snd_soc_dapm_put_volsw()
3347 unsigned int invert = mc->invert; in snd_soc_dapm_put_volsw()
3349 int connect, rconnect = -1, change, reg_change = 0; in snd_soc_dapm_put_volsw()
3353 val = (ucontrol->value.integer.value[0] & mask); in snd_soc_dapm_put_volsw()
3357 val = max - val; in snd_soc_dapm_put_volsw()
3360 rval = (ucontrol->value.integer.value[1] & mask); in snd_soc_dapm_put_volsw()
3363 rval = max - rval; in snd_soc_dapm_put_volsw()
3366 mutex_lock_nested(&card->dapm_mutex, SND_SOC_DAPM_CLASS_RUNTIME); in snd_soc_dapm_put_volsw()
3370 dev_warn(dapm->dev, in snd_soc_dapm_put_volsw()
3372 kcontrol->id.name); in snd_soc_dapm_put_volsw()
3377 rval = rval << mc->rshift; in snd_soc_dapm_put_volsw()
3382 reg_change |= soc_dapm_test_bits(dapm, mc->rreg, in snd_soc_dapm_put_volsw()
3383 mask << mc->rshift, in snd_soc_dapm_put_volsw()
3391 update.reg2 = mc->rreg; in snd_soc_dapm_put_volsw()
3392 update.mask2 = mask << mc->rshift; in snd_soc_dapm_put_volsw()
3399 card->update = &update; in snd_soc_dapm_put_volsw()
3406 card->update = NULL; in snd_soc_dapm_put_volsw()
3409 mutex_unlock(&card->dapm_mutex); in snd_soc_dapm_put_volsw()
3419 * snd_soc_dapm_get_enum_double - dapm enumerated double mixer get callback
3431 struct snd_soc_card *card = dapm->card; in snd_soc_dapm_get_enum_double()
3432 struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; in snd_soc_dapm_get_enum_double()
3435 mutex_lock_nested(&card->dapm_mutex, SND_SOC_DAPM_CLASS_RUNTIME); in snd_soc_dapm_get_enum_double()
3436 if (e->reg != SND_SOC_NOPM && dapm_kcontrol_is_powered(kcontrol)) { in snd_soc_dapm_get_enum_double()
3437 reg_val = soc_dapm_read(dapm, e->reg); in snd_soc_dapm_get_enum_double()
3441 mutex_unlock(&card->dapm_mutex); in snd_soc_dapm_get_enum_double()
3443 val = (reg_val >> e->shift_l) & e->mask; in snd_soc_dapm_get_enum_double()
3444 ucontrol->value.enumerated.item[0] = snd_soc_enum_val_to_item(e, val); in snd_soc_dapm_get_enum_double()
3445 if (e->shift_l != e->shift_r) { in snd_soc_dapm_get_enum_double()
3446 val = (reg_val >> e->shift_r) & e->mask; in snd_soc_dapm_get_enum_double()
3448 ucontrol->value.enumerated.item[1] = val; in snd_soc_dapm_get_enum_double()
3456 * snd_soc_dapm_put_enum_double - dapm enumerated double mixer set callback
3468 struct snd_soc_card *card = dapm->card; in snd_soc_dapm_put_enum_double()
3469 struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; in snd_soc_dapm_put_enum_double()
3470 unsigned int *item = ucontrol->value.enumerated.item; in snd_soc_dapm_put_enum_double()
3476 if (item[0] >= e->items) in snd_soc_dapm_put_enum_double()
3477 return -EINVAL; in snd_soc_dapm_put_enum_double()
3479 val = snd_soc_enum_item_to_val(e, item[0]) << e->shift_l; in snd_soc_dapm_put_enum_double()
3480 mask = e->mask << e->shift_l; in snd_soc_dapm_put_enum_double()
3481 if (e->shift_l != e->shift_r) { in snd_soc_dapm_put_enum_double()
3482 if (item[1] > e->items) in snd_soc_dapm_put_enum_double()
3483 return -EINVAL; in snd_soc_dapm_put_enum_double()
3484 val |= snd_soc_enum_item_to_val(e, item[1]) << e->shift_r; in snd_soc_dapm_put_enum_double()
3485 mask |= e->mask << e->shift_r; in snd_soc_dapm_put_enum_double()
3488 mutex_lock_nested(&card->dapm_mutex, SND_SOC_DAPM_CLASS_RUNTIME); in snd_soc_dapm_put_enum_double()
3492 if (e->reg != SND_SOC_NOPM) in snd_soc_dapm_put_enum_double()
3493 reg_change = soc_dapm_test_bits(dapm, e->reg, mask, val); in snd_soc_dapm_put_enum_double()
3498 update.reg = e->reg; in snd_soc_dapm_put_enum_double()
3501 card->update = &update; in snd_soc_dapm_put_enum_double()
3507 card->update = NULL; in snd_soc_dapm_put_enum_double()
3510 mutex_unlock(&card->dapm_mutex); in snd_soc_dapm_put_enum_double()
3520 * snd_soc_dapm_info_pin_switch - Info for a pin switch
3530 uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN; in snd_soc_dapm_info_pin_switch()
3531 uinfo->count = 1; in snd_soc_dapm_info_pin_switch()
3532 uinfo->value.integer.min = 0; in snd_soc_dapm_info_pin_switch()
3533 uinfo->value.integer.max = 1; in snd_soc_dapm_info_pin_switch()
3540 * snd_soc_dapm_get_pin_switch - Get information for a pin switch
3549 const char *pin = (const char *)kcontrol->private_value; in snd_soc_dapm_get_pin_switch()
3551 mutex_lock_nested(&card->dapm_mutex, SND_SOC_DAPM_CLASS_RUNTIME); in snd_soc_dapm_get_pin_switch()
3553 ucontrol->value.integer.value[0] = in snd_soc_dapm_get_pin_switch()
3554 snd_soc_dapm_get_pin_status(&card->dapm, pin); in snd_soc_dapm_get_pin_switch()
3556 mutex_unlock(&card->dapm_mutex); in snd_soc_dapm_get_pin_switch()
3563 * snd_soc_dapm_put_pin_switch - Set information for a pin switch
3572 const char *pin = (const char *)kcontrol->private_value; in snd_soc_dapm_put_pin_switch()
3574 if (ucontrol->value.integer.value[0]) in snd_soc_dapm_put_pin_switch()
3575 snd_soc_dapm_enable_pin(&card->dapm, pin); in snd_soc_dapm_put_pin_switch()
3577 snd_soc_dapm_disable_pin(&card->dapm, pin); in snd_soc_dapm_put_pin_switch()
3579 snd_soc_dapm_sync(&card->dapm); in snd_soc_dapm_put_pin_switch()
3594 return ERR_PTR(-ENOMEM); in snd_soc_dapm_new_control_unlocked()
3596 switch (w->id) { in snd_soc_dapm_new_control_unlocked()
3598 w->regulator = devm_regulator_get(dapm->dev, w->name); in snd_soc_dapm_new_control_unlocked()
3599 if (IS_ERR(w->regulator)) { in snd_soc_dapm_new_control_unlocked()
3600 ret = PTR_ERR(w->regulator); in snd_soc_dapm_new_control_unlocked()
3604 if (w->on_val & SND_SOC_DAPM_REGULATOR_BYPASS) { in snd_soc_dapm_new_control_unlocked()
3605 ret = regulator_allow_bypass(w->regulator, true); in snd_soc_dapm_new_control_unlocked()
3607 dev_warn(dapm->dev, in snd_soc_dapm_new_control_unlocked()
3609 w->name, ret); in snd_soc_dapm_new_control_unlocked()
3613 w->pinctrl = devm_pinctrl_get(dapm->dev); in snd_soc_dapm_new_control_unlocked()
3614 if (IS_ERR(w->pinctrl)) { in snd_soc_dapm_new_control_unlocked()
3615 ret = PTR_ERR(w->pinctrl); in snd_soc_dapm_new_control_unlocked()
3623 w->clk = devm_clk_get(dapm->dev, w->name); in snd_soc_dapm_new_control_unlocked()
3624 if (IS_ERR(w->clk)) { in snd_soc_dapm_new_control_unlocked()
3625 ret = PTR_ERR(w->clk); in snd_soc_dapm_new_control_unlocked()
3635 w->name = kasprintf(GFP_KERNEL, "%s %s", prefix, widget->name); in snd_soc_dapm_new_control_unlocked()
3637 w->name = kstrdup_const(widget->name, GFP_KERNEL); in snd_soc_dapm_new_control_unlocked()
3638 if (w->name == NULL) { in snd_soc_dapm_new_control_unlocked()
3639 kfree_const(w->sname); in snd_soc_dapm_new_control_unlocked()
3641 return ERR_PTR(-ENOMEM); in snd_soc_dapm_new_control_unlocked()
3644 switch (w->id) { in snd_soc_dapm_new_control_unlocked()
3646 w->is_ep = SND_SOC_DAPM_EP_SOURCE; in snd_soc_dapm_new_control_unlocked()
3647 w->power_check = dapm_generic_check_power; in snd_soc_dapm_new_control_unlocked()
3650 if (!dapm->card->fully_routed) in snd_soc_dapm_new_control_unlocked()
3651 w->is_ep = SND_SOC_DAPM_EP_SOURCE; in snd_soc_dapm_new_control_unlocked()
3652 w->power_check = dapm_generic_check_power; in snd_soc_dapm_new_control_unlocked()
3656 w->is_ep = SND_SOC_DAPM_EP_SINK; in snd_soc_dapm_new_control_unlocked()
3657 w->power_check = dapm_generic_check_power; in snd_soc_dapm_new_control_unlocked()
3660 if (!dapm->card->fully_routed) in snd_soc_dapm_new_control_unlocked()
3661 w->is_ep = SND_SOC_DAPM_EP_SINK; in snd_soc_dapm_new_control_unlocked()
3662 w->power_check = dapm_generic_check_power; in snd_soc_dapm_new_control_unlocked()
3666 w->is_ep = SND_SOC_DAPM_EP_SOURCE; in snd_soc_dapm_new_control_unlocked()
3667 w->power_check = dapm_always_on_check_power; in snd_soc_dapm_new_control_unlocked()
3670 w->is_ep = SND_SOC_DAPM_EP_SINK; in snd_soc_dapm_new_control_unlocked()
3671 w->power_check = dapm_always_on_check_power; in snd_soc_dapm_new_control_unlocked()
3697 w->power_check = dapm_generic_check_power; in snd_soc_dapm_new_control_unlocked()
3704 w->is_supply = 1; in snd_soc_dapm_new_control_unlocked()
3705 w->power_check = dapm_supply_check_power; in snd_soc_dapm_new_control_unlocked()
3708 w->power_check = dapm_always_on_check_power; in snd_soc_dapm_new_control_unlocked()
3712 w->dapm = dapm; in snd_soc_dapm_new_control_unlocked()
3713 INIT_LIST_HEAD(&w->list); in snd_soc_dapm_new_control_unlocked()
3714 INIT_LIST_HEAD(&w->dirty); in snd_soc_dapm_new_control_unlocked()
3716 list_add_tail(&w->list, &dapm->card->widgets); in snd_soc_dapm_new_control_unlocked()
3719 INIT_LIST_HEAD(&w->edges[dir]); in snd_soc_dapm_new_control_unlocked()
3720 w->endpoints[dir] = -1; in snd_soc_dapm_new_control_unlocked()
3724 w->connected = 1; in snd_soc_dapm_new_control_unlocked()
3728 if (ret != -EPROBE_DEFER) in snd_soc_dapm_new_control_unlocked()
3729 dev_err(dapm->dev, "ASoC: Failed to request %s: %d\n", in snd_soc_dapm_new_control_unlocked()
3730 w->name, ret); in snd_soc_dapm_new_control_unlocked()
3732 kfree_const(w->sname); in snd_soc_dapm_new_control_unlocked()
3738 * snd_soc_dapm_new_control - create new dapm control
3752 mutex_lock_nested(&dapm->card->dapm_mutex, SND_SOC_DAPM_CLASS_RUNTIME); in snd_soc_dapm_new_control()
3754 mutex_unlock(&dapm->card->dapm_mutex); in snd_soc_dapm_new_control()
3761 * snd_soc_dapm_new_controls - create new dapm controls
3778 mutex_lock_nested(&dapm->card->dapm_mutex, SND_SOC_DAPM_CLASS_INIT); in snd_soc_dapm_new_controls()
3787 mutex_unlock(&dapm->card->dapm_mutex); in snd_soc_dapm_new_controls()
3807 return -ENOMEM; in snd_soc_dai_link_event_pre_pmu()
3811 ret = -ENOMEM; in snd_soc_dai_link_event_pre_pmu()
3815 substream->runtime = runtime; in snd_soc_dai_link_event_pre_pmu()
3817 substream->stream = SNDRV_PCM_STREAM_CAPTURE; in snd_soc_dai_link_event_pre_pmu()
3819 source = path->source->priv; in snd_soc_dai_link_event_pre_pmu()
3823 dev_err(source->dev, in snd_soc_dai_link_event_pre_pmu()
3827 snd_soc_dai_activate(source, substream->stream); in snd_soc_dai_link_event_pre_pmu()
3830 substream->stream = SNDRV_PCM_STREAM_PLAYBACK; in snd_soc_dai_link_event_pre_pmu()
3832 sink = path->sink->priv; in snd_soc_dai_link_event_pre_pmu()
3836 dev_err(sink->dev, in snd_soc_dai_link_event_pre_pmu()
3840 snd_soc_dai_activate(sink, substream->stream); in snd_soc_dai_link_event_pre_pmu()
3843 substream->hw_opened = 1; in snd_soc_dai_link_event_pre_pmu()
3850 config = rtd->dai_link->params + rtd->params_select; in snd_soc_dai_link_event_pre_pmu()
3852 dev_err(w->dapm->dev, "ASoC: link config missing\n"); in snd_soc_dai_link_event_pre_pmu()
3853 ret = -EINVAL; in snd_soc_dai_link_event_pre_pmu()
3858 if (config->formats) { in snd_soc_dai_link_event_pre_pmu()
3859 fmt = ffs(config->formats) - 1; in snd_soc_dai_link_event_pre_pmu()
3861 dev_warn(w->dapm->dev, "ASoC: Invalid format %llx specified\n", in snd_soc_dai_link_event_pre_pmu()
3862 config->formats); in snd_soc_dai_link_event_pre_pmu()
3864 ret = -EINVAL; in snd_soc_dai_link_event_pre_pmu()
3869 hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE)->min = in snd_soc_dai_link_event_pre_pmu()
3870 config->rate_min; in snd_soc_dai_link_event_pre_pmu()
3871 hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE)->max = in snd_soc_dai_link_event_pre_pmu()
3872 config->rate_max; in snd_soc_dai_link_event_pre_pmu()
3873 hw_param_interval(params, SNDRV_PCM_HW_PARAM_CHANNELS)->min in snd_soc_dai_link_event_pre_pmu()
3874 = config->channels_min; in snd_soc_dai_link_event_pre_pmu()
3875 hw_param_interval(params, SNDRV_PCM_HW_PARAM_CHANNELS)->max in snd_soc_dai_link_event_pre_pmu()
3876 = config->channels_max; in snd_soc_dai_link_event_pre_pmu()
3878 substream->stream = SNDRV_PCM_STREAM_CAPTURE; in snd_soc_dai_link_event_pre_pmu()
3880 source = path->source->priv; in snd_soc_dai_link_event_pre_pmu()
3889 substream->stream = SNDRV_PCM_STREAM_PLAYBACK; in snd_soc_dai_link_event_pre_pmu()
3891 sink = path->sink->priv; in snd_soc_dai_link_event_pre_pmu()
3900 runtime->format = params_format(params); in snd_soc_dai_link_event_pre_pmu()
3901 runtime->subformat = params_subformat(params); in snd_soc_dai_link_event_pre_pmu()
3902 runtime->channels = params_channels(params); in snd_soc_dai_link_event_pre_pmu()
3903 runtime->rate = params_rate(params); in snd_soc_dai_link_event_pre_pmu()
3915 struct snd_pcm_substream *substream = w->priv; in snd_soc_dai_link_event()
3916 int ret = 0, saved_stream = substream->stream; in snd_soc_dai_link_event()
3918 if (WARN_ON(list_empty(&w->edges[SND_SOC_DAPM_DIR_OUT]) || in snd_soc_dai_link_event()
3919 list_empty(&w->edges[SND_SOC_DAPM_DIR_IN]))) in snd_soc_dai_link_event()
3920 return -EINVAL; in snd_soc_dai_link_event()
3932 sink = path->sink->priv; in snd_soc_dai_link_event()
3936 if (ret != 0 && ret != -ENOTSUPP) in snd_soc_dai_link_event()
3937 dev_warn(sink->dev, in snd_soc_dai_link_event()
3945 sink = path->sink->priv; in snd_soc_dai_link_event()
3949 if (ret != 0 && ret != -ENOTSUPP) in snd_soc_dai_link_event()
3950 dev_warn(sink->dev, in snd_soc_dai_link_event()
3955 substream->stream = SNDRV_PCM_STREAM_CAPTURE; in snd_soc_dai_link_event()
3957 source = path->source->priv; in snd_soc_dai_link_event()
3961 substream->stream = SNDRV_PCM_STREAM_PLAYBACK; in snd_soc_dai_link_event()
3963 sink = path->sink->priv; in snd_soc_dai_link_event()
3967 substream->stream = SNDRV_PCM_STREAM_CAPTURE; in snd_soc_dai_link_event()
3969 source = path->source->priv; in snd_soc_dai_link_event()
3970 snd_soc_dai_deactivate(source, substream->stream); in snd_soc_dai_link_event()
3974 substream->stream = SNDRV_PCM_STREAM_PLAYBACK; in snd_soc_dai_link_event()
3976 sink = path->sink->priv; in snd_soc_dai_link_event()
3977 snd_soc_dai_deactivate(sink, substream->stream); in snd_soc_dai_link_event()
3983 kfree(substream->runtime); in snd_soc_dai_link_event()
3988 ret = -EINVAL; in snd_soc_dai_link_event()
3993 substream->stream = saved_stream; in snd_soc_dai_link_event()
4001 struct snd_soc_pcm_runtime *rtd = w->priv; in snd_soc_dapm_dai_link_get()
4003 ucontrol->value.enumerated.item[0] = rtd->params_select; in snd_soc_dapm_dai_link_get()
4012 struct snd_soc_pcm_runtime *rtd = w->priv; in snd_soc_dapm_dai_link_put()
4015 if (w->power) in snd_soc_dapm_dai_link_put()
4016 return -EBUSY; in snd_soc_dapm_dai_link_put()
4018 if (ucontrol->value.enumerated.item[0] == rtd->params_select) in snd_soc_dapm_dai_link_put()
4021 if (ucontrol->value.enumerated.item[0] >= rtd->dai_link->num_params) in snd_soc_dapm_dai_link_put()
4022 return -EINVAL; in snd_soc_dapm_dai_link_put()
4024 rtd->params_select = ucontrol->value.enumerated.item[0]; in snd_soc_dapm_dai_link_put()
4037 devm_kfree(card->dev, (void *)*private_value); in snd_soc_dapm_free_kcontrol()
4043 devm_kfree(card->dev, (void *)w_param_text[count]); in snd_soc_dapm_free_kcontrol()
4044 devm_kfree(card->dev, w_param_text); in snd_soc_dapm_free_kcontrol()
4067 if (!config->stream_name) { in snd_soc_dapm_alloc_kcontrol()
4068 dev_warn(card->dapm.dev, in snd_soc_dapm_alloc_kcontrol()
4072 devm_kasprintf(card->dev, GFP_KERNEL, in snd_soc_dapm_alloc_kcontrol()
4076 w_param_text[count] = devm_kmemdup(card->dev, in snd_soc_dapm_alloc_kcontrol()
4077 config->stream_name, in snd_soc_dapm_alloc_kcontrol()
4078 strlen(config->stream_name) + 1, in snd_soc_dapm_alloc_kcontrol()
4090 (unsigned long) devm_kmemdup(card->dev, in snd_soc_dapm_alloc_kcontrol()
4094 dev_err(card->dev, "ASoC: Failed to create control for %s widget\n", in snd_soc_dapm_alloc_kcontrol()
4100 kcontrol_news = devm_kmemdup(card->dev, &kcontrol_dai_link[0], in snd_soc_dapm_alloc_kcontrol()
4104 dev_err(card->dev, "ASoC: Failed to create control for %s widget\n", in snd_soc_dapm_alloc_kcontrol()
4128 link_name = devm_kasprintf(card->dev, GFP_KERNEL, "%s-%s", in snd_soc_dapm_new_dai()
4129 rtd->dai_link->name, id); in snd_soc_dapm_new_dai()
4131 return ERR_PTR(-ENOMEM); in snd_soc_dapm_new_dai()
4143 if (rtd->dai_link->num_params > 1) { in snd_soc_dapm_new_dai()
4144 w_param_text = devm_kcalloc(card->dev, in snd_soc_dapm_new_dai()
4145 rtd->dai_link->num_params, in snd_soc_dapm_new_dai()
4148 ret = -ENOMEM; in snd_soc_dapm_new_dai()
4156 rtd->dai_link->params, in snd_soc_dapm_new_dai()
4157 rtd->dai_link->num_params, in snd_soc_dapm_new_dai()
4160 ret = -ENOMEM; in snd_soc_dapm_new_dai()
4166 dev_dbg(card->dev, "ASoC: adding %s widget\n", link_name); in snd_soc_dapm_new_dai()
4168 w = snd_soc_dapm_new_control_unlocked(&card->dapm, &template); in snd_soc_dapm_new_dai()
4171 dev_err(rtd->dev, "ASoC: Failed to create %s widget: %d\n", in snd_soc_dapm_new_dai()
4176 w->priv = substream; in snd_soc_dapm_new_dai()
4181 devm_kfree(card->dev, (void *)template.kcontrol_news); in snd_soc_dapm_new_dai()
4183 rtd->dai_link->num_params, w_param_text); in snd_soc_dapm_new_dai()
4185 devm_kfree(card->dev, link_name); in snd_soc_dapm_new_dai()
4195 WARN_ON(dapm->dev != dai->dev); in snd_soc_dapm_new_dai_widgets()
4200 if (dai->driver->playback.stream_name) { in snd_soc_dapm_new_dai_widgets()
4202 template.name = dai->driver->playback.stream_name; in snd_soc_dapm_new_dai_widgets()
4203 template.sname = dai->driver->playback.stream_name; in snd_soc_dapm_new_dai_widgets()
4205 dev_dbg(dai->dev, "ASoC: adding %s widget\n", in snd_soc_dapm_new_dai_widgets()
4212 w->priv = dai; in snd_soc_dapm_new_dai_widgets()
4213 dai->playback_widget = w; in snd_soc_dapm_new_dai_widgets()
4216 if (dai->driver->capture.stream_name) { in snd_soc_dapm_new_dai_widgets()
4218 template.name = dai->driver->capture.stream_name; in snd_soc_dapm_new_dai_widgets()
4219 template.sname = dai->driver->capture.stream_name; in snd_soc_dapm_new_dai_widgets()
4221 dev_dbg(dai->dev, "ASoC: adding %s widget\n", in snd_soc_dapm_new_dai_widgets()
4228 w->priv = dai; in snd_soc_dapm_new_dai_widgets()
4229 dai->capture_widget = w; in snd_soc_dapm_new_dai_widgets()
4238 struct snd_soc_dapm_widget *src, *sink; in snd_soc_dapm_link_dai_widgets() local
4243 switch (dai_w->id) { in snd_soc_dapm_link_dai_widgets()
4252 if (!dai_w->priv) { in snd_soc_dapm_link_dai_widgets()
4253 dev_dbg(card->dev, "dai widget %s has no DAI\n", in snd_soc_dapm_link_dai_widgets()
4254 dai_w->name); in snd_soc_dapm_link_dai_widgets()
4258 dai = dai_w->priv; in snd_soc_dapm_link_dai_widgets()
4262 if (w->dapm != dai_w->dapm) in snd_soc_dapm_link_dai_widgets()
4265 switch (w->id) { in snd_soc_dapm_link_dai_widgets()
4273 if (!w->sname || !strstr(w->sname, dai_w->sname)) in snd_soc_dapm_link_dai_widgets()
4276 if (dai_w->id == snd_soc_dapm_dai_in) { in snd_soc_dapm_link_dai_widgets()
4277 src = dai_w; in snd_soc_dapm_link_dai_widgets()
4280 src = w; in snd_soc_dapm_link_dai_widgets()
4283 dev_dbg(dai->dev, "%s -> %s\n", src->name, sink->name); in snd_soc_dapm_link_dai_widgets()
4284 snd_soc_dapm_add_path(w->dapm, src, sink, NULL, NULL); in snd_soc_dapm_link_dai_widgets()
4293 struct snd_soc_dapm_widget *src, in dapm_connect_dai_routes() argument
4298 dev_dbg(dapm->dev, "connected DAI link %s:%s -> %s:%s\n", in dapm_connect_dai_routes()
4299 src_dai->component->name, src->name, in dapm_connect_dai_routes()
4300 sink_dai->component->name, sink->name); in dapm_connect_dai_routes()
4303 snd_soc_dapm_add_path(dapm, src, dai, NULL, NULL); in dapm_connect_dai_routes()
4304 src = dai; in dapm_connect_dai_routes()
4307 snd_soc_dapm_add_path(dapm, src, sink, NULL, NULL); in dapm_connect_dai_routes()
4315 struct snd_soc_dai_link *dai_link = rtd->dai_link; in dapm_connect_dai_pair()
4318 struct snd_pcm_str *streams = rtd->pcm->streams; in dapm_connect_dai_pair()
4320 if (dai_link->params) { in dapm_connect_dai_pair()
4321 playback_cpu = cpu_dai->capture_widget; in dapm_connect_dai_pair()
4322 capture_cpu = cpu_dai->playback_widget; in dapm_connect_dai_pair()
4324 playback_cpu = cpu_dai->playback_widget; in dapm_connect_dai_pair()
4325 capture_cpu = cpu_dai->capture_widget; in dapm_connect_dai_pair()
4329 codec = codec_dai->playback_widget; in dapm_connect_dai_pair()
4332 if (dai_link->params && !rtd->playback_widget) { in dapm_connect_dai_pair()
4337 rtd->playback_widget = dai; in dapm_connect_dai_pair()
4340 dapm_connect_dai_routes(&card->dapm, cpu_dai, playback_cpu, in dapm_connect_dai_pair()
4341 rtd->playback_widget, in dapm_connect_dai_pair()
4347 codec = codec_dai->capture_widget; in dapm_connect_dai_pair()
4350 if (dai_link->params && !rtd->capture_widget) { in dapm_connect_dai_pair()
4355 rtd->capture_widget = dai; in dapm_connect_dai_pair()
4358 dapm_connect_dai_routes(&card->dapm, codec_dai, codec, in dapm_connect_dai_pair()
4359 rtd->capture_widget, in dapm_connect_dai_pair()
4375 if (w->id == snd_soc_dapm_dai_in) { in soc_dapm_dai_stream_event()
4385 w->active = 1; in soc_dapm_dai_stream_event()
4386 w->is_ep = ep; in soc_dapm_dai_stream_event()
4389 w->active = 0; in soc_dapm_dai_stream_event()
4390 w->is_ep = 0; in soc_dapm_dai_stream_event()
4411 * CODEC<->CODEC links have no direct connection. in snd_soc_dapm_connect_dai_link_widgets()
4413 if (rtd->dai_link->dynamic) in snd_soc_dapm_connect_dai_link_widgets()
4416 if (rtd->num_cpus == 1) { in snd_soc_dapm_connect_dai_link_widgets()
4420 } else if (rtd->num_codecs == rtd->num_cpus) { in snd_soc_dapm_connect_dai_link_widgets()
4425 dev_err(card->dev, in snd_soc_dapm_connect_dai_link_widgets()
4440 dapm_power_widgets(rtd->card, event); in soc_dapm_stream_event()
4444 * snd_soc_dapm_stream_event - send a stream event to the dapm core
4457 struct snd_soc_card *card = rtd->card; in snd_soc_dapm_stream_event()
4459 mutex_lock_nested(&card->dapm_mutex, SND_SOC_DAPM_CLASS_RUNTIME); in snd_soc_dapm_stream_event()
4461 mutex_unlock(&card->dapm_mutex); in snd_soc_dapm_stream_event()
4474 rtd->pop_wait = 1; in snd_soc_dapm_stream_stop()
4476 &rtd->delayed_work, in snd_soc_dapm_stream_stop()
4477 msecs_to_jiffies(rtd->pmdown_time)); in snd_soc_dapm_stream_stop()
4488 * snd_soc_dapm_enable_pin_unlocked - enable pin.
4508 * snd_soc_dapm_enable_pin - enable pin.
4522 mutex_lock_nested(&dapm->card->dapm_mutex, SND_SOC_DAPM_CLASS_RUNTIME); in snd_soc_dapm_enable_pin()
4526 mutex_unlock(&dapm->card->dapm_mutex); in snd_soc_dapm_enable_pin()
4533 * snd_soc_dapm_force_enable_pin_unlocked - force a pin to be enabled
4552 dev_err(dapm->dev, "ASoC: unknown pin %s\n", pin); in snd_soc_dapm_force_enable_pin_unlocked()
4553 return -EINVAL; in snd_soc_dapm_force_enable_pin_unlocked()
4556 dev_dbg(w->dapm->dev, "ASoC: force enable pin %s\n", pin); in snd_soc_dapm_force_enable_pin_unlocked()
4557 if (!w->connected) { in snd_soc_dapm_force_enable_pin_unlocked()
4559 * w->force does not affect the number of input or output paths, in snd_soc_dapm_force_enable_pin_unlocked()
4560 * so we only have to recheck if w->connected is changed in snd_soc_dapm_force_enable_pin_unlocked()
4564 w->connected = 1; in snd_soc_dapm_force_enable_pin_unlocked()
4566 w->force = 1; in snd_soc_dapm_force_enable_pin_unlocked()
4574 * snd_soc_dapm_force_enable_pin - force a pin to be enabled
4590 mutex_lock_nested(&dapm->card->dapm_mutex, SND_SOC_DAPM_CLASS_RUNTIME); in snd_soc_dapm_force_enable_pin()
4594 mutex_unlock(&dapm->card->dapm_mutex); in snd_soc_dapm_force_enable_pin()
4601 * snd_soc_dapm_disable_pin_unlocked - disable pin.
4620 * snd_soc_dapm_disable_pin - disable pin.
4634 mutex_lock_nested(&dapm->card->dapm_mutex, SND_SOC_DAPM_CLASS_RUNTIME); in snd_soc_dapm_disable_pin()
4638 mutex_unlock(&dapm->card->dapm_mutex); in snd_soc_dapm_disable_pin()
4645 * snd_soc_dapm_nc_pin_unlocked - permanently disable pin.
4668 * snd_soc_dapm_nc_pin - permanently disable pin.
4685 mutex_lock_nested(&dapm->card->dapm_mutex, SND_SOC_DAPM_CLASS_RUNTIME); in snd_soc_dapm_nc_pin()
4689 mutex_unlock(&dapm->card->dapm_mutex); in snd_soc_dapm_nc_pin()
4696 * snd_soc_dapm_get_pin_status - get audio pin status
4700 * Get audio pin status - connected or disconnected.
4710 return w->connected; in snd_soc_dapm_get_pin_status()
4717 * snd_soc_dapm_ignore_suspend - ignore suspend status for DAPM endpoint
4733 dev_err(dapm->dev, "ASoC: unknown pin %s\n", pin); in snd_soc_dapm_ignore_suspend()
4734 return -EINVAL; in snd_soc_dapm_ignore_suspend()
4737 w->ignore_suspend = 1; in snd_soc_dapm_ignore_suspend()
4744 * snd_soc_dapm_free - free dapm resources
4753 list_del(&dapm->list); in snd_soc_dapm_free()
4761 dapm->card = card; in snd_soc_dapm_init()
4762 dapm->component = component; in snd_soc_dapm_init()
4763 dapm->bias_level = SND_SOC_BIAS_OFF; in snd_soc_dapm_init()
4766 dapm->dev = component->dev; in snd_soc_dapm_init()
4767 dapm->idle_bias_off = !component->driver->idle_bias_on, in snd_soc_dapm_init()
4768 dapm->suspend_bias_off = component->driver->suspend_bias_off; in snd_soc_dapm_init()
4770 dapm->dev = card->dev; in snd_soc_dapm_init()
4773 INIT_LIST_HEAD(&dapm->list); in snd_soc_dapm_init()
4775 list_add(&dapm->list, &card->dapm_list); in snd_soc_dapm_init()
4781 struct snd_soc_card *card = dapm->card; in soc_dapm_shutdown_dapm()
4786 mutex_lock(&card->dapm_mutex); in soc_dapm_shutdown_dapm()
4788 for_each_card_widgets(dapm->card, w) { in soc_dapm_shutdown_dapm()
4789 if (w->dapm != dapm) in soc_dapm_shutdown_dapm()
4791 if (w->power) { in soc_dapm_shutdown_dapm()
4793 w->new_power = 0; in soc_dapm_shutdown_dapm()
4802 if (dapm->bias_level == SND_SOC_BIAS_ON) in soc_dapm_shutdown_dapm()
4806 if (dapm->bias_level == SND_SOC_BIAS_PREPARE) in soc_dapm_shutdown_dapm()
4811 mutex_unlock(&card->dapm_mutex); in soc_dapm_shutdown_dapm()
4815 * snd_soc_dapm_shutdown - callback for system shutdown
4822 if (dapm != &card->dapm) { in snd_soc_dapm_shutdown()
4824 if (dapm->bias_level == SND_SOC_BIAS_STANDBY) in snd_soc_dapm_shutdown()
4830 soc_dapm_shutdown_dapm(&card->dapm); in snd_soc_dapm_shutdown()
4831 if (card->dapm.bias_level == SND_SOC_BIAS_STANDBY) in snd_soc_dapm_shutdown()
4832 snd_soc_dapm_set_bias_level(&card->dapm, in snd_soc_dapm_shutdown()