ASoC: fsl_ssi: Implement symmetric_channels and symmetric_samplebits
authorNicolin Chen <b42378@freescale.com>
Tue, 3 Dec 2013 10:38:07 +0000 (18:38 +0800)
committerMark Brown <broonie@linaro.org>
Tue, 3 Dec 2013 14:58:17 +0000 (14:58 +0000)
Since we introduced symmetric_channels and symmetric_samplebits, we implement
these two features to fsl_ssi so as to drop some no-more-needed code and make
the driver neat and clean.

Signed-off-by: Nicolin Chen <b42378@freescale.com>
Signed-off-by: Mark Brown <broonie@linaro.org>
sound/soc/fsl/fsl_ssi.c

index 90ff1071e29c51a59b7d4c1bc36d6b0c4121331d..f9f4569417ed81b8c1ef05d2d7b01a63630ab655 100644 (file)
@@ -119,8 +119,6 @@ static inline void write_ssi_mask(u32 __iomem *addr, u32 clear, u32 set)
  * @ssi: pointer to the SSI's registers
  * @ssi_phys: physical address of the SSI registers
  * @irq: IRQ of this SSI
- * @first_stream: pointer to the stream that was opened first
- * @second_stream: pointer to second stream
  * @playback: the number of playback streams opened
  * @capture: the number of capture streams opened
  * @cpu_dai: the CPU DAI for this device
@@ -132,8 +130,6 @@ struct fsl_ssi_private {
        struct ccsr_ssi __iomem *ssi;
        dma_addr_t ssi_phys;
        unsigned int irq;
-       struct snd_pcm_substream *first_stream;
-       struct snd_pcm_substream *second_stream;
        unsigned int fifo_depth;
        struct snd_soc_dai_driver cpu_dai_drv;
        struct device_attribute dev_attr;
@@ -438,54 +434,13 @@ static int fsl_ssi_startup(struct snd_pcm_substream *substream,
        struct snd_soc_pcm_runtime *rtd = substream->private_data;
        struct fsl_ssi_private *ssi_private =
                snd_soc_dai_get_drvdata(rtd->cpu_dai);
-       int synchronous = ssi_private->cpu_dai_drv.symmetric_rates;
 
-       /*
-        * If this is the first stream opened, then request the IRQ
-        * and initialize the SSI registers.
+       /* First, we only do fsl_ssi_setup() when SSI is going to be active.
+        * Second, fsl_ssi_setup was already called by ac97_init earlier if
+        * the driver is in ac97 mode.
         */
-       if (!ssi_private->first_stream) {
-               ssi_private->first_stream = substream;
-
-               /*
-                * fsl_ssi_setup was already called by ac97_init earlier if
-                * the driver is in ac97 mode.
-                */
-               if (!ssi_private->imx_ac97)
-                       fsl_ssi_setup(ssi_private);
-       } else {
-               if (synchronous) {
-                       struct snd_pcm_runtime *first_runtime =
-                               ssi_private->first_stream->runtime;
-                       /*
-                        * This is the second stream open, and we're in
-                        * synchronous mode, so we need to impose sample
-                        * sample size constraints. This is because STCCR is
-                        * used for playback and capture in synchronous mode,
-                        * so there's no way to specify different word
-                        * lengths.
-                        *
-                        * Note that this can cause a race condition if the
-                        * second stream is opened before the first stream is
-                        * fully initialized.  We provide some protection by
-                        * checking to make sure the first stream is
-                        * initialized, but it's not perfect.  ALSA sometimes
-                        * re-initializes the driver with a different sample
-                        * rate or size.  If the second stream is opened
-                        * before the first stream has received its final
-                        * parameters, then the second stream may be
-                        * constrained to the wrong sample rate or size.
-                        */
-                       if (first_runtime->sample_bits) {
-                               snd_pcm_hw_constraint_minmax(substream->runtime,
-                                               SNDRV_PCM_HW_PARAM_SAMPLE_BITS,
-                               first_runtime->sample_bits,
-                               first_runtime->sample_bits);
-                       }
-               }
-
-               ssi_private->second_stream = substream;
-       }
+       if (!dai->active && !ssi_private->imx_ac97)
+               fsl_ssi_setup(ssi_private);
 
        return 0;
 }
@@ -615,23 +570,6 @@ static int fsl_ssi_trigger(struct snd_pcm_substream *substream, int cmd,
        return 0;
 }
 
-/**
- * fsl_ssi_shutdown: shutdown the SSI
- *
- * Shutdown the SSI if there are no other substreams open.
- */
-static void fsl_ssi_shutdown(struct snd_pcm_substream *substream,
-                            struct snd_soc_dai *dai)
-{
-       struct snd_soc_pcm_runtime *rtd = substream->private_data;
-       struct fsl_ssi_private *ssi_private = snd_soc_dai_get_drvdata(rtd->cpu_dai);
-
-       if (ssi_private->first_stream == substream)
-               ssi_private->first_stream = ssi_private->second_stream;
-
-       ssi_private->second_stream = NULL;
-}
-
 static int fsl_ssi_dai_probe(struct snd_soc_dai *dai)
 {
        struct fsl_ssi_private *ssi_private = snd_soc_dai_get_drvdata(dai);
@@ -647,7 +585,6 @@ static int fsl_ssi_dai_probe(struct snd_soc_dai *dai)
 static const struct snd_soc_dai_ops fsl_ssi_dai_ops = {
        .startup        = fsl_ssi_startup,
        .hw_params      = fsl_ssi_hw_params,
-       .shutdown       = fsl_ssi_shutdown,
        .trigger        = fsl_ssi_trigger,
 };
 
@@ -722,7 +659,6 @@ static int fsl_ssi_ac97_trigger(struct snd_pcm_substream *substream, int cmd,
 
 static const struct snd_soc_dai_ops fsl_ssi_ac97_dai_ops = {
        .startup        = fsl_ssi_startup,
-       .shutdown       = fsl_ssi_shutdown,
        .trigger        = fsl_ssi_ac97_trigger,
 };
 
@@ -947,8 +883,11 @@ static int fsl_ssi_probe(struct platform_device *pdev)
        }
 
        /* Are the RX and the TX clocks locked? */
-       if (!of_find_property(np, "fsl,ssi-asynchronous", NULL))
+       if (!of_find_property(np, "fsl,ssi-asynchronous", NULL)) {
                ssi_private->cpu_dai_drv.symmetric_rates = 1;
+               ssi_private->cpu_dai_drv.symmetric_channels = 1;
+               ssi_private->cpu_dai_drv.symmetric_samplebits = 1;
+       }
 
        /* Determine the FIFO depth. */
        iprop = of_get_property(np, "fsl,fifo-depth", NULL);