diff options
Diffstat (limited to 'sound/soc/pxa/pxa2xx-i2s.c')
-rw-r--r-- | sound/soc/pxa/pxa2xx-i2s.c | 89 |
1 files changed, 44 insertions, 45 deletions
diff --git a/sound/soc/pxa/pxa2xx-i2s.c b/sound/soc/pxa/pxa2xx-i2s.c index c1a5275721e..3b473b200a8 100644 --- a/sound/soc/pxa/pxa2xx-i2s.c +++ b/sound/soc/pxa/pxa2xx-i2s.c @@ -80,6 +80,7 @@ struct pxa_i2s_port { }; static struct pxa_i2s_port pxa_i2s; static struct clk *clk_i2s; +static int clk_ena = 0; static struct pxa2xx_pcm_dma_params pxa2xx_i2s_pcm_stereo_out = { .name = "I2S PCM Stereo out", @@ -101,7 +102,7 @@ static int pxa2xx_i2s_startup(struct snd_pcm_substream *substream, struct snd_soc_dai *dai) { struct snd_soc_pcm_runtime *rtd = substream->private_data; - struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai; + struct snd_soc_dai *cpu_dai = rtd->cpu_dai; if (IS_ERR(clk_i2s)) return PTR_ERR(clk_i2s); @@ -162,13 +163,11 @@ static int pxa2xx_i2s_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params, struct snd_soc_dai *dai) { - struct snd_soc_pcm_runtime *rtd = substream->private_data; - struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai; struct pxa2xx_pcm_dma_params *dma_data; BUG_ON(IS_ERR(clk_i2s)); clk_enable(clk_i2s); - dai->private_data = dai; + clk_ena = 1; pxa_i2s_wait(); if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) @@ -176,7 +175,7 @@ static int pxa2xx_i2s_hw_params(struct snd_pcm_substream *substream, else dma_data = &pxa2xx_i2s_pcm_stereo_in; - snd_soc_dai_set_dma_data(cpu_dai, substream, dma_data); + snd_soc_dai_set_dma_data(dai, substream, dma_data); /* is port used by another stream */ if (!(SACR0 & SACR0_ENB)) { @@ -259,9 +258,9 @@ static void pxa2xx_i2s_shutdown(struct snd_pcm_substream *substream, if ((SACR1 & (SACR1_DREC | SACR1_DRPL)) == (SACR1_DREC | SACR1_DRPL)) { SACR0 &= ~SACR0_ENB; pxa_i2s_wait(); - if (dai->private_data != NULL) { + if (clk_ena) { clk_disable(clk_i2s); - dai->private_data = NULL; + clk_ena = 0; } } } @@ -300,6 +299,35 @@ static int pxa2xx_i2s_resume(struct snd_soc_dai *dai) #define pxa2xx_i2s_resume NULL #endif +static int pxa2xx_i2s_probe(struct snd_soc_dai *dai) +{ + clk_i2s = clk_get(dai->dev, "I2SCLK"); + if (IS_ERR(clk_i2s)) + return PTR_ERR(clk_i2s); + + /* + * PXA Developer's Manual: + * If SACR0[ENB] is toggled in the middle of a normal operation, + * the SACR0[RST] bit must also be set and cleared to reset all + * I2S controller registers. + */ + SACR0 = SACR0_RST; + SACR0 = 0; + /* Make sure RPL and REC are disabled */ + SACR1 = SACR1_DRPL | SACR1_DREC; + /* Along with FIFO servicing */ + SAIMR &= ~(SAIMR_RFS | SAIMR_TFS); + + return 0; +} + +static int pxa2xx_i2s_remove(struct snd_soc_dai *dai) +{ + clk_put(clk_i2s); + clk_i2s = ERR_PTR(-ENOENT); + return 0; +} + #define PXA2XX_I2S_RATES (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 |\ SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_22050 | SNDRV_PCM_RATE_44100 | \ SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_96000) @@ -313,9 +341,9 @@ static struct snd_soc_dai_ops pxa_i2s_dai_ops = { .set_sysclk = pxa2xx_i2s_set_dai_sysclk, }; -struct snd_soc_dai pxa_i2s_dai = { - .name = "pxa2xx-i2s", - .id = 0, +static struct snd_soc_dai_driver pxa_i2s_dai = { + .probe = pxa2xx_i2s_probe, + .remove = pxa2xx_i2s_remove, .suspend = pxa2xx_i2s_suspend, .resume = pxa2xx_i2s_resume, .playback = { @@ -332,49 +360,20 @@ struct snd_soc_dai pxa_i2s_dai = { .symmetric_rates = 1, }; -EXPORT_SYMBOL_GPL(pxa_i2s_dai); - -static int pxa2xx_i2s_probe(struct platform_device *dev) +static int pxa2xx_i2s_drv_probe(struct platform_device *pdev) { - int ret; - - clk_i2s = clk_get(&dev->dev, "I2SCLK"); - if (IS_ERR(clk_i2s)) - return PTR_ERR(clk_i2s); - - pxa_i2s_dai.dev = &dev->dev; - pxa_i2s_dai.private_data = NULL; - ret = snd_soc_register_dai(&pxa_i2s_dai); - if (ret != 0) - clk_put(clk_i2s); - - /* - * PXA Developer's Manual: - * If SACR0[ENB] is toggled in the middle of a normal operation, - * the SACR0[RST] bit must also be set and cleared to reset all - * I2S controller registers. - */ - SACR0 = SACR0_RST; - SACR0 = 0; - /* Make sure RPL and REC are disabled */ - SACR1 = SACR1_DRPL | SACR1_DREC; - /* Along with FIFO servicing */ - SAIMR &= ~(SAIMR_RFS | SAIMR_TFS); - - return ret; + return snd_soc_register_dai(&pdev->dev, &pxa_i2s_dai); } -static int __devexit pxa2xx_i2s_remove(struct platform_device *dev) +static int __devexit pxa2xx_i2s_drv_remove(struct platform_device *pdev) { - snd_soc_unregister_dai(&pxa_i2s_dai); - clk_put(clk_i2s); - clk_i2s = ERR_PTR(-ENOENT); + snd_soc_unregister_dai(&pdev->dev); return 0; } static struct platform_driver pxa2xx_i2s_driver = { - .probe = pxa2xx_i2s_probe, - .remove = __devexit_p(pxa2xx_i2s_remove), + .probe = pxa2xx_i2s_drv_probe, + .remove = __devexit_p(pxa2xx_i2s_drv_remove), .driver = { .name = "pxa2xx-i2s", |