aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorShengjiu Wang <shengjiu.wang@freescale.com>2014-09-15 22:13:16 -0400
committerMark Brown <broonie@kernel.org>2014-09-17 14:30:15 -0400
commitf4a43caba7d495699f98532b4faee90fd9980732 (patch)
treee788e62dba97bae9329ea747dd78cdf866aaf4aa
parentcf4f7fc3e7336e2e946880890e60ed36178889ea (diff)
ASoC: fsl_ssi: refine ipg clock usage in this module
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>
-rw-r--r--sound/soc/fsl/fsl_ssi.c53
1 files changed, 45 insertions, 8 deletions
diff --git a/sound/soc/fsl/fsl_ssi.c b/sound/soc/fsl/fsl_ssi.c
index 2fc3e6683e4f..16a1361b68b3 100644
--- a/sound/soc/fsl/fsl_ssi.c
+++ b/sound/soc/fsl/fsl_ssi.c
@@ -169,6 +169,7 @@ struct fsl_ssi_private {
169 u8 i2s_mode; 169 u8 i2s_mode;
170 bool use_dma; 170 bool use_dma;
171 bool use_dual_fifo; 171 bool use_dual_fifo;
172 bool has_ipg_clk_name;
172 unsigned int fifo_depth; 173 unsigned int fifo_depth;
173 struct fsl_ssi_rxtx_reg_val rxtx_reg_val; 174 struct fsl_ssi_rxtx_reg_val rxtx_reg_val;
174 175
@@ -530,6 +531,11 @@ static int fsl_ssi_startup(struct snd_pcm_substream *substream,
530 struct snd_soc_pcm_runtime *rtd = substream->private_data; 531 struct snd_soc_pcm_runtime *rtd = substream->private_data;
531 struct fsl_ssi_private *ssi_private = 532 struct fsl_ssi_private *ssi_private =
532 snd_soc_dai_get_drvdata(rtd->cpu_dai); 533 snd_soc_dai_get_drvdata(rtd->cpu_dai);
534 int ret;
535
536 ret = clk_prepare_enable(ssi_private->clk);
537 if (ret)
538 return ret;
533 539
534 /* When using dual fifo mode, it is safer to ensure an even period 540 /* When using dual fifo mode, it is safer to ensure an even period
535 * size. If appearing to an odd number while DMA always starts its 541 * size. If appearing to an odd number while DMA always starts its
@@ -544,6 +550,21 @@ static int fsl_ssi_startup(struct snd_pcm_substream *substream,
544} 550}
545 551
546/** 552/**
553 * fsl_ssi_shutdown: shutdown the SSI
554 *
555 */
556static void fsl_ssi_shutdown(struct snd_pcm_substream *substream,
557 struct snd_soc_dai *dai)
558{
559 struct snd_soc_pcm_runtime *rtd = substream->private_data;
560 struct fsl_ssi_private *ssi_private =
561 snd_soc_dai_get_drvdata(rtd->cpu_dai);
562
563 clk_disable_unprepare(ssi_private->clk);
564
565}
566
567/**
547 * fsl_ssi_set_bclk - configure Digital Audio Interface bit clock 568 * fsl_ssi_set_bclk - configure Digital Audio Interface bit clock
548 * 569 *
549 * Note: This function can be only called when using SSI as DAI master 570 * Note: This function can be only called when using SSI as DAI master
@@ -1043,6 +1064,7 @@ static int fsl_ssi_dai_probe(struct snd_soc_dai *dai)
1043 1064
1044static const struct snd_soc_dai_ops fsl_ssi_dai_ops = { 1065static const struct snd_soc_dai_ops fsl_ssi_dai_ops = {
1045 .startup = fsl_ssi_startup, 1066 .startup = fsl_ssi_startup,
1067 .shutdown = fsl_ssi_shutdown,
1046 .hw_params = fsl_ssi_hw_params, 1068 .hw_params = fsl_ssi_hw_params,
1047 .hw_free = fsl_ssi_hw_free, 1069 .hw_free = fsl_ssi_hw_free,
1048 .set_fmt = fsl_ssi_set_dai_fmt, 1070 .set_fmt = fsl_ssi_set_dai_fmt,
@@ -1168,17 +1190,22 @@ static int fsl_ssi_imx_probe(struct platform_device *pdev,
1168 u32 dmas[4]; 1190 u32 dmas[4];
1169 int ret; 1191 int ret;
1170 1192
1171 ssi_private->clk = devm_clk_get(&pdev->dev, NULL); 1193 if (ssi_private->has_ipg_clk_name)
1194 ssi_private->clk = devm_clk_get(&pdev->dev, "ipg");
1195 else
1196 ssi_private->clk = devm_clk_get(&pdev->dev, NULL);
1172 if (IS_ERR(ssi_private->clk)) { 1197 if (IS_ERR(ssi_private->clk)) {
1173 ret = PTR_ERR(ssi_private->clk); 1198 ret = PTR_ERR(ssi_private->clk);
1174 dev_err(&pdev->dev, "could not get clock: %d\n", ret); 1199 dev_err(&pdev->dev, "could not get clock: %d\n", ret);
1175 return ret; 1200 return ret;
1176 } 1201 }
1177 1202
1178 ret = clk_prepare_enable(ssi_private->clk); 1203 if (!ssi_private->has_ipg_clk_name) {
1179 if (ret) { 1204 ret = clk_prepare_enable(ssi_private->clk);
1180 dev_err(&pdev->dev, "clk_prepare_enable failed: %d\n", ret); 1205 if (ret) {
1181 return ret; 1206 dev_err(&pdev->dev, "clk_prepare_enable failed: %d\n", ret);
1207 return ret;
1208 }
1182 } 1209 }
1183 1210
1184 /* For those SLAVE implementations, we ingore non-baudclk cases 1211 /* For those SLAVE implementations, we ingore non-baudclk cases
@@ -1236,8 +1263,9 @@ static int fsl_ssi_imx_probe(struct platform_device *pdev,
1236 return 0; 1263 return 0;
1237 1264
1238error_pcm: 1265error_pcm:
1239 clk_disable_unprepare(ssi_private->clk);
1240 1266
1267 if (!ssi_private->has_ipg_clk_name)
1268 clk_disable_unprepare(ssi_private->clk);
1241 return ret; 1269 return ret;
1242} 1270}
1243 1271
@@ -1246,7 +1274,8 @@ static void fsl_ssi_imx_clean(struct platform_device *pdev,
1246{ 1274{
1247 if (!ssi_private->use_dma) 1275 if (!ssi_private->use_dma)
1248 imx_pcm_fiq_exit(pdev); 1276 imx_pcm_fiq_exit(pdev);
1249 clk_disable_unprepare(ssi_private->clk); 1277 if (!ssi_private->has_ipg_clk_name)
1278 clk_disable_unprepare(ssi_private->clk);
1250} 1279}
1251 1280
1252static int fsl_ssi_probe(struct platform_device *pdev) 1281static int fsl_ssi_probe(struct platform_device *pdev)
@@ -1321,8 +1350,16 @@ static int fsl_ssi_probe(struct platform_device *pdev)
1321 return -ENOMEM; 1350 return -ENOMEM;
1322 } 1351 }
1323 1352
1324 ssi_private->regs = devm_regmap_init_mmio(&pdev->dev, iomem, 1353 ret = of_property_match_string(np, "clock-names", "ipg");
1354 if (ret < 0) {
1355 ssi_private->has_ipg_clk_name = false;
1356 ssi_private->regs = devm_regmap_init_mmio(&pdev->dev, iomem,
1325 &fsl_ssi_regconfig); 1357 &fsl_ssi_regconfig);
1358 } else {
1359 ssi_private->has_ipg_clk_name = true;
1360 ssi_private->regs = devm_regmap_init_mmio_clk(&pdev->dev,
1361 "ipg", iomem, &fsl_ssi_regconfig);
1362 }
1326 if (IS_ERR(ssi_private->regs)) { 1363 if (IS_ERR(ssi_private->regs)) {
1327 dev_err(&pdev->dev, "Failed to init register map\n"); 1364 dev_err(&pdev->dev, "Failed to init register map\n");
1328 return PTR_ERR(ssi_private->regs); 1365 return PTR_ERR(ssi_private->regs);