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

Commit 4f56cde1 authored by Kuninori Morimoto's avatar Kuninori Morimoto Committed by Mark Brown
Browse files

ASoC: sh: fsi: add fsi_set_master_clk



Current FSI driver is using set_rate call back function which is for
master mode.
By this patch, it is used from fsi_set_master_clk.
This patch is preparation of cleanup suspend/resume patch.

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 0ffe296a
Loading
Loading
Loading
Loading
+87 −77
Original line number Diff line number Diff line
@@ -558,6 +558,82 @@ static void fsi_spdif_clk_ctrl(struct fsi_priv *fsi, int enable)
/*
 *		clock function
 */
static int fsi_set_master_clk(struct device *dev, struct fsi_priv *fsi,
			      long rate, int enable)
{
	struct fsi_master *master = fsi_get_master(fsi);
	set_rate_func set_rate = fsi_get_info_set_rate(master);
	int fsi_ver = master->core->ver;
	int ret;

	ret = set_rate(dev, fsi_is_port_a(fsi), rate, enable);
	if (ret < 0) /* error */
		return ret;

	if (!enable)
		return 0;

	if (ret > 0) {
		u32 data = 0;

		switch (ret & SH_FSI_ACKMD_MASK) {
		default:
			/* FALL THROUGH */
		case SH_FSI_ACKMD_512:
			data |= (0x0 << 12);
			break;
		case SH_FSI_ACKMD_256:
			data |= (0x1 << 12);
			break;
		case SH_FSI_ACKMD_128:
			data |= (0x2 << 12);
			break;
		case SH_FSI_ACKMD_64:
			data |= (0x3 << 12);
			break;
		case SH_FSI_ACKMD_32:
			if (fsi_ver < 2)
				dev_err(dev, "unsupported ACKMD\n");
			else
				data |= (0x4 << 12);
			break;
		}

		switch (ret & SH_FSI_BPFMD_MASK) {
		default:
			/* FALL THROUGH */
		case SH_FSI_BPFMD_32:
			data |= (0x0 << 8);
			break;
		case SH_FSI_BPFMD_64:
			data |= (0x1 << 8);
			break;
		case SH_FSI_BPFMD_128:
			data |= (0x2 << 8);
			break;
		case SH_FSI_BPFMD_256:
			data |= (0x3 << 8);
			break;
		case SH_FSI_BPFMD_512:
			data |= (0x4 << 8);
			break;
		case SH_FSI_BPFMD_16:
			if (fsi_ver < 2)
				dev_err(dev, "unsupported ACKMD\n");
			else
				data |= (0x7 << 8);
			break;
		}

		fsi_reg_mask_set(fsi, CKG1, (ACKMD_MASK | BPFMD_MASK) , data);
		udelay(10);
		ret = 0;
	}

	return ret;

}

