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

Commit 919567d9 authored by Kuninori Morimoto's avatar Kuninori Morimoto Committed by Mark Brown
Browse files

ASoC: rsnd: make sure SSI parent/child uses same number of sound channel.



SSI parent/child need to use same number of sound data channel
if these are sharing clock/ws pin. this patch makes it sure.

Signed-off-by: default avatarKuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Signed-off-by: default avatarMark Brown <broonie@kernel.org>
parent 8c5c79a1
Loading
Loading
Loading
Loading
+34 −0
Original line number Original line Diff line number Diff line
@@ -66,6 +66,7 @@ struct rsnd_ssi {


	u32 cr_own;
	u32 cr_own;
	u32 cr_clk;
	u32 cr_clk;
	int chan;
	int err;
	int err;
	unsigned int usrcnt;
	unsigned int usrcnt;
};
};
@@ -264,6 +265,8 @@ static void rsnd_ssi_hw_stop(struct rsnd_ssi *ssi)
		}
		}


		rsnd_mod_hw_stop(&ssi->mod);
		rsnd_mod_hw_stop(&ssi->mod);

		ssi->chan = 0;
	}
	}


	dev_dbg(dev, "%s[%d] hw stopped\n",
	dev_dbg(dev, "%s[%d] hw stopped\n",
@@ -340,6 +343,35 @@ static int rsnd_ssi_quit(struct rsnd_mod *mod,
	return 0;
	return 0;
}
}


static int rsnd_ssi_hw_params(struct rsnd_mod *mod,
			      struct snd_pcm_substream *substream,
			      struct snd_pcm_hw_params *params)
{
	struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod);
	struct rsnd_ssi *ssi_parent = rsnd_ssi_parent(ssi);
	int chan = params_channels(params);

	/*
	 * Already working.
	 * It will happen if SSI has parent/child connection.
	 */
	if (ssi->usrcnt) {
		/*
		 * it is error if child <-> parent SSI uses
		 * different channels.
		 */
		if (ssi->chan != chan)
			return -EIO;
	}

	/* It will be removed on rsnd_ssi_hw_stop */
	ssi->chan = chan;
	if (ssi_parent)
		return rsnd_ssi_hw_params(&ssi_parent->mod, substream, params);

	return 0;
}

static void rsnd_ssi_record_error(struct rsnd_ssi *ssi, u32 status)
static void rsnd_ssi_record_error(struct rsnd_ssi *ssi, u32 status)
{
{
	/* under/over flow error */
	/* under/over flow error */
@@ -460,6 +492,7 @@ static struct rsnd_mod_ops rsnd_ssi_pio_ops = {
	.quit	= rsnd_ssi_quit,
	.quit	= rsnd_ssi_quit,
	.start	= rsnd_ssi_start,
	.start	= rsnd_ssi_start,
	.stop	= rsnd_ssi_stop,
	.stop	= rsnd_ssi_stop,
	.hw_params = rsnd_ssi_hw_params,
};
};


static int rsnd_ssi_dma_probe(struct rsnd_mod *mod,
static int rsnd_ssi_dma_probe(struct rsnd_mod *mod,
@@ -569,6 +602,7 @@ static struct rsnd_mod_ops rsnd_ssi_dma_ops = {
	.start	= rsnd_ssi_dma_start,
	.start	= rsnd_ssi_dma_start,
	.stop	= rsnd_ssi_dma_stop,
	.stop	= rsnd_ssi_dma_stop,
	.fallback = rsnd_ssi_fallback,
	.fallback = rsnd_ssi_fallback,
	.hw_params = rsnd_ssi_hw_params,
};
};


int rsnd_ssi_is_dma_mode(struct rsnd_mod *mod)
int rsnd_ssi_is_dma_mode(struct rsnd_mod *mod)