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))
186 return !list_empty(&w->dirty);
191 dapm_assert_locked(w->dapm);
194 dev_vdbg(w->dapm->dev, "Marking %s dirty due to %s\n",
195 w->name, reason);
196 list_add_tail(&w->dirty, &w->dapm->card->dapm_dirty);
215 dapm_assert_locked(w->dapm);
217 if (w->endpoints[dir] == -1)
220 list_add_tail(&w->work_list, &list);
221 w->endpoints[dir] = -1;
225 if (p->is_supply || p->weak || !p->connect)
227 node = p->node[rdir];
228 if (node->endpoints[dir] != -1) {
229 node->endpoints[dir] = -1;
230 list_add_tail(&node->work_list, &list);
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)
294 * so there is no need to re-check the path.
296 if (p->source->endpoints[SND_SOC_DAPM_DIR_IN] != 0)
297 dapm_widget_invalidate_input_paths(p->sink);
298 if (p->sink->endpoints[SND_SOC_DAPM_DIR_OUT] != 0)
299 dapm_widget_invalidate_output_paths(p->source);
309 if (w->is_ep) {
311 if (w->is_ep & SND_SOC_DAPM_EP_SINK)
313 if (w->is_ep & SND_SOC_DAPM_EP_SOURCE)
334 w->name = kasprintf(GFP_KERNEL, "%s %s", prefix, _widget->name);
336 w->name = kstrdup_const(_widget->name, GFP_KERNEL);
337 if (!w->name)
340 if (_widget->sname) {
341 w->sname = kstrdup_const(_widget->sname, GFP_KERNEL);
342 if (!w->sname) {
343 kfree_const(w->name);
369 return -ENOMEM;
371 INIT_LIST_HEAD(&data->paths);
373 switch (widget->id) {
377 mc = (struct soc_mixer_control *)kcontrol->private_value;
379 if (mc->autodisable) {
383 dev_warn(widget->dapm->dev,
390 ret = -ENOMEM;
395 template.reg = mc->reg;
396 template.mask = (1 << fls(mc->max)) - 1;
397 template.shift = mc->shift;
398 if (mc->invert)
399 template.off_val = mc->max;
406 data->value = template.on_val;
408 data->widget =
409 snd_soc_dapm_new_control_unlocked(widget->dapm,
412 if (IS_ERR(data->widget)) {
413 ret = PTR_ERR(data->widget);
420 e = (struct soc_enum *)kcontrol->private_value;
422 if (e->autodisable) {
428 ret = -ENOMEM;
433 template.reg = e->reg;
434 template.mask = e->mask;
435 template.shift = e->shift_l;
441 data->value = template.on_val;
443 data->widget = snd_soc_dapm_new_control_unlocked(
444 widget->dapm, &template);
446 if (IS_ERR(data->widget)) {
447 ret = PTR_ERR(data->widget);
451 snd_soc_dapm_add_path(widget->dapm, data->widget,
453 } else if (e->reg != SND_SOC_NOPM) {
454 data->value = soc_dapm_read(widget->dapm, e->reg) &
455 (e->mask << e->shift_l);
462 kcontrol->private_data = data;
475 list_del(&data->paths);
476 kfree(data->wlist);
485 return data->wlist;
495 if (data->wlist)
496 n = data->wlist->num_widgets + 1;
500 new_wlist = krealloc(data->wlist,
504 return -ENOMEM;
506 new_wlist->num_widgets = n;
507 new_wlist->widgets[n - 1] = widget;
509 data->wlist = new_wlist;
519 list_add_tail(&path->list_kcontrol, &data->paths);
526 if (!data->widget)
529 return data->widget->power;
537 return &data->paths;
548 return data->value;
557 if (data->value == value)
560 if (data->widget) {
561 switch (dapm_kcontrol_get_wlist(kcontrol)->widgets[0]->id) {
565 data->widget->on_val = value & data->widget->mask;
569 data->widget->on_val = value >> data->widget->shift;
572 data->widget->on_val = value;
577 data->value = value;
583 * snd_soc_dapm_kcontrol_widget() - Returns the widget associated to a
590 return dapm_kcontrol_get_wlist(kcontrol)->widgets[0];
595 * snd_soc_dapm_kcontrol_dapm() - Returns the dapm context associated to a
605 return dapm_kcontrol_get_wlist(kcontrol)->widgets[0]->dapm;
615 memset(&card->dapm_stats, 0, sizeof(card->dapm_stats));
618 w->new_power = w->power;
619 w->power_checked = false;
625 if (!dapm->component)
627 return dapm->component->name_prefix;
632 if (!dapm->component)
633 return -EIO;
634 return snd_soc_component_read(dapm->component, reg);
640 if (!dapm->component)
641 return -EIO;
642 return snd_soc_component_update_bits(dapm->component, reg,
649 if (!dapm->component)
650 return -EIO;
651 return snd_soc_component_test_bits(dapm->component, reg, mask, value);
656 if (dapm->component)
657 snd_soc_component_async_complete(dapm->component);
664 struct list_head *wlist = &w->dapm->card->widgets;
669 if (!strcmp(name, w->name))
681 * snd_soc_dapm_force_bias_level() - Sets the DAPM bias level
685 * Forces the DAPM bias level to a specific state. It will call the bias level
688 * the normal bias level sequencing, meaning any intermediate states between the
689 * current and the target state will not be entered.
691 * Note that the change in bias level is only temporary and the next time
702 if (dapm->component)
703 ret = snd_soc_component_set_bias_level(dapm->component, level);
706 dapm->bias_level = level;
713 * snd_soc_dapm_set_bias_level - set the bias level for the system
717 * Configure the bias (power) levels for the SoC audio device.
724 struct snd_soc_card *card = dapm->card;
733 if (dapm != &card->dapm)
751 const struct snd_kcontrol_new *kcontrol = &w->kcontrol_news[0];
752 struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
756 if (e->reg != SND_SOC_NOPM) {
758 val = soc_dapm_read(dapm, e->reg);
759 val = (val >> e->shift_l) & e->mask;
771 i = match_string(e->texts, e->items, control_name);
773 return -ENODEV;
775 path->name = e->texts[i];
776 path->connect = (i == item);
786 p->sink->kcontrol_news[i].private_value;
787 unsigned int reg = mc->reg;
788 unsigned int invert = mc->invert;
791 unsigned int shift = mc->shift;
792 unsigned int max = mc->max;
793 unsigned int mask = (1 << fls(max)) - 1;
794 unsigned int val = soc_dapm_read(p->sink->dapm, reg);
809 if (reg != mc->rreg)
810 val = soc_dapm_read(p->sink->dapm, mc->rreg);
811 val = (val >> mc->rshift) & mask;
816 val = max - val;
817 p->connect = !!val;
825 p->connect = invert;
836 for (i = 0; i < path->sink->num_kcontrols; i++) {
837 if (!strcmp(control_name, path->sink->kcontrol_news[i].name)) {
838 path->name = path->sink->kcontrol_news[i].name;
843 return -ENODEV;
856 for_each_card_widgets(dapm->card, w) {
857 if (w == kcontrolw || w->dapm != kcontrolw->dapm)
859 for (i = 0; i < w->num_kcontrols; i++) {
860 if (&w->kcontrol_news[i] == kcontrol_new) {
861 if (w->kcontrols)
862 *kcontrol = w->kcontrols[i];
878 struct snd_soc_dapm_context *dapm = w->dapm;
879 struct snd_card *card = dapm->card->snd_card;
895 shared = dapm_is_shared_kcontrol(dapm, w, &w->kcontrol_news[kci],
903 switch (w->id) {
922 return -EINVAL;
925 if (w->no_wname_in_kcontrol_name)
936 w->name + prefix_len,
937 w->kcontrol_news[kci].name);
939 return -ENOMEM;
944 name = w->name + prefix_len;
947 name = w->kcontrol_news[kci].name;
950 kcontrol = snd_soc_cnew(&w->kcontrol_news[kci], NULL, name,
953 ret = -ENOMEM;
957 kcontrol->private_free = dapm_kcontrol_free;
967 dev_err(dapm->dev,
969 w->name, name, ret);
976 w->kcontrols[kci] = kcontrol;
992 for (i = 0; i < w->num_kcontrols; i++) {
996 if (path->name != (char *)w->kcontrol_news[i].name)
999 if (!w->kcontrols[i]) {
1005 dapm_kcontrol_add_path(w->kcontrols[i], path);
1007 data = snd_kcontrol_chip(w->kcontrols[i]);
1008 if (data->widget)
1009 snd_soc_dapm_add_path(data->widget->dapm,
1010 data->widget,
1011 path->source,
1022 struct snd_soc_dapm_context *dapm = w->dapm;
1028 switch (w->id) {
1038 return -EINVAL;
1041 if (w->num_kcontrols != 1) {
1042 dev_err(dapm->dev,
1044 w->name);
1045 return -EINVAL;
1048 if (list_empty(&w->edges[dir])) {
1049 dev_err(dapm->dev, "ASoC: %s %s has no paths\n", type, w->name);
1050 return -EINVAL;
1058 if (path->name)
1059 dapm_kcontrol_add_path(w->kcontrols[0], path);
1070 for (i = 0; i < w->num_kcontrols; i++) {
1083 struct snd_soc_pcm_runtime *rtd = w->priv;
1086 if (rtd->dai_link->num_c2c_params <= 1)
1090 for (i = 0; i < w->num_kcontrols; i++) {
1091 struct snd_soc_dapm_context *dapm = w->dapm;
1092 struct snd_card *card = dapm->card->snd_card;
1093 struct snd_kcontrol *kcontrol = snd_soc_cnew(&w->kcontrol_news[i],
1094 w, w->name, NULL);
1098 dev_err(dapm->dev,
1100 w->name, w->kcontrol_news[i].name, ret);
1103 kcontrol->private_data = w;
1104 w->kcontrols[i] = kcontrol;
1111 * the ALSA card - when we are suspending the ALSA state for the card
1116 int level = snd_power_get_state(widget->dapm->card->snd_card);
1121 if (widget->ignore_suspend)
1122 dev_dbg(widget->dapm->dev, "ASoC: %s ignoring suspend\n",
1123 widget->name);
1124 return widget->ignore_suspend;
1148 return -ENOMEM;
1150 (*list)->num_widgets = size;
1153 (*list)->widgets[i++] = w;
1155 (*list)->num_widgets = i;
1171 widget->endpoints[dir] = -1;
1174 if (path->weak || path->is_supply)
1177 if (path->walking)
1180 if (path->connect) {
1181 path->walking = 1;
1182 invalidate_paths_ep(path->node[dir], dir);
1183 path->walking = 0;
1207 if (widget->endpoints[dir] >= 0)
1208 return widget->endpoints[dir];
1214 list_add_tail(&widget->work_list, list);
1221 if ((widget->is_ep & SND_SOC_DAPM_DIR_TO_EP(dir)) && widget->connected) {
1222 widget->endpoints[dir] = snd_soc_dapm_suspend_check(widget);
1223 return widget->endpoints[dir];
1229 if (path->weak || path->is_supply)
1232 if (path->walking)
1237 if (path->connect) {
1238 path->walking = 1;
1239 con += fn(path->node[dir], list, custom_stop_condition);
1240 path->walking = 0;
1244 widget->endpoints[dir] = con;
1286 * snd_soc_dapm_dai_get_connected_widgets - query audio path and it's widgets.
1295 * current mixer and mux kcontrol settings. Creates list of valid widgets.
1309 struct snd_soc_card *card = dai->component->card;
1355 soc_dapm_async_complete(w->dapm);
1358 if (w->on_val & SND_SOC_DAPM_REGULATOR_BYPASS) {
1359 ret = regulator_allow_bypass(w->regulator, false);
1361 dev_warn(w->dapm->dev,
1363 w->name, ret);
1366 return regulator_enable(w->regulator);
1368 if (w->on_val & SND_SOC_DAPM_REGULATOR_BYPASS) {
1369 ret = regulator_allow_bypass(w->regulator, true);
1371 dev_warn(w->dapm->dev,
1373 w->name, ret);
1376 return regulator_disable_deferred(w->regulator, w->shift);
1387 struct snd_soc_dapm_pinctrl_priv *priv = w->priv;
1388 struct pinctrl *p = w->pinctrl;
1392 return -EIO;
1395 s = pinctrl_lookup_state(p, priv->active_state);
1397 s = pinctrl_lookup_state(p, priv->sleep_state);
1412 if (!w->clk)
1413 return -EIO;
1415 soc_dapm_async_complete(w->dapm);
1418 return clk_prepare_enable(w->clk);
1420 clk_disable_unprepare(w->clk);
1430 if (w->power_checked)
1431 return w->new_power;
1433 if (w->force)
1434 w->new_power = 1;
1436 w->new_power = w->power_check(w);
1438 w->power_checked = true;
1440 return w->new_power;
1466 if (path->weak)
1469 if (path->connected &&
1470 !path->connected(path->source, path->sink))
1473 if (dapm_widget_power_check(path->sink))
1482 return w->connected;
1499 WARN_ONCE(sort[a->id] == 0, "offset a->id %d not initialized\n", a->id);
1500 WARN_ONCE(sort[b->id] == 0, "offset b->id %d not initialized\n", b->id);
1502 if (sort[a->id] != sort[b->id])
1503 return sort[a->id] - sort[b->id];
1504 if (a->subseq != b->subseq) {
1506 return a->subseq - b->subseq;
1508 return b->subseq - a->subseq;
1510 if (a->reg != b->reg)
1511 return a->reg - b->reg;
1512 if (a->dapm != b->dapm)
1513 return (unsigned long)a->dapm - (unsigned long)b->dapm;
1527 list_add_tail(&new_widget->power_list, &w->power_list);
1531 list_add_tail(&new_widget->power_list, list);
1570 if (w->new_power != power)
1573 if (w->event && (w->event_flags & event)) {
1576 pop_dbg(w->dapm->dev, card->pop_time, "pop test : %s %s\n",
1577 w->name, ev_name);
1578 soc_dapm_async_complete(w->dapm);
1580 ret = w->event(w, NULL, event);
1583 dev_err(w->dapm->dev, "ASoC: %s: %s event failed: %d\n",
1584 ev_name, w->name, ret);
1599 reg = w->reg;
1600 dapm = w->dapm;
1603 WARN_ON(reg != w->reg || dapm != w->dapm);
1604 w->power = w->new_power;
1606 mask |= w->mask << w->shift;
1607 if (w->power)
1608 value |= w->on_val << w->shift;
1610 value |= w->off_val << w->shift;
1612 pop_dbg(dapm->dev, card->pop_time,
1614 w->name, reg, value, mask);
1626 pop_dbg(dapm->dev, card->pop_time,
1628 value, mask, reg, card->pop_time);
1629 pop_wait(card->pop_time);
1641 * We walk over a pre-sorted list of widgets to apply power to. In
1653 int cur_sort = -1;
1654 int cur_subseq = -1;
1669 if (sort[w->id] != cur_sort || w->reg != cur_reg ||
1670 w->dapm != cur_dapm || w->subseq != cur_subseq) {
1674 if (cur_dapm && cur_dapm->component) {
1678 cur_dapm->component,
1682 if (cur_dapm && w->dapm != cur_dapm)
1686 cur_sort = -1;
1692 switch (w->id) {
1694 if (!w->event)
1698 ret = w->event(w,
1701 ret = w->event(w,
1706 if (!w->event)
1710 ret = w->event(w,
1713 ret = w->event(w,
1719 cur_sort = sort[w->id];
1720 cur_subseq = w->subseq;
1721 cur_reg = w->reg;
1722 cur_dapm = w->dapm;
1723 list_move(&w->power_list, &pending);
1728 dev_err(w->dapm->dev,
1735 if (cur_dapm && cur_dapm->component) {
1739 cur_dapm->component,
1749 struct snd_soc_dapm_update *update = card->update;
1755 if (!update || !dapm_kcontrol_is_powered(update->kcontrol))
1758 wlist = dapm_kcontrol_get_wlist(update->kcontrol);
1761 if (w->event && (w->event_flags & SND_SOC_DAPM_PRE_REG)) {
1762 ret = w->event(w, update->kcontrol, SND_SOC_DAPM_PRE_REG);
1764 dev_err(w->dapm->dev, "ASoC: %s DAPM pre-event failed: %d\n",
1765 w->name, ret);
1772 ret = soc_dapm_update_bits(w->dapm, update->reg, update->mask,
1773 update->val);
1775 dev_err(w->dapm->dev, "ASoC: %s DAPM update failed: %d\n",
1776 w->name, ret);
1778 if (update->has_second_set) {
1779 ret = soc_dapm_update_bits(w->dapm, update->reg2,
1780 update->mask2, update->val2);
1782 dev_err(w->dapm->dev,
1784 w->name, ret);
1788 if (w->event && (w->event_flags & SND_SOC_DAPM_POST_REG)) {
1789 ret = w->event(w, update->kcontrol, SND_SOC_DAPM_POST_REG);
1791 dev_err(w->dapm->dev, "ASoC: %s DAPM post-event failed: %d\n",
1792 w->name, ret);
1797 /* Async callback run prior to DAPM sequences - brings to _PREPARE if
1806 if (d->bias_level == SND_SOC_BIAS_OFF &&
1807 d->target_bias_level != SND_SOC_BIAS_OFF) {
1808 if (d->dev && cookie)
1809 pm_runtime_get_sync(d->dev);
1813 dev_err(d->dev,
1814 "ASoC: Failed to turn on bias: %d\n", ret);
1818 if ((d->target_bias_level == SND_SOC_BIAS_ON &&
1819 d->bias_level != SND_SOC_BIAS_ON) ||
1820 (d->target_bias_level != SND_SOC_BIAS_ON &&
1821 d->bias_level == SND_SOC_BIAS_ON)) {
1824 dev_err(d->dev,
1825 "ASoC: Failed to prepare bias: %d\n", ret);
1829 /* Async callback run prior to DAPM sequences - brings to their final
1837 /* If we just powered the last thing off drop to standby bias */
1838 if (d->bias_level == SND_SOC_BIAS_PREPARE &&
1839 (d->target_bias_level == SND_SOC_BIAS_STANDBY ||
1840 d->target_bias_level == SND_SOC_BIAS_OFF)) {
1843 dev_err(d->dev, "ASoC: Failed to apply standby bias: %d\n",
1847 /* If we're in standby and can support bias off then do that */
1848 if (d->bias_level == SND_SOC_BIAS_STANDBY &&
1849 d->target_bias_level == SND_SOC_BIAS_OFF) {
1852 dev_err(d->dev, "ASoC: Failed to turn off bias: %d\n",
1855 if (d->dev && cookie)
1856 pm_runtime_put(d->dev);
1859 /* If we just powered up then move to active bias */
1860 if (d->bias_level == SND_SOC_BIAS_PREPARE &&
1861 d->target_bias_level == SND_SOC_BIAS_ON) {
1864 dev_err(d->dev, "ASoC: Failed to apply active bias: %d\n",
1880 if (power != peer->power)
1891 switch (w->id) {
1904 if (w->power == power)
1914 dapm_widget_set_peer_power(path->source, power, path->connect);
1919 if (!w->is_supply)
1921 dapm_widget_set_peer_power(path->sink, power, path->connect);
1932 if (dapm->idle_bias_off)
1935 switch (snd_power_get_state(dapm->card->snd_card)) {
1938 return dapm->suspend_bias_off;
1948 * A complete path is a route that has valid endpoints i.e.:-
1950 * o DAC to output pin.
1953 * o DAC to ADC (loopback).
1962 enum snd_soc_bias_level bias;
1971 d->target_bias_level = SND_SOC_BIAS_OFF;
1973 d->target_bias_level = SND_SOC_BIAS_STANDBY;
1984 list_for_each_entry(w, &card->dapm_dirty, dirty) {
1989 switch (w->id) {
1995 list_del_init(&w->dirty);
1999 if (w->new_power) {
2000 d = w->dapm;
2005 * generally don't require full power. Signal
2009 switch (w->id) {
2018 if (d->target_bias_level < SND_SOC_BIAS_STANDBY)
2019 d->target_bias_level = SND_SOC_BIAS_STANDBY;
2022 d->target_bias_level = SND_SOC_BIAS_ON;
2029 /* Force all contexts in the card to the same bias state if
2032 bias = SND_SOC_BIAS_OFF;
2034 if (d->target_bias_level > bias)
2035 bias = d->target_bias_level;
2038 d->target_bias_level = bias;
2042 /* Run card bias changes at first */
2043 dapm_pre_sequence_async(&card->dapm, 0);
2044 /* Run other bias changes in parallel */
2046 if (d != &card->dapm && d->bias_level != d->target_bias_level)
2068 /* Run all the bias changes in parallel */
2070 if (d != &card->dapm && d->bias_level != d->target_bias_level)
2075 /* Run card bias changes at last */
2076 dapm_post_sequence_async(&card->dapm, 0);
2080 if (!d->component)
2083 ret = snd_soc_component_stream_event(d->component, event);
2088 pop_dbg(card->dev, card->pop_time,
2089 "DAPM sequencing finished, waiting %dms\n", card->pop_time);
2090 pop_wait(card->pop_time);
2109 [snd_soc_dapm_dac] = "dac",
2144 struct snd_soc_dapm_widget *w = file->private_data;
2156 return -ENOMEM;
2158 snd_soc_dapm_mutex_lock_root(w->dapm);
2161 if (w->is_supply) {
2170 w->name, w->power ? "On" : "Off",
2171 w->force ? " (forced)" : "", in, out);
2173 if (w->reg >= 0)
2174 ret += scnprintf(buf + ret, PAGE_SIZE - ret,
2175 " - R%d(0x%x) mask 0x%x",
2176 w->reg, w->reg, w->mask << w->shift);
2178 ret += scnprintf(buf + ret, PAGE_SIZE - ret, "\n");
2180 if (w->sname)
2181 ret += scnprintf(buf + ret, PAGE_SIZE - ret, " stream %s %s\n",
2182 w->sname,
2183 w->active ? "active" : "inactive");
2185 ret += scnprintf(buf + ret, PAGE_SIZE - ret, " widget-type %s\n",
2186 snd_soc_dapm_type_name[w->id]);
2191 if (p->connected && !p->connected(p->source, p->sink))
2194 if (!p->connect)
2197 c_name = p->node[rdir]->dapm->component ?
2198 p->node[rdir]->dapm->component->name : NULL;
2199 ret += scnprintf(buf + ret, PAGE_SIZE - ret,
2202 p->name ? p->name : "static",
2203 p->node[rdir]->name, c_name);
2207 snd_soc_dapm_mutex_unlock(w->dapm);
2224 struct snd_soc_dapm_context *dapm = file->private_data;
2227 switch (dapm->bias_level) {
2241 WARN(1, "Unknown bias_level %d\n", dapm->bias_level);
2262 dapm->debugfs_dapm = debugfs_create_dir("dapm", parent);
2264 debugfs_create_file("bias_level", 0444, dapm->debugfs_dapm, dapm,
2270 struct snd_soc_dapm_context *dapm = w->dapm;
2272 if (!dapm->debugfs_dapm || !w->name)
2275 debugfs_create_file(w->name, 0444, dapm->debugfs_dapm, w,
2281 struct snd_soc_dapm_context *dapm = w->dapm;
2283 if (!dapm->debugfs_dapm || !w->name)
2286 debugfs_lookup_and_remove(w->name, dapm->debugfs_dapm);
2291 debugfs_remove_recursive(dapm->debugfs_dapm);
2292 dapm->debugfs_dapm = NULL;
2316 * soc_dapm_connect_path() - Connects or disconnects a path
2325 if (path->connect == connect)
2328 path->connect = connect;
2329 dapm_mark_dirty(path->source, reason);
2330 dapm_mark_dirty(path->sink, reason);
2348 if (e && !(strcmp(path->name, e->texts[mux])))
2366 struct snd_soc_card *card = dapm->card;
2370 card->update = update;
2372 card->update = NULL;
2431 struct snd_soc_card *card = dapm->card;
2435 card->update = update;
2436 ret = soc_dapm_mixer_update_power(card, kcontrol, connect, -1);
2437 card->update = NULL;
2456 if (!cmpnt->card)
2459 for_each_card_widgets(cmpnt->card, w) {
2460 if (w->dapm != dapm)
2464 switch (w->id) {
2481 if (w->name)
2483 w->name, w->power ? "On":"Off");
2517 snd_soc_dapm_mutex_lock_root(rtd->card);
2520 struct snd_soc_component *cmpnt = codec_dai->component;
2525 snd_soc_dapm_mutex_unlock(rtd->card);
2539 list_del(&path->list_node[SND_SOC_DAPM_DIR_IN]);
2540 list_del(&path->list_node[SND_SOC_DAPM_DIR_OUT]);
2541 list_del(&path->list_kcontrol);
2542 list_del(&path->list);
2547 * snd_soc_dapm_free_widget - Free specified widget
2560 list_del(&w->list);
2561 list_del(&w->dirty);
2574 kfree(w->kcontrols);
2575 kfree_const(w->name);
2576 kfree_const(w->sname);
2586 for_each_card_widgets_safe(dapm->card, w, next_w) {
2587 if (w->dapm != dapm)
2592 dapm->wcache_sink = NULL;
2593 dapm->wcache_source = NULL;
2614 for_each_card_widgets(dapm->card, w) {
2615 if (!strcmp(w->name, pin_name)) {
2616 if (w->dapm == dapm)
2643 dev_err(dapm->dev, "ASoC: DAPM unknown pin %s\n", pin);
2644 return -EINVAL;
2647 if (w->connected != status) {
2654 w->connected = status;
2656 w->force = 0;
2674 * snd_soc_dapm_sync_unlocked - scan and power dapm paths
2690 if (!snd_soc_card_is_instantiated(dapm->card))
2693 return dapm_power_widgets(dapm->card, SND_SOC_DAPM_STREAM_NOP);
2698 * snd_soc_dapm_sync - scan and power dapm paths
2721 switch (w->id) {
2729 dev_dbg(w->dapm->dev, "%s DAI route %s -> %s\n",
2730 w->channel < channels ? "Connecting" : "Disconnecting",
2731 p->source->name, p->sink->name);
2733 if (w->channel < channels)
2745 int dir = substream->stream;
2756 dev_dbg(dai->dev, "Update DAI routes for %s %s\n", dai->name, snd_pcm_direction_name(dir));
2759 ret = dapm_update_dai_chan(p, p->sink, channels);
2765 ret = dapm_update_dai_chan(p, p->source, channels);
2780 snd_soc_dapm_mutex_lock(rtd->card);
2782 snd_soc_dapm_mutex_unlock(rtd->card);
2790 struct snd_soc_component *component = widget->dapm->component;
2791 const char *wname = widget->name;
2793 if (component && component->name_prefix)
2794 wname += strlen(component->name_prefix) + 1; /* plus space */
2801 * dapm_update_widget_flags() - Re-compute widget sink and source flags
2815 switch (w->id) {
2818 if (w->dapm->card->fully_routed)
2822 if (p->source->id == snd_soc_dapm_micbias ||
2823 p->source->id == snd_soc_dapm_mic ||
2824 p->source->id == snd_soc_dapm_line ||
2825 p->source->id == snd_soc_dapm_output) {
2833 if (w->dapm->card->fully_routed)
2837 if (p->sink->id == snd_soc_dapm_spk ||
2838 p->sink->id == snd_soc_dapm_hp ||
2839 p->sink->id == snd_soc_dapm_line ||
2840 p->sink->id == snd_soc_dapm_input) {
2849 if (!list_empty(&w->edges[dir]))
2857 w->is_ep = ep;
2870 switch (source->id) {
2878 switch (sink->id) {
2890 dev_err(dapm->dev,
2891 "Direct connection between demux and mixer/mux not supported for path %s -> [%s] -> %s\n",
2892 source->name, control, sink->name);
2893 return -EINVAL;
2895 dev_err(dapm->dev,
2896 "Control not supported for path %s -> [%s] -> %s\n",
2897 source->name, control, sink->name);
2898 return -EINVAL;
2914 if (wsink->is_supply && !wsource->is_supply) {
2915 dev_err(dapm->dev,
2916 "Connecting non-supply widget to supply widget is not supported (%s -> %s)\n",
2917 wsource->name, wsink->name);
2918 return -EINVAL;
2921 if (connected && !wsource->is_supply) {
2922 dev_err(dapm->dev,
2923 "connected() callback only supported for supply widgets (%s -> %s)\n",
2924 wsource->name, wsink->name);
2925 return -EINVAL;
2928 if (wsource->is_supply && control) {
2929 dev_err(dapm->dev,
2930 "Conditional paths are not supported for supply widgets (%s -> [%s] -> %s)\n",
2931 wsource->name, control, wsink->name);
2932 return -EINVAL;
2941 return -ENOMEM;
2943 path->node[SND_SOC_DAPM_DIR_IN] = wsource;
2944 path->node[SND_SOC_DAPM_DIR_OUT] = wsink;
2946 path->connected = connected;
2947 INIT_LIST_HEAD(&path->list);
2948 INIT_LIST_HEAD(&path->list_kcontrol);
2950 if (wsource->is_supply || wsink->is_supply)
2951 path->is_supply = 1;
2955 path->connect = 1;
2957 switch (wsource->id) {
2967 switch (wsink->id) {
2985 list_add(&path->list, &dapm->card->paths);
2988 list_add(&path->list_node[dir], &path->node[dir]->edges[dir]);
2991 dapm_update_widget_flags(path->node[dir]);
2992 dapm_mark_dirty(path->node[dir], "Route added");
2995 if (snd_soc_card_is_instantiated(dapm->card) && path->connect)
3021 prefix, route->sink);
3024 prefix, route->source);
3027 sink = route->sink;
3028 source = route->source;
3031 wsource = dapm_wcache_lookup(dapm->wcache_source, source);
3032 wsink = dapm_wcache_lookup(dapm->wcache_sink, sink);
3039 * current DAPM context
3041 for_each_card_widgets(dapm->card, w) {
3042 if (!wsink && !(strcmp(w->name, sink))) {
3044 if (w->dapm == dapm) {
3051 dev_warn(dapm->dev,
3053 w->name);
3056 if (!wsource && !(strcmp(w->name, source))) {
3058 if (w->dapm == dapm) {
3065 dev_warn(dapm->dev,
3067 w->name);
3076 ret = -ENODEV;
3084 dapm->wcache_sink = wsink;
3085 dapm->wcache_source = wsource;
3087 ret = snd_soc_dapm_add_path(dapm, wsource, wsink, route->control,
3088 route->connected);
3091 dev_err(dapm->dev, "ASoC: Failed to add route %s%s -%s%s%s> %s%s\n",
3093 !route->control ? "" : "> [",
3094 !route->control ? "" : route->control,
3095 !route->control ? "" : "] -",
3110 if (route->control) {
3111 dev_err(dapm->dev,
3113 return -EINVAL;
3119 prefix, route->sink);
3122 prefix, route->source);
3125 sink = route->sink;
3126 source = route->source;
3130 list_for_each_entry(p, &dapm->card->paths, list) {
3131 if (strcmp(p->source->name, source) != 0)
3133 if (strcmp(p->sink->name, sink) != 0)
3140 struct snd_soc_dapm_widget *wsource = path->source;
3141 struct snd_soc_dapm_widget *wsink = path->sink;
3145 if (path->connect)
3154 dev_warn(dapm->dev, "ASoC: Route %s->%s does not exist\n",
3162 * snd_soc_dapm_add_routes - Add routes between DAPM widgets
3193 * snd_soc_dapm_del_routes - Remove routes between DAPM widgets
3220 route->source,
3223 route->sink,
3229 dev_err(dapm->dev, "ASoC: Unable to find source %s for weak route\n",
3230 route->source);
3231 return -ENODEV;
3235 dev_err(dapm->dev, "ASoC: Unable to find sink %s for weak route\n",
3236 route->sink);
3237 return -ENODEV;
3240 if (route->control || route->connected)
3241 dev_warn(dapm->dev, "ASoC: Ignoring control for weak route %s->%s\n",
3242 route->source, route->sink);
3245 if (path->sink == sink) {
3246 path->weak = 1;
3252 dev_err(dapm->dev, "ASoC: No path found for weak route %s->%s\n",
3253 route->source, route->sink);
3255 dev_warn(dapm->dev, "ASoC: %d paths found for weak route %s->%s\n",
3256 count, route->source, route->sink);
3262 * snd_soc_dapm_weak_routes - Mark routes between DAPM widgets as weak
3297 * snd_soc_dapm_new_widgets - add new dapm widgets
3313 if (w->new)
3316 if (w->num_kcontrols) {
3317 w->kcontrols = kcalloc(w->num_kcontrols,
3320 if (!w->kcontrols) {
3322 return -ENOMEM;
3326 switch(w->id) {
3349 if (w->reg >= 0) {
3350 val = soc_dapm_read(w->dapm, w->reg);
3351 val = val >> w->shift;
3352 val &= w->mask;
3353 if (val == w->on_val)
3354 w->power = 1;
3357 w->new = 1;
3370 * snd_soc_dapm_get_volsw - dapm mixer get callback
3383 (struct soc_mixer_control *)kcontrol->private_value;
3384 int reg = mc->reg;
3385 unsigned int shift = mc->shift;
3386 int max = mc->max;
3388 unsigned int mask = (1 << fls(max)) - 1;
3389 unsigned int invert = mc->invert;
3397 if (reg != mc->rreg)
3398 reg_val = soc_dapm_read(dapm, mc->rreg);
3401 rval = (reg_val >> mc->rshift) & mask;
3412 ucontrol->value.integer.value[0] = max - val;
3414 ucontrol->value.integer.value[0] = val;
3418 ucontrol->value.integer.value[1] = max - rval;
3420 ucontrol->value.integer.value[1] = rval;
3428 * snd_soc_dapm_put_volsw - dapm mixer set callback
3440 struct snd_soc_card *card = dapm->card;
3442 (struct soc_mixer_control *)kcontrol->private_value;
3443 int reg = mc->reg;
3444 unsigned int shift = mc->shift;
3445 int max = mc->max;
3447 unsigned int mask = (1 << width) - 1;
3448 unsigned int invert = mc->invert;
3450 int connect, rconnect = -1, change, reg_change = 0;
3454 val = (ucontrol->value.integer.value[0] & mask);
3458 val = max - val;
3461 rval = (ucontrol->value.integer.value[1] & mask);
3464 rval = max - rval;
3471 dev_warn(dapm->dev,
3473 kcontrol->id.name);
3478 rval = rval << mc->rshift;
3483 reg_change |= soc_dapm_test_bits(dapm, mc->rreg,
3484 mask << mc->rshift,
3492 update.reg2 = mc->rreg;
3493 update.mask2 = mask << mc->rshift;
3500 card->update = &update;
3506 card->update = NULL;
3519 * snd_soc_dapm_get_enum_double - dapm enumerated double mixer get callback
3531 struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
3535 if (e->reg != SND_SOC_NOPM && dapm_kcontrol_is_powered(kcontrol)) {
3536 reg_val = soc_dapm_read(dapm, e->reg);
3542 val = (reg_val >> e->shift_l) & e->mask;
3543 ucontrol->value.enumerated.item[0] = snd_soc_enum_val_to_item(e, val);
3544 if (e->shift_l != e->shift_r) {
3545 val = (reg_val >> e->shift_r) & e->mask;
3547 ucontrol->value.enumerated.item[1] = val;
3555 * snd_soc_dapm_put_enum_double - dapm enumerated double mixer set callback
3567 struct snd_soc_card *card = dapm->card;
3568 struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
3569 unsigned int *item = ucontrol->value.enumerated.item;
3575 if (item[0] >= e->items)
3576 return -EINVAL;
3578 val = snd_soc_enum_item_to_val(e, item[0]) << e->shift_l;
3579 mask = e->mask << e->shift_l;
3580 if (e->shift_l != e->shift_r) {
3581 if (item[1] > e->items)
3582 return -EINVAL;
3583 val |= snd_soc_enum_item_to_val(e, item[1]) << e->shift_r;
3584 mask |= e->mask << e->shift_r;
3591 if (e->reg != SND_SOC_NOPM)
3592 reg_change = soc_dapm_test_bits(dapm, e->reg, mask, val);
3597 update.reg = e->reg;
3600 card->update = &update;
3605 card->update = NULL;
3618 * snd_soc_dapm_info_pin_switch - Info for a pin switch
3628 uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
3629 uinfo->count = 1;
3630 uinfo->value.integer.min = 0;
3631 uinfo->value.integer.max = 1;
3638 * snd_soc_dapm_get_pin_switch - Get information for a pin switch
3647 const char *pin = (const char *)kcontrol->private_value;
3651 ucontrol->value.integer.value[0] =
3652 snd_soc_dapm_get_pin_status(&card->dapm, pin);
3661 * snd_soc_dapm_put_pin_switch - Set information for a pin switch
3670 const char *pin = (const char *)kcontrol->private_value;
3674 ret = __snd_soc_dapm_set_pin(&card->dapm, pin,
3675 !!ucontrol->value.integer.value[0]);
3678 snd_soc_dapm_sync(&card->dapm);
3689 int ret = -ENOMEM;
3695 switch (w->id) {
3697 w->regulator = devm_regulator_get(dapm->dev, widget->name);
3698 if (IS_ERR(w->regulator)) {
3699 ret = PTR_ERR(w->regulator);
3703 if (w->on_val & SND_SOC_DAPM_REGULATOR_BYPASS) {
3704 ret = regulator_allow_bypass(w->regulator, true);
3706 dev_warn(dapm->dev,
3708 w->name, ret);
3712 w->pinctrl = devm_pinctrl_get(dapm->dev);
3713 if (IS_ERR(w->pinctrl)) {
3714 ret = PTR_ERR(w->pinctrl);
3722 w->clk = devm_clk_get(dapm->dev, widget->name);
3723 if (IS_ERR(w->clk)) {
3724 ret = PTR_ERR(w->clk);
3732 switch (w->id) {
3734 w->is_ep = SND_SOC_DAPM_EP_SOURCE;
3735 w->power_check = dapm_generic_check_power;
3738 if (!dapm->card->fully_routed)
3739 w->is_ep = SND_SOC_DAPM_EP_SOURCE;
3740 w->power_check = dapm_generic_check_power;
3744 w->is_ep = SND_SOC_DAPM_EP_SINK;
3745 w->power_check = dapm_generic_check_power;
3748 if (!dapm->card->fully_routed)
3749 w->is_ep = SND_SOC_DAPM_EP_SINK;
3750 w->power_check = dapm_generic_check_power;
3754 w->is_ep = SND_SOC_DAPM_EP_SOURCE;
3755 w->power_check = dapm_always_on_check_power;
3758 w->is_ep = SND_SOC_DAPM_EP_SINK;
3759 w->power_check = dapm_always_on_check_power;
3785 w->power_check = dapm_generic_check_power;
3792 w->is_supply = 1;
3793 w->power_check = dapm_supply_check_power;
3796 w->power_check = dapm_always_on_check_power;
3800 w->dapm = dapm;
3801 INIT_LIST_HEAD(&w->list);
3802 INIT_LIST_HEAD(&w->dirty);
3804 list_add_tail(&w->list, &dapm->card->widgets);
3807 INIT_LIST_HEAD(&w->edges[dir]);
3808 w->endpoints[dir] = -1;
3812 w->connected = 1;
3816 dev_err_probe(dapm->dev, ret, "ASoC: Failed to request %s\n",
3817 w->name);
3818 kfree_const(w->name);
3819 kfree_const(w->sname);
3826 * snd_soc_dapm_new_control - create new dapm control
3849 * snd_soc_dapm_new_controls - create new dapm controls
3903 return -ENOMEM;
3907 return -ENOMEM;
3909 substream->runtime = runtime;
3911 substream->stream = SNDRV_PCM_STREAM_CAPTURE;
3913 source = path->source->priv;
3919 snd_soc_dai_activate(source, substream->stream);
3922 substream->stream = SNDRV_PCM_STREAM_PLAYBACK;
3924 sink = path->sink->priv;
3930 snd_soc_dai_activate(sink, substream->stream);
3933 substream->hw_opened = 1;
3940 config = rtd->dai_link->c2c_params + rtd->c2c_params_select;
3942 dev_err(w->dapm->dev, "ASoC: link config missing\n");
3943 return -EINVAL;
3947 if (!config->formats) {
3948 dev_warn(w->dapm->dev, "ASoC: Invalid format was specified\n");
3950 return -EINVAL;
3953 fmt = ffs(config->formats) - 1;
3956 hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE)->min =
3957 config->rate_min;
3958 hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE)->max =
3959 config->rate_max;
3960 hw_param_interval(params, SNDRV_PCM_HW_PARAM_CHANNELS)->min
3961 = config->channels_min;
3962 hw_param_interval(params, SNDRV_PCM_HW_PARAM_CHANNELS)->max
3963 = config->channels_max;
3965 substream->stream = SNDRV_PCM_STREAM_CAPTURE;
3967 source = path->source->priv;
3976 substream->stream = SNDRV_PCM_STREAM_PLAYBACK;
3978 sink = path->sink->priv;
3987 runtime->format = params_format(params);
3988 runtime->subformat = params_subformat(params);
3989 runtime->channels = params_channels(params);
3990 runtime->rate = params_rate(params);
4000 struct snd_pcm_substream *substream = w->priv;
4001 int ret = 0, saved_stream = substream->stream;
4003 if (WARN_ON(list_empty(&w->edges[SND_SOC_DAPM_DIR_OUT]) ||
4004 list_empty(&w->edges[SND_SOC_DAPM_DIR_IN])))
4005 return -EINVAL;
4017 source = path->source->priv;
4023 sink = path->sink->priv;
4029 sink = path->sink->priv;
4038 sink = path->sink->priv;
4044 substream->stream = SNDRV_PCM_STREAM_CAPTURE;
4046 source = path->source->priv;
4050 substream->stream = SNDRV_PCM_STREAM_PLAYBACK;
4052 sink = path->sink->priv;
4056 substream->stream = SNDRV_PCM_STREAM_CAPTURE;
4058 source = path->source->priv;
4059 snd_soc_dai_deactivate(source, substream->stream);
4063 substream->stream = SNDRV_PCM_STREAM_PLAYBACK;
4065 sink = path->sink->priv;
4066 snd_soc_dai_deactivate(sink, substream->stream);
4072 kfree(substream->runtime);
4073 substream->runtime = NULL;
4078 ret = -EINVAL;
4083 substream->stream = saved_stream;
4091 struct snd_soc_pcm_runtime *rtd = w->priv;
4093 ucontrol->value.enumerated.item[0] = rtd->c2c_params_select;
4102 struct snd_soc_pcm_runtime *rtd = w->priv;
4105 if (w->power)
4106 return -EBUSY;
4108 if (ucontrol->value.enumerated.item[0] == rtd->c2c_params_select)
4111 if (ucontrol->value.enumerated.item[0] >= rtd->dai_link->num_c2c_params)
4112 return -EINVAL;
4114 rtd->c2c_params_select = ucontrol->value.enumerated.item[0];
4127 devm_kfree(card->dev, (void *)*private_value);
4133 devm_kfree(card->dev, (void *)w_param_text[count]);
4134 devm_kfree(card->dev, w_param_text);
4157 if (!config->stream_name) {
4158 dev_warn(card->dapm.dev,
4162 devm_kasprintf(card->dev, GFP_KERNEL,
4166 w_param_text[count] = devm_kmemdup(card->dev,
4167 config->stream_name,
4168 strlen(config->stream_name) + 1,
4180 (unsigned long) devm_kmemdup(card->dev,
4184 dev_err(card->dev, "ASoC: Failed to create control for %s widget\n",
4190 kcontrol_news = devm_kmemdup(card->dev, &kcontrol_dai_link[0],
4194 dev_err(card->dev, "ASoC: Failed to create control for %s widget\n",
4218 int ret = -ENOMEM;
4220 link_name = devm_kasprintf(card->dev, GFP_KERNEL, "%s-%s",
4221 rtd->dai_link->name, id);
4229 if (rtd->dai_link->num_c2c_params > 1) {
4230 w_param_text = devm_kcalloc(card->dev,
4231 rtd->dai_link->num_c2c_params,
4238 rtd->dai_link->c2c_params,
4239 rtd->dai_link->num_c2c_params,
4255 dev_dbg(card->dev, "ASoC: adding %s widget\n", link_name);
4257 w = snd_soc_dapm_new_control_unlocked(&card->dapm, &template);
4263 w->priv = substream;
4268 devm_kfree(card->dev, (void *)template.kcontrol_news);
4270 rtd->dai_link->num_c2c_params, w_param_text);
4272 devm_kfree(card->dev, link_name);
4274 dev_err(rtd->dev, "ASoC: Failed to create %s-%s widget: %d\n",
4275 rtd->dai_link->name, id, ret);
4280 * snd_soc_dapm_new_dai_widgets - Create new DAPM widgets
4292 WARN_ON(dapm->dev != dai->dev);
4297 if (dai->driver->playback.stream_name) {
4299 template.name = dai->driver->playback.stream_name;
4300 template.sname = dai->driver->playback.stream_name;
4302 dev_dbg(dai->dev, "ASoC: adding %s widget\n",
4309 w->priv = dai;
4313 if (dai->driver->capture.stream_name) {
4315 template.name = dai->driver->capture.stream_name;
4316 template.sname = dai->driver->capture.stream_name;
4318 dev_dbg(dai->dev, "ASoC: adding %s widget\n",
4325 w->priv = dai;
4341 switch (dai_w->id) {
4350 if (!dai_w->priv) {
4351 dev_dbg(card->dev, "dai widget %s has no DAI\n",
4352 dai_w->name);
4356 dai = dai_w->priv;
4360 if (w->dapm != dai_w->dapm)
4363 switch (w->id) {
4371 if (!w->sname || !strstr(w->sname, dai_w->sname))
4374 if (dai_w->id == snd_soc_dapm_dai_in) {
4381 dev_dbg(dai->dev, "%s -> %s\n", src->name, sink->name);
4382 snd_soc_dapm_add_path(w->dapm, src, sink, NULL, NULL);
4396 dev_dbg(dapm->dev, "connected DAI link %s:%s -> %s:%s\n",
4397 src_dai->component->name, src->name,
4398 sink_dai->component->name, sink->name);
4413 struct snd_soc_dai_link *dai_link = rtd->dai_link;
4436 if (dai_link->c2c_params && !rtd->c2c_widget[stream]) {
4437 struct snd_pcm_substream *substream = rtd->pcm->streams[stream].substream;
4444 rtd->c2c_widget[stream] = dai;
4447 dapm_connect_dai_routes(&card->dapm, src_dai[stream], *src[stream],
4448 rtd->c2c_widget[stream],
4465 if (w->id == snd_soc_dapm_dai_in) {
4475 w->active = 1;
4476 w->is_ep = ep;
4479 w->active = 0;
4480 w->is_ep = 0;
4504 * CODEC<->CODEC links have no direct connection.
4506 if (rtd->dai_link->dynamic)
4511 * soc.h :: [dai_link->ch_maps Image sample]
4514 cpu_dai = snd_soc_rtd_to_cpu(rtd, ch_maps->cpu);
4515 codec_dai = snd_soc_rtd_to_codec(rtd, ch_maps->codec);
4531 dapm_power_widgets(rtd->card, event);
4535 * snd_soc_dapm_stream_event - send a stream event to the dapm core
4548 struct snd_soc_card *card = rtd->card;
4565 rtd->pop_wait = 1;
4567 &rtd->delayed_work,
4568 msecs_to_jiffies(rtd->pmdown_time));
4579 * snd_soc_dapm_enable_pin_unlocked - enable pin.
4599 * snd_soc_dapm_enable_pin - enable pin.
4624 * snd_soc_dapm_force_enable_pin_unlocked - force a pin to be enabled
4629 * intended for use with microphone bias supplies used in microphone
4643 dev_err(dapm->dev, "ASoC: unknown pin %s\n", pin);
4644 return -EINVAL;
4647 dev_dbg(w->dapm->dev, "ASoC: force enable pin %s\n", pin);
4648 if (!w->connected) {
4650 * w->force does not affect the number of input or output paths,
4651 * so we only have to recheck if w->connected is changed
4655 w->connected = 1;
4657 w->force = 1;
4665 * snd_soc_dapm_force_enable_pin - force a pin to be enabled
4670 * intended for use with microphone bias supplies used in microphone
4692 * snd_soc_dapm_disable_pin_unlocked - disable pin.
4711 * snd_soc_dapm_disable_pin - disable pin.
4736 * snd_soc_dapm_nc_pin_unlocked - permanently disable pin.
4759 * snd_soc_dapm_nc_pin - permanently disable pin.
4787 * snd_soc_dapm_get_pin_status - get audio pin status
4791 * Get audio pin status - connected or disconnected.
4801 return w->connected;
4808 * snd_soc_dapm_ignore_suspend - ignore suspend status for DAPM endpoint
4824 dev_err(dapm->dev, "ASoC: unknown pin %s\n", pin);
4825 return -EINVAL;
4828 w->ignore_suspend = 1;
4835 * snd_soc_dapm_free - free dapm resources
4844 list_del(&dapm->list);
4852 dapm->card = card;
4853 dapm->component = component;
4854 dapm->bias_level = SND_SOC_BIAS_OFF;
4857 dapm->dev = component->dev;
4858 dapm->idle_bias_off = !component->driver->idle_bias_on;
4859 dapm->suspend_bias_off = component->driver->suspend_bias_off;
4861 dapm->dev = card->dev;
4864 INIT_LIST_HEAD(&dapm->list);
4866 list_add(&dapm->list, &card->dapm_list);
4872 struct snd_soc_card *card = dapm->card;
4879 for_each_card_widgets(dapm->card, w) {
4880 if (w->dapm != dapm)
4882 if (w->power) {
4884 w->new_power = 0;
4893 if (dapm->bias_level == SND_SOC_BIAS_ON)
4897 if (dapm->bias_level == SND_SOC_BIAS_PREPARE)
4906 * snd_soc_dapm_shutdown - callback for system shutdown
4913 if (dapm != &card->dapm) {
4915 if (dapm->bias_level == SND_SOC_BIAS_STANDBY)
4921 soc_dapm_shutdown_dapm(&card->dapm);
4922 if (card->dapm.bias_level == SND_SOC_BIAS_STANDBY)
4923 snd_soc_dapm_set_bias_level(&card->dapm,