diff options
author | Mark Brown <broonie@linaro.org> | 2014-01-16 07:42:53 -0500 |
---|---|---|
committer | Mark Brown <broonie@linaro.org> | 2014-01-16 07:42:53 -0500 |
commit | 99896f714a0a940d84476bc6208319f70af30789 (patch) | |
tree | 89002aa02e1308caf0c6a9d99fb5a722aee750e0 | |
parent | a9b68d3b90988dd13c668d6b1d45cdca1557f070 (diff) | |
parent | f7d3c17096f6cbca8f0113d5a092ffcc72c7bf41 (diff) |
Merge remote-tracking branch 'asoc/topic/dapm' into for-tiwai
-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; |