aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKuninori Morimoto <kuninori.morimoto.gx@renesas.com>2015-04-10 04:50:30 -0400
committerMark Brown <broonie@kernel.org>2015-04-27 15:57:38 -0400
commit919567d914b3c134e60c01db72a03a0adc5f41b9 (patch)
treef46c5e4d47afae9e9f35dffd0dadc23577e39548
parent8c5c79a1cd51ce1b4fec8bbaecd17d599478bd27 (diff)
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: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com> Signed-off-by: Mark Brown <broonie@kernel.org>
-rw-r--r--sound/soc/sh/rcar/ssi.c34
1 files changed, 34 insertions, 0 deletions
diff --git a/sound/soc/sh/rcar/ssi.c b/sound/soc/sh/rcar/ssi.c
index 2ef48a44c4ab..5b89723c3206 100644
--- a/sound/soc/sh/rcar/ssi.c
+++ b/sound/soc/sh/rcar/ssi.c
@@ -66,6 +66,7 @@ struct rsnd_ssi {
66 66
67 u32 cr_own; 67 u32 cr_own;
68 u32 cr_clk; 68 u32 cr_clk;
69 int chan;
69 int err; 70 int err;
70 unsigned int usrcnt; 71 unsigned int usrcnt;
71}; 72};
@@ -264,6 +265,8 @@ static void rsnd_ssi_hw_stop(struct rsnd_ssi *ssi)
264 } 265 }
265 266
266 rsnd_mod_hw_stop(&ssi->mod); 267 rsnd_mod_hw_stop(&ssi->mod);
268
269 ssi->chan = 0;
267 } 270 }
268 271
269 dev_dbg(dev, "%s[%d] hw stopped\n", 272 dev_dbg(dev, "%s[%d] hw stopped\n",
@@ -340,6 +343,35 @@ static int rsnd_ssi_quit(struct rsnd_mod *mod,
340 return 0; 343 return 0;
341} 344}
342 345
346static int rsnd_ssi_hw_params(struct rsnd_mod *mod,
347 struct snd_pcm_substream *substream,
348 struct snd_pcm_hw_params *params)
349{
350 struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod);
351 struct rsnd_ssi *ssi_parent = rsnd_ssi_parent(ssi);
352 int chan = params_channels(params);
353
354 /*
355 * Already working.
356 * It will happen if SSI has parent/child connection.
357 */
358 if (ssi->usrcnt) {
359 /*
360 * it is error if child <-> parent SSI uses
361 * different channels.
362 */
363 if (ssi->chan != chan)
364 return -EIO;
365 }
366
367 /* It will be removed on rsnd_ssi_hw_stop */
368 ssi->chan = chan;
369 if (ssi_parent)
370 return rsnd_ssi_hw_params(&ssi_parent->mod, substream, params);
371
372 return 0;
373}
374
343static void rsnd_ssi_record_error(struct rsnd_ssi *ssi, u32 status) 375static void rsnd_ssi_record_error(struct rsnd_ssi *ssi, u32 status)
344{ 376{
345 /* under/over flow error */ 377 /* under/over flow error */
@@ -460,6 +492,7 @@ static struct rsnd_mod_ops rsnd_ssi_pio_ops = {
460 .quit = rsnd_ssi_quit, 492 .quit = rsnd_ssi_quit,
461 .start = rsnd_ssi_start, 493 .start = rsnd_ssi_start,
462 .stop = rsnd_ssi_stop, 494 .stop = rsnd_ssi_stop,
495 .hw_params = rsnd_ssi_hw_params,
463}; 496};
464 497
465static int rsnd_ssi_dma_probe(struct rsnd_mod *mod, 498static int rsnd_ssi_dma_probe(struct rsnd_mod *mod,
@@ -569,6 +602,7 @@ static struct rsnd_mod_ops rsnd_ssi_dma_ops = {
569 .start = rsnd_ssi_dma_start, 602 .start = rsnd_ssi_dma_start,
570 .stop = rsnd_ssi_dma_stop, 603 .stop = rsnd_ssi_dma_stop,
571 .fallback = rsnd_ssi_fallback, 604 .fallback = rsnd_ssi_fallback,
605 .hw_params = rsnd_ssi_hw_params,
572}; 606};
573 607
574int rsnd_ssi_is_dma_mode(struct rsnd_mod *mod) 608int rsnd_ssi_is_dma_mode(struct rsnd_mod *mod)