Merge remote-tracking branches 'asoc/topic/jz4740', 'asoc/topic/kirkwood', 'asoc...
authorMark Brown <broonie@kernel.org>
Wed, 23 Sep 2015 18:01:22 +0000 (11:01 -0700)
committerMark Brown <broonie@kernel.org>
Wed, 23 Sep 2015 18:01:22 +0000 (11:01 -0700)
sound/soc/jz4740/jz4740-i2s.c
sound/soc/kirkwood/armada-370-db.c
sound/soc/mediatek/mt8173-max98090.c
sound/soc/mediatek/mt8173-rt5650-rt5676.c
sound/soc/mxs/mxs-sgtl5000.c
sound/soc/soc-pcm.c

index b05fb1c1a8483e18ea7e5226325563ea82d044c0..794a3499e567c3a907e70b8c1c57aafce6aab207 100644 (file)
@@ -485,6 +485,7 @@ static const struct of_device_id jz4740_of_matches[] = {
        { .compatible = "ingenic,jz4780-i2s", .data = (void *)JZ_I2S_JZ4780 },
        { /* sentinel */ }
 };
+MODULE_DEVICE_TABLE(of, jz4740_of_matches);
 #endif
 
 static int jz4740_i2s_dev_probe(struct platform_device *pdev)
index de7563bdc5c28e2c7954a00ca9929e508176d718..e0304d544f26ba45660e94fa98942d2416ddb94a 100644 (file)
@@ -130,6 +130,7 @@ static const struct of_device_id a370db_dt_ids[] = {
        { .compatible = "marvell,a370db-audio" },
        { },
 };
+MODULE_DEVICE_TABLE(of, a370db_dt_ids);
 
 static struct platform_driver a370db_driver = {
        .driver         = {
index 684e8a78bed0640310e0b54e292df725b409fe22..71a1a35047bafd085881efd5369f5275bf9a050f 100644 (file)
@@ -179,21 +179,13 @@ static int mt8173_max98090_dev_probe(struct platform_device *pdev)
        }
        card->dev = &pdev->dev;
 
-       ret = snd_soc_register_card(card);
+       ret = devm_snd_soc_register_card(&pdev->dev, card);
        if (ret)
                dev_err(&pdev->dev, "%s snd_soc_register_card fail %d\n",
                        __func__, ret);
        return ret;
 }
 
-static int mt8173_max98090_dev_remove(struct platform_device *pdev)
-{
-       struct snd_soc_card *card = platform_get_drvdata(pdev);
-
-       snd_soc_unregister_card(card);
-       return 0;
-}
-
 static const struct of_device_id mt8173_max98090_dt_match[] = {
        { .compatible = "mediatek,mt8173-max98090", },
        { }
@@ -209,7 +201,6 @@ static struct platform_driver mt8173_max98090_driver = {
 #endif
        },
        .probe = mt8173_max98090_dev_probe,
-       .remove = mt8173_max98090_dev_remove,
 };
 
 module_platform_driver(mt8173_max98090_driver);
index 86cf9752f18a343791eaeeff8ca8ab9c2c4a83e8..50ba538eccb3f771da9c08685d4e33aa0cbfa80b 100644 (file)
@@ -246,21 +246,13 @@ static int mt8173_rt5650_rt5676_dev_probe(struct platform_device *pdev)
        card->dev = &pdev->dev;
        platform_set_drvdata(pdev, card);
 
-       ret = snd_soc_register_card(card);
+       ret = devm_snd_soc_register_card(&pdev->dev, card);
        if (ret)
                dev_err(&pdev->dev, "%s snd_soc_register_card fail %d\n",
                        __func__, ret);
        return ret;
 }
 
-static int mt8173_rt5650_rt5676_dev_remove(struct platform_device *pdev)
-{
-       struct snd_soc_card *card = platform_get_drvdata(pdev);
-
-       snd_soc_unregister_card(card);
-       return 0;
-}
-
 static const struct of_device_id mt8173_rt5650_rt5676_dt_match[] = {
        { .compatible = "mediatek,mt8173-rt5650-rt5676", },
        { }
@@ -276,7 +268,6 @@ static struct platform_driver mt8173_rt5650_rt5676_driver = {
 #endif
        },
        .probe = mt8173_rt5650_rt5676_dev_probe,
-       .remove = mt8173_rt5650_rt5676_dev_remove,
 };
 
 module_platform_driver(mt8173_rt5650_rt5676_driver);
