ASoC: sh: fsi: remove pm_runtime from fsi_dai_set_fmt.
authorKuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Mon, 23 May 2011 11:46:07 +0000 (20:46 +0900)
committerMark Brown <broonie@opensource.wolfsonmicro.com>
Tue, 24 May 2011 10:41:48 +0000 (18:41 +0800)
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>
sound/soc/sh/fsi.c

index fec1a7dcf90bc8aec40fb9fb7794e5a1ca77d835..a1081c755239e5670f41941a580195c9d007309f 100644 (file)
@@ -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;
 }