diff options
Diffstat (limited to 'sound')
-rw-r--r-- | sound/soc/codecs/arizona.c | 32 |
1 files changed, 29 insertions, 3 deletions
diff --git a/sound/soc/codecs/arizona.c b/sound/soc/codecs/arizona.c index d0bcca959111..901b53e1d7bc 100644 --- a/sound/soc/codecs/arizona.c +++ b/sound/soc/codecs/arizona.c | |||
@@ -588,12 +588,25 @@ static int arizona_hw_params(struct snd_pcm_substream *substream, | |||
588 | return 0; | 588 | return 0; |
589 | } | 589 | } |
590 | 590 | ||
591 | static const char *arizona_dai_clk_str(int clk_id) | ||
592 | { | ||
593 | switch (clk_id) { | ||
594 | case ARIZONA_CLK_SYSCLK: | ||
595 | return "SYSCLK"; | ||
596 | case ARIZONA_CLK_ASYNCCLK: | ||
597 | return "ASYNCCLK"; | ||
598 | default: | ||
599 | return "Unknown clock"; | ||
600 | } | ||
601 | } | ||
602 | |||
591 | static int arizona_dai_set_sysclk(struct snd_soc_dai *dai, | 603 | static int arizona_dai_set_sysclk(struct snd_soc_dai *dai, |
592 | int clk_id, unsigned int freq, int dir) | 604 | int clk_id, unsigned int freq, int dir) |
593 | { | 605 | { |
594 | struct snd_soc_codec *codec = dai->codec; | 606 | struct snd_soc_codec *codec = dai->codec; |
595 | struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec); | 607 | struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec); |
596 | struct arizona_dai_priv *dai_priv = &priv->dai[dai->id - 1]; | 608 | struct arizona_dai_priv *dai_priv = &priv->dai[dai->id - 1]; |
609 | struct snd_soc_dapm_route routes[2]; | ||
597 | 610 | ||
598 | switch (clk_id) { | 611 | switch (clk_id) { |
599 | case ARIZONA_CLK_SYSCLK: | 612 | case ARIZONA_CLK_SYSCLK: |
@@ -603,15 +616,28 @@ static int arizona_dai_set_sysclk(struct snd_soc_dai *dai, | |||
603 | return -EINVAL; | 616 | return -EINVAL; |
604 | } | 617 | } |
605 | 618 | ||
606 | if (clk_id != dai_priv->clk && dai->active) { | 619 | if (clk_id == dai_priv->clk) |
620 | return 0; | ||
621 | |||
622 | if (dai->active) { | ||
607 | dev_err(codec->dev, "Can't change clock on active DAI %d\n", | 623 | dev_err(codec->dev, "Can't change clock on active DAI %d\n", |
608 | dai->id); | 624 | dai->id); |
609 | return -EBUSY; | 625 | return -EBUSY; |
610 | } | 626 | } |
611 | 627 | ||
612 | dai_priv->clk = clk_id; | 628 | memset(&routes, 0, sizeof(routes)); |
629 | routes[0].sink = dai->driver->capture.stream_name; | ||
630 | routes[1].sink = dai->driver->playback.stream_name; | ||
613 | 631 | ||
614 | return 0; | 632 | routes[0].source = arizona_dai_clk_str(dai_priv->clk); |
633 | routes[1].source = arizona_dai_clk_str(dai_priv->clk); | ||
634 | snd_soc_dapm_del_routes(&codec->dapm, routes, ARRAY_SIZE(routes)); | ||
635 | |||
636 | routes[0].source = arizona_dai_clk_str(clk_id); | ||
637 | routes[1].source = arizona_dai_clk_str(clk_id); | ||
638 | snd_soc_dapm_add_routes(&codec->dapm, routes, ARRAY_SIZE(routes)); | ||
639 | |||
640 | return snd_soc_dapm_sync(&codec->dapm); | ||
615 | } | 641 | } |
616 | 642 | ||
617 | const struct snd_soc_dai_ops arizona_dai_ops = { | 643 | const struct snd_soc_dai_ops arizona_dai_ops = { |