index 6e6fce6a14ba6dc1c2ab14d054df8f5b07b2caea..2b23ffbac6b126cdff2674f68133dea77c40f546 100644 (file)
@@ -142,7 +142,7 @@ static int mxs_sgtl5000_probe(struct platform_device *pdev)
        card->dev = &pdev->dev;
        platform_set_drvdata(pdev, card);
 
-       ret = snd_soc_register_card(card);
+       ret = devm_snd_soc_register_card(&pdev->dev, card);
        if (ret) {
                dev_err(&pdev->dev, "snd_soc_register_card failed (%d)\n",
                        ret);
@@ -154,12 +154,8 @@ static int mxs_sgtl5000_probe(struct platform_device *pdev)
 
 static int mxs_sgtl5000_remove(struct platform_device *pdev)
 {
-       struct snd_soc_card *card = platform_get_drvdata(pdev);
-
        mxs_saif_put_mclk(0);
 
-       snd_soc_unregister_card(card);
-
        return 0;
 }
 
index 70e4b9d8bdcdfd3fb83f37615a29fae64036d4c0..317395824cd794d093e74b98013a8f2537b89056 100644 (file)
 
 #define DPCM_MAX_BE_USERS      8
 
+/*
+ * snd_soc_dai_stream_valid() - check if a DAI supports the given stream
+ *
+ * Returns true if the DAI supports the indicated stream type.
+ */
+static bool snd_soc_dai_stream_valid(struct snd_soc_dai *dai, int stream)
+{
+       struct snd_soc_pcm_stream *codec_stream;
+
+       if (stream == SNDRV_PCM_STREAM_PLAYBACK)
+               codec_stream = &dai->driver->playback;
+       else
+               codec_stream = &dai->driver->capture;
+
+       /* If the codec specifies any rate at all, it supports the stream. */
+       return codec_stream->rates;
+}
+
 /**
  * snd_soc_runtime_activate() - Increment active count for PCM runtime components
  * @rtd: ASoC PCM runtime that is activated
@@ -371,6 +389,20 @@ static void soc_pcm_init_runtime_hw(struct snd_pcm_substream *substream)
 
        /* first calculate min/max only for CODECs in the DAI link */
        for (i = 0; i < rtd->num_codecs; i++) {
+
+               /*
+                * Skip CODECs which don't support the current stream type.
+                * Otherwise, since the rate, channel, and format values will
+                * zero in that case, we would have no usable settings left,
+                * causing the resulting setup to fail.
+                * At least one CODEC should match, otherwise we should have
+                * bailed out on a higher level, since there would be no
+                * CODEC to support the transfer direction in that case.
+                */
+               if (!snd_soc_dai_stream_valid(rtd->codec_dais[i],
+                                             substream->stream))
+                       continue;
+
                codec_dai_drv = rtd->codec_dais[i]->driver;
                if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
                        codec_stream = &codec_dai_drv->playback;
@@ -827,6 +859,23 @@ static int soc_pcm_hw_params(struct snd_pcm_substream *substream,
                struct snd_soc_dai *codec_dai = rtd->codec_dais[i];
                struct snd_pcm_hw_params codec_params;
 
+               /*
+                * Skip CODECs which don't support the current stream type,
+                * the idea being that if a CODEC is not used for the currently
+                * set up transfer direction, it should not need to be
+                * configured, especially since the configuration used might
+                * not even be supported by that CODEC. There may be cases
+                * however where a CODEC needs to be set up although it is
+                * actually not being used for the transfer, e.g. if a
+                * capture-only CODEC is acting as an LRCLK and/or BCLK master
+                * for the DAI link including a playback-only CODEC.
+                * If this becomes necessary, we will have to augment the
+                * machine driver setup with information on how to act, so
+                * we can do the right thing here.
+                */
+               if (!snd_soc_dai_stream_valid(codec_dai, substream->stream))
+                       continue;
+
                /* copy params for each codec */
                codec_params = *params;