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

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
...@@ -66,6 +66,7 @@ struct rsnd_ssi { ...@@ -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) ...@@ -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, ...@@ -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 = { ...@@ -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 = { ...@@ -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)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment