Lines Matching +full:dac +full:- +full:full +full:- +full:bias +full:- +full:current

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
14 // o Automatic Mic Bias support
15 // o Jack insertion power event initiation - e.g. hp insertion will enable
43 #define DAPM_UPDATE_STAT(widget, val) widget->dapm->card->dapm_stats.val++;
68 /* dapm power sequences - make this per codec in the future */
153 if (snd_soc_card_is_instantiated(dapm->card)) in dapm_assert_locked()
186 return !list_empty(&w->dirty); in dapm_dirty_widget()
191 dapm_assert_locked(w->dapm); in dapm_mark_dirty()
194 dev_vdbg(w->dapm->dev, "Marking %s dirty due to %s\n", in dapm_mark_dirty()
195 w->name, reason); in dapm_mark_dirty()
196 list_add_tail(&w->dirty, &w->dapm->card->dapm_dirty); in dapm_mark_dirty()
215 dapm_assert_locked(w->dapm); in dapm_widget_invalidate_paths()
217 if (w->endpoints[dir] == -1) in dapm_widget_invalidate_paths()
220 list_add_tail(&w->work_list, &list); in dapm_widget_invalidate_paths()
221 w->endpoints[dir] = -1; in dapm_widget_invalidate_paths()
225 if (p->is_supply || p->weak || !p->connect) in dapm_widget_invalidate_paths()
227 node = p->node[rdir]; in dapm_widget_invalidate_paths()
228 if (node->endpoints[dir] != -1) { in dapm_widget_invalidate_paths()
229 node->endpoints[dir] = -1; in dapm_widget_invalidate_paths()
230 list_add_tail(&node->work_list, &list); in dapm_widget_invalidate_paths()
237 * dapm_widget_invalidate_input_paths() - Invalidate the cached number of
254 * dapm_widget_invalidate_output_paths() - Invalidate the cached number of
271 * dapm_path_invalidate() - Invalidates the cached number of inputs and outputs
287 if (p->weak || p->is_supply) in dapm_path_invalidate()
294 * so there is no need to re-check the path. in dapm_path_invalidate()
296 if (p->source->endpoints[SND_SOC_DAPM_DIR_IN] != 0) in dapm_path_invalidate()
297 dapm_widget_invalidate_input_paths(p->sink); in dapm_path_invalidate()
298 if (p->sink->endpoints[SND_SOC_DAPM_DIR_OUT] != 0) in dapm_path_invalidate()
299 dapm_widget_invalidate_output_paths(p->source); in dapm_path_invalidate()
309 if (w->is_ep) { in dapm_mark_endpoints_dirty()
311 if (w->is_ep & SND_SOC_DAPM_EP_SINK) in dapm_mark_endpoints_dirty()
313 if (w->is_ep & SND_SOC_DAPM_EP_SOURCE) in dapm_mark_endpoints_dirty()
333 w->name = kasprintf(GFP_KERNEL, "%s %s", prefix, _widget->name); in dapm_cnew_widget()
335 w->name = kstrdup_const(_widget->name, GFP_KERNEL); in dapm_cnew_widget()
336 if (!w->name) in dapm_cnew_widget()
339 if (_widget->sname) { in dapm_cnew_widget()
340 w->sname = kstrdup_const(_widget->sname, GFP_KERNEL); in dapm_cnew_widget()
341 if (!w->sname) { in dapm_cnew_widget()
342 kfree_const(w->name); in dapm_cnew_widget()
368 return -ENOMEM; in dapm_kcontrol_data_alloc()
370 INIT_LIST_HEAD(&data->paths); in dapm_kcontrol_data_alloc()
372 switch (widget->id) { in dapm_kcontrol_data_alloc()
376 mc = (struct soc_mixer_control *)kcontrol->private_value; in dapm_kcontrol_data_alloc()
378 if (mc->autodisable) { in dapm_kcontrol_data_alloc()
382 dev_warn(widget->dapm->dev, in dapm_kcontrol_data_alloc()
389 ret = -ENOMEM; in dapm_kcontrol_data_alloc()
394 template.reg = mc->reg; in dapm_kcontrol_data_alloc()
395 template.mask = (1 << fls(mc->max)) - 1; in dapm_kcontrol_data_alloc()
396 template.shift = mc->shift; in dapm_kcontrol_data_alloc()
397 if (mc->invert) in dapm_kcontrol_data_alloc()
398 template.off_val = mc->max; in dapm_kcontrol_data_alloc()
405 data->value = template.on_val; in dapm_kcontrol_data_alloc()
407 data->widget = in dapm_kcontrol_data_alloc()
408 snd_soc_dapm_new_control_unlocked(widget->dapm, in dapm_kcontrol_data_alloc()
411 if (IS_ERR(data->widget)) { in dapm_kcontrol_data_alloc()
412 ret = PTR_ERR(data->widget); in dapm_kcontrol_data_alloc()
419 e = (struct soc_enum *)kcontrol->private_value; in dapm_kcontrol_data_alloc()
421 if (e->autodisable) { in dapm_kcontrol_data_alloc()
427 ret = -ENOMEM; in dapm_kcontrol_data_alloc()
432 template.reg = e->reg; in dapm_kcontrol_data_alloc()
433 template.mask = e->mask; in dapm_kcontrol_data_alloc()
434 template.shift = e->shift_l; in dapm_kcontrol_data_alloc()
440 data->value = template.on_val; in dapm_kcontrol_data_alloc()
442 data->widget = snd_soc_dapm_new_control_unlocked( in dapm_kcontrol_data_alloc()
443 widget->dapm, &template); in dapm_kcontrol_data_alloc()
445 if (IS_ERR(data->widget)) { in dapm_kcontrol_data_alloc()
446 ret = PTR_ERR(data->widget); in dapm_kcontrol_data_alloc()
450 snd_soc_dapm_add_path(widget->dapm, data->widget, in dapm_kcontrol_data_alloc()
452 } else if (e->reg != SND_SOC_NOPM) { in dapm_kcontrol_data_alloc()
453 data->value = soc_dapm_read(widget->dapm, e->reg) & in dapm_kcontrol_data_alloc()
454 (e->mask << e->shift_l); in dapm_kcontrol_data_alloc()
461 kcontrol->private_data = data; in dapm_kcontrol_data_alloc()
474 list_del(&data->paths); in dapm_kcontrol_free()
475 kfree(data->wlist); in dapm_kcontrol_free()
484 return data->wlist; in dapm_kcontrol_get_wlist()
494 if (data->wlist) in dapm_kcontrol_add_widget()
495 n = data->wlist->num_widgets + 1; in dapm_kcontrol_add_widget()
499 new_wlist = krealloc(data->wlist, in dapm_kcontrol_add_widget()
503 return -ENOMEM; in dapm_kcontrol_add_widget()
505 new_wlist->num_widgets = n; in dapm_kcontrol_add_widget()
506 new_wlist->widgets[n - 1] = widget; in dapm_kcontrol_add_widget()
508 data->wlist = new_wlist; in dapm_kcontrol_add_widget()
518 list_add_tail(&path->list_kcontrol, &data->paths); in dapm_kcontrol_add_path()
525 if (!data->widget) in dapm_kcontrol_is_powered()
528 return data->widget->power; in dapm_kcontrol_is_powered()
536 return &data->paths; in dapm_kcontrol_get_path_list()
547 return data->value; in dapm_kcontrol_get_value()
556 if (data->value == value) in dapm_kcontrol_set_value()
559 if (data->widget) { in dapm_kcontrol_set_value()
560 switch (dapm_kcontrol_get_wlist(kcontrol)->widgets[0]->id) { in dapm_kcontrol_set_value()
564 data->widget->on_val = value & data->widget->mask; in dapm_kcontrol_set_value()
568 data->widget->on_val = value >> data->widget->shift; in dapm_kcontrol_set_value()
571 data->widget->on_val = value; in dapm_kcontrol_set_value()
576 data->value = value; in dapm_kcontrol_set_value()
582 * snd_soc_dapm_kcontrol_widget() - Returns the widget associated to a
589 return dapm_kcontrol_get_wlist(kcontrol)->widgets[0]; in snd_soc_dapm_kcontrol_widget()
594 * snd_soc_dapm_kcontrol_dapm() - Returns the dapm context associated to a
604 return dapm_kcontrol_get_wlist(kcontrol)->widgets[0]->dapm; in snd_soc_dapm_kcontrol_dapm()
614 memset(&card->dapm_stats, 0, sizeof(card->dapm_stats)); in dapm_reset()
617 w->new_power = w->power; in dapm_reset()
618 w->power_checked = false; in dapm_reset()
624 if (!dapm->component) in soc_dapm_prefix()
626 return dapm->component->name_prefix; in soc_dapm_prefix()
631 if (!dapm->component) in soc_dapm_read()
632 return -EIO; in soc_dapm_read()
633 return snd_soc_component_read(dapm->component, reg); in soc_dapm_read()
639 if (!dapm->component) in soc_dapm_update_bits()
640 return -EIO; in soc_dapm_update_bits()
641 return snd_soc_component_update_bits(dapm->component, reg, in soc_dapm_update_bits()
648 if (!dapm->component) in soc_dapm_test_bits()
649 return -EIO; in soc_dapm_test_bits()
650 return snd_soc_component_test_bits(dapm->component, reg, mask, value); in soc_dapm_test_bits()
655 if (dapm->component) in soc_dapm_async_complete()
656 snd_soc_component_async_complete(dapm->component); in soc_dapm_async_complete()
663 struct list_head *wlist = &w->dapm->card->widgets; in dapm_wcache_lookup()
668 if (!strcmp(name, w->name)) in dapm_wcache_lookup()
680 * snd_soc_dapm_force_bias_level() - Sets the DAPM bias level
684 * Forces the DAPM bias level to a specific state. It will call the bias level
687 * the normal bias level sequencing, meaning any intermediate states between the
688 * current and the target state will not be entered.
690 * Note that the change in bias level is only temporary and the next time
701 if (dapm->component) in snd_soc_dapm_force_bias_level()
702 ret = snd_soc_component_set_bias_level(dapm->component, level); in snd_soc_dapm_force_bias_level()
705 dapm->bias_level = level; in snd_soc_dapm_force_bias_level()
712 * snd_soc_dapm_set_bias_level - set the bias level for the system
716 * Configure the bias (power) levels for the SoC audio device.
723 struct snd_soc_card *card = dapm->card; in snd_soc_dapm_set_bias_level()
732 if (dapm != &card->dapm) in snd_soc_dapm_set_bias_level()
750 const struct snd_kcontrol_new *kcontrol = &w->kcontrol_news[0]; in dapm_connect_mux()
751 struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; in dapm_connect_mux()
755 if (e->reg != SND_SOC_NOPM) { in dapm_connect_mux()
757 val = soc_dapm_read(dapm, e->reg); in dapm_connect_mux()
758 val = (val >> e->shift_l) & e->mask; in dapm_connect_mux()
770 i = match_string(e->texts, e->items, control_name); in dapm_connect_mux()
772 return -ENODEV; in dapm_connect_mux()
774 path->name = e->texts[i]; in dapm_connect_mux()
775 path->connect = (i == item); in dapm_connect_mux()
785 p->sink->kcontrol_news[i].private_value; in dapm_set_mixer_path_status()
786 unsigned int reg = mc->reg; in dapm_set_mixer_path_status()
787 unsigned int invert = mc->invert; in dapm_set_mixer_path_status()
790 unsigned int shift = mc->shift; in dapm_set_mixer_path_status()
791 unsigned int max = mc->max; in dapm_set_mixer_path_status()
792 unsigned int mask = (1 << fls(max)) - 1; in dapm_set_mixer_path_status()
793 unsigned int val = soc_dapm_read(p->sink->dapm, reg); in dapm_set_mixer_path_status()
808 if (reg != mc->rreg) in dapm_set_mixer_path_status()
809 val = soc_dapm_read(p->sink->dapm, mc->rreg); in dapm_set_mixer_path_status()
810 val = (val >> mc->rshift) & mask; in dapm_set_mixer_path_status()
815 val = max - val; in dapm_set_mixer_path_status()
816 p->connect = !!val; in dapm_set_mixer_path_status()
824 p->connect = invert; in dapm_set_mixer_path_status()
835 for (i = 0; i < path->sink->num_kcontrols; i++) { in dapm_connect_mixer()
836 if (!strcmp(control_name, path->sink->kcontrol_news[i].name)) { in dapm_connect_mixer()
837 path->name = path->sink->kcontrol_news[i].name; in dapm_connect_mixer()
842 return -ENODEV; in dapm_connect_mixer()
855 for_each_card_widgets(dapm->card, w) { in dapm_is_shared_kcontrol()
856 if (w == kcontrolw || w->dapm != kcontrolw->dapm) in dapm_is_shared_kcontrol()
858 for (i = 0; i < w->num_kcontrols; i++) { in dapm_is_shared_kcontrol()
859 if (&w->kcontrol_news[i] == kcontrol_new) { in dapm_is_shared_kcontrol()
860 if (w->kcontrols) in dapm_is_shared_kcontrol()
861 *kcontrol = w->kcontrols[i]; in dapm_is_shared_kcontrol()
877 struct snd_soc_dapm_context *dapm = w->dapm; in dapm_create_or_share_kcontrol()
878 struct snd_card *card = dapm->card->snd_card; in dapm_create_or_share_kcontrol()
894 shared = dapm_is_shared_kcontrol(dapm, w, &w->kcontrol_news[kci], in dapm_create_or_share_kcontrol()
902 switch (w->id) { in dapm_create_or_share_kcontrol()
921 return -EINVAL; in dapm_create_or_share_kcontrol()
924 if (w->no_wname_in_kcontrol_name) in dapm_create_or_share_kcontrol()
935 w->name + prefix_len, in dapm_create_or_share_kcontrol()
936 w->kcontrol_news[kci].name); in dapm_create_or_share_kcontrol()
938 return -ENOMEM; in dapm_create_or_share_kcontrol()
943 name = w->name + prefix_len; in dapm_create_or_share_kcontrol()
946 name = w->kcontrol_news[kci].name; in dapm_create_or_share_kcontrol()
949 kcontrol = snd_soc_cnew(&w->kcontrol_news[kci], NULL, name, in dapm_create_or_share_kcontrol()
952 ret = -ENOMEM; in dapm_create_or_share_kcontrol()
956 kcontrol->private_free = dapm_kcontrol_free; in dapm_create_or_share_kcontrol()
966 dev_err(dapm->dev, in dapm_create_or_share_kcontrol()
968 w->name, name, ret); in dapm_create_or_share_kcontrol()
975 w->kcontrols[kci] = kcontrol; in dapm_create_or_share_kcontrol()
991 for (i = 0; i < w->num_kcontrols; i++) { in dapm_new_mixer()
995 if (path->name != (char *)w->kcontrol_news[i].name) in dapm_new_mixer()
998 if (!w->kcontrols[i]) { in dapm_new_mixer()
1004 dapm_kcontrol_add_path(w->kcontrols[i], path); in dapm_new_mixer()
1006 data = snd_kcontrol_chip(w->kcontrols[i]); in dapm_new_mixer()
1007 if (data->widget) in dapm_new_mixer()
1008 snd_soc_dapm_add_path(data->widget->dapm, in dapm_new_mixer()
1009 data->widget, in dapm_new_mixer()
1010 path->source, in dapm_new_mixer()
1021 struct snd_soc_dapm_context *dapm = w->dapm; in dapm_new_mux()
1027 switch (w->id) { in dapm_new_mux()
1037 return -EINVAL; in dapm_new_mux()
1040 if (w->num_kcontrols != 1) { in dapm_new_mux()
1041 dev_err(dapm->dev, in dapm_new_mux()
1043 w->name); in dapm_new_mux()
1044 return -EINVAL; in dapm_new_mux()
1047 if (list_empty(&w->edges[dir])) { in dapm_new_mux()
1048 dev_err(dapm->dev, "ASoC: %s %s has no paths\n", type, w->name); in dapm_new_mux()
1049 return -EINVAL; in dapm_new_mux()
1057 if (path->name) in dapm_new_mux()
1058 dapm_kcontrol_add_path(w->kcontrols[0], path); in dapm_new_mux()
1069 for (i = 0; i < w->num_kcontrols; i++) { in dapm_new_pga()
1082 struct snd_soc_pcm_runtime *rtd = w->priv; in dapm_new_dai_link()
1085 if (rtd->dai_link->num_c2c_params <= 1) in dapm_new_dai_link()
1089 for (i = 0; i < w->num_kcontrols; i++) { in dapm_new_dai_link()
1090 struct snd_soc_dapm_context *dapm = w->dapm; in dapm_new_dai_link()
1091 struct snd_card *card = dapm->card->snd_card; in dapm_new_dai_link()
1092 struct snd_kcontrol *kcontrol = snd_soc_cnew(&w->kcontrol_news[i], in dapm_new_dai_link()
1093 w, w->name, NULL); in dapm_new_dai_link()
1097 dev_err(dapm->dev, in dapm_new_dai_link()
1099 w->name, w->kcontrol_news[i].name, ret); in dapm_new_dai_link()
1102 kcontrol->private_data = w; in dapm_new_dai_link()
1103 w->kcontrols[i] = kcontrol; in dapm_new_dai_link()
1110 * the ALSA card - when we are suspending the ALSA state for the card
1115 int level = snd_power_get_state(widget->dapm->card->snd_card); in snd_soc_dapm_suspend_check()
1120 if (widget->ignore_suspend) in snd_soc_dapm_suspend_check()
1121 dev_dbg(widget->dapm->dev, "ASoC: %s ignoring suspend\n", in snd_soc_dapm_suspend_check()
1122 widget->name); in snd_soc_dapm_suspend_check()
1123 return widget->ignore_suspend; in snd_soc_dapm_suspend_check()
1147 return -ENOMEM; in dapm_widget_list_create()
1149 (*list)->num_widgets = size; in dapm_widget_list_create()
1152 (*list)->widgets[i++] = w; in dapm_widget_list_create()
1154 (*list)->num_widgets = i; in dapm_widget_list_create()
1170 widget->endpoints[dir] = -1; in invalidate_paths_ep()
1173 if (path->weak || path->is_supply) in invalidate_paths_ep()
1176 if (path->walking) in invalidate_paths_ep()
1179 if (path->connect) { in invalidate_paths_ep()
1180 path->walking = 1; in invalidate_paths_ep()
1181 invalidate_paths_ep(path->node[dir], dir); in invalidate_paths_ep()
1182 path->walking = 0; in invalidate_paths_ep()
1206 if (widget->endpoints[dir] >= 0) in is_connected_ep()
1207 return widget->endpoints[dir]; in is_connected_ep()
1213 list_add_tail(&widget->work_list, list); in is_connected_ep()
1220 if ((widget->is_ep & SND_SOC_DAPM_DIR_TO_EP(dir)) && widget->connected) { in is_connected_ep()
1221 widget->endpoints[dir] = snd_soc_dapm_suspend_check(widget); in is_connected_ep()
1222 return widget->endpoints[dir]; in is_connected_ep()
1228 if (path->weak || path->is_supply) in is_connected_ep()
1231 if (path->walking) in is_connected_ep()
1236 if (path->connect) { in is_connected_ep()
1237 path->walking = 1; in is_connected_ep()
1238 con += fn(path->node[dir], list, custom_stop_condition); in is_connected_ep()
1239 path->walking = 0; in is_connected_ep()
1243 widget->endpoints[dir] = con; in is_connected_ep()
1285 * snd_soc_dapm_dai_get_connected_widgets - query audio path and it's widgets.
1294 * current mixer and mux kcontrol settings. Creates list of valid widgets.
1308 struct snd_soc_card *card = dai->component->card; in snd_soc_dapm_dai_get_connected_widgets()
1354 soc_dapm_async_complete(w->dapm); in dapm_regulator_event()
1357 if (w->on_val & SND_SOC_DAPM_REGULATOR_BYPASS) { in dapm_regulator_event()
1358 ret = regulator_allow_bypass(w->regulator, false); in dapm_regulator_event()
1360 dev_warn(w->dapm->dev, in dapm_regulator_event()
1362 w->name, ret); in dapm_regulator_event()
1365 return regulator_enable(w->regulator); in dapm_regulator_event()
1367 if (w->on_val & SND_SOC_DAPM_REGULATOR_BYPASS) { in dapm_regulator_event()
1368 ret = regulator_allow_bypass(w->regulator, true); in dapm_regulator_event()
1370 dev_warn(w->dapm->dev, in dapm_regulator_event()
1372 w->name, ret); in dapm_regulator_event()
1375 return regulator_disable_deferred(w->regulator, w->shift); in dapm_regulator_event()
1386 struct snd_soc_dapm_pinctrl_priv *priv = w->priv; in dapm_pinctrl_event()
1387 struct pinctrl *p = w->pinctrl; in dapm_pinctrl_event()
1391 return -EIO; in dapm_pinctrl_event()
1394 s = pinctrl_lookup_state(p, priv->active_state); in dapm_pinctrl_event()
1396 s = pinctrl_lookup_state(p, priv->sleep_state); in dapm_pinctrl_event()
1411 if (!w->clk) in dapm_clock_event()
1412 return -EIO; in dapm_clock_event()
1414 soc_dapm_async_complete(w->dapm); in dapm_clock_event()
1417 return clk_prepare_enable(w->clk); in dapm_clock_event()
1419 clk_disable_unprepare(w->clk); in dapm_clock_event()
1429 if (w->power_checked) in dapm_widget_power_check()
1430 return w->new_power; in dapm_widget_power_check()
1432 if (w->force) in dapm_widget_power_check()
1433 w->new_power = 1; in dapm_widget_power_check()
1435 w->new_power = w->power_check(w); in dapm_widget_power_check()
1437 w->power_checked = true; in dapm_widget_power_check()
1439 return w->new_power; in dapm_widget_power_check()
1465 if (path->weak) in dapm_supply_check_power()
1468 if (path->connected && in dapm_supply_check_power()
1469 !path->connected(path->source, path->sink)) in dapm_supply_check_power()
1472 if (dapm_widget_power_check(path->sink)) in dapm_supply_check_power()
1481 return w->connected; in dapm_always_on_check_power()
1498 WARN_ONCE(sort[a->id] == 0, "offset a->id %d not initialized\n", a->id); in dapm_seq_compare()
1499 WARN_ONCE(sort[b->id] == 0, "offset b->id %d not initialized\n", b->id); in dapm_seq_compare()
1501 if (sort[a->id] != sort[b->id]) in dapm_seq_compare()
1502 return sort[a->id] - sort[b->id]; in dapm_seq_compare()
1503 if (a->subseq != b->subseq) { in dapm_seq_compare()
1505 return a->subseq - b->subseq; in dapm_seq_compare()
1507 return b->subseq - a->subseq; in dapm_seq_compare()
1509 if (a->reg != b->reg) in dapm_seq_compare()
1510 return a->reg - b->reg; in dapm_seq_compare()
1511 if (a->dapm != b->dapm) in dapm_seq_compare()
1512 return (unsigned long)a->dapm - (unsigned long)b->dapm; in dapm_seq_compare()
1526 list_add_tail(&new_widget->power_list, &w->power_list); in dapm_seq_insert()
1530 list_add_tail(&new_widget->power_list, list); in dapm_seq_insert()
1569 if (w->new_power != power) in dapm_seq_check_event()
1572 if (w->event && (w->event_flags & event)) { in dapm_seq_check_event()
1575 pop_dbg(w->dapm->dev, card->pop_time, "pop test : %s %s\n", in dapm_seq_check_event()
1576 w->name, ev_name); in dapm_seq_check_event()
1577 soc_dapm_async_complete(w->dapm); in dapm_seq_check_event()
1579 ret = w->event(w, NULL, event); in dapm_seq_check_event()
1582 dev_err(w->dapm->dev, "ASoC: %s: %s event failed: %d\n", in dapm_seq_check_event()
1583 ev_name, w->name, ret); in dapm_seq_check_event()
1598 reg = w->reg; in dapm_seq_run_coalesced()
1599 dapm = w->dapm; in dapm_seq_run_coalesced()
1602 WARN_ON(reg != w->reg || dapm != w->dapm); in dapm_seq_run_coalesced()
1603 w->power = w->new_power; in dapm_seq_run_coalesced()
1605 mask |= w->mask << w->shift; in dapm_seq_run_coalesced()
1606 if (w->power) in dapm_seq_run_coalesced()
1607 value |= w->on_val << w->shift; in dapm_seq_run_coalesced()
1609 value |= w->off_val << w->shift; in dapm_seq_run_coalesced()
1611 pop_dbg(dapm->dev, card->pop_time, in dapm_seq_run_coalesced()
1613 w->name, reg, value, mask); in dapm_seq_run_coalesced()
1625 pop_dbg(dapm->dev, card->pop_time, in dapm_seq_run_coalesced()
1627 value, mask, reg, card->pop_time); in dapm_seq_run_coalesced()
1628 pop_wait(card->pop_time); in dapm_seq_run_coalesced()
1640 * We walk over a pre-sorted list of widgets to apply power to. In
1652 int cur_sort = -1; in dapm_seq_run()
1653 int cur_subseq = -1; in dapm_seq_run()
1668 if (sort[w->id] != cur_sort || w->reg != cur_reg || in dapm_seq_run()
1669 w->dapm != cur_dapm || w->subseq != cur_subseq) { in dapm_seq_run()
1673 if (cur_dapm && cur_dapm->component) { in dapm_seq_run()
1677 cur_dapm->component, in dapm_seq_run()
1681 if (cur_dapm && w->dapm != cur_dapm) in dapm_seq_run()
1685 cur_sort = -1; in dapm_seq_run()
1691 switch (w->id) { in dapm_seq_run()
1693 if (!w->event) in dapm_seq_run()
1697 ret = w->event(w, in dapm_seq_run()
1700 ret = w->event(w, in dapm_seq_run()
1705 if (!w->event) in dapm_seq_run()
1709 ret = w->event(w, in dapm_seq_run()
1712 ret = w->event(w, in dapm_seq_run()
1718 cur_sort = sort[w->id]; in dapm_seq_run()
1719 cur_subseq = w->subseq; in dapm_seq_run()
1720 cur_reg = w->reg; in dapm_seq_run()
1721 cur_dapm = w->dapm; in dapm_seq_run()
1722 list_move(&w->power_list, &pending); in dapm_seq_run()
1727 dev_err(w->dapm->dev, in dapm_seq_run()
1734 if (cur_dapm && cur_dapm->component) { in dapm_seq_run()
1738 cur_dapm->component, in dapm_seq_run()
1753 if (!update || !dapm_kcontrol_is_powered(update->kcontrol)) in dapm_widget_update()
1756 wlist = dapm_kcontrol_get_wlist(update->kcontrol); in dapm_widget_update()
1759 if (w->event && (w->event_flags & SND_SOC_DAPM_PRE_REG)) { in dapm_widget_update()
1760 ret = w->event(w, update->kcontrol, SND_SOC_DAPM_PRE_REG); in dapm_widget_update()
1762 dev_err(w->dapm->dev, "ASoC: %s DAPM pre-event failed: %d\n", in dapm_widget_update()
1763 w->name, ret); in dapm_widget_update()
1770 ret = soc_dapm_update_bits(w->dapm, update->reg, update->mask, in dapm_widget_update()
1771 update->val); in dapm_widget_update()
1773 dev_err(w->dapm->dev, "ASoC: %s DAPM update failed: %d\n", in dapm_widget_update()
1774 w->name, ret); in dapm_widget_update()
1776 if (update->has_second_set) { in dapm_widget_update()
1777 ret = soc_dapm_update_bits(w->dapm, update->reg2, in dapm_widget_update()
1778 update->mask2, update->val2); in dapm_widget_update()
1780 dev_err(w->dapm->dev, in dapm_widget_update()
1782 w->name, ret); in dapm_widget_update()
1786 if (w->event && (w->event_flags & SND_SOC_DAPM_POST_REG)) { in dapm_widget_update()
1787 ret = w->event(w, update->kcontrol, SND_SOC_DAPM_POST_REG); in dapm_widget_update()
1789 dev_err(w->dapm->dev, "ASoC: %s DAPM post-event failed: %d\n", in dapm_widget_update()
1790 w->name, ret); in dapm_widget_update()
1795 /* Async callback run prior to DAPM sequences - brings to _PREPARE if
1804 if (d->bias_level == SND_SOC_BIAS_OFF && in dapm_pre_sequence_async()
1805 d->target_bias_level != SND_SOC_BIAS_OFF) { in dapm_pre_sequence_async()
1806 if (d->dev && cookie) in dapm_pre_sequence_async()
1807 pm_runtime_get_sync(d->dev); in dapm_pre_sequence_async()
1811 dev_err(d->dev, in dapm_pre_sequence_async()
1812 "ASoC: Failed to turn on bias: %d\n", ret); in dapm_pre_sequence_async()
1816 if ((d->target_bias_level == SND_SOC_BIAS_ON && in dapm_pre_sequence_async()
1817 d->bias_level != SND_SOC_BIAS_ON) || in dapm_pre_sequence_async()
1818 (d->target_bias_level != SND_SOC_BIAS_ON && in dapm_pre_sequence_async()
1819 d->bias_level == SND_SOC_BIAS_ON)) { in dapm_pre_sequence_async()
1822 dev_err(d->dev, in dapm_pre_sequence_async()
1823 "ASoC: Failed to prepare bias: %d\n", ret); in dapm_pre_sequence_async()
1827 /* Async callback run prior to DAPM sequences - brings to their final
1835 /* If we just powered the last thing off drop to standby bias */ in dapm_post_sequence_async()
1836 if (d->bias_level == SND_SOC_BIAS_PREPARE && in dapm_post_sequence_async()
1837 (d->target_bias_level == SND_SOC_BIAS_STANDBY || in dapm_post_sequence_async()
1838 d->target_bias_level == SND_SOC_BIAS_OFF)) { in dapm_post_sequence_async()
1841 dev_err(d->dev, "ASoC: Failed to apply standby bias: %d\n", in dapm_post_sequence_async()
1845 /* If we're in standby and can support bias off then do that */ in dapm_post_sequence_async()
1846 if (d->bias_level == SND_SOC_BIAS_STANDBY && in dapm_post_sequence_async()
1847 d->target_bias_level == SND_SOC_BIAS_OFF) { in dapm_post_sequence_async()
1850 dev_err(d->dev, "ASoC: Failed to turn off bias: %d\n", in dapm_post_sequence_async()
1853 if (d->dev && cookie) in dapm_post_sequence_async()
1854 pm_runtime_put(d->dev); in dapm_post_sequence_async()
1857 /* If we just powered up then move to active bias */ in dapm_post_sequence_async()
1858 if (d->bias_level == SND_SOC_BIAS_PREPARE && in dapm_post_sequence_async()
1859 d->target_bias_level == SND_SOC_BIAS_ON) { in dapm_post_sequence_async()
1862 dev_err(d->dev, "ASoC: Failed to apply active bias: %d\n", in dapm_post_sequence_async()
1878 if (power != peer->power) in dapm_widget_set_peer_power()
1889 switch (w->id) { in dapm_power_one_widget()
1902 if (w->power == power) in dapm_power_one_widget()
1912 dapm_widget_set_peer_power(path->source, power, path->connect); in dapm_power_one_widget()
1917 if (!w->is_supply) in dapm_power_one_widget()
1919 dapm_widget_set_peer_power(path->sink, power, path->connect); in dapm_power_one_widget()
1930 if (dapm->idle_bias_off) in dapm_idle_bias_off()
1933 switch (snd_power_get_state(dapm->card->snd_card)) { in dapm_idle_bias_off()
1936 return dapm->suspend_bias_off; in dapm_idle_bias_off()
1946 * A complete path is a route that has valid endpoints i.e.:-
1948 * o DAC to output pin.
1951 * o DAC to ADC (loopback).
1961 enum snd_soc_bias_level bias; in dapm_power_widgets() local
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()
2004 * generally don't require full power. Signal 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()
2028 /* Force all contexts in the card to the same bias state if in dapm_power_widgets()
2031 bias = SND_SOC_BIAS_OFF; 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()
2041 /* Run card bias changes at first */ in dapm_power_widgets()
2042 dapm_pre_sequence_async(&card->dapm, 0); in dapm_power_widgets()
2043 /* Run other bias changes in parallel */ in dapm_power_widgets()
2045 if (d != &card->dapm && d->bias_level != d->target_bias_level) in dapm_power_widgets()
2067 /* Run all the bias changes in parallel */ in dapm_power_widgets()
2069 if (d != &card->dapm && d->bias_level != d->target_bias_level) in dapm_power_widgets()
2074 /* Run card bias changes at last */ 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()
2108 [snd_soc_dapm_dac] = "dac",
2143 struct snd_soc_dapm_widget *w = file->private_data; in dapm_widget_power_read_file()
2155 return -ENOMEM; in dapm_widget_power_read_file()
2157 snd_soc_dapm_mutex_lock_root(w->dapm); in dapm_widget_power_read_file()
2160 if (w->is_supply) { in dapm_widget_power_read_file()
2169 w->name, w->power ? "On" : "Off", in dapm_widget_power_read_file()
2170 w->force ? " (forced)" : "", in, out); in dapm_widget_power_read_file()
2172 if (w->reg >= 0) in dapm_widget_power_read_file()
2173 ret += scnprintf(buf + ret, PAGE_SIZE - ret, in dapm_widget_power_read_file()
2174 " - R%d(0x%x) mask 0x%x", in dapm_widget_power_read_file()
2175 w->reg, w->reg, w->mask << w->shift); in dapm_widget_power_read_file()
2177 ret += scnprintf(buf + ret, PAGE_SIZE - ret, "\n"); in dapm_widget_power_read_file()
2179 if (w->sname) in dapm_widget_power_read_file()
2180 ret += scnprintf(buf + ret, PAGE_SIZE - ret, " stream %s %s\n", in dapm_widget_power_read_file()
2181 w->sname, in dapm_widget_power_read_file()
2182 w->active ? "active" : "inactive"); in dapm_widget_power_read_file()
2184 ret += scnprintf(buf + ret, PAGE_SIZE - ret, " widget-type %s\n", in dapm_widget_power_read_file()
2185 snd_soc_dapm_type_name[w->id]); in dapm_widget_power_read_file()
2190 if (p->connected && !p->connected(p->source, p->sink)) in dapm_widget_power_read_file()
2193 if (!p->connect) in dapm_widget_power_read_file()
2196 c_name = p->node[rdir]->dapm->component ? in dapm_widget_power_read_file()
2197 p->node[rdir]->dapm->component->name : NULL; in dapm_widget_power_read_file()
2198 ret += scnprintf(buf + ret, PAGE_SIZE - ret, in dapm_widget_power_read_file()
2201 p->name ? p->name : "static", in dapm_widget_power_read_file()
2202 p->node[rdir]->name, c_name); in dapm_widget_power_read_file()
2206 snd_soc_dapm_mutex_unlock(w->dapm); in dapm_widget_power_read_file()
2223 struct snd_soc_dapm_context *dapm = file->private_data; in dapm_bias_read_file()
2226 switch (dapm->bias_level) { in dapm_bias_read_file()
2240 WARN(1, "Unknown bias_level %d\n", dapm->bias_level); in dapm_bias_read_file()
2261 dapm->debugfs_dapm = debugfs_create_dir("dapm", parent); in snd_soc_dapm_debugfs_init()
2263 debugfs_create_file("bias_level", 0444, dapm->debugfs_dapm, dapm, in snd_soc_dapm_debugfs_init()
2269 struct snd_soc_dapm_context *dapm = w->dapm; in dapm_debugfs_add_widget()
2271 if (!dapm->debugfs_dapm || !w->name) in dapm_debugfs_add_widget()
2274 debugfs_create_file(w->name, 0444, dapm->debugfs_dapm, w, in dapm_debugfs_add_widget()
2280 struct snd_soc_dapm_context *dapm = w->dapm; in dapm_debugfs_free_widget()
2282 if (!dapm->debugfs_dapm || !w->name) in dapm_debugfs_free_widget()
2285 debugfs_lookup_and_remove(w->name, dapm->debugfs_dapm); in dapm_debugfs_free_widget()
2290 debugfs_remove_recursive(dapm->debugfs_dapm); in dapm_debugfs_cleanup()
2291 dapm->debugfs_dapm = NULL; in dapm_debugfs_cleanup()
2315 * soc_dapm_connect_path() - Connects or disconnects a path
2324 if (path->connect == connect) in soc_dapm_connect_path()
2327 path->connect = connect; in soc_dapm_connect_path()
2328 dapm_mark_dirty(path->source, reason); in soc_dapm_connect_path()
2329 dapm_mark_dirty(path->sink, reason); in soc_dapm_connect_path()
2349 if (e && !(strcmp(path->name, e->texts[mux]))) in soc_dapm_mux_update_power()
2367 struct snd_soc_card *card = dapm->card; in snd_soc_dapm_mux_update_power()
2431 struct snd_soc_card *card = dapm->card; in snd_soc_dapm_mixer_update_power()
2435 ret = soc_dapm_mixer_update_power(card, kcontrol, update, connect, -1); in snd_soc_dapm_mixer_update_power()
2454 if (!cmpnt->card) in dapm_widget_show_component()
2457 for_each_card_widgets(cmpnt->card, w) { in dapm_widget_show_component()
2458 if (w->dapm != dapm) in dapm_widget_show_component()
2462 switch (w->id) { in dapm_widget_show_component()
2479 if (w->name) in dapm_widget_show_component()
2481 w->name, w->power ? "On":"Off"); in dapm_widget_show_component()
2515 snd_soc_dapm_mutex_lock_root(rtd->card); in dapm_widget_show()
2518 struct snd_soc_component *cmpnt = codec_dai->component; in dapm_widget_show()
2523 snd_soc_dapm_mutex_unlock(rtd->card); in dapm_widget_show()
2537 list_del(&path->list_node[SND_SOC_DAPM_DIR_IN]); in dapm_free_path()
2538 list_del(&path->list_node[SND_SOC_DAPM_DIR_OUT]); in dapm_free_path()
2539 list_del(&path->list_kcontrol); in dapm_free_path()
2540 list_del(&path->list); in dapm_free_path()
2545 * snd_soc_dapm_free_widget - Free specified widget
2558 list_del(&w->list); in snd_soc_dapm_free_widget()
2559 list_del(&w->dirty); in snd_soc_dapm_free_widget()
2572 kfree(w->kcontrols); in snd_soc_dapm_free_widget()
2573 kfree_const(w->name); in snd_soc_dapm_free_widget()
2574 kfree_const(w->sname); in snd_soc_dapm_free_widget()
2584 for_each_card_widgets_safe(dapm->card, w, next_w) { in dapm_free_widgets()
2585 if (w->dapm != dapm) in dapm_free_widgets()
2590 dapm->wcache_sink = NULL; in dapm_free_widgets()
2591 dapm->wcache_source = NULL; in dapm_free_widgets()
2612 for_each_card_widgets(dapm->card, w) { in dapm_find_widget()
2613 if (!strcmp(w->name, pin_name)) { in dapm_find_widget()
2614 if (w->dapm == dapm) in dapm_find_widget()
2641 dev_err(dapm->dev, "ASoC: DAPM unknown pin %s\n", pin); in __snd_soc_dapm_set_pin()
2642 return -EINVAL; in __snd_soc_dapm_set_pin()
2645 if (w->connected != status) { in __snd_soc_dapm_set_pin()
2652 w->connected = status; in __snd_soc_dapm_set_pin()
2654 w->force = 0; in __snd_soc_dapm_set_pin()
2672 * snd_soc_dapm_sync_unlocked - scan and power dapm paths
2688 if (!snd_soc_card_is_instantiated(dapm->card)) in snd_soc_dapm_sync_unlocked()
2691 return dapm_power_widgets(dapm->card, SND_SOC_DAPM_STREAM_NOP, NULL); in snd_soc_dapm_sync_unlocked()
2696 * snd_soc_dapm_sync - scan and power dapm paths
2719 switch (w->id) { in dapm_update_dai_chan()
2727 dev_dbg(w->dapm->dev, "%s DAI route %s -> %s\n", in dapm_update_dai_chan()
2728 w->channel < channels ? "Connecting" : "Disconnecting", in dapm_update_dai_chan()
2729 p->source->name, p->sink->name); in dapm_update_dai_chan()
2731 if (w->channel < channels) in dapm_update_dai_chan()
2743 int dir = substream->stream; in dapm_update_dai_unlocked()
2754 dev_dbg(dai->dev, "Update DAI routes for %s %s\n", dai->name, snd_pcm_direction_name(dir)); in dapm_update_dai_unlocked()
2757 ret = dapm_update_dai_chan(p, p->sink, channels); in dapm_update_dai_unlocked()
2763 ret = dapm_update_dai_chan(p, p->source, channels); in dapm_update_dai_unlocked()
2778 snd_soc_dapm_mutex_lock(rtd->card); in snd_soc_dapm_update_dai()
2780 snd_soc_dapm_mutex_unlock(rtd->card); in snd_soc_dapm_update_dai()
2787 struct snd_soc_component *component = widget->dapm->component; in snd_soc_dapm_widget_name_cmp()
2788 const char *wname = widget->name; in snd_soc_dapm_widget_name_cmp()
2790 if (component && component->name_prefix) in snd_soc_dapm_widget_name_cmp()
2791 wname += strlen(component->name_prefix) + 1; /* plus space */ in snd_soc_dapm_widget_name_cmp()
2798 * dapm_update_widget_flags() - Re-compute widget sink and source flags
2812 switch (w->id) { in dapm_update_widget_flags()
2815 if (w->dapm->card->fully_routed) in dapm_update_widget_flags()
2819 if (p->source->id == snd_soc_dapm_micbias || in dapm_update_widget_flags()
2820 p->source->id == snd_soc_dapm_mic || in dapm_update_widget_flags()
2821 p->source->id == snd_soc_dapm_line || in dapm_update_widget_flags()
2822 p->source->id == snd_soc_dapm_output) { in dapm_update_widget_flags()
2830 if (w->dapm->card->fully_routed) in dapm_update_widget_flags()
2834 if (p->sink->id == snd_soc_dapm_spk || in dapm_update_widget_flags()
2835 p->sink->id == snd_soc_dapm_hp || in dapm_update_widget_flags()
2836 p->sink->id == snd_soc_dapm_line || in dapm_update_widget_flags()
2837 p->sink->id == snd_soc_dapm_input) { in dapm_update_widget_flags()
2846 if (!list_empty(&w->edges[dir])) in dapm_update_widget_flags()
2854 w->is_ep = ep; in dapm_update_widget_flags()
2867 switch (source->id) { in snd_soc_dapm_check_dynamic_path()
2875 switch (sink->id) { in snd_soc_dapm_check_dynamic_path()
2887 dev_err(dapm->dev, in snd_soc_dapm_check_dynamic_path()
2888 "Direct connection between demux and mixer/mux not supported for path %s -> [%s] -> %s\n", in snd_soc_dapm_check_dynamic_path()
2889 source->name, control, sink->name); in snd_soc_dapm_check_dynamic_path()
2890 return -EINVAL; in snd_soc_dapm_check_dynamic_path()
2892 dev_err(dapm->dev, in snd_soc_dapm_check_dynamic_path()
2893 "Control not supported for path %s -> [%s] -> %s\n", in snd_soc_dapm_check_dynamic_path()
2894 source->name, control, sink->name); in snd_soc_dapm_check_dynamic_path()
2895 return -EINVAL; in snd_soc_dapm_check_dynamic_path()
2911 if (wsink->is_supply && !wsource->is_supply) { in snd_soc_dapm_add_path()
2912 dev_err(dapm->dev, in snd_soc_dapm_add_path()
2913 "Connecting non-supply widget to supply widget is not supported (%s -> %s)\n", in snd_soc_dapm_add_path()
2914 wsource->name, wsink->name); in snd_soc_dapm_add_path()
2915 return -EINVAL; in snd_soc_dapm_add_path()
2918 if (connected && !wsource->is_supply) { in snd_soc_dapm_add_path()
2919 dev_err(dapm->dev, in snd_soc_dapm_add_path()
2920 "connected() callback only supported for supply widgets (%s -> %s)\n", in snd_soc_dapm_add_path()
2921 wsource->name, wsink->name); in snd_soc_dapm_add_path()
2922 return -EINVAL; in snd_soc_dapm_add_path()
2925 if (wsource->is_supply && control) { in snd_soc_dapm_add_path()
2926 dev_err(dapm->dev, in snd_soc_dapm_add_path()
2927 "Conditional paths are not supported for supply widgets (%s -> [%s] -> %s)\n", in snd_soc_dapm_add_path()
2928 wsource->name, control, wsink->name); in snd_soc_dapm_add_path()
2929 return -EINVAL; in snd_soc_dapm_add_path()
2938 return -ENOMEM; in snd_soc_dapm_add_path()
2940 path->node[SND_SOC_DAPM_DIR_IN] = wsource; in snd_soc_dapm_add_path()
2941 path->node[SND_SOC_DAPM_DIR_OUT] = wsink; in snd_soc_dapm_add_path()
2943 path->connected = connected; in snd_soc_dapm_add_path()
2944 INIT_LIST_HEAD(&path->list); in snd_soc_dapm_add_path()
2945 INIT_LIST_HEAD(&path->list_kcontrol); in snd_soc_dapm_add_path()
2947 if (wsource->is_supply || wsink->is_supply) in snd_soc_dapm_add_path()
2948 path->is_supply = 1; in snd_soc_dapm_add_path()
2952 path->connect = 1; in snd_soc_dapm_add_path()
2954 switch (wsource->id) { in snd_soc_dapm_add_path()
2964 switch (wsink->id) { in snd_soc_dapm_add_path()
2982 list_add(&path->list, &dapm->card->paths); in snd_soc_dapm_add_path()
2985 list_add(&path->list_node[dir], &path->node[dir]->edges[dir]); in snd_soc_dapm_add_path()
2988 dapm_update_widget_flags(path->node[dir]); in snd_soc_dapm_add_path()
2989 dapm_mark_dirty(path->node[dir], "Route added"); in snd_soc_dapm_add_path()
2992 if (snd_soc_card_is_instantiated(dapm->card) && path->connect) in snd_soc_dapm_add_path()
3018 prefix, route->sink); in snd_soc_dapm_add_route()
3021 prefix, route->source); in snd_soc_dapm_add_route()
3024 sink = route->sink; in snd_soc_dapm_add_route()
3025 source = route->source; in snd_soc_dapm_add_route()
3028 wsource = dapm_wcache_lookup(dapm->wcache_source, source); in snd_soc_dapm_add_route()
3029 wsink = dapm_wcache_lookup(dapm->wcache_sink, sink); in snd_soc_dapm_add_route()
3036 * current DAPM context in snd_soc_dapm_add_route()
3038 for_each_card_widgets(dapm->card, w) { in snd_soc_dapm_add_route()
3039 if (!wsink && !(strcmp(w->name, sink))) { in snd_soc_dapm_add_route()
3041 if (w->dapm == dapm) { in snd_soc_dapm_add_route()
3048 dev_warn(dapm->dev, in snd_soc_dapm_add_route()
3050 w->name); in snd_soc_dapm_add_route()
3053 if (!wsource && !(strcmp(w->name, source))) { in snd_soc_dapm_add_route()
3055 if (w->dapm == dapm) { in snd_soc_dapm_add_route()
3062 dev_warn(dapm->dev, in snd_soc_dapm_add_route()
3064 w->name); in snd_soc_dapm_add_route()
3073 ret = -ENODEV; in snd_soc_dapm_add_route()
3081 dapm->wcache_sink = wsink; in snd_soc_dapm_add_route()
3082 dapm->wcache_source = wsource; in snd_soc_dapm_add_route()
3084 ret = snd_soc_dapm_add_path(dapm, wsource, wsink, route->control, in snd_soc_dapm_add_route()
3085 route->connected); in snd_soc_dapm_add_route()
3088 dev_err(dapm->dev, "ASoC: Failed to add route %s%s -%s%s%s> %s%s\n", in snd_soc_dapm_add_route()
3090 !route->control ? "" : "> [", in snd_soc_dapm_add_route()
3091 !route->control ? "" : route->control, in snd_soc_dapm_add_route()
3092 !route->control ? "" : "] -", in snd_soc_dapm_add_route()
3107 if (route->control) { in snd_soc_dapm_del_route()
3108 dev_err(dapm->dev, in snd_soc_dapm_del_route()
3110 return -EINVAL; in snd_soc_dapm_del_route()
3116 prefix, route->sink); in snd_soc_dapm_del_route()
3119 prefix, route->source); in snd_soc_dapm_del_route()
3122 sink = route->sink; in snd_soc_dapm_del_route()
3123 source = route->source; in snd_soc_dapm_del_route()
3127 list_for_each_entry(p, &dapm->card->paths, list) { in snd_soc_dapm_del_route()
3128 if (strcmp(p->source->name, source) != 0) in snd_soc_dapm_del_route()
3130 if (strcmp(p->sink->name, sink) != 0) in snd_soc_dapm_del_route()
3137 struct snd_soc_dapm_widget *wsource = path->source; in snd_soc_dapm_del_route()
3138 struct snd_soc_dapm_widget *wsink = path->sink; in snd_soc_dapm_del_route()
3142 if (path->connect) in snd_soc_dapm_del_route()
3151 dev_warn(dapm->dev, "ASoC: Route %s->%s does not exist\n", in snd_soc_dapm_del_route()
3159 * snd_soc_dapm_add_routes - Add routes between DAPM widgets
3190 * snd_soc_dapm_del_routes - Remove routes between DAPM widgets
3217 route->source, in snd_soc_dapm_weak_route()
3220 route->sink, in snd_soc_dapm_weak_route()
3226 dev_err(dapm->dev, "ASoC: Unable to find source %s for weak route\n", in snd_soc_dapm_weak_route()
3227 route->source); in snd_soc_dapm_weak_route()
3228 return -ENODEV; in snd_soc_dapm_weak_route()
3232 dev_err(dapm->dev, "ASoC: Unable to find sink %s for weak route\n", in snd_soc_dapm_weak_route()
3233 route->sink); in snd_soc_dapm_weak_route()
3234 return -ENODEV; in snd_soc_dapm_weak_route()
3237 if (route->control || route->connected) in snd_soc_dapm_weak_route()
3238 dev_warn(dapm->dev, "ASoC: Ignoring control for weak route %s->%s\n", in snd_soc_dapm_weak_route()
3239 route->source, route->sink); in snd_soc_dapm_weak_route()
3242 if (path->sink == sink) { in snd_soc_dapm_weak_route()
3243 path->weak = 1; in snd_soc_dapm_weak_route()
3249 dev_err(dapm->dev, "ASoC: No path found for weak route %s->%s\n", in snd_soc_dapm_weak_route()
3250 route->source, route->sink); in snd_soc_dapm_weak_route()
3252 dev_warn(dapm->dev, "ASoC: %d paths found for weak route %s->%s\n", in snd_soc_dapm_weak_route()
3253 count, route->source, route->sink); in snd_soc_dapm_weak_route()
3259 * snd_soc_dapm_weak_routes - Mark routes between DAPM widgets as weak
3294 * snd_soc_dapm_new_widgets - add new dapm widgets
3310 if (w->new) in snd_soc_dapm_new_widgets()
3313 if (w->num_kcontrols) { in snd_soc_dapm_new_widgets()
3314 w->kcontrols = kcalloc(w->num_kcontrols, in snd_soc_dapm_new_widgets()
3317 if (!w->kcontrols) { in snd_soc_dapm_new_widgets()
3319 return -ENOMEM; in snd_soc_dapm_new_widgets()
3323 switch(w->id) { in snd_soc_dapm_new_widgets()
3346 if (w->reg >= 0) { in snd_soc_dapm_new_widgets()
3347 val = soc_dapm_read(w->dapm, w->reg); in snd_soc_dapm_new_widgets()
3348 val = val >> w->shift; in snd_soc_dapm_new_widgets()
3349 val &= w->mask; in snd_soc_dapm_new_widgets()
3350 if (val == w->on_val) in snd_soc_dapm_new_widgets()
3351 w->power = 1; in snd_soc_dapm_new_widgets()
3354 w->new = 1; in snd_soc_dapm_new_widgets()
3367 * snd_soc_dapm_get_volsw - dapm mixer get callback
3380 (struct soc_mixer_control *)kcontrol->private_value; in snd_soc_dapm_get_volsw()
3381 int reg = mc->reg; in snd_soc_dapm_get_volsw()
3382 unsigned int shift = mc->shift; in snd_soc_dapm_get_volsw()
3383 int max = mc->max; in snd_soc_dapm_get_volsw()
3385 unsigned int mask = (1 << fls(max)) - 1; in snd_soc_dapm_get_volsw()
3386 unsigned int invert = mc->invert; in snd_soc_dapm_get_volsw()
3394 if (reg != mc->rreg) in snd_soc_dapm_get_volsw()
3395 reg_val = soc_dapm_read(dapm, mc->rreg); in snd_soc_dapm_get_volsw()
3398 rval = (reg_val >> mc->rshift) & mask; in snd_soc_dapm_get_volsw()
3409 ucontrol->value.integer.value[0] = max - val; in snd_soc_dapm_get_volsw()
3411 ucontrol->value.integer.value[0] = val; in snd_soc_dapm_get_volsw()
3415 ucontrol->value.integer.value[1] = max - rval; in snd_soc_dapm_get_volsw()
3417 ucontrol->value.integer.value[1] = rval; in snd_soc_dapm_get_volsw()
3425 * snd_soc_dapm_put_volsw - dapm mixer set callback
3437 struct snd_soc_card *card = dapm->card; in snd_soc_dapm_put_volsw()
3439 (struct soc_mixer_control *)kcontrol->private_value; in snd_soc_dapm_put_volsw()
3440 int reg = mc->reg; in snd_soc_dapm_put_volsw()
3441 unsigned int shift = mc->shift; in snd_soc_dapm_put_volsw()
3442 int max = mc->max; in snd_soc_dapm_put_volsw()
3444 unsigned int mask = (1 << width) - 1; in snd_soc_dapm_put_volsw()
3445 unsigned int invert = mc->invert; in snd_soc_dapm_put_volsw()
3447 int connect, rconnect = -1, change, reg_change = 0; in snd_soc_dapm_put_volsw()
3452 val = (ucontrol->value.integer.value[0] & mask); in snd_soc_dapm_put_volsw()
3456 val = max - val; in snd_soc_dapm_put_volsw()
3459 rval = (ucontrol->value.integer.value[1] & mask); in snd_soc_dapm_put_volsw()
3462 rval = max - rval; in snd_soc_dapm_put_volsw()
3469 dev_warn(dapm->dev, in snd_soc_dapm_put_volsw()
3471 kcontrol->id.name); in snd_soc_dapm_put_volsw()
3476 rval = rval << mc->rshift; in snd_soc_dapm_put_volsw()
3481 reg_change |= soc_dapm_test_bits(dapm, mc->rreg, in snd_soc_dapm_put_volsw()
3482 mask << mc->rshift, in snd_soc_dapm_put_volsw()
3490 update.reg2 = mc->rreg; in snd_soc_dapm_put_volsw()
3491 update.mask2 = mask << mc->rshift; in snd_soc_dapm_put_volsw()
3513 * snd_soc_dapm_get_enum_double - dapm enumerated double mixer get callback
3525 struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; in snd_soc_dapm_get_enum_double()
3529 if (e->reg != SND_SOC_NOPM && dapm_kcontrol_is_powered(kcontrol)) { in snd_soc_dapm_get_enum_double()
3530 reg_val = soc_dapm_read(dapm, e->reg); in snd_soc_dapm_get_enum_double()
3536 val = (reg_val >> e->shift_l) & e->mask; in snd_soc_dapm_get_enum_double()
3537 ucontrol->value.enumerated.item[0] = snd_soc_enum_val_to_item(e, val); in snd_soc_dapm_get_enum_double()
3538 if (e->shift_l != e->shift_r) { in snd_soc_dapm_get_enum_double()
3539 val = (reg_val >> e->shift_r) & e->mask; in snd_soc_dapm_get_enum_double()
3541 ucontrol->value.enumerated.item[1] = val; in snd_soc_dapm_get_enum_double()
3549 * snd_soc_dapm_put_enum_double - dapm enumerated double mixer set callback
3561 struct snd_soc_card *card = dapm->card; in snd_soc_dapm_put_enum_double()
3562 struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; in snd_soc_dapm_put_enum_double()
3563 unsigned int *item = ucontrol->value.enumerated.item; in snd_soc_dapm_put_enum_double()
3570 if (item[0] >= e->items) in snd_soc_dapm_put_enum_double()
3571 return -EINVAL; in snd_soc_dapm_put_enum_double()
3573 val = snd_soc_enum_item_to_val(e, item[0]) << e->shift_l; in snd_soc_dapm_put_enum_double()
3574 mask = e->mask << e->shift_l; in snd_soc_dapm_put_enum_double()
3575 if (e->shift_l != e->shift_r) { in snd_soc_dapm_put_enum_double()
3576 if (item[1] > e->items) in snd_soc_dapm_put_enum_double()
3577 return -EINVAL; in snd_soc_dapm_put_enum_double()
3578 val |= snd_soc_enum_item_to_val(e, item[1]) << e->shift_r; in snd_soc_dapm_put_enum_double()
3579 mask |= e->mask << e->shift_r; in snd_soc_dapm_put_enum_double()
3586 if (e->reg != SND_SOC_NOPM) in snd_soc_dapm_put_enum_double()
3587 reg_change = soc_dapm_test_bits(dapm, e->reg, mask, val); in snd_soc_dapm_put_enum_double()
3592 update.reg = e->reg; in snd_soc_dapm_put_enum_double()
3610 * snd_soc_dapm_info_pin_switch - Info for a pin switch
3620 uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN; in snd_soc_dapm_info_pin_switch()
3621 uinfo->count = 1; in snd_soc_dapm_info_pin_switch()
3622 uinfo->value.integer.min = 0; in snd_soc_dapm_info_pin_switch()
3623 uinfo->value.integer.max = 1; in snd_soc_dapm_info_pin_switch()
3630 * snd_soc_dapm_get_pin_switch - Get information for a pin switch
3639 const char *pin = (const char *)kcontrol->private_value; in snd_soc_dapm_get_pin_switch()
3643 ucontrol->value.integer.value[0] = in snd_soc_dapm_get_pin_switch()
3644 snd_soc_dapm_get_pin_status(&card->dapm, pin); in snd_soc_dapm_get_pin_switch()
3653 * snd_soc_dapm_put_pin_switch - Set information for a pin switch
3662 const char *pin = (const char *)kcontrol->private_value; in snd_soc_dapm_put_pin_switch()
3666 ret = __snd_soc_dapm_set_pin(&card->dapm, pin, in snd_soc_dapm_put_pin_switch()
3667 !!ucontrol->value.integer.value[0]); in snd_soc_dapm_put_pin_switch()
3670 snd_soc_dapm_sync(&card->dapm); in snd_soc_dapm_put_pin_switch()
3681 int ret = -ENOMEM; in snd_soc_dapm_new_control_unlocked()
3687 switch (w->id) { in snd_soc_dapm_new_control_unlocked()
3689 w->regulator = devm_regulator_get(dapm->dev, widget->name); in snd_soc_dapm_new_control_unlocked()
3690 if (IS_ERR(w->regulator)) { in snd_soc_dapm_new_control_unlocked()
3691 ret = PTR_ERR(w->regulator); in snd_soc_dapm_new_control_unlocked()
3695 if (w->on_val & SND_SOC_DAPM_REGULATOR_BYPASS) { in snd_soc_dapm_new_control_unlocked()
3696 ret = regulator_allow_bypass(w->regulator, true); in snd_soc_dapm_new_control_unlocked()
3698 dev_warn(dapm->dev, in snd_soc_dapm_new_control_unlocked()
3700 w->name, ret); in snd_soc_dapm_new_control_unlocked()
3704 w->pinctrl = devm_pinctrl_get(dapm->dev); in snd_soc_dapm_new_control_unlocked()
3705 if (IS_ERR(w->pinctrl)) { in snd_soc_dapm_new_control_unlocked()
3706 ret = PTR_ERR(w->pinctrl); in snd_soc_dapm_new_control_unlocked()
3714 w->clk = devm_clk_get(dapm->dev, widget->name); in snd_soc_dapm_new_control_unlocked()
3715 if (IS_ERR(w->clk)) { in snd_soc_dapm_new_control_unlocked()
3716 ret = PTR_ERR(w->clk); in snd_soc_dapm_new_control_unlocked()
3724 switch (w->id) { in snd_soc_dapm_new_control_unlocked()
3726 w->is_ep = SND_SOC_DAPM_EP_SOURCE; in snd_soc_dapm_new_control_unlocked()
3727 w->power_check = dapm_generic_check_power; in snd_soc_dapm_new_control_unlocked()
3730 if (!dapm->card->fully_routed) in snd_soc_dapm_new_control_unlocked()
3731 w->is_ep = SND_SOC_DAPM_EP_SOURCE; in snd_soc_dapm_new_control_unlocked()
3732 w->power_check = dapm_generic_check_power; in snd_soc_dapm_new_control_unlocked()
3736 w->is_ep = SND_SOC_DAPM_EP_SINK; in snd_soc_dapm_new_control_unlocked()
3737 w->power_check = dapm_generic_check_power; in snd_soc_dapm_new_control_unlocked()
3740 if (!dapm->card->fully_routed) in snd_soc_dapm_new_control_unlocked()
3741 w->is_ep = SND_SOC_DAPM_EP_SINK; in snd_soc_dapm_new_control_unlocked()
3742 w->power_check = dapm_generic_check_power; in snd_soc_dapm_new_control_unlocked()
3746 w->is_ep = SND_SOC_DAPM_EP_SOURCE; in snd_soc_dapm_new_control_unlocked()
3747 w->power_check = dapm_always_on_check_power; in snd_soc_dapm_new_control_unlocked()
3750 w->is_ep = SND_SOC_DAPM_EP_SINK; in snd_soc_dapm_new_control_unlocked()
3751 w->power_check = dapm_always_on_check_power; in snd_soc_dapm_new_control_unlocked()
3777 w->power_check = dapm_generic_check_power; in snd_soc_dapm_new_control_unlocked()
3784 w->is_supply = 1; in snd_soc_dapm_new_control_unlocked()
3785 w->power_check = dapm_supply_check_power; in snd_soc_dapm_new_control_unlocked()
3788 w->power_check = dapm_always_on_check_power; in snd_soc_dapm_new_control_unlocked()
3792 w->dapm = dapm; in snd_soc_dapm_new_control_unlocked()
3793 INIT_LIST_HEAD(&w->list); in snd_soc_dapm_new_control_unlocked()
3794 INIT_LIST_HEAD(&w->dirty); in snd_soc_dapm_new_control_unlocked()
3796 list_add_tail(&w->list, &dapm->card->widgets); in snd_soc_dapm_new_control_unlocked()
3799 INIT_LIST_HEAD(&w->edges[dir]); in snd_soc_dapm_new_control_unlocked()
3800 w->endpoints[dir] = -1; in snd_soc_dapm_new_control_unlocked()
3804 w->connected = 1; in snd_soc_dapm_new_control_unlocked()
3808 dev_err_probe(dapm->dev, ret, "ASoC: Failed to request %s\n", in snd_soc_dapm_new_control_unlocked()
3809 w->name); in snd_soc_dapm_new_control_unlocked()
3810 kfree_const(w->name); in snd_soc_dapm_new_control_unlocked()
3811 kfree_const(w->sname); in snd_soc_dapm_new_control_unlocked()
3818 * snd_soc_dapm_new_control - create new dapm control
3841 * snd_soc_dapm_new_controls - create new dapm controls
3895 return -ENOMEM; in snd_soc_dai_link_event_pre_pmu()
3899 return -ENOMEM; in snd_soc_dai_link_event_pre_pmu()
3901 substream->runtime = runtime; in snd_soc_dai_link_event_pre_pmu()
3903 substream->stream = SNDRV_PCM_STREAM_CAPTURE; in snd_soc_dai_link_event_pre_pmu()
3905 source = path->source->priv; in snd_soc_dai_link_event_pre_pmu()
3911 snd_soc_dai_activate(source, substream->stream); in snd_soc_dai_link_event_pre_pmu()
3914 substream->stream = SNDRV_PCM_STREAM_PLAYBACK; in snd_soc_dai_link_event_pre_pmu()
3916 sink = path->sink->priv; in snd_soc_dai_link_event_pre_pmu()
3922 snd_soc_dai_activate(sink, substream->stream); in snd_soc_dai_link_event_pre_pmu()
3925 substream->hw_opened = 1; in snd_soc_dai_link_event_pre_pmu()
3932 config = rtd->dai_link->c2c_params + rtd->c2c_params_select; in snd_soc_dai_link_event_pre_pmu()
3934 dev_err(w->dapm->dev, "ASoC: link config missing\n"); in snd_soc_dai_link_event_pre_pmu()
3935 return -EINVAL; in snd_soc_dai_link_event_pre_pmu()
3939 if (!config->formats) { in snd_soc_dai_link_event_pre_pmu()
3940 dev_warn(w->dapm->dev, "ASoC: Invalid format was specified\n"); in snd_soc_dai_link_event_pre_pmu()
3942 return -EINVAL; in snd_soc_dai_link_event_pre_pmu()
3945 fmt = ffs(config->formats) - 1; in snd_soc_dai_link_event_pre_pmu()
3948 hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE)->min = in snd_soc_dai_link_event_pre_pmu()
3949 config->rate_min; in snd_soc_dai_link_event_pre_pmu()
3950 hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE)->max = in snd_soc_dai_link_event_pre_pmu()
3951 config->rate_max; in snd_soc_dai_link_event_pre_pmu()
3952 hw_param_interval(params, SNDRV_PCM_HW_PARAM_CHANNELS)->min in snd_soc_dai_link_event_pre_pmu()
3953 = config->channels_min; in snd_soc_dai_link_event_pre_pmu()
3954 hw_param_interval(params, SNDRV_PCM_HW_PARAM_CHANNELS)->max in snd_soc_dai_link_event_pre_pmu()
3955 = config->channels_max; in snd_soc_dai_link_event_pre_pmu()
3957 substream->stream = SNDRV_PCM_STREAM_CAPTURE; in snd_soc_dai_link_event_pre_pmu()
3959 source = path->source->priv; in snd_soc_dai_link_event_pre_pmu()
3968 substream->stream = SNDRV_PCM_STREAM_PLAYBACK; in snd_soc_dai_link_event_pre_pmu()
3970 sink = path->sink->priv; in snd_soc_dai_link_event_pre_pmu()
3979 runtime->format = params_format(params); in snd_soc_dai_link_event_pre_pmu()
3980 runtime->subformat = params_subformat(params); in snd_soc_dai_link_event_pre_pmu()
3981 runtime->channels = params_channels(params); in snd_soc_dai_link_event_pre_pmu()
3982 runtime->rate = params_rate(params); in snd_soc_dai_link_event_pre_pmu()
3992 struct snd_pcm_substream *substream = w->priv; in snd_soc_dai_link_event()
3993 int ret = 0, saved_stream = substream->stream; in snd_soc_dai_link_event()
3995 if (WARN_ON(list_empty(&w->edges[SND_SOC_DAPM_DIR_OUT]) || in snd_soc_dai_link_event()
3996 list_empty(&w->edges[SND_SOC_DAPM_DIR_IN]))) in snd_soc_dai_link_event()
3997 return -EINVAL; in snd_soc_dai_link_event()
4009 source = path->source->priv; in snd_soc_dai_link_event()
4015 sink = path->sink->priv; in snd_soc_dai_link_event()
4021 sink = path->sink->priv; in snd_soc_dai_link_event()
4030 sink = path->sink->priv; in snd_soc_dai_link_event()
4036 substream->stream = SNDRV_PCM_STREAM_CAPTURE; in snd_soc_dai_link_event()
4038 source = path->source->priv; in snd_soc_dai_link_event()
4042 substream->stream = SNDRV_PCM_STREAM_PLAYBACK; in snd_soc_dai_link_event()
4044 sink = path->sink->priv; in snd_soc_dai_link_event()
4048 substream->stream = SNDRV_PCM_STREAM_CAPTURE; in snd_soc_dai_link_event()
4050 source = path->source->priv; in snd_soc_dai_link_event()
4051 snd_soc_dai_deactivate(source, substream->stream); in snd_soc_dai_link_event()
4055 substream->stream = SNDRV_PCM_STREAM_PLAYBACK; in snd_soc_dai_link_event()
4057 sink = path->sink->priv; in snd_soc_dai_link_event()
4058 snd_soc_dai_deactivate(sink, substream->stream); in snd_soc_dai_link_event()
4064 kfree(substream->runtime); in snd_soc_dai_link_event()
4065 substream->runtime = NULL; in snd_soc_dai_link_event()
4070 ret = -EINVAL; in snd_soc_dai_link_event()
4075 substream->stream = saved_stream; in snd_soc_dai_link_event()
4083 struct snd_soc_pcm_runtime *rtd = w->priv; in snd_soc_dapm_dai_link_get()
4085 ucontrol->value.enumerated.item[0] = rtd->c2c_params_select; in snd_soc_dapm_dai_link_get()
4094 struct snd_soc_pcm_runtime *rtd = w->priv; in snd_soc_dapm_dai_link_put()
4097 if (w->power) in snd_soc_dapm_dai_link_put()
4098 return -EBUSY; in snd_soc_dapm_dai_link_put()
4100 if (ucontrol->value.enumerated.item[0] == rtd->c2c_params_select) in snd_soc_dapm_dai_link_put()
4103 if (ucontrol->value.enumerated.item[0] >= rtd->dai_link->num_c2c_params) in snd_soc_dapm_dai_link_put()
4104 return -EINVAL; in snd_soc_dapm_dai_link_put()
4106 rtd->c2c_params_select = ucontrol->value.enumerated.item[0]; in snd_soc_dapm_dai_link_put()
4119 devm_kfree(card->dev, (void *)*private_value); in snd_soc_dapm_free_kcontrol()
4125 devm_kfree(card->dev, (void *)w_param_text[count]); in snd_soc_dapm_free_kcontrol()
4126 devm_kfree(card->dev, w_param_text); in snd_soc_dapm_free_kcontrol()
4149 if (!config->stream_name) { in snd_soc_dapm_alloc_kcontrol()
4150 dev_warn(card->dapm.dev, in snd_soc_dapm_alloc_kcontrol()
4154 devm_kasprintf(card->dev, GFP_KERNEL, in snd_soc_dapm_alloc_kcontrol()
4158 w_param_text[count] = devm_kmemdup(card->dev, in snd_soc_dapm_alloc_kcontrol()
4159 config->stream_name, in snd_soc_dapm_alloc_kcontrol()
4160 strlen(config->stream_name) + 1, in snd_soc_dapm_alloc_kcontrol()
4172 (unsigned long) devm_kmemdup(card->dev, in snd_soc_dapm_alloc_kcontrol()
4176 dev_err(card->dev, "ASoC: Failed to create control for %s widget\n", in snd_soc_dapm_alloc_kcontrol()
4182 kcontrol_news = devm_kmemdup(card->dev, &kcontrol_dai_link[0], in snd_soc_dapm_alloc_kcontrol()
4186 dev_err(card->dev, "ASoC: Failed to create control for %s widget\n", in snd_soc_dapm_alloc_kcontrol()
4210 int ret = -ENOMEM; in snd_soc_dapm_new_dai()
4212 link_name = devm_kasprintf(card->dev, GFP_KERNEL, "%s-%s", in snd_soc_dapm_new_dai()
4213 rtd->dai_link->name, id); in snd_soc_dapm_new_dai()
4221 if (rtd->dai_link->num_c2c_params > 1) { in snd_soc_dapm_new_dai()
4222 w_param_text = devm_kcalloc(card->dev, in snd_soc_dapm_new_dai()
4223 rtd->dai_link->num_c2c_params, in snd_soc_dapm_new_dai()
4230 rtd->dai_link->c2c_params, in snd_soc_dapm_new_dai()
4231 rtd->dai_link->num_c2c_params, in snd_soc_dapm_new_dai()
4247 dev_dbg(card->dev, "ASoC: adding %s widget\n", link_name); in snd_soc_dapm_new_dai()
4249 w = snd_soc_dapm_new_control_unlocked(&card->dapm, &template); in snd_soc_dapm_new_dai()
4255 w->priv = substream; in snd_soc_dapm_new_dai()
4260 devm_kfree(card->dev, (void *)template.kcontrol_news); in snd_soc_dapm_new_dai()
4262 rtd->dai_link->num_c2c_params, w_param_text); in snd_soc_dapm_new_dai()
4264 devm_kfree(card->dev, link_name); in snd_soc_dapm_new_dai()
4266 dev_err(rtd->dev, "ASoC: Failed to create %s-%s widget: %d\n", in snd_soc_dapm_new_dai()
4267 rtd->dai_link->name, id, ret); in snd_soc_dapm_new_dai()
4272 * snd_soc_dapm_new_dai_widgets - Create new DAPM widgets
4284 WARN_ON(dapm->dev != dai->dev); in snd_soc_dapm_new_dai_widgets()
4289 if (dai->driver->playback.stream_name) { in snd_soc_dapm_new_dai_widgets()
4291 template.name = dai->driver->playback.stream_name; in snd_soc_dapm_new_dai_widgets()
4292 template.sname = dai->driver->playback.stream_name; in snd_soc_dapm_new_dai_widgets()
4294 dev_dbg(dai->dev, "ASoC: adding %s widget\n", in snd_soc_dapm_new_dai_widgets()
4301 w->priv = dai; in snd_soc_dapm_new_dai_widgets()
4305 if (dai->driver->capture.stream_name) { in snd_soc_dapm_new_dai_widgets()
4307 template.name = dai->driver->capture.stream_name; in snd_soc_dapm_new_dai_widgets()
4308 template.sname = dai->driver->capture.stream_name; in snd_soc_dapm_new_dai_widgets()
4310 dev_dbg(dai->dev, "ASoC: adding %s widget\n", in snd_soc_dapm_new_dai_widgets()
4317 w->priv = dai; in snd_soc_dapm_new_dai_widgets()
4333 switch (dai_w->id) { in snd_soc_dapm_link_dai_widgets()
4342 if (!dai_w->priv) { in snd_soc_dapm_link_dai_widgets()
4343 dev_dbg(card->dev, "dai widget %s has no DAI\n", in snd_soc_dapm_link_dai_widgets()
4344 dai_w->name); in snd_soc_dapm_link_dai_widgets()
4348 dai = dai_w->priv; in snd_soc_dapm_link_dai_widgets()
4352 if (w->dapm != dai_w->dapm) in snd_soc_dapm_link_dai_widgets()
4355 switch (w->id) { in snd_soc_dapm_link_dai_widgets()
4363 if (!w->sname || !strstr(w->sname, dai_w->sname)) in snd_soc_dapm_link_dai_widgets()
4366 if (dai_w->id == snd_soc_dapm_dai_in) { in snd_soc_dapm_link_dai_widgets()
4373 dev_dbg(dai->dev, "%s -> %s\n", src->name, sink->name); in snd_soc_dapm_link_dai_widgets()
4374 snd_soc_dapm_add_path(w->dapm, src, sink, NULL, NULL); in snd_soc_dapm_link_dai_widgets()
4388 dev_dbg(dapm->dev, "connected DAI link %s:%s -> %s:%s\n", in dapm_connect_dai_routes()
4389 src_dai->component->name, src->name, in dapm_connect_dai_routes()
4390 sink_dai->component->name, sink->name); in dapm_connect_dai_routes()
4405 struct snd_soc_dai_link *dai_link = rtd->dai_link; in dapm_connect_dai_pair()
4428 if (dai_link->c2c_params && !rtd->c2c_widget[stream]) { in dapm_connect_dai_pair()
4429 struct snd_pcm_substream *substream = rtd->pcm->streams[stream].substream; in dapm_connect_dai_pair()
4436 rtd->c2c_widget[stream] = dai; in dapm_connect_dai_pair()
4439 dapm_connect_dai_routes(&card->dapm, src_dai[stream], *src[stream], in dapm_connect_dai_pair()
4440 rtd->c2c_widget[stream], in dapm_connect_dai_pair()
4457 if (w->id == snd_soc_dapm_dai_in) { in soc_dapm_dai_stream_event()
4467 w->active = 1; in soc_dapm_dai_stream_event()
4468 w->is_ep = ep; in soc_dapm_dai_stream_event()
4471 w->active = 0; in soc_dapm_dai_stream_event()
4472 w->is_ep = 0; in soc_dapm_dai_stream_event()
4496 * CODEC<->CODEC links have no direct connection. in snd_soc_dapm_connect_dai_link_widgets()
4498 if (rtd->dai_link->dynamic) in snd_soc_dapm_connect_dai_link_widgets()
4503 * soc.h :: [dai_link->ch_maps Image sample] in snd_soc_dapm_connect_dai_link_widgets()
4506 cpu_dai = snd_soc_rtd_to_cpu(rtd, ch_maps->cpu); in snd_soc_dapm_connect_dai_link_widgets()
4507 codec_dai = snd_soc_rtd_to_codec(rtd, ch_maps->codec); in snd_soc_dapm_connect_dai_link_widgets()
4523 dapm_power_widgets(rtd->card, event, NULL); in soc_dapm_stream_event()
4527 * snd_soc_dapm_stream_event - send a stream event to the dapm core
4540 struct snd_soc_card *card = rtd->card; in snd_soc_dapm_stream_event()
4557 rtd->pop_wait = 1; in snd_soc_dapm_stream_stop()
4559 &rtd->delayed_work, in snd_soc_dapm_stream_stop()
4560 msecs_to_jiffies(rtd->pmdown_time)); in snd_soc_dapm_stream_stop()
4571 * snd_soc_dapm_enable_pin_unlocked - enable pin.
4591 * snd_soc_dapm_enable_pin - enable pin.
4616 * snd_soc_dapm_force_enable_pin_unlocked - force a pin to be enabled
4621 * intended for use with microphone bias supplies used in microphone
4635 dev_err(dapm->dev, "ASoC: unknown pin %s\n", pin); in snd_soc_dapm_force_enable_pin_unlocked()
4636 return -EINVAL; in snd_soc_dapm_force_enable_pin_unlocked()
4639 dev_dbg(w->dapm->dev, "ASoC: force enable pin %s\n", pin); in snd_soc_dapm_force_enable_pin_unlocked()
4640 if (!w->connected) { in snd_soc_dapm_force_enable_pin_unlocked()
4642 * w->force does not affect the number of input or output paths, in snd_soc_dapm_force_enable_pin_unlocked()
4643 * so we only have to recheck if w->connected is changed in snd_soc_dapm_force_enable_pin_unlocked()
4647 w->connected = 1; in snd_soc_dapm_force_enable_pin_unlocked()
4649 w->force = 1; in snd_soc_dapm_force_enable_pin_unlocked()
4657 * snd_soc_dapm_force_enable_pin - force a pin to be enabled
4662 * intended for use with microphone bias supplies used in microphone
4684 * snd_soc_dapm_disable_pin_unlocked - disable pin.
4703 * snd_soc_dapm_disable_pin - disable pin.
4728 * snd_soc_dapm_nc_pin_unlocked - permanently disable pin.
4751 * snd_soc_dapm_nc_pin - permanently disable pin.
4779 * snd_soc_dapm_get_pin_status - get audio pin status
4783 * Get audio pin status - connected or disconnected.
4793 return w->connected; in snd_soc_dapm_get_pin_status()
4800 * snd_soc_dapm_ignore_suspend - ignore suspend status for DAPM endpoint
4816 dev_err(dapm->dev, "ASoC: unknown pin %s\n", pin); in snd_soc_dapm_ignore_suspend()
4817 return -EINVAL; in snd_soc_dapm_ignore_suspend()
4820 w->ignore_suspend = 1; in snd_soc_dapm_ignore_suspend()
4827 * snd_soc_dapm_free - free dapm resources
4836 list_del(&dapm->list); in snd_soc_dapm_free()
4844 dapm->card = card; in snd_soc_dapm_init()
4845 dapm->component = component; in snd_soc_dapm_init()
4846 dapm->bias_level = SND_SOC_BIAS_OFF; in snd_soc_dapm_init()
4849 dapm->dev = component->dev; in snd_soc_dapm_init()
4850 dapm->idle_bias_off = !component->driver->idle_bias_on; in snd_soc_dapm_init()
4851 dapm->suspend_bias_off = component->driver->suspend_bias_off; in snd_soc_dapm_init()
4853 dapm->dev = card->dev; in snd_soc_dapm_init()
4856 INIT_LIST_HEAD(&dapm->list); in snd_soc_dapm_init()
4858 list_add(&dapm->list, &card->dapm_list); in snd_soc_dapm_init()
4863 struct snd_soc_card *card = dapm->card; in soc_dapm_shutdown_dapm()
4870 for_each_card_widgets(dapm->card, w) { in soc_dapm_shutdown_dapm()
4871 if (w->dapm != dapm) in soc_dapm_shutdown_dapm()
4873 if (w->power) { in soc_dapm_shutdown_dapm()
4875 w->new_power = 0; in soc_dapm_shutdown_dapm()
4884 if (dapm->bias_level == SND_SOC_BIAS_ON) in soc_dapm_shutdown_dapm()
4888 if (dapm->bias_level == SND_SOC_BIAS_PREPARE) in soc_dapm_shutdown_dapm()
4897 * snd_soc_dapm_shutdown - callback for system shutdown
4904 if (dapm != &card->dapm) { in snd_soc_dapm_shutdown()
4906 if (dapm->bias_level == SND_SOC_BIAS_STANDBY) in snd_soc_dapm_shutdown()
4912 soc_dapm_shutdown_dapm(&card->dapm); in snd_soc_dapm_shutdown()
4913 if (card->dapm.bias_level == SND_SOC_BIAS_STANDBY) in snd_soc_dapm_shutdown()
4914 snd_soc_dapm_set_bias_level(&card->dapm, in snd_soc_dapm_shutdown()