Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 9478e0b6 authored by Kuninori Morimoto's avatar Kuninori Morimoto Committed by Mark Brown
Browse files

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: default avatarKuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Acked-by: default avatarLiam Girdwood <lrg@ti.com>
Signed-off-by: default avatarMark Brown <broonie@opensource.wolfsonmicro.com>
parent 2e651baf
Loading
Loading
Loading
Loading
+32 −20
Original line number Original line Diff line number Diff line
@@ -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;
}
}