aboutsummaryrefslogtreecommitdiffstats
path: root/sound/soc/soc-dapm.c
diff options
context:
space:
mode:
Diffstat (limited to 'sound/soc/soc-dapm.c')
-rw-r--r--sound/soc/soc-dapm.c306
1 files changed, 173 insertions, 133 deletions
diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c
index a74b9bf23d9f..8348352dc2c6 100644
--- a/sound/soc/soc-dapm.c
+++ b/sound/soc/soc-dapm.c
@@ -350,12 +350,27 @@ static bool dapm_kcontrol_set_value(const struct snd_kcontrol *kcontrol,
350} 350}
351 351
352/** 352/**
353 * snd_soc_dapm_kcontrol_dapm() - Returns the dapm context associated to a
354 * kcontrol
355 * @kcontrol: The kcontrol
356 *
357 * Note: This function must only be used on kcontrols that are known to have
358 * been registered for a CODEC. Otherwise the behaviour is undefined.
359 */
360struct snd_soc_dapm_context *snd_soc_dapm_kcontrol_dapm(
361 struct snd_kcontrol *kcontrol)
362{
363 return dapm_kcontrol_get_wlist(kcontrol)->widgets[0]->dapm;
364}
365EXPORT_SYMBOL_GPL(snd_soc_dapm_kcontrol_dapm);
366
367/**
353 * snd_soc_dapm_kcontrol_codec() - Returns the codec associated to a kcontrol 368 * snd_soc_dapm_kcontrol_codec() - Returns the codec associated to a kcontrol
354 * @kcontrol: The kcontrol 369 * @kcontrol: The kcontrol
355 */ 370 */
356struct snd_soc_codec *snd_soc_dapm_kcontrol_codec(struct snd_kcontrol *kcontrol) 371struct snd_soc_codec *snd_soc_dapm_kcontrol_codec(struct snd_kcontrol *kcontrol)
357{ 372{
358 return dapm_kcontrol_get_wlist(kcontrol)->widgets[0]->codec; 373 return snd_soc_dapm_to_codec(snd_soc_dapm_kcontrol_dapm(kcontrol));
359} 374}
360EXPORT_SYMBOL_GPL(snd_soc_dapm_kcontrol_codec); 375EXPORT_SYMBOL_GPL(snd_soc_dapm_kcontrol_codec);
361 376
@@ -375,23 +390,38 @@ static void dapm_reset(struct snd_soc_card *card)
375 } 390 }
376} 391}
377 392
378static int soc_widget_read(struct snd_soc_dapm_widget *w, int reg, 393static const char *soc_dapm_prefix(struct snd_soc_dapm_context *dapm)
394{
395 if (!dapm->component)
396 return NULL;
397 return dapm->component->name_prefix;
398}
399
400static int soc_dapm_read(struct snd_soc_dapm_context *dapm, int reg,
379 unsigned int *value) 401 unsigned int *value)
380{ 402{
381 if (!w->dapm->component) 403 if (!dapm->component)
382 return -EIO; 404 return -EIO;
383 return snd_soc_component_read(w->dapm->component, reg, value); 405 return snd_soc_component_read(dapm->component, reg, value);
384} 406}
385 407
386static int soc_widget_update_bits(struct snd_soc_dapm_widget *w, 408static int soc_dapm_update_bits(struct snd_soc_dapm_context *dapm,
387 int reg, unsigned int mask, unsigned int value) 409 int reg, unsigned int mask, unsigned int value)
388{ 410{
389 if (!w->dapm->component) 411 if (!dapm->component)
390 return -EIO; 412 return -EIO;
391 return snd_soc_component_update_bits_async(w->dapm->component, reg, 413 return snd_soc_component_update_bits_async(dapm->component, reg,
392 mask, value); 414 mask, value);
393} 415}
394 416
417static int soc_dapm_test_bits(struct snd_soc_dapm_context *dapm,
418 int reg, unsigned int mask, unsigned int value)
419{
420 if (!dapm->component)
421 return -EIO;
422 return snd_soc_component_test_bits(dapm->component, reg, mask, value);
423}
424
395static void soc_dapm_async_complete(struct snd_soc_dapm_context *dapm) 425static void soc_dapm_async_complete(struct snd_soc_dapm_context *dapm)
396{ 426{
397 if (dapm->component) 427 if (dapm->component)
@@ -420,15 +450,10 @@ static int snd_soc_dapm_set_bias_level(struct snd_soc_dapm_context *dapm,
420 if (ret != 0) 450 if (ret != 0)
421 goto out; 451 goto out;
422 452
423 if (dapm->codec) { 453 if (dapm->set_bias_level)
424 if (dapm->codec->driver->set_bias_level) 454 ret = dapm->set_bias_level(dapm, level);
425 ret = dapm->codec->driver->set_bias_level(dapm->codec, 455 else if (!card || dapm != &card->dapm)
426 level);
427 else
428 dapm->bias_level = level;
429 } else if (!card || dapm != &card->dapm) {
430 dapm->bias_level = level; 456 dapm->bias_level = level;
431 }
432 457
433 if (ret != 0) 458 if (ret != 0)
434 goto out; 459 goto out;
@@ -452,7 +477,7 @@ static int dapm_connect_mux(struct snd_soc_dapm_context *dapm,
452 int i; 477 int i;
453 478
454 if (e->reg != SND_SOC_NOPM) { 479 if (e->reg != SND_SOC_NOPM) {
455 soc_widget_read(dest, e->reg, &val); 480 soc_dapm_read(dapm, e->reg, &val);
456 val = (val >> e->shift_l) & e->mask; 481 val = (val >> e->shift_l) & e->mask;
457 item = snd_soc_enum_val_to_item(e, val); 482 item = snd_soc_enum_val_to_item(e, val);
458 } else { 483 } else {
@@ -496,7 +521,7 @@ static void dapm_set_mixer_path_status(struct snd_soc_dapm_widget *w,
496 unsigned int val; 521 unsigned int val;
497 522
498 if (reg != SND_SOC_NOPM) { 523 if (reg != SND_SOC_NOPM) {
499 soc_widget_read(w, reg, &val); 524 soc_dapm_read(w->dapm, reg, &val);
500 val = (val >> shift) & mask; 525 val = (val >> shift) & mask;
501 if (invert) 526 if (invert)
502 val = max - val; 527 val = max - val;
@@ -570,11 +595,7 @@ static int dapm_create_or_share_mixmux_kcontrol(struct snd_soc_dapm_widget *w,
570 const char *name; 595 const char *name;
571 int ret; 596 int ret;
572 597
573 if (dapm->codec) 598 prefix = soc_dapm_prefix(dapm);
574 prefix = dapm->codec->name_prefix;
575 else
576 prefix = NULL;
577
578 if (prefix) 599 if (prefix)
579 prefix_len = strlen(prefix) + 1; 600 prefix_len = strlen(prefix) + 1;
580 else 601 else
@@ -1308,16 +1329,18 @@ static void dapm_seq_check_event(struct snd_soc_card *card,
1308static void dapm_seq_run_coalesced(struct snd_soc_card *card, 1329static void dapm_seq_run_coalesced(struct snd_soc_card *card,
1309 struct list_head *pending) 1330 struct list_head *pending)
1310{ 1331{
1332 struct snd_soc_dapm_context *dapm;
1311 struct snd_soc_dapm_widget *w; 1333 struct snd_soc_dapm_widget *w;
1312 int reg; 1334 int reg;
1313 unsigned int value = 0; 1335 unsigned int value = 0;
1314 unsigned int mask = 0; 1336 unsigned int mask = 0;
1315 1337
1316 reg = list_first_entry(pending, struct snd_soc_dapm_widget, 1338 w = list_first_entry(pending, struct snd_soc_dapm_widget, power_list);
1317 power_list)->reg; 1339 reg = w->reg;
1340 dapm = w->dapm;
1318 1341
1319 list_for_each_entry(w, pending, power_list) { 1342 list_for_each_entry(w, pending, power_list) {
1320 WARN_ON(reg != w->reg); 1343 WARN_ON(reg != w->reg || dapm != w->dapm);
1321 w->power = w->new_power; 1344 w->power = w->new_power;
1322 1345
1323 mask |= w->mask << w->shift; 1346 mask |= w->mask << w->shift;
@@ -1326,7 +1349,7 @@ static void dapm_seq_run_coalesced(struct snd_soc_card *card,
1326 else 1349 else
1327 value |= w->off_val << w->shift; 1350 value |= w->off_val << w->shift;
1328 1351
1329 pop_dbg(w->dapm->dev, card->pop_time, 1352 pop_dbg(dapm->dev, card->pop_time,
1330 "pop test : Queue %s: reg=0x%x, 0x%x/0x%x\n", 1353 "pop test : Queue %s: reg=0x%x, 0x%x/0x%x\n",
1331 w->name, reg, value, mask); 1354 w->name, reg, value, mask);
1332 1355
@@ -1339,14 +1362,12 @@ static void dapm_seq_run_coalesced(struct snd_soc_card *card,
1339 /* Any widget will do, they should all be updating the 1362 /* Any widget will do, they should all be updating the
1340 * same register. 1363 * same register.
1341 */ 1364 */
1342 w = list_first_entry(pending, struct snd_soc_dapm_widget,
1343 power_list);
1344 1365
1345 pop_dbg(w->dapm->dev, card->pop_time, 1366 pop_dbg(dapm->dev, card->pop_time,
1346 "pop test : Applying 0x%x/0x%x to %x in %dms\n", 1367 "pop test : Applying 0x%x/0x%x to %x in %dms\n",
1347 value, mask, reg, card->pop_time); 1368 value, mask, reg, card->pop_time);
1348 pop_wait(card->pop_time); 1369 pop_wait(card->pop_time);
1349 soc_widget_update_bits(w, reg, mask, value); 1370 soc_dapm_update_bits(dapm, reg, mask, value);
1350 } 1371 }
1351 1372
1352 list_for_each_entry(w, pending, power_list) { 1373 list_for_each_entry(w, pending, power_list) {
@@ -1492,7 +1513,8 @@ static void dapm_widget_update(struct snd_soc_card *card)
1492 if (!w) 1513 if (!w)
1493 return; 1514 return;
1494 1515
1495 ret = soc_widget_update_bits(w, update->reg, update->mask, update->val); 1516 ret = soc_dapm_update_bits(w->dapm, update->reg, update->mask,
1517 update->val);
1496 if (ret < 0) 1518 if (ret < 0)
1497 dev_err(w->dapm->dev, "ASoC: %s DAPM update failed: %d\n", 1519 dev_err(w->dapm->dev, "ASoC: %s DAPM update failed: %d\n",
1498 w->name, ret); 1520 w->name, ret);
@@ -2062,17 +2084,13 @@ int snd_soc_dapm_mixer_update_power(struct snd_soc_dapm_context *dapm,
2062} 2084}
2063EXPORT_SYMBOL_GPL(snd_soc_dapm_mixer_update_power); 2085EXPORT_SYMBOL_GPL(snd_soc_dapm_mixer_update_power);
2064 2086
2065/* show dapm widget status in sys fs */ 2087static ssize_t dapm_widget_show_codec(struct snd_soc_codec *codec, char *buf)
2066static ssize_t dapm_widget_show(struct device *dev,
2067 struct device_attribute *attr, char *buf)
2068{ 2088{
2069 struct snd_soc_pcm_runtime *rtd = dev_get_drvdata(dev);
2070 struct snd_soc_codec *codec =rtd->codec;
2071 struct snd_soc_dapm_widget *w; 2089 struct snd_soc_dapm_widget *w;
2072 int count = 0; 2090 int count = 0;
2073 char *state = "not set"; 2091 char *state = "not set";
2074 2092
2075 list_for_each_entry(w, &codec->card->widgets, list) { 2093 list_for_each_entry(w, &codec->component.card->widgets, list) {
2076 if (w->dapm != &codec->dapm) 2094 if (w->dapm != &codec->dapm)
2077 continue; 2095 continue;
2078 2096
@@ -2120,6 +2138,21 @@ static ssize_t dapm_widget_show(struct device *dev,
2120 return count; 2138 return count;
2121} 2139}
2122 2140
2141/* show dapm widget status in sys fs */
2142static ssize_t dapm_widget_show(struct device *dev,
2143 struct device_attribute *attr, char *buf)
2144{
2145 struct snd_soc_pcm_runtime *rtd = dev_get_drvdata(dev);
2146 int i, count = 0;
2147
2148 for (i = 0; i < rtd->num_codecs; i++) {
2149 struct snd_soc_codec *codec = rtd->codec_dais[i]->codec;
2150 count += dapm_widget_show_codec(codec, buf + count);
2151 }
2152
2153 return count;
2154}
2155
2123static DEVICE_ATTR(dapm_widget, 0444, dapm_widget_show, NULL); 2156static DEVICE_ATTR(dapm_widget, 0444, dapm_widget_show, NULL);
2124 2157
2125int snd_soc_dapm_sys_add(struct device *dev) 2158int snd_soc_dapm_sys_add(struct device *dev)
@@ -2371,14 +2404,16 @@ static int snd_soc_dapm_add_route(struct snd_soc_dapm_context *dapm,
2371 const char *source; 2404 const char *source;
2372 char prefixed_sink[80]; 2405 char prefixed_sink[80];
2373 char prefixed_source[80]; 2406 char prefixed_source[80];
2407 const char *prefix;
2374 int ret; 2408 int ret;
2375 2409
2376 if (dapm->codec && dapm->codec->name_prefix) { 2410 prefix = soc_dapm_prefix(dapm);
2411 if (prefix) {
2377 snprintf(prefixed_sink, sizeof(prefixed_sink), "%s %s", 2412 snprintf(prefixed_sink, sizeof(prefixed_sink), "%s %s",
2378 dapm->codec->name_prefix, route->sink); 2413 prefix, route->sink);
2379 sink = prefixed_sink; 2414 sink = prefixed_sink;
2380 snprintf(prefixed_source, sizeof(prefixed_source), "%s %s", 2415 snprintf(prefixed_source, sizeof(prefixed_source), "%s %s",
2381 dapm->codec->name_prefix, route->source); 2416 prefix, route->source);
2382 source = prefixed_source; 2417 source = prefixed_source;
2383 } else { 2418 } else {
2384 sink = route->sink; 2419 sink = route->sink;
@@ -2439,6 +2474,7 @@ static int snd_soc_dapm_del_route(struct snd_soc_dapm_context *dapm,
2439 const char *source; 2474 const char *source;
2440 char prefixed_sink[80]; 2475 char prefixed_sink[80];
2441 char prefixed_source[80]; 2476 char prefixed_source[80];
2477 const char *prefix;
2442 2478
2443 if (route->control) { 2479 if (route->control) {
2444 dev_err(dapm->dev, 2480 dev_err(dapm->dev,
@@ -2446,12 +2482,13 @@ static int snd_soc_dapm_del_route(struct snd_soc_dapm_context *dapm,
2446 return -EINVAL; 2482 return -EINVAL;
2447 } 2483 }
2448 2484
2449 if (dapm->codec && dapm->codec->name_prefix) { 2485 prefix = soc_dapm_prefix(dapm);
2486 if (prefix) {
2450 snprintf(prefixed_sink, sizeof(prefixed_sink), "%s %s", 2487 snprintf(prefixed_sink, sizeof(prefixed_sink), "%s %s",
2451 dapm->codec->name_prefix, route->sink); 2488 prefix, route->sink);
2452 sink = prefixed_sink; 2489 sink = prefixed_sink;
2453 snprintf(prefixed_source, sizeof(prefixed_source), "%s %s", 2490 snprintf(prefixed_source, sizeof(prefixed_source), "%s %s",
2454 dapm->codec->name_prefix, route->source); 2491 prefix, route->source);
2455 source = prefixed_source; 2492 source = prefixed_source;
2456 } else { 2493 } else {
2457 sink = route->sink; 2494 sink = route->sink;
@@ -2670,7 +2707,7 @@ int snd_soc_dapm_new_widgets(struct snd_soc_card *card)
2670 2707
2671 /* Read the initial power state from the device */ 2708 /* Read the initial power state from the device */
2672 if (w->reg >= 0) { 2709 if (w->reg >= 0) {
2673 soc_widget_read(w, w->reg, &val); 2710 soc_dapm_read(w->dapm, w->reg, &val);
2674 val = val >> w->shift; 2711 val = val >> w->shift;
2675 val &= w->mask; 2712 val &= w->mask;
2676 if (val == w->on_val) 2713 if (val == w->on_val)
@@ -2701,8 +2738,8 @@ EXPORT_SYMBOL_GPL(snd_soc_dapm_new_widgets);
2701int snd_soc_dapm_get_volsw(struct snd_kcontrol *kcontrol, 2738int snd_soc_dapm_get_volsw(struct snd_kcontrol *kcontrol,
2702 struct snd_ctl_elem_value *ucontrol) 2739 struct snd_ctl_elem_value *ucontrol)
2703{ 2740{
2704 struct snd_soc_codec *codec = snd_soc_dapm_kcontrol_codec(kcontrol); 2741 struct snd_soc_dapm_context *dapm = snd_soc_dapm_kcontrol_dapm(kcontrol);
2705 struct snd_soc_card *card = codec->card; 2742 struct snd_soc_card *card = dapm->card;
2706 struct soc_mixer_control *mc = 2743 struct soc_mixer_control *mc =
2707 (struct soc_mixer_control *)kcontrol->private_value; 2744 (struct soc_mixer_control *)kcontrol->private_value;
2708 int reg = mc->reg; 2745 int reg = mc->reg;
@@ -2711,17 +2748,20 @@ int snd_soc_dapm_get_volsw(struct snd_kcontrol *kcontrol,
2711 unsigned int mask = (1 << fls(max)) - 1; 2748 unsigned int mask = (1 << fls(max)) - 1;
2712 unsigned int invert = mc->invert; 2749 unsigned int invert = mc->invert;
2713 unsigned int val; 2750 unsigned int val;
2751 int ret = 0;
2714 2752
2715 if (snd_soc_volsw_is_stereo(mc)) 2753 if (snd_soc_volsw_is_stereo(mc))
2716 dev_warn(codec->dapm.dev, 2754 dev_warn(dapm->dev,
2717 "ASoC: Control '%s' is stereo, which is not supported\n", 2755 "ASoC: Control '%s' is stereo, which is not supported\n",
2718 kcontrol->id.name); 2756 kcontrol->id.name);
2719 2757
2720 mutex_lock_nested(&card->dapm_mutex, SND_SOC_DAPM_CLASS_RUNTIME); 2758 mutex_lock_nested(&card->dapm_mutex, SND_SOC_DAPM_CLASS_RUNTIME);
2721 if (dapm_kcontrol_is_powered(kcontrol) && reg != SND_SOC_NOPM) 2759 if (dapm_kcontrol_is_powered(kcontrol) && reg != SND_SOC_NOPM) {
2722 val = (snd_soc_read(codec, reg) >> shift) & mask; 2760 ret = soc_dapm_read(dapm, reg, &val);
2723 else 2761 val = (val >> shift) & mask;
2762 } else {
2724 val = dapm_kcontrol_get_value(kcontrol); 2763 val = dapm_kcontrol_get_value(kcontrol);
2764 }
2725 mutex_unlock(&card->dapm_mutex); 2765 mutex_unlock(&card->dapm_mutex);
2726 2766
2727 if (invert) 2767 if (invert)
@@ -2729,7 +2769,7 @@ int snd_soc_dapm_get_volsw(struct snd_kcontrol *kcontrol,
2729 else 2769 else
2730 ucontrol->value.integer.value[0] = val; 2770 ucontrol->value.integer.value[0] = val;
2731 2771
2732 return 0; 2772 return ret;
2733} 2773}
2734EXPORT_SYMBOL_GPL(snd_soc_dapm_get_volsw); 2774EXPORT_SYMBOL_GPL(snd_soc_dapm_get_volsw);
2735 2775
@@ -2745,8 +2785,8 @@ EXPORT_SYMBOL_GPL(snd_soc_dapm_get_volsw);
2745int snd_soc_dapm_put_volsw(struct snd_kcontrol *kcontrol, 2785int snd_soc_dapm_put_volsw(struct snd_kcontrol *kcontrol,
2746 struct snd_ctl_elem_value *ucontrol) 2786 struct snd_ctl_elem_value *ucontrol)
2747{ 2787{
2748 struct snd_soc_codec *codec = snd_soc_dapm_kcontrol_codec(kcontrol); 2788 struct snd_soc_dapm_context *dapm = snd_soc_dapm_kcontrol_dapm(kcontrol);
2749 struct snd_soc_card *card = codec->card; 2789 struct snd_soc_card *card = dapm->card;
2750 struct soc_mixer_control *mc = 2790 struct soc_mixer_control *mc =
2751 (struct soc_mixer_control *)kcontrol->private_value; 2791 (struct soc_mixer_control *)kcontrol->private_value;
2752 int reg = mc->reg; 2792 int reg = mc->reg;
@@ -2755,12 +2795,12 @@ int snd_soc_dapm_put_volsw(struct snd_kcontrol *kcontrol,
2755 unsigned int mask = (1 << fls(max)) - 1; 2795 unsigned int mask = (1 << fls(max)) - 1;
2756 unsigned int invert = mc->invert; 2796 unsigned int invert = mc->invert;
2757 unsigned int val; 2797 unsigned int val;
2758 int connect, change; 2798 int connect, change, reg_change = 0;
2759 struct snd_soc_dapm_update update; 2799 struct snd_soc_dapm_update update;
2760 int ret = 0; 2800 int ret = 0;
2761 2801
2762 if (snd_soc_volsw_is_stereo(mc)) 2802 if (snd_soc_volsw_is_stereo(mc))
2763 dev_warn(codec->dapm.dev, 2803 dev_warn(dapm->dev,
2764 "ASoC: Control '%s' is stereo, which is not supported\n", 2804 "ASoC: Control '%s' is stereo, which is not supported\n",
2765 kcontrol->id.name); 2805 kcontrol->id.name);
2766 2806
@@ -2773,20 +2813,23 @@ int snd_soc_dapm_put_volsw(struct snd_kcontrol *kcontrol,
2773 mutex_lock_nested(&card->dapm_mutex, SND_SOC_DAPM_CLASS_RUNTIME); 2813 mutex_lock_nested(&card->dapm_mutex, SND_SOC_DAPM_CLASS_RUNTIME);
2774 2814
2775 change = dapm_kcontrol_set_value(kcontrol, val); 2815 change = dapm_kcontrol_set_value(kcontrol, val);
2776 if (change) {
2777 if (reg != SND_SOC_NOPM) {
2778 mask = mask << shift;
2779 val = val << shift;
2780
2781 if (snd_soc_test_bits(codec, reg, mask, val)) {
2782 update.kcontrol = kcontrol;
2783 update.reg = reg;
2784 update.mask = mask;
2785 update.val = val;
2786 card->update = &update;
2787 }
2788 2816
2817 if (reg != SND_SOC_NOPM) {
2818 mask = mask << shift;
2819 val = val << shift;
2820
2821 reg_change = soc_dapm_test_bits(dapm, reg, mask, val);
2822 }
2823
2824 if (change || reg_change) {
2825 if (reg_change) {
2826 update.kcontrol = kcontrol;
2827 update.reg = reg;
2828 update.mask = mask;
2829 update.val = val;
2830 card->update = &update;
2789 } 2831 }
2832 change |= reg_change;
2790 2833
2791 ret = soc_dapm_mixer_update_power(card, kcontrol, connect); 2834 ret = soc_dapm_mixer_update_power(card, kcontrol, connect);
2792 2835
@@ -2814,12 +2857,13 @@ EXPORT_SYMBOL_GPL(snd_soc_dapm_put_volsw);
2814int snd_soc_dapm_get_enum_double(struct snd_kcontrol *kcontrol, 2857int snd_soc_dapm_get_enum_double(struct snd_kcontrol *kcontrol,
2815 struct snd_ctl_elem_value *ucontrol) 2858 struct snd_ctl_elem_value *ucontrol)
2816{ 2859{
2817 struct snd_soc_codec *codec = snd_soc_dapm_kcontrol_codec(kcontrol); 2860 struct snd_soc_dapm_context *dapm = snd_soc_dapm_kcontrol_dapm(kcontrol);
2818 struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; 2861 struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
2819 unsigned int reg_val, val; 2862 unsigned int reg_val, val;
2863 int ret = 0;
2820 2864
2821 if (e->reg != SND_SOC_NOPM) 2865 if (e->reg != SND_SOC_NOPM)
2822 reg_val = snd_soc_read(codec, e->reg); 2866 ret = soc_dapm_read(dapm, e->reg, &reg_val);
2823 else 2867 else
2824 reg_val = dapm_kcontrol_get_value(kcontrol); 2868 reg_val = dapm_kcontrol_get_value(kcontrol);
2825 2869
@@ -2831,7 +2875,7 @@ int snd_soc_dapm_get_enum_double(struct snd_kcontrol *kcontrol,
2831 ucontrol->value.enumerated.item[1] = val; 2875 ucontrol->value.enumerated.item[1] = val;
2832 } 2876 }
2833 2877
2834 return 0; 2878 return ret;
2835} 2879}
2836EXPORT_SYMBOL_GPL(snd_soc_dapm_get_enum_double); 2880EXPORT_SYMBOL_GPL(snd_soc_dapm_get_enum_double);
2837 2881
@@ -2847,8 +2891,8 @@ EXPORT_SYMBOL_GPL(snd_soc_dapm_get_enum_double);
2847int snd_soc_dapm_put_enum_double(struct snd_kcontrol *kcontrol, 2891int snd_soc_dapm_put_enum_double(struct snd_kcontrol *kcontrol,
2848 struct snd_ctl_elem_value *ucontrol) 2892 struct snd_ctl_elem_value *ucontrol)
2849{ 2893{
2850 struct snd_soc_codec *codec = snd_soc_dapm_kcontrol_codec(kcontrol); 2894 struct snd_soc_dapm_context *dapm = snd_soc_dapm_kcontrol_dapm(kcontrol);
2851 struct snd_soc_card *card = codec->card; 2895 struct snd_soc_card *card = dapm->card;
2852 struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; 2896 struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
2853 unsigned int *item = ucontrol->value.enumerated.item; 2897 unsigned int *item = ucontrol->value.enumerated.item;
2854 unsigned int val, change; 2898 unsigned int val, change;
@@ -2871,7 +2915,7 @@ int snd_soc_dapm_put_enum_double(struct snd_kcontrol *kcontrol,
2871 mutex_lock_nested(&card->dapm_mutex, SND_SOC_DAPM_CLASS_RUNTIME); 2915 mutex_lock_nested(&card->dapm_mutex, SND_SOC_DAPM_CLASS_RUNTIME);
2872 2916
2873 if (e->reg != SND_SOC_NOPM) 2917 if (e->reg != SND_SOC_NOPM)
2874 change = snd_soc_test_bits(codec, e->reg, mask, val); 2918 change = soc_dapm_test_bits(dapm, e->reg, mask, val);
2875 else 2919 else
2876 change = dapm_kcontrol_set_value(kcontrol, val); 2920 change = dapm_kcontrol_set_value(kcontrol, val);
2877 2921
@@ -2968,6 +3012,7 @@ snd_soc_dapm_new_control(struct snd_soc_dapm_context *dapm,
2968 const struct snd_soc_dapm_widget *widget) 3012 const struct snd_soc_dapm_widget *widget)
2969{ 3013{
2970 struct snd_soc_dapm_widget *w; 3014 struct snd_soc_dapm_widget *w;
3015 const char *prefix;
2971 int ret; 3016 int ret;
2972 3017
2973 if ((w = dapm_cnew_widget(widget)) == NULL) 3018 if ((w = dapm_cnew_widget(widget)) == NULL)
@@ -3008,9 +3053,9 @@ snd_soc_dapm_new_control(struct snd_soc_dapm_context *dapm,
3008 break; 3053 break;
3009 } 3054 }
3010 3055
3011 if (dapm->codec && dapm->codec->name_prefix) 3056 prefix = soc_dapm_prefix(dapm);
3012 w->name = kasprintf(GFP_KERNEL, "%s %s", 3057 if (prefix)
3013 dapm->codec->name_prefix, widget->name); 3058 w->name = kasprintf(GFP_KERNEL, "%s %s", prefix, widget->name);
3014 else 3059 else
3015 w->name = kasprintf(GFP_KERNEL, "%s", widget->name); 3060 w->name = kasprintf(GFP_KERNEL, "%s", widget->name);
3016 3061
@@ -3063,7 +3108,6 @@ snd_soc_dapm_new_control(struct snd_soc_dapm_context *dapm,
3063 3108
3064 w->dapm = dapm; 3109 w->dapm = dapm;
3065 w->codec = dapm->codec; 3110 w->codec = dapm->codec;
3066 w->platform = dapm->platform;
3067 INIT_LIST_HEAD(&w->sources); 3111 INIT_LIST_HEAD(&w->sources);
3068 INIT_LIST_HEAD(&w->sinks); 3112 INIT_LIST_HEAD(&w->sinks);
3069 INIT_LIST_HEAD(&w->list); 3113 INIT_LIST_HEAD(&w->list);
@@ -3170,27 +3214,15 @@ static int snd_soc_dai_link_event(struct snd_soc_dapm_widget *w,
3170 3214
3171 switch (event) { 3215 switch (event) {
3172 case SND_SOC_DAPM_PRE_PMU: 3216 case SND_SOC_DAPM_PRE_PMU:
3173 if (source->driver->ops && source->driver->ops->hw_params) { 3217 substream.stream = SNDRV_PCM_STREAM_CAPTURE;
3174 substream.stream = SNDRV_PCM_STREAM_CAPTURE; 3218 ret = soc_dai_hw_params(&substream, params, source);
3175 ret = source->driver->ops->hw_params(&substream, 3219 if (ret < 0)
3176 params, source); 3220 goto out;
3177 if (ret != 0) {
3178 dev_err(source->dev,
3179 "ASoC: hw_params() failed: %d\n", ret);
3180 goto out;
3181 }
3182 }
3183 3221
3184 if (sink->driver->ops && sink->driver->ops->hw_params) { 3222 substream.stream = SNDRV_PCM_STREAM_PLAYBACK;
3185 substream.stream = SNDRV_PCM_STREAM_PLAYBACK; 3223 ret = soc_dai_hw_params(&substream, params, sink);
3186 ret = sink->driver->ops->hw_params(&substream, params, 3224 if (ret < 0)
3187 sink); 3225 goto out;
3188 if (ret != 0) {
3189 dev_err(sink->dev,
3190 "ASoC: hw_params() failed: %d\n", ret);
3191 goto out;
3192 }
3193 }
3194 break; 3226 break;
3195 3227
3196 case SND_SOC_DAPM_POST_PMU: 3228 case SND_SOC_DAPM_POST_PMU:
@@ -3362,25 +3394,15 @@ int snd_soc_dapm_link_dai_widgets(struct snd_soc_card *card)
3362 return 0; 3394 return 0;
3363} 3395}
3364 3396
3365void snd_soc_dapm_connect_dai_link_widgets(struct snd_soc_card *card) 3397static void dapm_connect_dai_link_widgets(struct snd_soc_card *card,
3398 struct snd_soc_pcm_runtime *rtd)
3366{ 3399{
3367 struct snd_soc_pcm_runtime *rtd = card->rtd; 3400 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
3368 struct snd_soc_dapm_widget *sink, *source; 3401 struct snd_soc_dapm_widget *sink, *source;
3369 struct snd_soc_dai *cpu_dai, *codec_dai;
3370 int i; 3402 int i;
3371 3403
3372 /* for each BE DAI link... */ 3404 for (i = 0; i < rtd->num_codecs; i++) {
3373 for (i = 0; i < card->num_rtd; i++) { 3405 struct snd_soc_dai *codec_dai = rtd->codec_dais[i];
3374 rtd = &card->rtd[i];
3375 cpu_dai = rtd->cpu_dai;
3376 codec_dai = rtd->codec_dai;
3377
3378 /*
3379 * dynamic FE links have no fixed DAI mapping.
3380 * CODEC<->CODEC links have no direct connection.
3381 */
3382 if (rtd->dai_link->dynamic || rtd->dai_link->params)
3383 continue;
3384 3406
3385 /* there is no point in connecting BE DAI links with dummies */ 3407 /* there is no point in connecting BE DAI links with dummies */
3386 if (snd_soc_dai_is_dummy(codec_dai) || 3408 if (snd_soc_dai_is_dummy(codec_dai) ||
@@ -3392,8 +3414,8 @@ void snd_soc_dapm_connect_dai_link_widgets(struct snd_soc_card *card)
3392 source = cpu_dai->playback_widget; 3414 source = cpu_dai->playback_widget;
3393 sink = codec_dai->playback_widget; 3415 sink = codec_dai->playback_widget;
3394 dev_dbg(rtd->dev, "connected DAI link %s:%s -> %s:%s\n", 3416 dev_dbg(rtd->dev, "connected DAI link %s:%s -> %s:%s\n",
3395 cpu_dai->codec->name, source->name, 3417 cpu_dai->component->name, source->name,
3396 codec_dai->platform->name, sink->name); 3418 codec_dai->component->name, sink->name);
3397 3419
3398 snd_soc_dapm_add_path(&card->dapm, source, sink, 3420 snd_soc_dapm_add_path(&card->dapm, source, sink,
3399 NULL, NULL); 3421 NULL, NULL);
@@ -3404,8 +3426,8 @@ void snd_soc_dapm_connect_dai_link_widgets(struct snd_soc_card *card)
3404 source = codec_dai->capture_widget; 3426 source = codec_dai->capture_widget;
3405 sink = cpu_dai->capture_widget; 3427 sink = cpu_dai->capture_widget;
3406 dev_dbg(rtd->dev, "connected DAI link %s:%s -> %s:%s\n", 3428 dev_dbg(rtd->dev, "connected DAI link %s:%s -> %s:%s\n",
3407 codec_dai->codec->name, source->name, 3429 codec_dai->component->name, source->name,
3408 cpu_dai->platform->name, sink->name); 3430 cpu_dai->component->name, sink->name);
3409 3431
3410 snd_soc_dapm_add_path(&card->dapm, source, sink, 3432 snd_soc_dapm_add_path(&card->dapm, source, sink,
3411 NULL, NULL); 3433 NULL, NULL);
@@ -3442,11 +3464,34 @@ static void soc_dapm_dai_stream_event(struct snd_soc_dai *dai, int stream,
3442 } 3464 }
3443} 3465}
3444 3466
3467void snd_soc_dapm_connect_dai_link_widgets(struct snd_soc_card *card)
3468{
3469 struct snd_soc_pcm_runtime *rtd = card->rtd;
3470 int i;
3471
3472 /* for each BE DAI link... */
3473 for (i = 0; i < card->num_rtd; i++) {
3474 rtd = &card->rtd[i];
3475
3476 /*
3477 * dynamic FE links have no fixed DAI mapping.
3478 * CODEC<->CODEC links have no direct connection.
3479 */
3480 if (rtd->dai_link->dynamic || rtd->dai_link->params)
3481 continue;
3482
3483 dapm_connect_dai_link_widgets(card, rtd);
3484 }
3485}
3486
3445static void soc_dapm_stream_event(struct snd_soc_pcm_runtime *rtd, int stream, 3487static void soc_dapm_stream_event(struct snd_soc_pcm_runtime *rtd, int stream,
3446 int event) 3488 int event)
3447{ 3489{
3490 int i;
3491
3448 soc_dapm_dai_stream_event(rtd->cpu_dai, stream, event); 3492 soc_dapm_dai_stream_event(rtd->cpu_dai, stream, event);
3449 soc_dapm_dai_stream_event(rtd->codec_dai, stream, event); 3493 for (i = 0; i < rtd->num_codecs; i++)
3494 soc_dapm_dai_stream_event(rtd->codec_dais[i], stream, event);
3450 3495
3451 dapm_power_widgets(rtd->card, event); 3496 dapm_power_widgets(rtd->card, event);
3452} 3497}
@@ -3755,36 +3800,31 @@ static bool snd_soc_dapm_widget_in_card_paths(struct snd_soc_card *card,
3755} 3800}
3756 3801
3757/** 3802/**
3758 * snd_soc_dapm_auto_nc_codec_pins - call snd_soc_dapm_nc_pin for unused pins 3803 * snd_soc_dapm_auto_nc_pins - call snd_soc_dapm_nc_pin for unused pins
3759 * @codec: The codec whose pins should be processed 3804 * @card: The card whose pins should be processed
3760 * 3805 *
3761 * Automatically call snd_soc_dapm_nc_pin() for any external pins in the codec 3806 * Automatically call snd_soc_dapm_nc_pin() for any external pins in the card
3762 * which are unused. Pins are used if they are connected externally to the 3807 * which are unused. Pins are used if they are connected externally to a
3763 * codec, whether that be to some other device, or a loop-back connection to 3808 * component, whether that be to some other device, or a loop-back connection to
3764 * the codec itself. 3809 * the component itself.
3765 */ 3810 */
3766void snd_soc_dapm_auto_nc_codec_pins(struct snd_soc_codec *codec) 3811void snd_soc_dapm_auto_nc_pins(struct snd_soc_card *card)
3767{ 3812{
3768 struct snd_soc_card *card = codec->card;
3769 struct snd_soc_dapm_context *dapm = &codec->dapm;
3770 struct snd_soc_dapm_widget *w; 3813 struct snd_soc_dapm_widget *w;
3771 3814
3772 dev_dbg(codec->dev, "ASoC: Auto NC: DAPMs: card:%p codec:%p\n", 3815 dev_dbg(card->dev, "ASoC: Auto NC: DAPMs: card:%p\n", &card->dapm);
3773 &card->dapm, &codec->dapm);
3774 3816
3775 list_for_each_entry(w, &card->widgets, list) { 3817 list_for_each_entry(w, &card->widgets, list) {
3776 if (w->dapm != dapm)
3777 continue;
3778 switch (w->id) { 3818 switch (w->id) {
3779 case snd_soc_dapm_input: 3819 case snd_soc_dapm_input:
3780 case snd_soc_dapm_output: 3820 case snd_soc_dapm_output:
3781 case snd_soc_dapm_micbias: 3821 case snd_soc_dapm_micbias:
3782 dev_dbg(codec->dev, "ASoC: Auto NC: Checking widget %s\n", 3822 dev_dbg(card->dev, "ASoC: Auto NC: Checking widget %s\n",
3783 w->name); 3823 w->name);
3784 if (!snd_soc_dapm_widget_in_card_paths(card, w)) { 3824 if (!snd_soc_dapm_widget_in_card_paths(card, w)) {
3785 dev_dbg(codec->dev, 3825 dev_dbg(card->dev,
3786 "... Not in map; disabling\n"); 3826 "... Not in map; disabling\n");
3787 snd_soc_dapm_nc_pin(dapm, w->name); 3827 snd_soc_dapm_nc_pin(w->dapm, w->name);
3788 } 3828 }
3789 break; 3829 break;
3790 default: 3830 default: