diff options
| -rw-r--r-- | include/sound/soc-dai.h | 2 | ||||
| -rw-r--r-- | include/sound/soc-dapm.h | 1 | ||||
| -rw-r--r-- | sound/soc/soc-core.c | 1 | ||||
| -rw-r--r-- | sound/soc/soc-dapm.c | 75 | ||||
| -rw-r--r-- | sound/soc/soc-utils.c | 7 |
5 files changed, 75 insertions, 11 deletions
diff --git a/include/sound/soc-dai.h b/include/sound/soc-dai.h index 243d3b689699..71f27c403194 100644 --- a/include/sound/soc-dai.h +++ b/include/sound/soc-dai.h | |||
| @@ -123,6 +123,8 @@ int snd_soc_dai_set_tristate(struct snd_soc_dai *dai, int tristate); | |||
| 123 | int snd_soc_dai_digital_mute(struct snd_soc_dai *dai, int mute, | 123 | int snd_soc_dai_digital_mute(struct snd_soc_dai *dai, int mute, |
| 124 | int direction); | 124 | int direction); |
| 125 | 125 | ||
| 126 | int snd_soc_dai_is_dummy(struct snd_soc_dai *dai); | ||
| 127 | |||
| 126 | struct snd_soc_dai_ops { | 128 | struct snd_soc_dai_ops { |
| 127 | /* | 129 | /* |
| 128 | * DAI clocking configuration, all optional. | 130 | * DAI clocking configuration, all optional. |
diff --git a/include/sound/soc-dapm.h b/include/sound/soc-dapm.h index 56ebdfca6273..68d92e36facd 100644 --- a/include/sound/soc-dapm.h +++ b/include/sound/soc-dapm.h | |||
| @@ -412,6 +412,7 @@ int snd_soc_dapm_new_controls(struct snd_soc_dapm_context *dapm, | |||
| 412 | int snd_soc_dapm_new_dai_widgets(struct snd_soc_dapm_context *dapm, | 412 | int snd_soc_dapm_new_dai_widgets(struct snd_soc_dapm_context *dapm, |
| 413 | struct snd_soc_dai *dai); | 413 | struct snd_soc_dai *dai); |
| 414 | int snd_soc_dapm_link_dai_widgets(struct snd_soc_card *card); | 414 | int snd_soc_dapm_link_dai_widgets(struct snd_soc_card *card); |
| 415 | void snd_soc_dapm_connect_dai_link_widgets(struct snd_soc_card *card); | ||
| 415 | int snd_soc_dapm_new_pcm(struct snd_soc_card *card, | 416 | int snd_soc_dapm_new_pcm(struct snd_soc_card *card, |
| 416 | const struct snd_soc_pcm_stream *params, | 417 | const struct snd_soc_pcm_stream *params, |
| 417 | struct snd_soc_dapm_widget *source, | 418 | struct snd_soc_dapm_widget *source, |
diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c index 18583660efbc..fe1df50805a3 100644 --- a/sound/soc/soc-core.c +++ b/sound/soc/soc-core.c | |||
| @@ -1728,6 +1728,7 @@ static int snd_soc_instantiate_card(struct snd_soc_card *card) | |||
| 1728 | } | 1728 | } |
| 1729 | 1729 | ||
| 1730 | snd_soc_dapm_link_dai_widgets(card); | 1730 | snd_soc_dapm_link_dai_widgets(card); |
| 1731 | snd_soc_dapm_connect_dai_link_widgets(card); | ||
| 1731 | 1732 | ||
| 1732 | if (card->controls) | 1733 | if (card->controls) |
| 1733 | snd_soc_add_card_controls(card, card->controls, card->num_controls); | 1734 | snd_soc_add_card_controls(card, card->controls, card->num_controls); |
diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c index 67e63ab1f11e..2a44fe9122a2 100644 --- a/sound/soc/soc-dapm.c +++ b/sound/soc/soc-dapm.c | |||
| @@ -371,12 +371,16 @@ static void dapm_reset(struct snd_soc_card *card) | |||
| 371 | } | 371 | } |
| 372 | } | 372 | } |
| 373 | 373 | ||
| 374 | static int soc_widget_read(struct snd_soc_dapm_widget *w, int reg) | 374 | static int soc_widget_read(struct snd_soc_dapm_widget *w, int reg, |
| 375 | unsigned int *value) | ||
| 375 | { | 376 | { |
| 376 | if (w->codec) | 377 | if (w->codec) { |
| 377 | return snd_soc_read(w->codec, reg); | 378 | *value = snd_soc_read(w->codec, reg); |
| 378 | else if (w->platform) | 379 | return 0; |
| 379 | return snd_soc_platform_read(w->platform, reg); | 380 | } else if (w->platform) { |
| 381 | *value = snd_soc_platform_read(w->platform, reg); | ||
| 382 | return 0; | ||
| 383 | } | ||
| 380 | 384 | ||
| 381 | dev_err(w->dapm->dev, "ASoC: no valid widget read method\n"); | 385 | dev_err(w->dapm->dev, "ASoC: no valid widget read method\n"); |
| 382 | return -1; | 386 | return -1; |
| @@ -430,13 +434,12 @@ static int soc_widget_update_bits_locked(struct snd_soc_dapm_widget *w, | |||
| 430 | return ret; | 434 | return ret; |
| 431 | } else { | 435 | } else { |
| 432 | soc_widget_lock(w); | 436 | soc_widget_lock(w); |
| 433 | ret = soc_widget_read(w, reg); | 437 | ret = soc_widget_read(w, reg, &old); |
| 434 | if (ret < 0) { | 438 | if (ret < 0) { |
| 435 | soc_widget_unlock(w); | 439 | soc_widget_unlock(w); |
| 436 | return ret; | 440 | return ret; |
| 437 | } | 441 | } |
| 438 | 442 | ||
| 439 | old = ret; | ||
| 440 | new = (old & ~mask) | (value & mask); | 443 | new = (old & ~mask) | (value & mask); |
| 441 | change = old != new; | 444 | change = old != new; |
| 442 | if (change) { | 445 | if (change) { |
| @@ -513,7 +516,7 @@ static void dapm_set_path_status(struct snd_soc_dapm_widget *w, | |||
| 513 | unsigned int invert = mc->invert; | 516 | unsigned int invert = mc->invert; |
| 514 | 517 | ||
| 515 | if (reg != SND_SOC_NOPM) { | 518 | if (reg != SND_SOC_NOPM) { |
| 516 | val = soc_widget_read(w, reg); | 519 | soc_widget_read(w, reg, &val); |
| 517 | val = (val >> shift) & mask; | 520 | val = (val >> shift) & mask; |
| 518 | if (invert) | 521 | if (invert) |
| 519 | val = max - val; | 522 | val = max - val; |
| @@ -529,7 +532,7 @@ static void dapm_set_path_status(struct snd_soc_dapm_widget *w, | |||
| 529 | w->kcontrol_news[i].private_value; | 532 | w->kcontrol_news[i].private_value; |
| 530 | int val, item; | 533 | int val, item; |
| 531 | 534 | ||
| 532 | val = soc_widget_read(w, e->reg); | 535 | soc_widget_read(w, e->reg, &val); |
| 533 | item = (val >> e->shift_l) & e->mask; | 536 | item = (val >> e->shift_l) & e->mask; |
| 534 | 537 | ||
| 535 | if (item < e->max && !strcmp(p->name, e->texts[item])) | 538 | if (item < e->max && !strcmp(p->name, e->texts[item])) |
| @@ -558,7 +561,7 @@ static void dapm_set_path_status(struct snd_soc_dapm_widget *w, | |||
| 558 | w->kcontrol_news[i].private_value; | 561 | w->kcontrol_news[i].private_value; |
| 559 | int val, item; | 562 | int val, item; |
| 560 | 563 | ||
| 561 | val = soc_widget_read(w, e->reg); | 564 | soc_widget_read(w, e->reg, &val); |
| 562 | val = (val >> e->shift_l) & e->mask; | 565 | val = (val >> e->shift_l) & e->mask; |
| 563 | for (item = 0; item < e->max; item++) { | 566 | for (item = 0; item < e->max; item++) { |
| 564 | if (val == e->values[item]) | 567 | if (val == e->values[item]) |
| @@ -2782,7 +2785,8 @@ int snd_soc_dapm_new_widgets(struct snd_soc_card *card) | |||
| 2782 | 2785 | ||
| 2783 | /* Read the initial power state from the device */ | 2786 | /* Read the initial power state from the device */ |
| 2784 | if (w->reg >= 0) { | 2787 | if (w->reg >= 0) { |
| 2785 | val = soc_widget_read(w, w->reg) >> w->shift; | 2788 | soc_widget_read(w, w->reg, &val); |
| 2789 | val = val >> w->shift; | ||
| 2786 | val &= w->mask; | 2790 | val &= w->mask; |
| 2787 | if (val == w->on_val) | 2791 | if (val == w->on_val) |
| 2788 | w->power = 1; | 2792 | w->power = 1; |
| @@ -3634,6 +3638,55 @@ int snd_soc_dapm_link_dai_widgets(struct snd_soc_card *card) | |||
| 3634 | return 0; | 3638 | return 0; |
| 3635 | } | 3639 | } |
| 3636 | 3640 | ||
| 3641 | void snd_soc_dapm_connect_dai_link_widgets(struct snd_soc_card *card) | ||
| 3642 | { | ||
| 3643 | struct snd_soc_pcm_runtime *rtd = card->rtd; | ||
| 3644 | struct snd_soc_dai *cpu_dai, *codec_dai; | ||
| 3645 | struct snd_soc_dapm_route r; | ||
| 3646 | int i; | ||
| 3647 | |||
| 3648 | memset(&r, 0, sizeof(r)); | ||
| 3649 | |||
| 3650 | /* for each BE DAI link... */ | ||
| 3651 | for (i = 0; i < card->num_rtd; i++) { | ||
| 3652 | rtd = &card->rtd[i]; | ||
| 3653 | cpu_dai = rtd->cpu_dai; | ||
| 3654 | codec_dai = rtd->codec_dai; | ||
| 3655 | |||
| 3656 | /* dynamic FE links have no fixed DAI mapping */ | ||
| 3657 | if (rtd->dai_link->dynamic) | ||
| 3658 | continue; | ||
| 3659 | |||
| 3660 | /* there is no point in connecting BE DAI links with dummies */ | ||
| 3661 | if (snd_soc_dai_is_dummy(codec_dai) || | ||
| 3662 | snd_soc_dai_is_dummy(cpu_dai)) | ||
| 3663 | continue; | ||
| 3664 | |||
| 3665 | /* connect BE DAI playback if widgets are valid */ | ||
| 3666 | if (codec_dai->playback_widget && cpu_dai->playback_widget) { | ||
| 3667 | r.source = cpu_dai->playback_widget->name; | ||
| 3668 | r.sink = codec_dai->playback_widget->name; | ||
| 3669 | dev_dbg(rtd->dev, "connected DAI link %s:%s -> %s:%s\n", | ||
| 3670 | cpu_dai->codec->name, r.source, | ||
| 3671 | codec_dai->platform->name, r.sink); | ||
| 3672 | |||
| 3673 | snd_soc_dapm_add_route(&card->dapm, &r); | ||
| 3674 | } | ||
| 3675 | |||
| 3676 | /* connect BE DAI capture if widgets are valid */ | ||
| 3677 | if (codec_dai->capture_widget && cpu_dai->capture_widget) { | ||
| 3678 | r.source = codec_dai->capture_widget->name; | ||
| 3679 | r.sink = cpu_dai->capture_widget->name; | ||
| 3680 | dev_dbg(rtd->dev, "connected DAI link %s:%s -> %s:%s\n", | ||
| 3681 | codec_dai->codec->name, r.source, | ||
| 3682 | cpu_dai->platform->name, r.sink); | ||
| 3683 | |||
| 3684 | snd_soc_dapm_add_route(&card->dapm, &r); | ||
| 3685 | } | ||
| 3686 | |||
| 3687 | } | ||
| 3688 | } | ||
| 3689 | |||
| 3637 | static void soc_dapm_stream_event(struct snd_soc_pcm_runtime *rtd, int stream, | 3690 | static void soc_dapm_stream_event(struct snd_soc_pcm_runtime *rtd, int stream, |
| 3638 | int event) | 3691 | int event) |
| 3639 | { | 3692 | { |
diff --git a/sound/soc/soc-utils.c b/sound/soc/soc-utils.c index 6ebdfd9a1a1d..7f22ca35a413 100644 --- a/sound/soc/soc-utils.c +++ b/sound/soc/soc-utils.c | |||
| @@ -119,6 +119,13 @@ static struct snd_soc_dai_driver dummy_dai = { | |||
| 119 | }, | 119 | }, |
| 120 | }; | 120 | }; |
| 121 | 121 | ||
| 122 | int snd_soc_dai_is_dummy(struct snd_soc_dai *dai) | ||
| 123 | { | ||
| 124 | if (dai->driver == &dummy_dai) | ||
| 125 | return 1; | ||
| 126 | return 0; | ||
| 127 | } | ||
| 128 | |||
| 122 | static int snd_soc_dummy_probe(struct platform_device *pdev) | 129 | static int snd_soc_dummy_probe(struct platform_device *pdev) |
| 123 | { | 130 | { |
| 124 | int ret; | 131 | int ret; |
