[PATCH 1/1] ASoC: sirf-usp: Fixed a bug for playback and capture work at the same time

From: Rongjun Ying
Date: Wed Jul 23 2014 - 01:21:39 EST


1. The startup function invoked when the playback and capture.
If start playback when capturing, the registers are re-initinitialised.
That cause the playback fail. So move the startup code into runtime resume.
2. Modified: If non RUNTIME_PM support, the probe need enable clock and
initinitialise registers.
3. Refine code.

Signed-off-by: Rongjun Ying <rongjun.ying@xxxxxxx>
---
sound/soc/sirf/sirf-usp.c | 54 +++++++++++++++++++++++------------------------
1 file changed, 27 insertions(+), 27 deletions(-)

diff --git a/sound/soc/sirf/sirf-usp.c b/sound/soc/sirf/sirf-usp.c
index 9693bc2..3a73037 100644
--- a/sound/soc/sirf/sirf-usp.c
+++ b/sound/soc/sirf/sirf-usp.c
@@ -103,11 +103,8 @@ static int sirf_usp_pcm_set_dai_fmt(struct snd_soc_dai *dai,
return 0;
}

-static int sirf_usp_i2s_startup(struct snd_pcm_substream *substream,
- struct snd_soc_dai *dai)
+static void sirf_usp_i2s_init(struct sirf_usp *usp)
{
- struct sirf_usp *usp = snd_soc_dai_get_drvdata(dai);
-
/* Configure RISC mode */
regmap_update_bits(usp->regmap, USP_RISC_DSP_MODE,
USP_RISC_DSP_SEL, ~USP_RISC_DSP_SEL);
@@ -119,19 +116,16 @@ static int sirf_usp_i2s_startup(struct snd_pcm_substream *substream,
regmap_write(usp->regmap, USP_TX_DMA_IO_LEN, 0);
regmap_write(usp->regmap, USP_RX_DMA_IO_LEN, 0);

- regmap_write(usp->regmap, USP_RX_FRAME_CTRL, USP_SINGLE_SYNC_MODE);
-
- regmap_write(usp->regmap, USP_TX_FRAME_CTRL, USP_TXC_SLAVE_CLK_SAMPLE);
-
/* Configure Mode2 register */
regmap_write(usp->regmap, USP_MODE2, (1 << USP_RXD_DELAY_LEN_OFFSET) |
- (0 << USP_TXD_DELAY_LEN_OFFSET));
+ (0 << USP_TXD_DELAY_LEN_OFFSET) |
+ USP_TFS_CLK_SLAVE_MODE | USP_RFS_CLK_SLAVE_MODE);

/* Configure Mode1 register */
regmap_write(usp->regmap, USP_MODE1,
USP_SYNC_MODE | USP_EN | USP_TXD_ACT_EDGE_FALLING |
USP_RFS_ACT_LEVEL_LOGIC1 | USP_TFS_ACT_LEVEL_LOGIC1 |
- USP_TX_UFLOW_REPEAT_ZERO);
+ USP_TX_UFLOW_REPEAT_ZERO | USP_CLOCK_MODE_SLAVE);

/* Configure RX DMA IO Control register */
regmap_write(usp->regmap, USP_RX_DMA_IO_CTRL, 0);
@@ -155,8 +149,6 @@ static int sirf_usp_i2s_startup(struct snd_pcm_substream *substream,
/* Congiure TX FIFO Level Check register */
regmap_write(usp->regmap, USP_TX_FIFO_LEVEL_CHK,
TX_FIFO_SC(0x1B) | TX_FIFO_LC(0x0E) | TX_FIFO_HC(0x04));
-
- return 0;
}