#define fsi_module_init(m, d)	__fsi_module_clk_ctrl(m, d, 1)
#define fsi_module_kill(m, d)	__fsi_module_clk_ctrl(m, d, 0)
static void __fsi_module_clk_ctrl(struct fsi_master *master,
@@ -826,13 +902,11 @@ static void fsi_dai_shutdown(struct snd_pcm_substream *substream,
{
	struct fsi_priv *fsi = fsi_get_priv(substream);
	int is_play = fsi_is_play(substream);
	struct fsi_master *master = fsi_get_master(fsi);
	set_rate_func set_rate = fsi_get_info_set_rate(master);

	fsi_irq_disable(fsi, is_play);

	if (fsi_is_clk_master(fsi))
		set_rate(dai->dev, fsi_is_port_a(fsi), fsi->rate, 0);
		fsi_set_master_clk(dai->dev, fsi, fsi->rate, 0);

	fsi->rate = 0;

@@ -960,79 +1034,19 @@ static int fsi_dai_hw_params(struct snd_pcm_substream *substream,
			     struct snd_soc_dai *dai)
{
	struct fsi_priv *fsi = fsi_get_priv(substream);
	struct fsi_master *master = fsi_get_master(fsi);
	set_rate_func set_rate = fsi_get_info_set_rate(master);
	int fsi_ver = master->core->ver;
	long rate = params_rate(params);
	int ret;

	if (!fsi_is_clk_master(fsi))
		return 0;

	ret = set_rate(dai->dev, fsi_is_port_a(fsi), rate, 1);
	if (ret < 0) /* error */
	ret = fsi_set_master_clk(dai->dev, fsi, rate, 1);
	if (ret < 0)
		return ret;

	fsi->rate = rate;
	if (ret > 0) {
		u32 data = 0;

		switch (ret & SH_FSI_ACKMD_MASK) {
		default:
			/* FALL THROUGH */
		case SH_FSI_ACKMD_512:
			data |= (0x0 << 12);
			break;
		case SH_FSI_ACKMD_256:
			data |= (0x1 << 12);
			break;
		case SH_FSI_ACKMD_128:
			data |= (0x2 << 12);
			break;
		case SH_FSI_ACKMD_64:
			data |= (0x3 << 12);
			break;
		case SH_FSI_ACKMD_32:
			if (fsi_ver < 2)
				dev_err(dai->dev, "unsupported ACKMD\n");
			else
				data |= (0x4 << 12);
			break;
		}

		switch (ret & SH_FSI_BPFMD_MASK) {
		default:
			/* FALL THROUGH */
		case SH_FSI_BPFMD_32:
			data |= (0x0 << 8);
			break;
		case SH_FSI_BPFMD_64:
			data |= (0x1 << 8);
			break;
		case SH_FSI_BPFMD_128:
			data |= (0x2 << 8);
			break;
		case SH_FSI_BPFMD_256:
			data |= (0x3 << 8);
			break;
		case SH_FSI_BPFMD_512:
			data |= (0x4 << 8);
			break;
		case SH_FSI_BPFMD_16:
			if (fsi_ver < 2)
				dev_err(dai->dev, "unsupported ACKMD\n");
			else
				data |= (0x7 << 8);
			break;
		}

		fsi_reg_mask_set(fsi, CKG1, (ACKMD_MASK | BPFMD_MASK) , data);
		udelay(10);
		ret = 0;
	}

	return ret;

}

static struct snd_soc_dai_ops fsi_dai_ops = {
@@ -1301,8 +1315,7 @@ static int fsi_remove(struct platform_device *pdev)
}

static void __fsi_suspend(struct fsi_priv *fsi,
			  struct device *dev,
			  set_rate_func set_rate)
			  struct device *dev)
{
	fsi->saved_do_fmt	= fsi_reg_read(fsi, DO_FMT);
	fsi->saved_di_fmt	= fsi_reg_read(fsi, DI_FMT);
@@ -1311,12 +1324,11 @@ static void __fsi_suspend(struct fsi_priv *fsi,
	fsi->saved_out_sel	= fsi_reg_read(fsi, OUT_SEL);

	if (fsi_is_clk_master(fsi))
		set_rate(dev, fsi_is_port_a(fsi), fsi->rate, 0);
		fsi_set_master_clk(dev, fsi, fsi->rate, 0);
}

static void __fsi_resume(struct fsi_priv *fsi,
			 struct device *dev,
			 set_rate_func set_rate)
			 struct device *dev)
{
	fsi_reg_write(fsi, DO_FMT,	fsi->saved_do_fmt);
	fsi_reg_write(fsi, DI_FMT,	fsi->saved_di_fmt);
@@ -1325,18 +1337,17 @@ static void __fsi_resume(struct fsi_priv *fsi,
	fsi_reg_write(fsi, OUT_SEL,	fsi->saved_out_sel);

	if (fsi_is_clk_master(fsi))
		set_rate(dev, fsi_is_port_a(fsi), fsi->rate, 1);
		fsi_set_master_clk(dev, fsi, fsi->rate, 1);
}

static int fsi_suspend(struct device *dev)
{
	struct fsi_master *master = dev_get_drvdata(dev);
	set_rate_func set_rate = fsi_get_info_set_rate(master);

	pm_runtime_get_sync(dev);

	__fsi_suspend(&master->fsia, dev, set_rate);
	__fsi_suspend(&master->fsib, dev, set_rate);
	__fsi_suspend(&master->fsia, dev);
	__fsi_suspend(&master->fsib, dev);

	master->saved_a_mclk	= fsi_core_read(master, a_mclk);
	master->saved_b_mclk	= fsi_core_read(master, b_mclk);
@@ -1355,7 +1366,6 @@ static int fsi_suspend(struct device *dev)
static int fsi_resume(struct device *dev)
{
	struct fsi_master *master = dev_get_drvdata(dev);
	set_rate_func set_rate = fsi_get_info_set_rate(master);

	pm_runtime_get_sync(dev);

@@ -1368,8 +1378,8 @@ static int fsi_resume(struct device *dev)
	fsi_core_mask_set(master, iemsk, 0xffff, master->saved_iemsk);
	fsi_core_mask_set(master, imsk, 0xffff, master->saved_imsk);

	__fsi_resume(&master->fsia, dev, set_rate);
	__fsi_resume(&master->fsib, dev, set_rate);
	__fsi_resume(&master->fsia, dev);
	__fsi_resume(&master->fsib, dev);

	pm_runtime_put_sync(dev);