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>
This commit is contained in:
Kuninori Morimoto 2011-05-23 20:46:07 +09:00 committed by Mark Brown
parent 2e651bafa9
commit 9478e0b60f

View File

@ -176,8 +176,12 @@ struct fsi_priv {
struct fsi_stream playback; struct fsi_stream playback;
struct fsi_stream capture; struct fsi_stream capture;
u32 do_fmt;
u32 di_fmt;
int chan_num:16; int chan_num:16;
int clk_master:1; int clk_master:1;
int spdif:1;
long rate; long rate;
@ -298,6 +302,11 @@ static int fsi_is_port_a(struct fsi_priv *fsi)
return fsi->master->base == fsi->base; 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) static struct snd_soc_dai *fsi_get_dai(struct snd_pcm_substream *substream)
{ {
struct snd_soc_pcm_runtime *rtd = substream->private_data; 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); struct fsi_priv *fsi = fsi_get_priv(substream);
u32 flags = fsi_get_info_flags(fsi); u32 flags = fsi_get_info_flags(fsi);
u32 data; u32 data = 0;
int is_play = fsi_is_play(substream); int is_play = fsi_is_play(substream);
pm_runtime_get_sync(dai->dev); 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) */ /* clock inversion (CKG2) */
data = 0; data = 0;
@ -912,6 +926,16 @@ static int fsi_dai_startup(struct snd_pcm_substream *substream,
fsi_reg_write(fsi, CKG2, data); 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 */ /* irq clear */
fsi_irq_disable(fsi, is_play); fsi_irq_disable(fsi, is_play);
fsi_irq_clear_status(fsi); fsi_irq_clear_status(fsi);
@ -974,8 +998,8 @@ static int fsi_set_fmt_dai(struct fsi_priv *fsi, unsigned int fmt)
return -EINVAL; return -EINVAL;
} }
fsi_reg_write(fsi, DO_FMT, data); fsi->do_fmt = data;
fsi_reg_write(fsi, DI_FMT, data); fsi->di_fmt = data;
return 0; 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; data = CR_BWS_16 | CR_DTMD_SPDIF_PCM | CR_PCM;
fsi->chan_num = 2; fsi->chan_num = 2;
fsi_spdif_clk_ctrl(fsi, 1); fsi->spdif = 1;
fsi_reg_mask_set(fsi, OUT_SEL, DMMD, DMMD);
fsi_reg_write(fsi, DO_FMT, data); fsi->do_fmt = data;
fsi_reg_write(fsi, DI_FMT, data); fsi->di_fmt = data;
return 0; 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); struct fsi_master *master = fsi_get_master(fsi);
set_rate_func set_rate = fsi_get_info_set_rate(master); set_rate_func set_rate = fsi_get_info_set_rate(master);
u32 flags = fsi_get_info_flags(fsi); u32 flags = fsi_get_info_flags(fsi);
u32 data = 0;
int ret; int ret;
pm_runtime_get_sync(dai->dev);
/* set master/slave audio interface */ /* set master/slave audio interface */
switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
case SND_SOC_DAIFMT_CBM_CFM: case SND_SOC_DAIFMT_CBM_CFM:
data = DIMD | DOMD;
fsi->clk_master = 1; fsi->clk_master = 1;
break; break;
case SND_SOC_DAIFMT_CBS_CFS: case SND_SOC_DAIFMT_CBS_CFS:
break; break;
default: default:
ret = -EINVAL; return -EINVAL;
goto set_fmt_exit;
} }
if (fsi_is_clk_master(fsi) && !set_rate) { if (fsi_is_clk_master(fsi) && !set_rate) {
dev_err(dai->dev, "platform doesn't have set_rate\n"); dev_err(dai->dev, "platform doesn't have set_rate\n");
ret = -EINVAL; return -EINVAL;
goto set_fmt_exit;
} }
fsi_reg_mask_set(fsi, CKG1, (DIMD | DOMD), data);
/* set format */ /* set format */
switch (flags & SH_FSI_FMT_MASK) { switch (flags & SH_FSI_FMT_MASK) {
case SH_FSI_FMT_DAI: 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; ret = -EINVAL;
} }
set_fmt_exit:
pm_runtime_put_sync(dai->dev);
return ret; return ret;
} }