static int sirf_usp_pcm_hw_params(struct snd_pcm_substream *substream,
@@ -204,23 +196,19 @@ static int sirf_usp_pcm_hw_params(struct snd_pcm_substream *substream,
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
regmap_update_bits(usp->regmap, USP_TX_FRAME_CTRL,
USP_TXC_DATA_LEN_MASK | USP_TXC_FRAME_LEN_MASK
- | USP_TXC_SHIFTER_LEN_MASK,
+ | USP_TXC_SHIFTER_LEN_MASK | USP_TXC_SLAVE_CLK_SAMPLE,
((data_len - 1) << USP_TXC_DATA_LEN_OFFSET)
| ((frame_len - 1) << USP_TXC_FRAME_LEN_OFFSET)
- | ((shifter_len - 1) << USP_TXC_SHIFTER_LEN_OFFSET));
+ | ((shifter_len - 1) << USP_TXC_SHIFTER_LEN_OFFSET)
+ | USP_TXC_SLAVE_CLK_SAMPLE);
else
regmap_update_bits(usp->regmap, USP_RX_FRAME_CTRL,
USP_RXC_DATA_LEN_MASK | USP_RXC_FRAME_LEN_MASK
- | USP_RXC_SHIFTER_LEN_MASK,
+ | USP_RXC_SHIFTER_LEN_MASK | USP_SINGLE_SYNC_MODE,
((data_len - 1) << USP_RXC_DATA_LEN_OFFSET)
| ((frame_len - 1) << USP_RXC_FRAME_LEN_OFFSET)
- | ((shifter_len - 1) << USP_RXC_SHIFTER_LEN_OFFSET));
-
- regmap_update_bits(usp->regmap, USP_MODE1,
- USP_CLOCK_MODE_SLAVE, USP_CLOCK_MODE_SLAVE);
- regmap_update_bits(usp->regmap, USP_MODE2,
- USP_TFS_CLK_SLAVE_MODE | USP_RFS_CLK_SLAVE_MODE,
- USP_TFS_CLK_SLAVE_MODE | USP_RFS_CLK_SLAVE_MODE);
+ | ((shifter_len - 1) << USP_RXC_SHIFTER_LEN_OFFSET)
+ | USP_SINGLE_SYNC_MODE);

return 0;
}
@@ -253,7 +241,6 @@ static int sirf_usp_pcm_trigger(struct snd_pcm_substream *substream, int cmd,
}

static const struct snd_soc_dai_ops sirf_usp_pcm_dai_ops = {
- .startup = sirf_usp_i2s_startup,
.trigger = sirf_usp_pcm_trigger,
.set_fmt = sirf_usp_pcm_set_dai_fmt,
.hw_params = sirf_usp_pcm_hw_params,
@@ -282,7 +269,6 @@ static struct snd_soc_dai_driver sirf_usp_pcm_dai = {
.ops = &sirf_usp_pcm_dai_ops,
};

-#ifdef CONFIG_PM
static int sirf_usp_pcm_runtime_suspend(struct device *dev)
{
struct sirf_usp *usp = dev_get_drvdata(dev);
@@ -293,9 +279,15 @@ static int sirf_usp_pcm_runtime_suspend(struct device *dev)
static int sirf_usp_pcm_runtime_resume(struct device *dev)
{
struct sirf_usp *usp = dev_get_drvdata(dev);
- return clk_prepare_enable(usp->clk);
+ int ret;
+ ret = clk_prepare_enable(usp->clk);
+ if (ret) {
+ dev_err(dev, "clk_enable failed: %d\n", ret);
+ return ret;
+ }
+ sirf_usp_i2s_init(usp);
+ return 0;
}
-#endif

#ifdef CONFIG_PM_SLEEP
static int sirf_usp_pcm_suspend(struct device *dev)
@@ -369,6 +361,11 @@ static int sirf_usp_pcm_probe(struct platform_device *pdev)
}

pm_runtime_enable(&pdev->dev);
+ if (!pm_runtime_enabled(&pdev->dev)) {
+ ret = sirf_usp_pcm_runtime_resume(&pdev->dev);
+ if (ret)
+ return ret;
+ }

ret = devm_snd_soc_register_component(&pdev->dev, &sirf_usp_component,
&sirf_usp_pcm_dai, 1);
@@ -381,7 +378,10 @@ static int sirf_usp_pcm_probe(struct platform_device *pdev)

static int sirf_usp_pcm_remove(struct platform_device *pdev)
{
- pm_runtime_disable(&pdev->dev);
+ if (!pm_runtime_enabled(&pdev->dev))
+ sirf_usp_pcm_runtime_suspend(&pdev->dev);
+ else
+ pm_runtime_disable(&pdev->dev);
return 0;
}

--
1.9.3



Member of the CSR plc group of companies. CSR plc registered in England and Wales, registered number 4187346, registered office Churchill House, Cambridge Business Park, Cowley Road, Cambridge, CB4 0WZ, United Kingdom
More information can be found at www.csr.com. Keep up to date with CSR on our technical blog, www.csr.com/blog, CSR people blog, www.csr.com/people, YouTube, www.youtube.com/user/CSRplc, Facebook, www.facebook.com/pages/CSR/191038434253534, or follow us on Twitter at www.twitter.com/CSR_plc.
New for 2014, you can now access the wide range of products powered by aptX at www.aptx.com.
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/