From b20e53a826a7adc3bfd2772bd49a83b6f21b4cce Mon Sep 17 00:00:00 2001 From: Fabio Estevam Date: Fri, 23 May 2014 02:38:56 -0300 Subject: [PATCH 01/10] ASoC: fsl_ssi: Add suspend/resume support Doing a suspend/resume sequence while playing an audio track in the backgroung causes broken audio right after resume: root@freescale /$ aplay clarinet.wav & root@freescale /home$ Playing WAVE 'clarinet.wav' : Signed 16 bit Little Endian, Rate 44100 Hz, Mono root@freescale /home$ echo mem > /sys/power/state PM: Syncing filesystems ... done. Freezing user space processes ... (elapsed 0.002 seconds) done. Freezing remaining freezable tasks ... (elapsed 0.002 seconds) done. Suspending console(s) (use no_console_suspend to debug) PM: suspend of devices complete after 37.082 msecs PM: suspend devices took 0.040 seconds PM: late suspend of devices complete after 4.234 msecs PM: noirq suspend of devices complete after 4.618 msecs Disabling non-boot CPUs ... PM: noirq resume of devices complete after 4.013 msecs PM: early resume of devices complete after 4.000 msecs PM: resume of devices complete after 68.907 msecs PM: resume devices took 0.070 seconds Restarting tasks ... Suspended. Trying resume. Failed. Restarting stream. Done. Suspended. Trying resume. Failed. Restarting stream. Done. Suspended. Trying resume. Failed. Restarting stream. Done. Suspended. Trying resume. Failed. Restarting stream. Done. Suspended. Trying resume. Failed. Restarting stream. Done. Suspended. Trying resume. Failed. Restarting stream. Done. Suspended. Trying resume. Failed. Restarting stream. Done. .... Add SNDRV_PCM_TRIGGER_RESUME/SUSPEND cases so that we can gracefully handle system suspend/resume. Signed-off-by: Fabio Estevam Acked-by: Shawn Guo Signed-off-by: Mark Brown --- sound/soc/fsl/fsl_ssi.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/sound/soc/fsl/fsl_ssi.c b/sound/soc/fsl/fsl_ssi.c index e5d8819cf19f..ef504257e105 100644 --- a/sound/soc/fsl/fsl_ssi.c +++ b/sound/soc/fsl/fsl_ssi.c @@ -873,6 +873,7 @@ static int fsl_ssi_trigger(struct snd_pcm_substream *substream, int cmd, switch (cmd) { case SNDRV_PCM_TRIGGER_START: + case SNDRV_PCM_TRIGGER_RESUME: case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) fsl_ssi_tx_config(ssi_private, true); @@ -881,6 +882,7 @@ static int fsl_ssi_trigger(struct snd_pcm_substream *substream, int cmd, break; case SNDRV_PCM_TRIGGER_STOP: + case SNDRV_PCM_TRIGGER_SUSPEND: case SNDRV_PCM_TRIGGER_PAUSE_PUSH: if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) fsl_ssi_tx_config(ssi_private, false); From fcdbadef378bc9cc64cb8cbfd96c23fc15812923 Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Tue, 27 May 2014 10:24:18 +0200 Subject: [PATCH 02/10] ASoC: fsl-ssi: introduce SoC specific data Introduce a SoC data struct which contains the differences between the different SoCs this driver supports. This makes it easy to support more differences without having to introduce a new switch/case each time. Signed-off-by: Sascha Hauer Signed-off-by: Markus Pargmann Tested-By: Michael Grzeschik Signed-off-by: Mark Brown --- sound/soc/fsl/fsl_ssi.c | 127 ++++++++++++++++++---------------------- 1 file changed, 58 insertions(+), 69 deletions(-) diff --git a/sound/soc/fsl/fsl_ssi.c b/sound/soc/fsl/fsl_ssi.c index ef504257e105..fa650112925a 100644 --- a/sound/soc/fsl/fsl_ssi.c +++ b/sound/soc/fsl/fsl_ssi.c @@ -132,6 +132,12 @@ struct fsl_ssi_rxtx_reg_val { struct fsl_ssi_reg_val tx; }; +struct fsl_ssi_soc_data { + bool imx; + bool offline_config; + u32 sisr_write_mask; +}; + /** * fsl_ssi_private: per-SSI private data * @@ -153,7 +159,6 @@ struct fsl_ssi_private { struct platform_device *pdev; unsigned int dai_fmt; - enum fsl_ssi_type hw_type; bool use_dma; bool baudclk_locked; bool use_dual_fifo; @@ -168,36 +173,10 @@ struct fsl_ssi_private { struct fsl_ssi_rxtx_reg_val rxtx_reg_val; struct fsl_ssi_dbg dbg_stats; + + const struct fsl_ssi_soc_data *soc; }; -static const struct of_device_id fsl_ssi_ids[] = { - { .compatible = "fsl,mpc8610-ssi", .data = (void *) FSL_SSI_MCP8610}, - { .compatible = "fsl,imx51-ssi", .data = (void *) FSL_SSI_MX51}, - { .compatible = "fsl,imx35-ssi", .data = (void *) FSL_SSI_MX35}, - { .compatible = "fsl,imx21-ssi", .data = (void *) FSL_SSI_MX21}, - {} -}; -MODULE_DEVICE_TABLE(of, fsl_ssi_ids); - -static bool fsl_ssi_is_ac97(struct fsl_ssi_private *ssi_private) -{ - return !!(ssi_private->dai_fmt & SND_SOC_DAIFMT_AC97); -} - -static bool fsl_ssi_on_imx(struct fsl_ssi_private *ssi_private) -{ - switch (ssi_private->hw_type) { - case FSL_SSI_MX21: - case FSL_SSI_MX35: - case FSL_SSI_MX51: - return true; - case FSL_SSI_MCP8610: - return false; - } - - return false; -} - /* * imx51 and later SoCs have a slightly different IP that allows the * SSI configuration while the SSI unit is running. @@ -213,18 +192,48 @@ static bool fsl_ssi_on_imx(struct fsl_ssi_private *ssi_private) * while the SSI unit is running (SSIEN). So we support the necessary * online configuration of fsl-ssi starting at imx51. */ -static bool fsl_ssi_offline_config(struct fsl_ssi_private *ssi_private) -{ - switch (ssi_private->hw_type) { - case FSL_SSI_MCP8610: - case FSL_SSI_MX21: - case FSL_SSI_MX35: - return true; - case FSL_SSI_MX51: - return false; - } - return true; +static struct fsl_ssi_soc_data fsl_ssi_mpc8610 = { + .imx = false, + .offline_config = true, + .sisr_write_mask = CCSR_SSI_SISR_RFRC | CCSR_SSI_SISR_TFRC | + CCSR_SSI_SISR_ROE0 | CCSR_SSI_SISR_ROE1 | + CCSR_SSI_SISR_TUE0 | CCSR_SSI_SISR_TUE1, +}; + +static struct fsl_ssi_soc_data fsl_ssi_imx21 = { + .imx = true, + .offline_config = true, + .sisr_write_mask = 0, +}; + +static struct fsl_ssi_soc_data fsl_ssi_imx35 = { + .imx = true, + .offline_config = true, + .sisr_write_mask = CCSR_SSI_SISR_RFRC | CCSR_SSI_SISR_TFRC | + CCSR_SSI_SISR_ROE0 | CCSR_SSI_SISR_ROE1 | + CCSR_SSI_SISR_TUE0 | CCSR_SSI_SISR_TUE1, +}; + +static struct fsl_ssi_soc_data fsl_ssi_imx51 = { + .imx = true, + .offline_config = false, + .sisr_write_mask = CCSR_SSI_SISR_ROE0 | CCSR_SSI_SISR_ROE1 | + CCSR_SSI_SISR_TUE0 | CCSR_SSI_SISR_TUE1, +}; + +static const struct of_device_id fsl_ssi_ids[] = { + { .compatible = "fsl,mpc8610-ssi", .data = &fsl_ssi_mpc8610 }, + { .compatible = "fsl,imx51-ssi", .data = &fsl_ssi_imx51 }, + { .compatible = "fsl,imx35-ssi", .data = &fsl_ssi_imx35 }, + { .compatible = "fsl,imx21-ssi", .data = &fsl_ssi_imx21 }, + {} +}; +MODULE_DEVICE_TABLE(of, fsl_ssi_ids); + +static bool fsl_ssi_is_ac97(struct fsl_ssi_private *ssi_private) +{ + return !!(ssi_private->dai_fmt & SND_SOC_DAIFMT_AC97); } /** @@ -245,25 +254,6 @@ static irqreturn_t fsl_ssi_isr(int irq, void *dev_id) struct ccsr_ssi __iomem *ssi = ssi_private->ssi; __be32 sisr; __be32 sisr2; - __be32 sisr_write_mask = 0; - - switch (ssi_private->hw_type) { - case FSL_SSI_MX21: - sisr_write_mask = 0; - break; - - case FSL_SSI_MCP8610: - case FSL_SSI_MX35: - sisr_write_mask = CCSR_SSI_SISR_RFRC | CCSR_SSI_SISR_TFRC | - CCSR_SSI_SISR_ROE0 | CCSR_SSI_SISR_ROE1 | - CCSR_SSI_SISR_TUE0 | CCSR_SSI_SISR_TUE1; - break; - - case FSL_SSI_MX51: - sisr_write_mask = CCSR_SSI_SISR_ROE0 | CCSR_SSI_SISR_ROE1 | - CCSR_SSI_SISR_TUE0 | CCSR_SSI_SISR_TUE1; - break; - } /* We got an interrupt, so read the status register to see what we were interrupted for. We mask it with the Interrupt Enable register @@ -271,7 +261,7 @@ static irqreturn_t fsl_ssi_isr(int irq, void *dev_id) */ sisr = read_ssi(&ssi->sisr); - sisr2 = sisr & sisr_write_mask; + sisr2 = sisr & ssi_private->soc->sisr_write_mask; /* Clear the bits that we set */ if (sisr2) write_ssi(sisr2, &ssi->sisr); @@ -359,7 +349,7 @@ static void fsl_ssi_config(struct fsl_ssi_private *ssi_private, bool enable, * reconfiguration, so we have to enable all necessary flags at once * even if we do not use them later (capture and playback configuration) */ - if (fsl_ssi_offline_config(ssi_private)) { + if (ssi_private->soc->offline_config) { if ((enable && !nr_active_streams) || (!enable && !keep_active)) fsl_ssi_rxtx_config(ssi_private, enable); @@ -915,7 +905,7 @@ static int fsl_ssi_dai_probe(struct snd_soc_dai *dai) { struct fsl_ssi_private *ssi_private = snd_soc_dai_get_drvdata(dai); - if (fsl_ssi_on_imx(ssi_private) && ssi_private->use_dma) { + if (ssi_private->soc->imx && ssi_private->use_dma) { dai->playback_dma_data = &ssi_private->dma_params_tx; dai->capture_dma_data = &ssi_private->dma_params_rx; } @@ -1141,7 +1131,6 @@ static int fsl_ssi_probe(struct platform_device *pdev) int ret = 0; struct device_node *np = pdev->dev.of_node; const struct of_device_id *of_id; - enum fsl_ssi_type hw_type; const char *p, *sprop; const uint32_t *iprop; struct resource res; @@ -1156,9 +1145,8 @@ static int fsl_ssi_probe(struct platform_device *pdev) return -ENODEV; of_id = of_match_device(fsl_ssi_ids, &pdev->dev); - if (!of_id) + if (!of_id || !of_id->data) return -EINVAL; - hw_type = (enum fsl_ssi_type) of_id->data; sprop = of_get_property(np, "fsl,mode", NULL); if (!sprop) { @@ -1175,9 +1163,10 @@ static int fsl_ssi_probe(struct platform_device *pdev) return -ENOMEM; } + ssi_private->soc = of_id->data; + ssi_private->use_dma = !of_property_read_bool(np, "fsl,fiq-stream-filter"); - ssi_private->hw_type = hw_type; if (ac97) { memcpy(&ssi_private->cpu_dai_drv, &fsl_ssi_ac97_dai, @@ -1232,7 +1221,7 @@ static int fsl_ssi_probe(struct platform_device *pdev) dev_set_drvdata(&pdev->dev, ssi_private); - if (fsl_ssi_on_imx(ssi_private)) { + if (ssi_private->soc->imx) { ret = fsl_ssi_imx_probe(pdev, ssi_private, ssi_private->ssi); if (ret) goto error_irqmap; @@ -1299,7 +1288,7 @@ error_irq: snd_soc_unregister_component(&pdev->dev); error_asoc_register: - if (fsl_ssi_on_imx(ssi_private)) + if (ssi_private->soc->imx) fsl_ssi_imx_clean(pdev, ssi_private); error_irqmap: @@ -1319,7 +1308,7 @@ static int fsl_ssi_remove(struct platform_device *pdev) platform_device_unregister(ssi_private->pdev); snd_soc_unregister_component(&pdev->dev); - if (fsl_ssi_on_imx(ssi_private)) + if (ssi_private->soc->imx) fsl_ssi_imx_clean(pdev, ssi_private); if (ssi_private->use_dma) From 85e59af24056ca7ffaf617cf6201c519e31dc668 Mon Sep 17 00:00:00 2001 From: Markus Pargmann Date: Tue, 27 May 2014 10:24:19 +0200 Subject: [PATCH 03/10] ASoC: fsl-ssi: make fsl,mode property optional The simple soundcard binding has its own way for specifying the dai format. To be able to use this binding we have to make the fsl,mode property optional. As the property is used in existing devicetrees keep the option around for compatibility reasons. Signed-off-by: Markus Pargmann Tested-By: Michael Grzeschik Signed-off-by: Mark Brown --- sound/soc/fsl/fsl_ssi.c | 41 ++++++++++++++++++++++++++--------------- 1 file changed, 26 insertions(+), 15 deletions(-) diff --git a/sound/soc/fsl/fsl_ssi.c b/sound/soc/fsl/fsl_ssi.c index fa650112925a..18eacf5e399d 100644 --- a/sound/soc/fsl/fsl_ssi.c +++ b/sound/soc/fsl/fsl_ssi.c @@ -660,12 +660,9 @@ static int fsl_ssi_hw_params(struct snd_pcm_substream *substream, return 0; } -/** - * fsl_ssi_set_dai_fmt - configure Digital Audio Interface Format. - */ -static int fsl_ssi_set_dai_fmt(struct snd_soc_dai *cpu_dai, unsigned int fmt) +static int _fsl_ssi_set_dai_fmt(struct fsl_ssi_private *ssi_private, + unsigned int fmt) { - struct fsl_ssi_private *ssi_private = snd_soc_dai_get_drvdata(cpu_dai); struct ccsr_ssi __iomem *ssi = ssi_private->ssi; u32 strcr = 0, stcr, srcr, scr, mask; u8 wm; @@ -804,6 +801,17 @@ static int fsl_ssi_set_dai_fmt(struct snd_soc_dai *cpu_dai, unsigned int fmt) fsl_ssi_setup_ac97(ssi_private); return 0; + +} + +/** + * fsl_ssi_set_dai_fmt - configure Digital Audio Interface Format. + */ +static int fsl_ssi_set_dai_fmt(struct snd_soc_dai *cpu_dai, unsigned int fmt) +{ + struct fsl_ssi_private *ssi_private = snd_soc_dai_get_drvdata(cpu_dai); + + return _fsl_ssi_set_dai_fmt(ssi_private, fmt); } /** @@ -1135,7 +1143,6 @@ static int fsl_ssi_probe(struct platform_device *pdev) const uint32_t *iprop; struct resource res; char name[64]; - bool ac97 = false; /* SSIs that are not connected on the board should have a * status = "disabled" @@ -1148,14 +1155,6 @@ static int fsl_ssi_probe(struct platform_device *pdev) if (!of_id || !of_id->data) return -EINVAL; - sprop = of_get_property(np, "fsl,mode", NULL); - if (!sprop) { - dev_err(&pdev->dev, "fsl,mode property is necessary\n"); - return -EINVAL; - } - if (!strcmp(sprop, "ac97-slave")) - ac97 = true; - ssi_private = devm_kzalloc(&pdev->dev, sizeof(*ssi_private), GFP_KERNEL); if (!ssi_private) { @@ -1165,10 +1164,19 @@ static int fsl_ssi_probe(struct platform_device *pdev) ssi_private->soc = of_id->data; + sprop = of_get_property(np, "fsl,mode", NULL); + if (sprop) { + if (!strcmp(sprop, "ac97-slave")) + ssi_private->dai_fmt = SND_SOC_DAIFMT_AC97; + else if (!strcmp(sprop, "i2s-slave")) + ssi_private->dai_fmt = SND_SOC_DAIFMT_I2S | + SND_SOC_DAIFMT_CBM_CFM; + } + ssi_private->use_dma = !of_property_read_bool(np, "fsl,fiq-stream-filter"); - if (ac97) { + if (fsl_ssi_is_ac97(ssi_private)) { memcpy(&ssi_private->cpu_dai_drv, &fsl_ssi_ac97_dai, sizeof(fsl_ssi_ac97_dai)); @@ -1279,6 +1287,9 @@ static int fsl_ssi_probe(struct platform_device *pdev) } done: + if (ssi_private->dai_fmt) + _fsl_ssi_set_dai_fmt(ssi_private, ssi_private->dai_fmt); + return 0; error_sound_card: From 8dd51e23a1ef3b5f22eeff4827260b75bafba620 Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Tue, 27 May 2014 10:24:20 +0200 Subject: [PATCH 04/10] ASoC: fsl-ssi: set bitclock in master mode from hw_params The fsl_ssi driver uses the .set_sysclk callback to configure the bitclock for master mode. This is unnecessary since the bitclock is known in hw_params. This patch configures the bitclock from .hw_params. .set_dai_sysclk now sets a bitclock frequency which is preferred over the default calculated bitclock frequency. Signed-off-by: Sascha Hauer Signed-off-by: Markus Pargmann Tested-By: Michael Grzeschik Signed-off-by: Mark Brown --- sound/soc/fsl/fsl_ssi.c | 40 ++++++++++++++++++++++++++++++++++++---- 1 file changed, 36 insertions(+), 4 deletions(-) diff --git a/sound/soc/fsl/fsl_ssi.c b/sound/soc/fsl/fsl_ssi.c index 18eacf5e399d..930095b1b72a 100644 --- a/sound/soc/fsl/fsl_ssi.c +++ b/sound/soc/fsl/fsl_ssi.c @@ -166,6 +166,7 @@ struct fsl_ssi_private { spinlock_t baudclk_lock; struct clk *baudclk; struct clk *clk; + unsigned int bitclk_freq; struct snd_dmaengine_dai_dma_data dma_params_tx; struct snd_dmaengine_dai_dma_data dma_params_rx; struct imx_pcm_fiq_params fiq_params; @@ -236,6 +237,12 @@ static bool fsl_ssi_is_ac97(struct fsl_ssi_private *ssi_private) return !!(ssi_private->dai_fmt & SND_SOC_DAIFMT_AC97); } +static bool fsl_ssi_is_i2s_master(struct fsl_ssi_private *ssi_private) +{ + return (ssi_private->dai_fmt & SND_SOC_DAIFMT_MASTER_MASK) == + SND_SOC_DAIFMT_CBS_CFS; +} + /** * fsl_ssi_isr: SSI interrupt handler * @@ -509,7 +516,7 @@ static int fsl_ssi_startup(struct snd_pcm_substream *substream, } /** - * fsl_ssi_set_dai_sysclk - configure Digital Audio Interface bit clock + * fsl_ssi_set_bclk - configure Digital Audio Interface bit clock * * Note: This function can be only called when using SSI as DAI master * @@ -517,8 +524,9 @@ static int fsl_ssi_startup(struct snd_pcm_substream *substream, * freq: Output BCLK frequency = samplerate * 32 (fixed) * channels * dir: SND_SOC_CLOCK_OUT -> TxBCLK, SND_SOC_CLOCK_IN -> RxBCLK. */ -static int fsl_ssi_set_dai_sysclk(struct snd_soc_dai *cpu_dai, - int clk_id, unsigned int freq, int dir) +static int fsl_ssi_set_bclk(struct snd_pcm_substream *substream, + struct snd_soc_dai *cpu_dai, + struct snd_pcm_hw_params *hw_params) { struct fsl_ssi_private *ssi_private = snd_soc_dai_get_drvdata(cpu_dai); struct ccsr_ssi __iomem *ssi = ssi_private->ssi; @@ -526,6 +534,13 @@ static int fsl_ssi_set_dai_sysclk(struct snd_soc_dai *cpu_dai, u32 pm = 999, div2, psr, stccr, mask, afreq, factor, i; unsigned long flags, clkrate, baudrate, tmprate; u64 sub, savesub = 100000; + unsigned int freq; + + /* Prefer the explicitly set bitclock frequency */ + if (ssi_private->bitclk_freq) + freq = ssi_private->bitclk_freq; + else + freq = params_channels(hw_params) * 32 * params_rate(hw_params); /* Don't apply it to any non-baudclk circumstance */ if (IS_ERR(ssi_private->baudclk)) @@ -583,7 +598,7 @@ static int fsl_ssi_set_dai_sysclk(struct snd_soc_dai *cpu_dai, mask = CCSR_SSI_SxCCR_PM_MASK | CCSR_SSI_SxCCR_DIV2 | CCSR_SSI_SxCCR_PSR; - if (dir == SND_SOC_CLOCK_OUT || synchronous) + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK || synchronous) write_ssi_mask(&ssi->stccr, mask, stccr); else write_ssi_mask(&ssi->srccr, mask, stccr); @@ -604,6 +619,16 @@ static int fsl_ssi_set_dai_sysclk(struct snd_soc_dai *cpu_dai, return 0; } +static int fsl_ssi_set_dai_sysclk(struct snd_soc_dai *cpu_dai, + int clk_id, unsigned int freq, int dir) +{ + struct fsl_ssi_private *ssi_private = snd_soc_dai_get_drvdata(cpu_dai); + + ssi_private->bitclk_freq = freq; + + return 0; +} + /** * fsl_ssi_hw_params - program the sample size * @@ -627,6 +652,7 @@ static int fsl_ssi_hw_params(struct snd_pcm_substream *substream, snd_pcm_format_width(params_format(hw_params)); u32 wl = CCSR_SSI_SxCCR_WL(sample_size); int enabled = read_ssi(&ssi->scr) & CCSR_SSI_SCR_SSIEN; + int ret; /* * If we're in synchronous mode, and the SSI is already enabled, @@ -635,6 +661,12 @@ static int fsl_ssi_hw_params(struct snd_pcm_substream *substream, if (enabled && ssi_private->cpu_dai_drv.symmetric_rates) return 0; + if (fsl_ssi_is_i2s_master(ssi_private)) { + ret = fsl_ssi_set_bclk(substream, cpu_dai, hw_params); + if (ret) + return ret; + } + /* * FIXME: The documentation says that SxCCR[WL] should not be * modified while the SSI is enabled. The only time this can From d8ced4793f3f114fa82fb423b71c2899caf8b7b0 Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Tue, 27 May 2014 10:24:21 +0200 Subject: [PATCH 05/10] ASoC: fsl-ssi: remove unnecessary spinlock The baudclock_locked variable is only used in functions which are serialized anyway from the core. No need to have a lock around the variable, so remove it. Signed-off-by: Sascha Hauer Signed-off-by: Markus Pargmann Tested-By: Michael Grzeschik Signed-off-by: Mark Brown --- sound/soc/fsl/fsl_ssi.c | 21 ++++----------------- 1 file changed, 4 insertions(+), 17 deletions(-) diff --git a/sound/soc/fsl/fsl_ssi.c b/sound/soc/fsl/fsl_ssi.c index 930095b1b72a..b3033d9108b2 100644 --- a/sound/soc/fsl/fsl_ssi.c +++ b/sound/soc/fsl/fsl_ssi.c @@ -163,7 +163,6 @@ struct fsl_ssi_private { bool baudclk_locked; bool use_dual_fifo; u8 i2s_mode; - spinlock_t baudclk_lock; struct clk *baudclk; struct clk *clk; unsigned int bitclk_freq; @@ -495,13 +494,9 @@ 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); - unsigned long flags; - if (!dai->active && !fsl_ssi_is_ac97(ssi_private)) { - spin_lock_irqsave(&ssi_private->baudclk_lock, flags); + if (!dai->active && !fsl_ssi_is_ac97(ssi_private)) ssi_private->baudclk_locked = false; - spin_unlock_irqrestore(&ssi_private->baudclk_lock, flags); - } /* When using dual fifo mode, it is safer to ensure an even period * size. If appearing to an odd number while DMA always starts its @@ -532,7 +527,7 @@ static int fsl_ssi_set_bclk(struct snd_pcm_substream *substream, struct ccsr_ssi __iomem *ssi = ssi_private->ssi; int synchronous = ssi_private->cpu_dai_drv.symmetric_rates, ret; u32 pm = 999, div2, psr, stccr, mask, afreq, factor, i; - unsigned long flags, clkrate, baudrate, tmprate; + unsigned long clkrate, baudrate, tmprate; u64 sub, savesub = 100000; unsigned int freq; @@ -603,18 +598,14 @@ static int fsl_ssi_set_bclk(struct snd_pcm_substream *substream, else write_ssi_mask(&ssi->srccr, mask, stccr); - spin_lock_irqsave(&ssi_private->baudclk_lock, flags); if (!ssi_private->baudclk_locked) { ret = clk_set_rate(ssi_private->baudclk, baudrate); if (ret) { - spin_unlock_irqrestore(&ssi_private->baudclk_lock, - flags); dev_err(cpu_dai->dev, "failed to set baudclk rate\n"); return -EINVAL; } ssi_private->baudclk_locked = true; } - spin_unlock_irqrestore(&ssi_private->baudclk_lock, flags); return 0; } @@ -899,7 +890,6 @@ static int fsl_ssi_trigger(struct snd_pcm_substream *substream, int cmd, struct snd_soc_pcm_runtime *rtd = substream->private_data; struct fsl_ssi_private *ssi_private = snd_soc_dai_get_drvdata(rtd->cpu_dai); struct ccsr_ssi __iomem *ssi = ssi_private->ssi; - unsigned long flags; switch (cmd) { case SNDRV_PCM_TRIGGER_START: @@ -920,11 +910,9 @@ static int fsl_ssi_trigger(struct snd_pcm_substream *substream, int cmd, fsl_ssi_rx_config(ssi_private, false); if (!fsl_ssi_is_ac97(ssi_private) && (read_ssi(&ssi->scr) & - (CCSR_SSI_SCR_TE | CCSR_SSI_SCR_RE)) == 0) { - spin_lock_irqsave(&ssi_private->baudclk_lock, flags); + (CCSR_SSI_SCR_TE | CCSR_SSI_SCR_RE)) == 0) ssi_private->baudclk_locked = false; - spin_unlock_irqrestore(&ssi_private->baudclk_lock, flags); - } + break; default: @@ -1257,7 +1245,6 @@ static int fsl_ssi_probe(struct platform_device *pdev) ssi_private->fifo_depth = 8; ssi_private->baudclk_locked = false; - spin_lock_init(&ssi_private->baudclk_lock); dev_set_drvdata(&pdev->dev, ssi_private); From b5dd91b3dcf937ce42583711fe4d679cacdbd2d0 Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Tue, 27 May 2014 10:24:22 +0200 Subject: [PATCH 06/10] ASoC: fsl-ssi: Set framerate divider correctly for i2s master mode In i2s master mode the fsl_ssi driver depends on someone calling .set_tdm_slot correctly. In this mode though only a DC value of 2 is allowed, so set it in this case and no longer depend on .set_tdm_slot. Signed-off-by: Sascha Hauer Signed-off-by: Markus Pargmann Tested-By: Michael Grzeschik Signed-off-by: Mark Brown --- sound/soc/fsl/fsl_ssi.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/sound/soc/fsl/fsl_ssi.c b/sound/soc/fsl/fsl_ssi.c index b3033d9108b2..dbcde106adca 100644 --- a/sound/soc/fsl/fsl_ssi.c +++ b/sound/soc/fsl/fsl_ssi.c @@ -709,6 +709,10 @@ static int _fsl_ssi_set_dai_fmt(struct fsl_ssi_private *ssi_private, switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { case SND_SOC_DAIFMT_CBS_CFS: ssi_private->i2s_mode |= CCSR_SSI_SCR_I2S_MODE_MASTER; + write_ssi_mask(&ssi->stccr, CCSR_SSI_SxCCR_DC_MASK, + CCSR_SSI_SxCCR_DC(2)); + write_ssi_mask(&ssi->srccr, CCSR_SSI_SxCCR_DC_MASK, + CCSR_SSI_SxCCR_DC(2)); break; case SND_SOC_DAIFMT_CBM_CFM: ssi_private->i2s_mode |= CCSR_SSI_SCR_I2S_MODE_SLAVE; From d429d8e3324cae120784a1e194ef6ea62aeb327e Mon Sep 17 00:00:00 2001 From: Markus Pargmann Date: Tue, 27 May 2014 10:24:23 +0200 Subject: [PATCH 07/10] ASoC: fsl-ssi: Fix baudclock handling The baudclock may be used and set by different streams. Allow only the first stream to set the bitclock rate. Other streams have to try to get to the correct rate without modifying the bitclock rate using the SSI internal clock modifiers. The variable baudclk_streams is introduced to keep track of the active streams that are using the baudclock. This way we know if the baudclock may be set and whether we may enable/disable the clock. baudclock enable/disable is moved to hw_params()/hw_free(). This way we can keep track of the baudclock in those two functions and avoid a running clock while it is not used. As hw_params()/hw_free() may be called multiple times for the same stream, we have to use baudclk_streams variable to know whether we may enable/disable the clock. Signed-off-by: Markus Pargmann Tested-By: Michael Grzeschik Signed-off-by: Mark Brown --- sound/soc/fsl/fsl_ssi.c | 62 +++++++++++++++++++++++++++-------------- 1 file changed, 41 insertions(+), 21 deletions(-) diff --git a/sound/soc/fsl/fsl_ssi.c b/sound/soc/fsl/fsl_ssi.c index dbcde106adca..ac786601b9d6 100644 --- a/sound/soc/fsl/fsl_ssi.c +++ b/sound/soc/fsl/fsl_ssi.c @@ -160,11 +160,11 @@ struct fsl_ssi_private { unsigned int dai_fmt; bool use_dma; - bool baudclk_locked; bool use_dual_fifo; u8 i2s_mode; struct clk *baudclk; struct clk *clk; + unsigned int baudclk_streams; unsigned int bitclk_freq; struct snd_dmaengine_dai_dma_data dma_params_tx; struct snd_dmaengine_dai_dma_data dma_params_rx; @@ -495,9 +495,6 @@ static int fsl_ssi_startup(struct snd_pcm_substream *substream, struct fsl_ssi_private *ssi_private = snd_soc_dai_get_drvdata(rtd->cpu_dai); - if (!dai->active && !fsl_ssi_is_ac97(ssi_private)) - ssi_private->baudclk_locked = false; - /* When using dual fifo mode, it is safer to ensure an even period * size. If appearing to an odd number while DMA always starts its * task from fifo0, fifo1 would be neglected at the end of each @@ -530,6 +527,7 @@ static int fsl_ssi_set_bclk(struct snd_pcm_substream *substream, unsigned long clkrate, baudrate, tmprate; u64 sub, savesub = 100000; unsigned int freq; + bool baudclk_is_used; /* Prefer the explicitly set bitclock frequency */ if (ssi_private->bitclk_freq) @@ -541,6 +539,8 @@ static int fsl_ssi_set_bclk(struct snd_pcm_substream *substream, if (IS_ERR(ssi_private->baudclk)) return -EINVAL; + baudclk_is_used = ssi_private->baudclk_streams & ~(BIT(substream->stream)); + /* It should be already enough to divide clock by setting pm alone */ psr = 0; div2 = 0; @@ -553,7 +553,11 @@ static int fsl_ssi_set_bclk(struct snd_pcm_substream *substream, continue; tmprate = freq * factor * (i + 2); - clkrate = clk_round_rate(ssi_private->baudclk, tmprate); + + if (baudclk_is_used) + clkrate = clk_get_rate(ssi_private->baudclk); + else + clkrate = clk_round_rate(ssi_private->baudclk, tmprate); do_div(clkrate, factor); afreq = (u32)clkrate / (i + 1); @@ -598,13 +602,12 @@ static int fsl_ssi_set_bclk(struct snd_pcm_substream *substream, else write_ssi_mask(&ssi->srccr, mask, stccr); - if (!ssi_private->baudclk_locked) { + if (!baudclk_is_used) { ret = clk_set_rate(ssi_private->baudclk, baudrate); if (ret) { dev_err(cpu_dai->dev, "failed to set baudclk rate\n"); return -EINVAL; } - ssi_private->baudclk_locked = true; } return 0; @@ -656,6 +659,15 @@ static int fsl_ssi_hw_params(struct snd_pcm_substream *substream, ret = fsl_ssi_set_bclk(substream, cpu_dai, hw_params); if (ret) return ret; + + /* Do not enable the clock if it is already enabled */ + if (!(ssi_private->baudclk_streams & BIT(substream->stream))) { + ret = clk_prepare_enable(ssi_private->baudclk); + if (ret) + return ret; + + ssi_private->baudclk_streams |= BIT(substream->stream); + } } /* @@ -683,6 +695,22 @@ static int fsl_ssi_hw_params(struct snd_pcm_substream *substream, return 0; } +static int fsl_ssi_hw_free(struct snd_pcm_substream *substream, + struct snd_soc_dai *cpu_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 (fsl_ssi_is_i2s_master(ssi_private) && + ssi_private->baudclk_streams & BIT(substream->stream)) { + clk_disable_unprepare(ssi_private->baudclk); + ssi_private->baudclk_streams &= ~BIT(substream->stream); + } + + return 0; +} + static int _fsl_ssi_set_dai_fmt(struct fsl_ssi_private *ssi_private, unsigned int fmt) { @@ -692,6 +720,11 @@ static int _fsl_ssi_set_dai_fmt(struct fsl_ssi_private *ssi_private, ssi_private->dai_fmt = fmt; + if (fsl_ssi_is_i2s_master(ssi_private) && IS_ERR(ssi_private->baudclk)) { + dev_err(&ssi_private->pdev->dev, "baudclk is missing which is necessary for master mode\n"); + return -EINVAL; + } + fsl_ssi_setup_reg_vals(ssi_private); scr = read_ssi(&ssi->scr) & ~(CCSR_SSI_SCR_SYN | CCSR_SSI_SCR_I2S_MODE_MASK); @@ -912,11 +945,6 @@ static int fsl_ssi_trigger(struct snd_pcm_substream *substream, int cmd, fsl_ssi_tx_config(ssi_private, false); else fsl_ssi_rx_config(ssi_private, false); - - if (!fsl_ssi_is_ac97(ssi_private) && (read_ssi(&ssi->scr) & - (CCSR_SSI_SCR_TE | CCSR_SSI_SCR_RE)) == 0) - ssi_private->baudclk_locked = false; - break; default: @@ -948,6 +976,7 @@ 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, + .hw_free = fsl_ssi_hw_free, .set_fmt = fsl_ssi_set_dai_fmt, .set_sysclk = fsl_ssi_set_dai_sysclk, .set_tdm_slot = fsl_ssi_set_dai_tdm_slot, @@ -1087,8 +1116,6 @@ static int fsl_ssi_imx_probe(struct platform_device *pdev, if (IS_ERR(ssi_private->baudclk)) dev_dbg(&pdev->dev, "could not get baud clock: %ld\n", PTR_ERR(ssi_private->baudclk)); - else - clk_prepare_enable(ssi_private->baudclk); /* * We have burstsize be "fifo_depth - 2" to match the SSI @@ -1139,9 +1166,6 @@ static int fsl_ssi_imx_probe(struct platform_device *pdev, return 0; error_pcm: - if (!IS_ERR(ssi_private->baudclk)) - clk_disable_unprepare(ssi_private->baudclk); - clk_disable_unprepare(ssi_private->clk); return ret; @@ -1152,8 +1176,6 @@ static void fsl_ssi_imx_clean(struct platform_device *pdev, { if (!ssi_private->use_dma) imx_pcm_fiq_exit(pdev); - if (!IS_ERR(ssi_private->baudclk)) - clk_disable_unprepare(ssi_private->baudclk); clk_disable_unprepare(ssi_private->clk); } @@ -1248,8 +1270,6 @@ static int fsl_ssi_probe(struct platform_device *pdev) /* Older 8610 DTs didn't have the fifo-depth property */ ssi_private->fifo_depth = 8; - ssi_private->baudclk_locked = false; - dev_set_drvdata(&pdev->dev, ssi_private); if (ssi_private->soc->imx) { From 737a6b418a83d8de87e0170010dce9fc2399b4e8 Mon Sep 17 00:00:00 2001 From: Markus Pargmann Date: Tue, 27 May 2014 10:24:24 +0200 Subject: [PATCH 08/10] ASoC: fsl-ssi: reorder and document fsl_ssi_private Reorder all variables in struct fsl_ssi_private to have groups that make sense together. The patch also updates the struct documentation. Signed-off-by: Markus Pargmann Tested-By: Michael Grzeschik Signed-off-by: Mark Brown --- sound/soc/fsl/fsl_ssi.c | 58 ++++++++++++++++++++++++++++++----------- 1 file changed, 43 insertions(+), 15 deletions(-) diff --git a/sound/soc/fsl/fsl_ssi.c b/sound/soc/fsl/fsl_ssi.c index ac786601b9d6..9fe3a1068f67 100644 --- a/sound/soc/fsl/fsl_ssi.c +++ b/sound/soc/fsl/fsl_ssi.c @@ -141,36 +141,64 @@ struct fsl_ssi_soc_data { /** * fsl_ssi_private: per-SSI private data * - * @ssi: pointer to the SSI's registers - * @ssi_phys: physical address of the SSI registers + * @ssi: Pointer to the memory area * @irq: IRQ of this SSI - * @playback: the number of playback streams opened - * @capture: the number of capture streams opened - * @cpu_dai: the CPU DAI for this device - * @dev_attr: the sysfs device attribute structure - * @stats: SSI statistics + * @cpu_dai_drv: CPU DAI driver for this device + * + * @dai_fmt: DAI configuration this device is currently used with + * @i2s_mode: i2s and network mode configuration of the device. Is used to + * switch between normal and i2s/network mode + * mode depending on the number of channels + * @use_dma: DMA is used or FIQ with stream filter + * @use_dual_fifo: DMA with support for both FIFOs used + * @fifo_deph: Depth of the SSI FIFOs + * @rxtx_reg_val: Specific register settings for receive/transmit configuration + * + * @clk: SSI clock + * @baudclk: SSI baud clock for master mode + * @baudclk_streams: Active streams that are using baudclk + * @bitclk_freq: bitclock frequency set by .set_dai_sysclk + * + * @dma_params_tx: DMA transmit parameters + * @dma_params_rx: DMA receive parameters + * @ssi_phys: physical address of the SSI registers + * + * @fiq_params: FIQ stream filtering parameters + * + * @pdev: Pointer to pdev used for deprecated fsl-ssi sound card + * + * @dbg_stats: Debugging statistics + * + * @soc: SoC specifc data */ struct fsl_ssi_private { struct ccsr_ssi __iomem *ssi; - dma_addr_t ssi_phys; unsigned int irq; - unsigned int fifo_depth; struct snd_soc_dai_driver cpu_dai_drv; - struct platform_device *pdev; - unsigned int dai_fmt; + unsigned int dai_fmt; + u8 i2s_mode; bool use_dma; bool use_dual_fifo; - u8 i2s_mode; - struct clk *baudclk; + unsigned int fifo_depth; + struct fsl_ssi_rxtx_reg_val rxtx_reg_val; + struct clk *clk; + struct clk *baudclk; unsigned int baudclk_streams; unsigned int bitclk_freq; + + /* DMA params */ struct snd_dmaengine_dai_dma_data dma_params_tx; struct snd_dmaengine_dai_dma_data dma_params_rx; + dma_addr_t ssi_phys; + + /* params for non-dma FIQ stream filtered mode */ struct imx_pcm_fiq_params fiq_params; - /* Register values for rx/tx configuration */ - struct fsl_ssi_rxtx_reg_val rxtx_reg_val; + + /* Used when using fsl-ssi as sound-card. This is only used by ppc and + * should be replaced with simple-sound-card. */ + struct platform_device *pdev; struct fsl_ssi_dbg dbg_stats; From 432481220101166a0b33dc6f951b38a8af3d281c Mon Sep 17 00:00:00 2001 From: Markus Pargmann Date: Tue, 27 May 2014 10:24:25 +0200 Subject: [PATCH 09/10] ASoC: fsl-ssi: Use regmap This patch replaces the ssi specific functions write_ssi, read_ssi and write_ssi_mask by standard regmap function calls. Signed-off-by: Markus Pargmann Tested-By: Michael Grzeschik Signed-off-by: Mark Brown --- sound/soc/fsl/Kconfig | 1 + sound/soc/fsl/fsl_ssi.c | 241 ++++++++++++++++++++++------------------ sound/soc/fsl/fsl_ssi.h | 50 ++++----- 3 files changed, 158 insertions(+), 134 deletions(-) diff --git a/sound/soc/fsl/Kconfig b/sound/soc/fsl/Kconfig index 338a91642471..2d6281f1e1f4 100644 --- a/sound/soc/fsl/Kconfig +++ b/sound/soc/fsl/Kconfig @@ -4,6 +4,7 @@ config SND_SOC_FSL_SAI select SND_SOC_GENERIC_DMAENGINE_PCM config SND_SOC_FSL_SSI + select REGMAP_MMIO tristate config SND_SOC_FSL_SPDIF diff --git a/sound/soc/fsl/fsl_ssi.c b/sound/soc/fsl/fsl_ssi.c index 9fe3a1068f67..8d58b50bfbee 100644 --- a/sound/soc/fsl/fsl_ssi.c +++ b/sound/soc/fsl/fsl_ssi.c @@ -53,25 +53,6 @@ #include "fsl_ssi.h" #include "imx-pcm.h" -#ifdef PPC -#define read_ssi(addr) in_be32(addr) -#define write_ssi(val, addr) out_be32(addr, val) -#define write_ssi_mask(addr, clear, set) clrsetbits_be32(addr, clear, set) -#else -#define read_ssi(addr) readl(addr) -#define write_ssi(val, addr) writel(val, addr) -/* - * FIXME: Proper locking should be added at write_ssi_mask caller level - * to ensure this register read/modify/write sequence is race free. - */ -static inline void write_ssi_mask(u32 __iomem *addr, u32 clear, u32 set) -{ - u32 val = readl(addr); - val = (val & ~clear) | set; - writel(val, addr); -} -#endif - /** * FSLSSI_I2S_RATES: sample rates supported by the I2S * @@ -131,6 +112,13 @@ struct fsl_ssi_rxtx_reg_val { struct fsl_ssi_reg_val rx; struct fsl_ssi_reg_val tx; }; +static const struct regmap_config fsl_ssi_regconfig = { + .max_register = CCSR_SSI_SACCDIS, + .reg_bits = 32, + .val_bits = 32, + .reg_stride = 4, + .val_format_endian = REGMAP_ENDIAN_NATIVE, +}; struct fsl_ssi_soc_data { bool imx; @@ -141,7 +129,7 @@ struct fsl_ssi_soc_data { /** * fsl_ssi_private: per-SSI private data * - * @ssi: Pointer to the memory area + * @reg: Pointer to the regmap registers * @irq: IRQ of this SSI * @cpu_dai_drv: CPU DAI driver for this device * @@ -172,7 +160,7 @@ struct fsl_ssi_soc_data { * @soc: SoC specifc data */ struct fsl_ssi_private { - struct ccsr_ssi __iomem *ssi; + struct regmap *regs; unsigned int irq; struct snd_soc_dai_driver cpu_dai_drv; @@ -285,7 +273,7 @@ static bool fsl_ssi_is_i2s_master(struct fsl_ssi_private *ssi_private) static irqreturn_t fsl_ssi_isr(int irq, void *dev_id) { struct fsl_ssi_private *ssi_private = dev_id; - struct ccsr_ssi __iomem *ssi = ssi_private->ssi; + struct regmap *regs = ssi_private->regs; __be32 sisr; __be32 sisr2; @@ -293,12 +281,12 @@ static irqreturn_t fsl_ssi_isr(int irq, void *dev_id) were interrupted for. We mask it with the Interrupt Enable register so that we only check for events that we're interested in. */ - sisr = read_ssi(&ssi->sisr); + regmap_read(regs, CCSR_SSI_SISR, &sisr); sisr2 = sisr & ssi_private->soc->sisr_write_mask; /* Clear the bits that we set */ if (sisr2) - write_ssi(sisr2, &ssi->sisr); + regmap_write(regs, CCSR_SSI_SISR, sisr2); fsl_ssi_dbg_isr(&ssi_private->dbg_stats, sisr); @@ -311,17 +299,26 @@ static irqreturn_t fsl_ssi_isr(int irq, void *dev_id) static void fsl_ssi_rxtx_config(struct fsl_ssi_private *ssi_private, bool enable) { - struct ccsr_ssi __iomem *ssi = ssi_private->ssi; + struct regmap *regs = ssi_private->regs; struct fsl_ssi_rxtx_reg_val *vals = &ssi_private->rxtx_reg_val; if (enable) { - write_ssi_mask(&ssi->sier, 0, vals->rx.sier | vals->tx.sier); - write_ssi_mask(&ssi->srcr, 0, vals->rx.srcr | vals->tx.srcr); - write_ssi_mask(&ssi->stcr, 0, vals->rx.stcr | vals->tx.stcr); + regmap_update_bits(regs, CCSR_SSI_SIER, + vals->rx.sier | vals->tx.sier, + vals->rx.sier | vals->tx.sier); + regmap_update_bits(regs, CCSR_SSI_SRCR, + vals->rx.srcr | vals->tx.srcr, + vals->rx.srcr | vals->tx.srcr); + regmap_update_bits(regs, CCSR_SSI_STCR, + vals->rx.stcr | vals->tx.stcr, + vals->rx.stcr | vals->tx.stcr); } else { - write_ssi_mask(&ssi->srcr, vals->rx.srcr | vals->tx.srcr, 0); - write_ssi_mask(&ssi->stcr, vals->rx.stcr | vals->tx.stcr, 0); - write_ssi_mask(&ssi->sier, vals->rx.sier | vals->tx.sier, 0); + regmap_update_bits(regs, CCSR_SSI_SRCR, + vals->rx.srcr | vals->tx.srcr, 0); + regmap_update_bits(regs, CCSR_SSI_STCR, + vals->rx.stcr | vals->tx.stcr, 0); + regmap_update_bits(regs, CCSR_SSI_SIER, + vals->rx.sier | vals->tx.sier, 0); } } @@ -352,13 +349,17 @@ static void fsl_ssi_rxtx_config(struct fsl_ssi_private *ssi_private, static void fsl_ssi_config(struct fsl_ssi_private *ssi_private, bool enable, struct fsl_ssi_reg_val *vals) { - struct ccsr_ssi __iomem *ssi = ssi_private->ssi; + struct regmap *regs = ssi_private->regs; struct fsl_ssi_reg_val *avals; - u32 scr_val = read_ssi(&ssi->scr); - int nr_active_streams = !!(scr_val & CCSR_SSI_SCR_TE) + - !!(scr_val & CCSR_SSI_SCR_RE); + int nr_active_streams; + u32 scr_val; int keep_active; + regmap_read(regs, CCSR_SSI_SCR, &scr_val); + + nr_active_streams = !!(scr_val & CCSR_SSI_SCR_TE) + + !!(scr_val & CCSR_SSI_SCR_RE); + if (nr_active_streams - 1 > 0) keep_active = 1; else @@ -375,7 +376,7 @@ static void fsl_ssi_config(struct fsl_ssi_private *ssi_private, bool enable, if (!enable) { u32 scr = fsl_ssi_disable_val(vals->scr, avals->scr, keep_active); - write_ssi_mask(&ssi->scr, scr, 0); + regmap_update_bits(regs, CCSR_SSI_SCR, scr, 0); } /* @@ -396,9 +397,9 @@ static void fsl_ssi_config(struct fsl_ssi_private *ssi_private, bool enable, * (online configuration) */ if (enable) { - write_ssi_mask(&ssi->sier, 0, vals->sier); - write_ssi_mask(&ssi->srcr, 0, vals->srcr); - write_ssi_mask(&ssi->stcr, 0, vals->stcr); + regmap_update_bits(regs, CCSR_SSI_SIER, vals->sier, vals->sier); + regmap_update_bits(regs, CCSR_SSI_SRCR, vals->srcr, vals->srcr); + regmap_update_bits(regs, CCSR_SSI_STCR, vals->stcr, vals->stcr); } else { u32 sier; u32 srcr; @@ -421,15 +422,15 @@ static void fsl_ssi_config(struct fsl_ssi_private *ssi_private, bool enable, stcr = fsl_ssi_disable_val(vals->stcr, avals->stcr, keep_active); - write_ssi_mask(&ssi->srcr, srcr, 0); - write_ssi_mask(&ssi->stcr, stcr, 0); - write_ssi_mask(&ssi->sier, sier, 0); + regmap_update_bits(regs, CCSR_SSI_SRCR, srcr, 0); + regmap_update_bits(regs, CCSR_SSI_STCR, stcr, 0); + regmap_update_bits(regs, CCSR_SSI_SIER, sier, 0); } config_done: /* Enabling of subunits is done after configuration */ if (enable) - write_ssi_mask(&ssi->scr, 0, vals->scr); + regmap_update_bits(regs, CCSR_SSI_SCR, vals->scr, vals->scr); } @@ -480,32 +481,33 @@ static void fsl_ssi_setup_reg_vals(struct fsl_ssi_private *ssi_private) static void fsl_ssi_setup_ac97(struct fsl_ssi_private *ssi_private) { - struct ccsr_ssi __iomem *ssi = ssi_private->ssi; + struct regmap *regs = ssi_private->regs; /* * Setup the clock control register */ - write_ssi(CCSR_SSI_SxCCR_WL(17) | CCSR_SSI_SxCCR_DC(13), - &ssi->stccr); - write_ssi(CCSR_SSI_SxCCR_WL(17) | CCSR_SSI_SxCCR_DC(13), - &ssi->srccr); + regmap_write(regs, CCSR_SSI_STCCR, + CCSR_SSI_SxCCR_WL(17) | CCSR_SSI_SxCCR_DC(13)); + regmap_write(regs, CCSR_SSI_SRCCR, + CCSR_SSI_SxCCR_WL(17) | CCSR_SSI_SxCCR_DC(13)); /* * Enable AC97 mode and startup the SSI */ - write_ssi(CCSR_SSI_SACNT_AC97EN | CCSR_SSI_SACNT_FV, - &ssi->sacnt); - write_ssi(0xff, &ssi->saccdis); - write_ssi(0x300, &ssi->saccen); + regmap_write(regs, CCSR_SSI_SACNT, + CCSR_SSI_SACNT_AC97EN | CCSR_SSI_SACNT_FV); + regmap_write(regs, CCSR_SSI_SACCDIS, 0xff); + regmap_write(regs, CCSR_SSI_SACCEN, 0x300); /* * Enable SSI, Transmit and Receive. AC97 has to communicate with the * codec before a stream is started. */ - write_ssi_mask(&ssi->scr, 0, CCSR_SSI_SCR_SSIEN | - CCSR_SSI_SCR_TE | CCSR_SSI_SCR_RE); + regmap_update_bits(regs, CCSR_SSI_SCR, + CCSR_SSI_SCR_SSIEN | CCSR_SSI_SCR_TE | CCSR_SSI_SCR_RE, + CCSR_SSI_SCR_SSIEN | CCSR_SSI_SCR_TE | CCSR_SSI_SCR_RE); - write_ssi(CCSR_SSI_SOR_WAIT(3), &ssi->sor); + regmap_write(regs, CCSR_SSI_SOR, CCSR_SSI_SOR_WAIT(3)); } /** @@ -549,7 +551,7 @@ static int fsl_ssi_set_bclk(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *hw_params) { struct fsl_ssi_private *ssi_private = snd_soc_dai_get_drvdata(cpu_dai); - struct ccsr_ssi __iomem *ssi = ssi_private->ssi; + struct regmap *regs = ssi_private->regs; int synchronous = ssi_private->cpu_dai_drv.symmetric_rates, ret; u32 pm = 999, div2, psr, stccr, mask, afreq, factor, i; unsigned long clkrate, baudrate, tmprate; @@ -626,9 +628,9 @@ static int fsl_ssi_set_bclk(struct snd_pcm_substream *substream, CCSR_SSI_SxCCR_PSR; if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK || synchronous) - write_ssi_mask(&ssi->stccr, mask, stccr); + regmap_update_bits(regs, CCSR_SSI_STCCR, mask, stccr); else - write_ssi_mask(&ssi->srccr, mask, stccr); + regmap_update_bits(regs, CCSR_SSI_SRCCR, mask, stccr); if (!baudclk_is_used) { ret = clk_set_rate(ssi_private->baudclk, baudrate); @@ -668,13 +670,17 @@ static int fsl_ssi_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *hw_params, struct snd_soc_dai *cpu_dai) { struct fsl_ssi_private *ssi_private = snd_soc_dai_get_drvdata(cpu_dai); - struct ccsr_ssi __iomem *ssi = ssi_private->ssi; + struct regmap *regs = ssi_private->regs; unsigned int channels = params_channels(hw_params); unsigned int sample_size = snd_pcm_format_width(params_format(hw_params)); u32 wl = CCSR_SSI_SxCCR_WL(sample_size); - int enabled = read_ssi(&ssi->scr) & CCSR_SSI_SCR_SSIEN; int ret; + u32 scr_val; + int enabled; + + regmap_read(regs, CCSR_SSI_SCR, &scr_val); + enabled = scr_val & CCSR_SSI_SCR_SSIEN; /* * If we're in synchronous mode, and the SSI is already enabled, @@ -711,12 +717,14 @@ static int fsl_ssi_hw_params(struct snd_pcm_substream *substream, /* In synchronous mode, the SSI uses STCCR for capture */ if ((substream->stream == SNDRV_PCM_STREAM_PLAYBACK) || ssi_private->cpu_dai_drv.symmetric_rates) - write_ssi_mask(&ssi->stccr, CCSR_SSI_SxCCR_WL_MASK, wl); + regmap_update_bits(regs, CCSR_SSI_STCCR, CCSR_SSI_SxCCR_WL_MASK, + wl); else - write_ssi_mask(&ssi->srccr, CCSR_SSI_SxCCR_WL_MASK, wl); + regmap_update_bits(regs, CCSR_SSI_SRCCR, CCSR_SSI_SxCCR_WL_MASK, + wl); if (!fsl_ssi_is_ac97(ssi_private)) - write_ssi_mask(&ssi->scr, + regmap_update_bits(regs, CCSR_SSI_SCR, CCSR_SSI_SCR_NET | CCSR_SSI_SCR_I2S_MODE_MASK, channels == 1 ? 0 : ssi_private->i2s_mode); @@ -742,7 +750,7 @@ static int fsl_ssi_hw_free(struct snd_pcm_substream *substream, static int _fsl_ssi_set_dai_fmt(struct fsl_ssi_private *ssi_private, unsigned int fmt) { - struct ccsr_ssi __iomem *ssi = ssi_private->ssi; + struct regmap *regs = ssi_private->regs; u32 strcr = 0, stcr, srcr, scr, mask; u8 wm; @@ -755,14 +763,17 @@ static int _fsl_ssi_set_dai_fmt(struct fsl_ssi_private *ssi_private, fsl_ssi_setup_reg_vals(ssi_private); - scr = read_ssi(&ssi->scr) & ~(CCSR_SSI_SCR_SYN | CCSR_SSI_SCR_I2S_MODE_MASK); + regmap_read(regs, CCSR_SSI_SCR, &scr); + scr &= ~(CCSR_SSI_SCR_SYN | CCSR_SSI_SCR_I2S_MODE_MASK); scr |= CCSR_SSI_SCR_SYNC_TX_FS; mask = CCSR_SSI_STCR_TXBIT0 | CCSR_SSI_STCR_TFDIR | CCSR_SSI_STCR_TXDIR | CCSR_SSI_STCR_TSCKP | CCSR_SSI_STCR_TFSI | CCSR_SSI_STCR_TFSL | CCSR_SSI_STCR_TEFS; - stcr = read_ssi(&ssi->stcr) & ~mask; - srcr = read_ssi(&ssi->srcr) & ~mask; + regmap_read(regs, CCSR_SSI_STCR, &stcr); + regmap_read(regs, CCSR_SSI_SRCR, &srcr); + stcr &= ~mask; + srcr &= ~mask; ssi_private->i2s_mode = CCSR_SSI_SCR_NET; switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { @@ -770,10 +781,12 @@ static int _fsl_ssi_set_dai_fmt(struct fsl_ssi_private *ssi_private, switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { case SND_SOC_DAIFMT_CBS_CFS: ssi_private->i2s_mode |= CCSR_SSI_SCR_I2S_MODE_MASTER; - write_ssi_mask(&ssi->stccr, CCSR_SSI_SxCCR_DC_MASK, - CCSR_SSI_SxCCR_DC(2)); - write_ssi_mask(&ssi->srccr, CCSR_SSI_SxCCR_DC_MASK, - CCSR_SSI_SxCCR_DC(2)); + regmap_update_bits(regs, CCSR_SSI_STCCR, + CCSR_SSI_SxCCR_DC_MASK, + CCSR_SSI_SxCCR_DC(2)); + regmap_update_bits(regs, CCSR_SSI_SRCCR, + CCSR_SSI_SxCCR_DC_MASK, + CCSR_SSI_SxCCR_DC(2)); break; case SND_SOC_DAIFMT_CBM_CFM: ssi_private->i2s_mode |= CCSR_SSI_SCR_I2S_MODE_SLAVE; @@ -852,9 +865,9 @@ static int _fsl_ssi_set_dai_fmt(struct fsl_ssi_private *ssi_private, scr |= CCSR_SSI_SCR_SYN; } - write_ssi(stcr, &ssi->stcr); - write_ssi(srcr, &ssi->srcr); - write_ssi(scr, &ssi->scr); + regmap_write(regs, CCSR_SSI_STCR, stcr); + regmap_write(regs, CCSR_SSI_SRCR, srcr); + regmap_write(regs, CCSR_SSI_SCR, scr); /* * Set the watermark for transmit FIFI 0 and receive FIFO 0. We don't @@ -872,16 +885,16 @@ static int _fsl_ssi_set_dai_fmt(struct fsl_ssi_private *ssi_private, else wm = ssi_private->fifo_depth; - write_ssi(CCSR_SSI_SFCSR_TFWM0(wm) | CCSR_SSI_SFCSR_RFWM0(wm) | - CCSR_SSI_SFCSR_TFWM1(wm) | CCSR_SSI_SFCSR_RFWM1(wm), - &ssi->sfcsr); + regmap_write(regs, CCSR_SSI_SFCSR, + CCSR_SSI_SFCSR_TFWM0(wm) | CCSR_SSI_SFCSR_RFWM0(wm) | + CCSR_SSI_SFCSR_TFWM1(wm) | CCSR_SSI_SFCSR_RFWM1(wm)); if (ssi_private->use_dual_fifo) { - write_ssi_mask(&ssi->srcr, CCSR_SSI_SRCR_RFEN1, + regmap_update_bits(regs, CCSR_SSI_SRCR, CCSR_SSI_SRCR_RFEN1, CCSR_SSI_SRCR_RFEN1); - write_ssi_mask(&ssi->stcr, CCSR_SSI_STCR_TFEN1, + regmap_update_bits(regs, CCSR_SSI_STCR, CCSR_SSI_STCR_TFEN1, CCSR_SSI_STCR_TFEN1); - write_ssi_mask(&ssi->scr, CCSR_SSI_SCR_TCH_EN, + regmap_update_bits(regs, CCSR_SSI_SCR, CCSR_SSI_SCR_TCH_EN, CCSR_SSI_SCR_TCH_EN); } @@ -911,31 +924,34 @@ static int fsl_ssi_set_dai_tdm_slot(struct snd_soc_dai *cpu_dai, u32 tx_mask, u32 rx_mask, int slots, int slot_width) { struct fsl_ssi_private *ssi_private = snd_soc_dai_get_drvdata(cpu_dai); - struct ccsr_ssi __iomem *ssi = ssi_private->ssi; + struct regmap *regs = ssi_private->regs; u32 val; /* The slot number should be >= 2 if using Network mode or I2S mode */ - val = read_ssi(&ssi->scr) & (CCSR_SSI_SCR_I2S_MODE_MASK | CCSR_SSI_SCR_NET); + regmap_read(regs, CCSR_SSI_SCR, &val); + val &= CCSR_SSI_SCR_I2S_MODE_MASK | CCSR_SSI_SCR_NET; if (val && slots < 2) { dev_err(cpu_dai->dev, "slot number should be >= 2 in I2S or NET\n"); return -EINVAL; } - write_ssi_mask(&ssi->stccr, CCSR_SSI_SxCCR_DC_MASK, + regmap_update_bits(regs, CCSR_SSI_STCCR, CCSR_SSI_SxCCR_DC_MASK, CCSR_SSI_SxCCR_DC(slots)); - write_ssi_mask(&ssi->srccr, CCSR_SSI_SxCCR_DC_MASK, + regmap_update_bits(regs, CCSR_SSI_SRCCR, CCSR_SSI_SxCCR_DC_MASK, CCSR_SSI_SxCCR_DC(slots)); /* The register SxMSKs needs SSI to provide essential clock due to * hardware design. So we here temporarily enable SSI to set them. */ - val = read_ssi(&ssi->scr) & CCSR_SSI_SCR_SSIEN; - write_ssi_mask(&ssi->scr, 0, CCSR_SSI_SCR_SSIEN); + regmap_read(regs, CCSR_SSI_SCR, &val); + val &= CCSR_SSI_SCR_SSIEN; + regmap_update_bits(regs, CCSR_SSI_SCR, CCSR_SSI_SCR_SSIEN, + CCSR_SSI_SCR_SSIEN); - write_ssi(tx_mask, &ssi->stmsk); - write_ssi(rx_mask, &ssi->srmsk); + regmap_write(regs, CCSR_SSI_STMSK, tx_mask); + regmap_write(regs, CCSR_SSI_SRMSK, rx_mask); - write_ssi_mask(&ssi->scr, CCSR_SSI_SCR_SSIEN, val); + regmap_update_bits(regs, CCSR_SSI_SCR, CCSR_SSI_SCR_SSIEN, val); return 0; } @@ -954,7 +970,7 @@ static int fsl_ssi_trigger(struct snd_pcm_substream *substream, int cmd, { struct snd_soc_pcm_runtime *rtd = substream->private_data; struct fsl_ssi_private *ssi_private = snd_soc_dai_get_drvdata(rtd->cpu_dai); - struct ccsr_ssi __iomem *ssi = ssi_private->ssi; + struct regmap *regs = ssi_private->regs; switch (cmd) { case SNDRV_PCM_TRIGGER_START: @@ -981,9 +997,9 @@ static int fsl_ssi_trigger(struct snd_pcm_substream *substream, int cmd, if (fsl_ssi_is_ac97(ssi_private)) { if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) - write_ssi(CCSR_SSI_SOR_TX_CLR, &ssi->sor); + regmap_write(regs, CCSR_SSI_SOR, CCSR_SSI_SOR_TX_CLR); else - write_ssi(CCSR_SSI_SOR_RX_CLR, &ssi->sor); + regmap_write(regs, CCSR_SSI_SOR, CCSR_SSI_SOR_RX_CLR); } return 0; @@ -1058,7 +1074,7 @@ static struct fsl_ssi_private *fsl_ac97_data; static void fsl_ssi_ac97_write(struct snd_ac97 *ac97, unsigned short reg, unsigned short val) { - struct ccsr_ssi *ssi = fsl_ac97_data->ssi; + struct regmap *regs = fsl_ac97_data->regs; unsigned int lreg; unsigned int lval; @@ -1067,12 +1083,12 @@ static void fsl_ssi_ac97_write(struct snd_ac97 *ac97, unsigned short reg, lreg = reg << 12; - write_ssi(lreg, &ssi->sacadd); + regmap_write(regs, CCSR_SSI_SACADD, lreg); lval = val << 4; - write_ssi(lval , &ssi->sacdat); + regmap_write(regs, CCSR_SSI_SACDAT, lval); - write_ssi_mask(&ssi->sacnt, CCSR_SSI_SACNT_RDWR_MASK, + regmap_update_bits(regs, CCSR_SSI_SACNT, CCSR_SSI_SACNT_RDWR_MASK, CCSR_SSI_SACNT_WR); udelay(100); } @@ -1080,19 +1096,21 @@ static void fsl_ssi_ac97_write(struct snd_ac97 *ac97, unsigned short reg, static unsigned short fsl_ssi_ac97_read(struct snd_ac97 *ac97, unsigned short reg) { - struct ccsr_ssi *ssi = fsl_ac97_data->ssi; + struct regmap *regs = fsl_ac97_data->regs; unsigned short val = -1; + u32 reg_val; unsigned int lreg; lreg = (reg & 0x7f) << 12; - write_ssi(lreg, &ssi->sacadd); - write_ssi_mask(&ssi->sacnt, CCSR_SSI_SACNT_RDWR_MASK, + regmap_write(regs, CCSR_SSI_SACADD, lreg); + regmap_update_bits(regs, CCSR_SSI_SACNT, CCSR_SSI_SACNT_RDWR_MASK, CCSR_SSI_SACNT_RD); udelay(100); - val = (read_ssi(&ssi->sacdat) >> 4) & 0xffff; + regmap_read(regs, CCSR_SSI_SACDAT, ®_val); + val = (reg_val >> 4) & 0xffff; return val; } @@ -1151,10 +1169,8 @@ static int fsl_ssi_imx_probe(struct platform_device *pdev, */ ssi_private->dma_params_tx.maxburst = ssi_private->fifo_depth - 2; ssi_private->dma_params_rx.maxburst = ssi_private->fifo_depth - 2; - ssi_private->dma_params_tx.addr = ssi_private->ssi_phys + - offsetof(struct ccsr_ssi, stx0); - ssi_private->dma_params_rx.addr = ssi_private->ssi_phys + - offsetof(struct ccsr_ssi, srx0); + ssi_private->dma_params_tx.addr = ssi_private->ssi_phys + CCSR_SSI_STX0; + ssi_private->dma_params_rx.addr = ssi_private->ssi_phys + CCSR_SSI_SRX0; ret = !of_property_read_u32_array(np, "dmas", dmas, 4); if (ssi_private->use_dma && !ret && dmas[2] == IMX_DMATYPE_SSI_DUAL) { @@ -1216,6 +1232,7 @@ static int fsl_ssi_probe(struct platform_device *pdev) const char *p, *sprop; const uint32_t *iprop; struct resource res; + void __iomem *iomem; char name[64]; /* SSIs that are not connected on the board should have a @@ -1270,12 +1287,20 @@ static int fsl_ssi_probe(struct platform_device *pdev) dev_err(&pdev->dev, "could not determine device resources\n"); return ret; } - ssi_private->ssi = of_iomap(np, 0); - if (!ssi_private->ssi) { + ssi_private->ssi_phys = res.start; + + iomem = devm_ioremap(&pdev->dev, res.start, resource_size(&res)); + if (!iomem) { dev_err(&pdev->dev, "could not map device resources\n"); return -ENOMEM; } - ssi_private->ssi_phys = res.start; + + ssi_private->regs = devm_regmap_init_mmio(&pdev->dev, iomem, + &fsl_ssi_regconfig); + if (IS_ERR(ssi_private->regs)) { + dev_err(&pdev->dev, "Failed to init register map\n"); + return PTR_ERR(ssi_private->regs); + } ssi_private->irq = irq_of_parse_and_map(np, 0); if (!ssi_private->irq) { @@ -1301,7 +1326,7 @@ static int fsl_ssi_probe(struct platform_device *pdev) dev_set_drvdata(&pdev->dev, ssi_private); if (ssi_private->soc->imx) { - ret = fsl_ssi_imx_probe(pdev, ssi_private, ssi_private->ssi); + ret = fsl_ssi_imx_probe(pdev, ssi_private, iomem); if (ret) goto error_irqmap; } diff --git a/sound/soc/fsl/fsl_ssi.h b/sound/soc/fsl/fsl_ssi.h index 71c3e7e4340d..506510540d0a 100644 --- a/sound/soc/fsl/fsl_ssi.h +++ b/sound/soc/fsl/fsl_ssi.h @@ -12,32 +12,30 @@ #ifndef _MPC8610_I2S_H #define _MPC8610_I2S_H -/* SSI Register Map */ -struct ccsr_ssi { - __be32 stx0; /* 0x.0000 - SSI Transmit Data Register 0 */ - __be32 stx1; /* 0x.0004 - SSI Transmit Data Register 1 */ - __be32 srx0; /* 0x.0008 - SSI Receive Data Register 0 */ - __be32 srx1; /* 0x.000C - SSI Receive Data Register 1 */ - __be32 scr; /* 0x.0010 - SSI Control Register */ - __be32 sisr; /* 0x.0014 - SSI Interrupt Status Register Mixed */ - __be32 sier; /* 0x.0018 - SSI Interrupt Enable Register */ - __be32 stcr; /* 0x.001C - SSI Transmit Configuration Register */ - __be32 srcr; /* 0x.0020 - SSI Receive Configuration Register */ - __be32 stccr; /* 0x.0024 - SSI Transmit Clock Control Register */ - __be32 srccr; /* 0x.0028 - SSI Receive Clock Control Register */ - __be32 sfcsr; /* 0x.002C - SSI FIFO Control/Status Register */ - __be32 str; /* 0x.0030 - SSI Test Register */ - __be32 sor; /* 0x.0034 - SSI Option Register */ - __be32 sacnt; /* 0x.0038 - SSI AC97 Control Register */ - __be32 sacadd; /* 0x.003C - SSI AC97 Command Address Register */ - __be32 sacdat; /* 0x.0040 - SSI AC97 Command Data Register */ - __be32 satag; /* 0x.0044 - SSI AC97 Tag Register */ - __be32 stmsk; /* 0x.0048 - SSI Transmit Time Slot Mask Register */ - __be32 srmsk; /* 0x.004C - SSI Receive Time Slot Mask Register */ - __be32 saccst; /* 0x.0050 - SSI AC97 Channel Status Register */ - __be32 saccen; /* 0x.0054 - SSI AC97 Channel Enable Register */ - __be32 saccdis; /* 0x.0058 - SSI AC97 Channel Disable Register */ -}; +/* SSI registers */ +#define CCSR_SSI_STX0 0x00 +#define CCSR_SSI_STX1 0x04 +#define CCSR_SSI_SRX0 0x08 +#define CCSR_SSI_SRX1 0x0c +#define CCSR_SSI_SCR 0x10 +#define CCSR_SSI_SISR 0x14 +#define CCSR_SSI_SIER 0x18 +#define CCSR_SSI_STCR 0x1c +#define CCSR_SSI_SRCR 0x20 +#define CCSR_SSI_STCCR 0x24 +#define CCSR_SSI_SRCCR 0x28 +#define CCSR_SSI_SFCSR 0x2c +#define CCSR_SSI_STR 0x30 +#define CCSR_SSI_SOR 0x34 +#define CCSR_SSI_SACNT 0x38 +#define CCSR_SSI_SACADD 0x3c +#define CCSR_SSI_SACDAT 0x40 +#define CCSR_SSI_SATAG 0x44 +#define CCSR_SSI_STMSK 0x48 +#define CCSR_SSI_SRMSK 0x4c +#define CCSR_SSI_SACCST 0x50 +#define CCSR_SSI_SACCEN 0x54 +#define CCSR_SSI_SACCDIS 0x58 #define CCSR_SSI_SCR_SYNC_TX_FS 0x00001000 #define CCSR_SSI_SCR_RFR_CLK_DIS 0x00000800 From 7b8751abdd34a2f924c37c29ad61d598f5d29e7b Mon Sep 17 00:00:00 2001 From: Alexander Shiyan Date: Fri, 23 May 2014 15:11:01 +0400 Subject: [PATCH 10/10] ASoC: fsl: Remove dependencies of boards for SND_SOC_EUKREA_TLV320 Eukrea-i.MX51 board was converted to use DT, ie we no longer have a MACH_EUKREA_MBIMXSD51_BASEBOARD symbol. Transformation of other boards planned for the near future, so this patch removes all these dependencies and restricts build of this driver to ARCH_MXC. Signed-off-by: Alexander Shiyan Signed-off-by: Mark Brown --- sound/soc/fsl/Kconfig | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/sound/soc/fsl/Kconfig b/sound/soc/fsl/Kconfig index 807448ceef96..f26a2dd698b5 100644 --- a/sound/soc/fsl/Kconfig +++ b/sound/soc/fsl/Kconfig @@ -207,12 +207,7 @@ config SND_SOC_PHYCORE_AC97 config SND_SOC_EUKREA_TLV320 tristate "Eukrea TLV320" - depends on MACH_EUKREA_MBIMX27_BASEBOARD \ - || MACH_EUKREA_MBIMXSD25_BASEBOARD \ - || MACH_EUKREA_MBIMXSD35_BASEBOARD \ - || MACH_EUKREA_MBIMXSD51_BASEBOARD \ - || (OF && ARM) - depends on I2C + depends on ARCH_MXC && I2C select SND_SOC_TLV320AIC23_I2C select SND_SOC_IMX_AUDMUX select SND_SOC_IMX_SSI