Skip to content

Commit

Permalink
ASoC: fsl_ssi: refine ipg clock usage in this module
Browse files Browse the repository at this point in the history
Check if ipg clock is in clock-names property, then we can move the
ipg clock enable and disable operation to startup and shutdown, that
is only enable ipg clock when ssi is working and keep clock is disabled
when ssi is in idle.
But when the checking is failed, remain the clock control as before.

Tested-by: Markus Pargmann <mpa@pengutronix.de>
Signed-off-by: Shengjiu Wang <shengjiu.wang@freescale.com>
Acked-by: Nicolin Chen <nicoleotsuka@gmail.com>
Signed-off-by: Mark Brown <broonie@kernel.org>
  • Loading branch information
Shengjiu Wang authored and Mark Brown committed Sep 17, 2014
1 parent cf4f7fc commit f4a43ca
Showing 1 changed file with 45 additions and 8 deletions.
53 changes: 45 additions & 8 deletions sound/soc/fsl/fsl_ssi.c
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,7 @@ struct fsl_ssi_private {
u8 i2s_mode;
bool use_dma;
bool use_dual_fifo;
bool has_ipg_clk_name;
unsigned int fifo_depth;
struct fsl_ssi_rxtx_reg_val rxtx_reg_val;

Expand Down Expand Up @@ -530,6 +531,11 @@ 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 ret;

ret = clk_prepare_enable(ssi_private->clk);
if (ret)
return ret;

/* 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
Expand All @@ -543,6 +549,21 @@ static int fsl_ssi_startup(struct snd_pcm_substream *substream,
return 0;
}

/**
* fsl_ssi_shutdown: shutdown the SSI
*
*/
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);

clk_disable_unprepare(ssi_private->clk);

}

/**
* fsl_ssi_set_bclk - configure Digital Audio Interface bit clock
*
Expand Down Expand Up @@ -1043,6 +1064,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,
.shutdown = fsl_ssi_shutdown,
.hw_params = fsl_ssi_hw_params,
.hw_free = fsl_ssi_hw_free,
.set_fmt = fsl_ssi_set_dai_fmt,
Expand Down Expand Up @@ -1168,17 +1190,22 @@ static int fsl_ssi_imx_probe(struct platform_device *pdev,
u32 dmas[4];
int ret;

ssi_private->clk = devm_clk_get(&pdev->dev, NULL);
if (ssi_private->has_ipg_clk_name)
ssi_private->clk = devm_clk_get(&pdev->dev, "ipg");
else
ssi_private->clk = devm_clk_get(&pdev->dev, NULL);
if (IS_ERR(ssi_private->clk)) {
ret = PTR_ERR(ssi_private->clk);
dev_err(&pdev->dev, "could not get clock: %d\n", ret);
return ret;
}

ret = clk_prepare_enable(ssi_private->clk);
if (ret) {
dev_err(&pdev->dev, "clk_prepare_enable failed: %d\n", ret);
return ret;
if (!ssi_private->has_ipg_clk_name) {
ret = clk_prepare_enable(ssi_private->clk);
if (ret) {
dev_err(&pdev->dev, "clk_prepare_enable failed: %d\n", ret);
return ret;
}
}

/* For those SLAVE implementations, we ingore non-baudclk cases
Expand Down Expand Up @@ -1236,8 +1263,9 @@ static int fsl_ssi_imx_probe(struct platform_device *pdev,
return 0;

error_pcm:
clk_disable_unprepare(ssi_private->clk);

if (!ssi_private->has_ipg_clk_name)
clk_disable_unprepare(ssi_private->clk);
return ret;
}

Expand All @@ -1246,7 +1274,8 @@ static void fsl_ssi_imx_clean(struct platform_device *pdev,
{
if (!ssi_private->use_dma)
imx_pcm_fiq_exit(pdev);
clk_disable_unprepare(ssi_private->clk);
if (!ssi_private->has_ipg_clk_name)
clk_disable_unprepare(ssi_private->clk);
}

static int fsl_ssi_probe(struct platform_device *pdev)
Expand Down Expand Up @@ -1321,8 +1350,16 @@ static int fsl_ssi_probe(struct platform_device *pdev)
return -ENOMEM;
}

ssi_private->regs = devm_regmap_init_mmio(&pdev->dev, iomem,
ret = of_property_match_string(np, "clock-names", "ipg");
if (ret < 0) {
ssi_private->has_ipg_clk_name = false;
ssi_private->regs = devm_regmap_init_mmio(&pdev->dev, iomem,
&fsl_ssi_regconfig);
} else {
ssi_private->has_ipg_clk_name = true;
ssi_private->regs = devm_regmap_init_mmio_clk(&pdev->dev,
"ipg", 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);
Expand Down

0 comments on commit f4a43ca

Please sign in to comment.