summaryrefslogtreecommitdiff
path: root/sound/soc/fsl/fsl_sai.c
diff options
context:
space:
mode:
authorNicolin Chen <Guangyu.Chen@freescale.com>2014-04-10 23:26:15 +0800
committerNitin Garg <nitin.garg@freescale.com>2015-01-15 21:16:47 -0600
commit5df32c1a9f998108a26fef79bb3e38b63c2b8265 (patch)
treef746a4db2ec66078a8478a88c9259ea5f6469a3f /sound/soc/fsl/fsl_sai.c
parent96c3599d62a6ce3093057b8b8cc246eb9ce72f57 (diff)
ASoC: fsl_sai: Add clock controls for SAI
The SAI mainly has the following clocks: bus clock control and configure registers and to generate synchronous interrupts and DMA requests. mclk1, mclk2, mclk3 to generate the bit clock when the receiver or transmitter is configured for an internally generated bit clock. So this patch adds these clocks and their clock controls to the driver. [ To concern the old DTB cases, I've added a bit of extra code to make the driver compatible with them. And by marking clock NULL if failed to get, the clk_prepare() or clk_get_rate() would easily return 0 so no further path should be broken. -- by Nicolin ] Signed-off-by: Nicolin Chen <Guangyu.Chen@freescale.com> Acked-by: Xiubo Li <Li.Xiubo@freescale.com> Signed-off-by: Mark Brown <broonie@linaro.org> (cherry picked from commit ca3e35c7a37cb59b12a1839d03c621cf8fa9a3d9)
Diffstat (limited to 'sound/soc/fsl/fsl_sai.c')
-rw-r--r--sound/soc/fsl/fsl_sai.c38
1 files changed, 36 insertions, 2 deletions
diff --git a/sound/soc/fsl/fsl_sai.c b/sound/soc/fsl/fsl_sai.c
index dde084273c64..1c93282fbd26 100644
--- a/sound/soc/fsl/fsl_sai.c
+++ b/sound/soc/fsl/fsl_sai.c
@@ -427,7 +427,15 @@ static int fsl_sai_startup(struct snd_pcm_substream *substream,
struct snd_soc_dai *cpu_dai)
{
struct fsl_sai *sai = snd_soc_dai_get_drvdata(cpu_dai);
+ struct device *dev = &sai->pdev->dev;
u32 reg;
+ int ret;
+
+ ret = clk_prepare_enable(sai->bus_clk);
+ if (ret) {
+ dev_err(dev, "failed to enable bus clock: %d\n", ret);
+ return ret;
+ }
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
reg = FSL_SAI_TCR3;
@@ -453,6 +461,8 @@ static void fsl_sai_shutdown(struct snd_pcm_substream *substream,
regmap_update_bits(sai->regmap, reg, FSL_SAI_CR3_TRCE,
~FSL_SAI_CR3_TRCE);
+
+ clk_disable_unprepare(sai->bus_clk);
}
static const struct snd_soc_dai_ops fsl_sai_pcm_dai_ops = {
@@ -585,7 +595,8 @@ static int fsl_sai_probe(struct platform_device *pdev)
struct fsl_sai *sai;
struct resource *res;
void __iomem *base;
- int irq, ret;
+ char tmp[8];
+ int irq, ret, i;
sai = devm_kzalloc(&pdev->dev, sizeof(*sai), GFP_KERNEL);
if (!sai)
@@ -608,12 +619,35 @@ static int fsl_sai_probe(struct platform_device *pdev)
return PTR_ERR(base);
sai->regmap = devm_regmap_init_mmio_clk(&pdev->dev,
- "sai", base, &fsl_sai_regmap_config);
+ "bus", base, &fsl_sai_regmap_config);
+
+ /* Compatible with old DTB cases */
+ if (IS_ERR(sai->regmap))
+ sai->regmap = devm_regmap_init_mmio_clk(&pdev->dev,
+ "sai", base, &fsl_sai_regmap_config);
if (IS_ERR(sai->regmap)) {
dev_err(&pdev->dev, "regmap init failed\n");
return PTR_ERR(sai->regmap);
}
+ /* No error out for old DTB cases but only mark the clock NULL */
+ sai->bus_clk = devm_clk_get(&pdev->dev, "bus");
+ if (IS_ERR(sai->bus_clk)) {
+ dev_err(&pdev->dev, "failed to get bus clock: %ld\n",
+ PTR_ERR(sai->bus_clk));
+ sai->bus_clk = NULL;
+ }
+
+ for (i = 0; i < FSL_SAI_MCLK_MAX; i++) {
+ sprintf(tmp, "mclk%d", i + 1);
+ sai->mclk_clk[i] = devm_clk_get(&pdev->dev, tmp);
+ if (IS_ERR(sai->mclk_clk[i])) {
+ dev_err(&pdev->dev, "failed to get mclk%d clock: %ld\n",
+ i + 1, PTR_ERR(sai->mclk_clk[i]));
+ sai->mclk_clk[i] = NULL;
+ }
+ }
+
irq = platform_get_irq(pdev, 0);
if (irq < 0) {
dev_err(&pdev->dev, "no irq for node %s\n", np->full_name);