diff options
Diffstat (limited to 'sound/soc/cirrus/ep93xx-i2s.c')
-rw-r--r-- | sound/soc/cirrus/ep93xx-i2s.c | 64 |
1 files changed, 42 insertions, 22 deletions
diff --git a/sound/soc/cirrus/ep93xx-i2s.c b/sound/soc/cirrus/ep93xx-i2s.c index 371708b17c09..522de4b80293 100644 --- a/sound/soc/cirrus/ep93xx-i2s.c +++ b/sound/soc/cirrus/ep93xx-i2s.c @@ -15,6 +15,7 @@ #include <linux/slab.h> #include <linux/clk.h> #include <linux/io.h> +#include <linux/of.h> #include <sound/core.h> #include <sound/dmaengine_pcm.h> @@ -111,9 +112,9 @@ static void ep93xx_i2s_enable(struct ep93xx_i2s_info *info, int stream) if ((ep93xx_i2s_read_reg(info, EP93XX_I2S_TX0EN) & 0x1) == 0 && (ep93xx_i2s_read_reg(info, EP93XX_I2S_RX0EN) & 0x1) == 0) { /* Enable clocks */ - clk_enable(info->mclk); - clk_enable(info->sclk); - clk_enable(info->lrclk); + clk_prepare_enable(info->mclk); + clk_prepare_enable(info->sclk); + clk_prepare_enable(info->lrclk); /* Enable i2s */ ep93xx_i2s_write_reg(info, EP93XX_I2S_GLCTRL, 1); @@ -156,9 +157,9 @@ static void ep93xx_i2s_disable(struct ep93xx_i2s_info *info, int stream) ep93xx_i2s_write_reg(info, EP93XX_I2S_GLCTRL, 0); /* Disable clocks */ - clk_disable(info->lrclk); - clk_disable(info->sclk); - clk_disable(info->mclk); + clk_disable_unprepare(info->lrclk); + clk_disable_unprepare(info->sclk); + clk_disable_unprepare(info->mclk); } } @@ -202,8 +203,18 @@ static int ep93xx_i2s_dai_probe(struct snd_soc_dai *dai) info->dma_params_rx.filter_data = &ep93xx_i2s_dma_data[SNDRV_PCM_STREAM_CAPTURE]; - dai->playback_dma_data = &info->dma_params_tx; - dai->capture_dma_data = &info->dma_params_rx; + snd_soc_dai_init_dma_data(dai, &info->dma_params_tx, + &info->dma_params_rx); + + return 0; +} + +static int ep93xx_i2s_startup(struct snd_pcm_substream *substream, + struct snd_soc_dai *dai) +{ + struct ep93xx_i2s_info *info = snd_soc_dai_get_drvdata(dai); + + ep93xx_i2s_enable(info, substream->stream); return 0; } @@ -245,14 +256,14 @@ static int ep93xx_i2s_set_dai_fmt(struct snd_soc_dai *cpu_dai, return -EINVAL; } - switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { - case SND_SOC_DAIFMT_CBS_CFS: - /* CPU is master */ + switch (fmt & SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK) { + case SND_SOC_DAIFMT_BP_FP: + /* CPU is provider */ clk_cfg |= EP93XX_I2S_CLKCFG_MASTER; break; - case SND_SOC_DAIFMT_CBM_CFM: - /* Codec is master */ + case SND_SOC_DAIFMT_BC_FC: + /* Codec is provider */ clk_cfg &= ~EP93XX_I2S_CLKCFG_MASTER; break; @@ -348,7 +359,6 @@ static int ep93xx_i2s_hw_params(struct snd_pcm_substream *substream, if (err) return err; - ep93xx_i2s_enable(info, substream->stream); return 0; } @@ -359,6 +369,8 @@ static int ep93xx_i2s_set_sysclk(struct snd_soc_dai *cpu_dai, int clk_id, if (dir == SND_SOC_CLOCK_IN || clk_id != 0) return -EINVAL; + if (!freq) + return 0; return clk_set_rate(info->mclk, freq); } @@ -395,6 +407,8 @@ static int ep93xx_i2s_resume(struct snd_soc_component *component) #endif static const struct snd_soc_dai_ops ep93xx_i2s_dai_ops = { + .probe = ep93xx_i2s_dai_probe, + .startup = ep93xx_i2s_startup, .shutdown = ep93xx_i2s_shutdown, .hw_params = ep93xx_i2s_hw_params, .set_sysclk = ep93xx_i2s_set_sysclk, @@ -404,8 +418,7 @@ static const struct snd_soc_dai_ops ep93xx_i2s_dai_ops = { #define EP93XX_I2S_FORMATS (SNDRV_PCM_FMTBIT_S32_LE) static struct snd_soc_dai_driver ep93xx_i2s_dai = { - .symmetric_rates= 1, - .probe = ep93xx_i2s_dai_probe, + .symmetric_rate = 1, .playback = { .channels_min = 2, .channels_max = 2, @@ -422,9 +435,10 @@ static struct snd_soc_dai_driver ep93xx_i2s_dai = { }; static const struct snd_soc_component_driver ep93xx_i2s_component = { - .name = "ep93xx-i2s", - .suspend = ep93xx_i2s_suspend, - .resume = ep93xx_i2s_resume, + .name = "ep93xx-i2s", + .suspend = ep93xx_i2s_suspend, + .resume = ep93xx_i2s_resume, + .legacy_dai_naming = 1, }; static int ep93xx_i2s_probe(struct platform_device *pdev) @@ -492,21 +506,27 @@ fail: return err; } -static int ep93xx_i2s_remove(struct platform_device *pdev) +static void ep93xx_i2s_remove(struct platform_device *pdev) { struct ep93xx_i2s_info *info = dev_get_drvdata(&pdev->dev); clk_put(info->lrclk); clk_put(info->sclk); clk_put(info->mclk); - return 0; } +static const struct of_device_id ep93xx_i2s_of_ids[] = { + { .compatible = "cirrus,ep9301-i2s" }, + {} +}; +MODULE_DEVICE_TABLE(of, ep93xx_i2s_of_ids); + static struct platform_driver ep93xx_i2s_driver = { .probe = ep93xx_i2s_probe, - .remove = ep93xx_i2s_remove, + .remove_new = ep93xx_i2s_remove, .driver = { .name = "ep93xx-i2s", + .of_match_table = ep93xx_i2s_of_ids, }, }; |