| From 387c7967931d638fd30d2a63ec171e42c71477bd Mon Sep 17 00:00:00 2001 |
| From: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com> |
| Date: Mon, 23 May 2011 20:46:07 +0900 |
| Subject: ASoC: sh: fsi: remove pm_runtime from fsi_dai_set_fmt. |
| |
| pm_runtime_get/put_sync were used to access FSI register in fsi_dai_set_fmt |
| which is called when ALSA probe. |
| But this register value will disappear after pm_runtime_put_sync |
| if platform is supporting RuntimePM. |
| To solve this issue, this patch adds new variable for format, |
| and remove pm_runtime_get/put_sync from fsi_dai_set_fmt. |
| |
| Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com> |
| Acked-by: Liam Girdwood <lrg@ti.com> |
| Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com> |
| (cherry picked from commit 9478e0b60fb4a7adde72d4a86b826d396b607a61) |
| |
| Signed-off-by: Simon Horman <horms@verge.net.au> |
| --- |
| sound/soc/sh/fsi.c | 52 ++++++++++++++++++++++++++++++++-------------------- |
| 1 file changed, 32 insertions(+), 20 deletions(-) |
| |
| diff --git a/sound/soc/sh/fsi.c b/sound/soc/sh/fsi.c |
| index 98c8296..0a09ea2 100644 |
| --- a/sound/soc/sh/fsi.c |
| +++ b/sound/soc/sh/fsi.c |
| @@ -176,8 +176,12 @@ struct fsi_priv { |
| struct fsi_stream playback; |
| struct fsi_stream capture; |
| |
| + u32 do_fmt; |
| + u32 di_fmt; |
| + |
| int chan_num:16; |
| int clk_master:1; |
| + int spdif:1; |
| |
| long rate; |
| |
| @@ -298,6 +302,11 @@ static int fsi_is_port_a(struct fsi_priv *fsi) |
| return fsi->master->base == fsi->base; |
| } |
| |
| +static int fsi_is_spdif(struct fsi_priv *fsi) |
| +{ |
| + return fsi->spdif; |
| +} |
| + |
| static struct snd_soc_dai *fsi_get_dai(struct snd_pcm_substream *substream) |
| { |
| struct snd_soc_pcm_runtime *rtd = substream->private_data; |
| @@ -893,11 +902,16 @@ static int fsi_dai_startup(struct snd_pcm_substream *substream, |
| { |
| struct fsi_priv *fsi = fsi_get_priv(substream); |
| u32 flags = fsi_get_info_flags(fsi); |
| - u32 data; |
| + u32 data = 0; |
| int is_play = fsi_is_play(substream); |
| |
| pm_runtime_get_sync(dai->dev); |
| |
| + /* clock setting */ |
| + if (fsi_is_clk_master(fsi)) |
| + data = DIMD | DOMD; |
| + |
| + fsi_reg_mask_set(fsi, CKG1, (DIMD | DOMD), data); |
| |
| /* clock inversion (CKG2) */ |
| data = 0; |
| @@ -912,6 +926,16 @@ static int fsi_dai_startup(struct snd_pcm_substream *substream, |
| |
| fsi_reg_write(fsi, CKG2, data); |
| |
| + /* set format */ |
| + fsi_reg_write(fsi, DO_FMT, fsi->do_fmt); |
| + fsi_reg_write(fsi, DI_FMT, fsi->di_fmt); |
| + |
| + /* spdif ? */ |
| + if (fsi_is_spdif(fsi)) { |
| + fsi_spdif_clk_ctrl(fsi, 1); |
| + fsi_reg_mask_set(fsi, OUT_SEL, DMMD, DMMD); |
| + } |
| + |
| /* irq clear */ |
| fsi_irq_disable(fsi, is_play); |
| fsi_irq_clear_status(fsi); |
| @@ -974,8 +998,8 @@ static int fsi_set_fmt_dai(struct fsi_priv *fsi, unsigned int fmt) |
| return -EINVAL; |
| } |
| |
| - fsi_reg_write(fsi, DO_FMT, data); |
| - fsi_reg_write(fsi, DI_FMT, data); |
| + fsi->do_fmt = data; |
| + fsi->di_fmt = data; |
| |
| return 0; |
| } |
| @@ -990,11 +1014,10 @@ static int fsi_set_fmt_spdif(struct fsi_priv *fsi) |
| |
| data = CR_BWS_16 | CR_DTMD_SPDIF_PCM | CR_PCM; |
| fsi->chan_num = 2; |
| - fsi_spdif_clk_ctrl(fsi, 1); |
| - fsi_reg_mask_set(fsi, OUT_SEL, DMMD, DMMD); |
| + fsi->spdif = 1; |
| |
| - fsi_reg_write(fsi, DO_FMT, data); |
| - fsi_reg_write(fsi, DI_FMT, data); |
| + fsi->do_fmt = data; |
| + fsi->di_fmt = data; |
| |
| return 0; |
| } |
| @@ -1005,32 +1028,24 @@ static int fsi_dai_set_fmt(struct snd_soc_dai *dai, unsigned int fmt) |
| struct fsi_master *master = fsi_get_master(fsi); |
| set_rate_func set_rate = fsi_get_info_set_rate(master); |
| u32 flags = fsi_get_info_flags(fsi); |
| - u32 data = 0; |
| int ret; |
| |
| - pm_runtime_get_sync(dai->dev); |
| - |
| /* set master/slave audio interface */ |
| switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { |
| case SND_SOC_DAIFMT_CBM_CFM: |
| - data = DIMD | DOMD; |
| fsi->clk_master = 1; |
| break; |
| case SND_SOC_DAIFMT_CBS_CFS: |
| break; |
| default: |
| - ret = -EINVAL; |
| - goto set_fmt_exit; |
| + return -EINVAL; |
| } |
| |
| if (fsi_is_clk_master(fsi) && !set_rate) { |
| dev_err(dai->dev, "platform doesn't have set_rate\n"); |
| - ret = -EINVAL; |
| - goto set_fmt_exit; |
| + return -EINVAL; |
| } |
| |
| - fsi_reg_mask_set(fsi, CKG1, (DIMD | DOMD), data); |
| - |
| /* set format */ |
| switch (flags & SH_FSI_FMT_MASK) { |
| case SH_FSI_FMT_DAI: |
| @@ -1043,9 +1058,6 @@ static int fsi_dai_set_fmt(struct snd_soc_dai *dai, unsigned int fmt) |
| ret = -EINVAL; |
| } |
| |
| -set_fmt_exit: |
| - pm_runtime_put_sync(dai->dev); |
| - |
| return ret; |
| } |
| |
| -- |
| 1.7.10.2.565.gbd578b5 |
| |