summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKuninori Morimoto <kuninori.morimoto.gx@renesas.com>2018-10-30 03:46:05 -0400
committerMark Brown <broonie@kernel.org>2018-11-05 06:27:29 -0500
commit7e7fe06de376e9874f4399dac81d65ea9b0a9507 (patch)
treef505d56070b42b2ff118cc781a53966912ea808e
parent0900d1e64815b3b8d4d04197aa135e77317176e1 (diff)
ASoC: rsnd: move .get_status under rsnd_mod_ops
Each mod needs to have .get_status, but current driver is handling it under rsnd_mod, instead of rsnd_mod_ops. It is not any make sence. This patch moves it to rsnd_mod_ops, and tidyup its parameter order to align to other callback functions. 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/adg.c2
-rw-r--r--sound/soc/sh/rcar/cmd.c11
-rw-r--r--sound/soc/sh/rcar/core.c10
-rw-r--r--sound/soc/sh/rcar/ctu.c3
-rw-r--r--sound/soc/sh/rcar/dma.c26
-rw-r--r--sound/soc/sh/rcar/dvc.c3
-rw-r--r--sound/soc/sh/rcar/mix.c3
-rw-r--r--sound/soc/sh/rcar/rsnd.h13
-rw-r--r--sound/soc/sh/rcar/src.c24
-rw-r--r--sound/soc/sh/rcar/ssi.c124
-rw-r--r--sound/soc/sh/rcar/ssiu.c37
11 files changed, 129 insertions, 127 deletions
diff --git a/sound/soc/sh/rcar/adg.c b/sound/soc/sh/rcar/adg.c
index 28327dd2c6cb..6768a66588eb 100644
--- a/sound/soc/sh/rcar/adg.c
+++ b/sound/soc/sh/rcar/adg.c
@@ -613,7 +613,7 @@ int rsnd_adg_probe(struct rsnd_priv *priv)
613 return -ENOMEM; 613 return -ENOMEM;
614 614
615 ret = rsnd_mod_init(priv, &adg->mod, &adg_ops, 615 ret = rsnd_mod_init(priv, &adg->mod, &adg_ops,
616 NULL, NULL, 0, 0); 616 NULL, 0, 0);
617 if (ret) 617 if (ret)
618 return ret; 618 return ret;
619 619
diff --git a/sound/soc/sh/rcar/cmd.c b/sound/soc/sh/rcar/cmd.c
index cc191cd5fb82..e6bb6a9a0684 100644
--- a/sound/soc/sh/rcar/cmd.c
+++ b/sound/soc/sh/rcar/cmd.c
@@ -116,10 +116,11 @@ static int rsnd_cmd_stop(struct rsnd_mod *mod,
116} 116}
117 117
118static struct rsnd_mod_ops rsnd_cmd_ops = { 118static struct rsnd_mod_ops rsnd_cmd_ops = {
119 .name = CMD_NAME, 119 .name = CMD_NAME,
120 .init = rsnd_cmd_init, 120 .init = rsnd_cmd_init,
121 .start = rsnd_cmd_start, 121 .start = rsnd_cmd_start,
122 .stop = rsnd_cmd_stop, 122 .stop = rsnd_cmd_stop,
123 .get_status = rsnd_mod_get_status,
123}; 124};
124 125
125static struct rsnd_mod *rsnd_cmd_mod_get(struct rsnd_priv *priv, int id) 126static struct rsnd_mod *rsnd_cmd_mod_get(struct rsnd_priv *priv, int id)
@@ -162,7 +163,7 @@ int rsnd_cmd_probe(struct rsnd_priv *priv)
162 for_each_rsnd_cmd(cmd, priv, i) { 163 for_each_rsnd_cmd(cmd, priv, i) {
163 ret = rsnd_mod_init(priv, rsnd_mod_get(cmd), 164 ret = rsnd_mod_init(priv, rsnd_mod_get(cmd),
164 &rsnd_cmd_ops, NULL, 165 &rsnd_cmd_ops, NULL,
165 rsnd_mod_get_status, RSND_MOD_CMD, i); 166 RSND_MOD_CMD, i);
166 if (ret) 167 if (ret)
167 return ret; 168 return ret;
168 } 169 }
diff --git a/sound/soc/sh/rcar/core.c b/sound/soc/sh/rcar/core.c
index f930f51b686f..5373eba5d572 100644
--- a/sound/soc/sh/rcar/core.c
+++ b/sound/soc/sh/rcar/core.c
@@ -137,8 +137,8 @@ struct dma_chan *rsnd_mod_dma_req(struct rsnd_dai_stream *io,
137 return mod->ops->dma_req(io, mod); 137 return mod->ops->dma_req(io, mod);
138} 138}
139 139
140u32 *rsnd_mod_get_status(struct rsnd_dai_stream *io, 140u32 *rsnd_mod_get_status(struct rsnd_mod *mod,
141 struct rsnd_mod *mod, 141 struct rsnd_dai_stream *io,
142 enum rsnd_mod_type type) 142 enum rsnd_mod_type type)
143{ 143{
144 return &mod->status; 144 return &mod->status;
@@ -148,9 +148,6 @@ int rsnd_mod_init(struct rsnd_priv *priv,
148 struct rsnd_mod *mod, 148 struct rsnd_mod *mod,
149 struct rsnd_mod_ops *ops, 149 struct rsnd_mod_ops *ops,
150 struct clk *clk, 150 struct clk *clk,
151 u32* (*get_status)(struct rsnd_dai_stream *io,
152 struct rsnd_mod *mod,
153 enum rsnd_mod_type type),
154 enum rsnd_mod_type type, 151 enum rsnd_mod_type type,
155 int id) 152 int id)
156{ 153{
@@ -164,7 +161,6 @@ int rsnd_mod_init(struct rsnd_priv *priv,
164 mod->type = type; 161 mod->type = type;
165 mod->clk = clk; 162 mod->clk = clk;
166 mod->priv = priv; 163 mod->priv = priv;
167 mod->get_status = get_status;
168 164
169 return ret; 165 return ret;
170} 166}
@@ -472,7 +468,7 @@ static int rsnd_status_update(u32 *status,
472 enum rsnd_mod_type *types = rsnd_mod_sequence[is_play]; \ 468 enum rsnd_mod_type *types = rsnd_mod_sequence[is_play]; \
473 for_each_rsnd_mod_arrays(i, mod, io, types, RSND_MOD_MAX) { \ 469 for_each_rsnd_mod_arrays(i, mod, io, types, RSND_MOD_MAX) { \
474 int tmp = 0; \ 470 int tmp = 0; \
475 u32 *status = mod->get_status(io, mod, types[i]); \ 471 u32 *status = mod->ops->get_status(mod, io, types[i]); \
476 int func_call = rsnd_status_update(status, \ 472 int func_call = rsnd_status_update(status, \
477 __rsnd_mod_shift_##fn, \ 473 __rsnd_mod_shift_##fn, \
478 __rsnd_mod_add_##fn, \ 474 __rsnd_mod_add_##fn, \
diff --git a/sound/soc/sh/rcar/ctu.c b/sound/soc/sh/rcar/ctu.c
index ad702377a6c3..28058474075b 100644
--- a/sound/soc/sh/rcar/ctu.c
+++ b/sound/soc/sh/rcar/ctu.c
@@ -341,6 +341,7 @@ static struct rsnd_mod_ops rsnd_ctu_ops = {
341 .quit = rsnd_ctu_quit, 341 .quit = rsnd_ctu_quit,
342 .hw_params = rsnd_ctu_hw_params, 342 .hw_params = rsnd_ctu_hw_params,
343 .pcm_new = rsnd_ctu_pcm_new, 343 .pcm_new = rsnd_ctu_pcm_new,
344 .get_status = rsnd_mod_get_status,
344}; 345};
345 346
346struct rsnd_mod *rsnd_ctu_mod_get(struct rsnd_priv *priv, int id) 347struct rsnd_mod *rsnd_ctu_mod_get(struct rsnd_priv *priv, int id)
@@ -404,7 +405,7 @@ int rsnd_ctu_probe(struct rsnd_priv *priv)
404 } 405 }
405 406
406 ret = rsnd_mod_init(priv, rsnd_mod_get(ctu), &rsnd_ctu_ops, 407 ret = rsnd_mod_init(priv, rsnd_mod_get(ctu), &rsnd_ctu_ops,
407 clk, rsnd_mod_get_status, RSND_MOD_CTU, i); 408 clk, RSND_MOD_CTU, i);
408 if (ret) { 409 if (ret) {
409 of_node_put(np); 410 of_node_put(np);
410 goto rsnd_ctu_probe_done; 411 goto rsnd_ctu_probe_done;
diff --git a/sound/soc/sh/rcar/dma.c b/sound/soc/sh/rcar/dma.c
index 6d1947515dc8..e5c30eec1190 100644
--- a/sound/soc/sh/rcar/dma.c
+++ b/sound/soc/sh/rcar/dma.c
@@ -289,12 +289,13 @@ static int rsnd_dmaen_pointer(struct rsnd_mod *mod,
289} 289}
290 290
291static struct rsnd_mod_ops rsnd_dmaen_ops = { 291static struct rsnd_mod_ops rsnd_dmaen_ops = {
292 .name = "audmac", 292 .name = "audmac",
293 .prepare = rsnd_dmaen_prepare, 293 .prepare = rsnd_dmaen_prepare,
294 .cleanup = rsnd_dmaen_cleanup, 294 .cleanup = rsnd_dmaen_cleanup,
295 .start = rsnd_dmaen_start, 295 .start = rsnd_dmaen_start,
296 .stop = rsnd_dmaen_stop, 296 .stop = rsnd_dmaen_stop,
297 .pointer= rsnd_dmaen_pointer, 297 .pointer = rsnd_dmaen_pointer,
298 .get_status = rsnd_mod_get_status,
298}; 299};
299 300
300/* 301/*
@@ -477,10 +478,11 @@ static int rsnd_dmapp_attach(struct rsnd_dai_stream *io,
477} 478}
478 479
479static struct rsnd_mod_ops rsnd_dmapp_ops = { 480static struct rsnd_mod_ops rsnd_dmapp_ops = {
480 .name = "audmac-pp", 481 .name = "audmac-pp",
481 .start = rsnd_dmapp_start, 482 .start = rsnd_dmapp_start,
482 .stop = rsnd_dmapp_stop, 483 .stop = rsnd_dmapp_stop,
483 .quit = rsnd_dmapp_stop, 484 .quit = rsnd_dmapp_stop,
485 .get_status = rsnd_mod_get_status,
484}; 486};
485 487
486/* 488/*
@@ -756,7 +758,7 @@ static int rsnd_dma_alloc(struct rsnd_dai_stream *io, struct rsnd_mod *mod,
756 *dma_mod = rsnd_mod_get(dma); 758 *dma_mod = rsnd_mod_get(dma);
757 759
758 ret = rsnd_mod_init(priv, *dma_mod, ops, NULL, 760 ret = rsnd_mod_init(priv, *dma_mod, ops, NULL,
759 rsnd_mod_get_status, type, dma_id); 761 type, dma_id);
760 if (ret < 0) 762 if (ret < 0)
761 return ret; 763 return ret;
762 764
@@ -823,5 +825,5 @@ int rsnd_dma_probe(struct rsnd_priv *priv)
823 priv->dma = dmac; 825 priv->dma = dmac;
824 826
825 /* dummy mem mod for debug */ 827 /* dummy mem mod for debug */
826 return rsnd_mod_init(NULL, &mem, &mem_ops, NULL, NULL, 0, 0); 828 return rsnd_mod_init(NULL, &mem, &mem_ops, NULL, 0, 0);
827} 829}
diff --git a/sound/soc/sh/rcar/dvc.c b/sound/soc/sh/rcar/dvc.c
index 2b16e0ce6bc5..d65f24bec991 100644
--- a/sound/soc/sh/rcar/dvc.c
+++ b/sound/soc/sh/rcar/dvc.c
@@ -306,6 +306,7 @@ static struct rsnd_mod_ops rsnd_dvc_ops = {
306 .init = rsnd_dvc_init, 306 .init = rsnd_dvc_init,
307 .quit = rsnd_dvc_quit, 307 .quit = rsnd_dvc_quit,
308 .pcm_new = rsnd_dvc_pcm_new, 308 .pcm_new = rsnd_dvc_pcm_new,
309 .get_status = rsnd_mod_get_status,
309}; 310};
310 311
311struct rsnd_mod *rsnd_dvc_mod_get(struct rsnd_priv *priv, int id) 312struct rsnd_mod *rsnd_dvc_mod_get(struct rsnd_priv *priv, int id)
@@ -365,7 +366,7 @@ int rsnd_dvc_probe(struct rsnd_priv *priv)
365 } 366 }
366 367
367 ret = rsnd_mod_init(priv, rsnd_mod_get(dvc), &rsnd_dvc_ops, 368 ret = rsnd_mod_init(priv, rsnd_mod_get(dvc), &rsnd_dvc_ops,
368 clk, rsnd_mod_get_status, RSND_MOD_DVC, i); 369 clk, RSND_MOD_DVC, i);
369 if (ret) { 370 if (ret) {
370 of_node_put(np); 371 of_node_put(np);
371 goto rsnd_dvc_probe_done; 372 goto rsnd_dvc_probe_done;
diff --git a/sound/soc/sh/rcar/mix.c b/sound/soc/sh/rcar/mix.c
index 8e3b57eaa708..a3e0370f5704 100644
--- a/sound/soc/sh/rcar/mix.c
+++ b/sound/soc/sh/rcar/mix.c
@@ -256,6 +256,7 @@ static struct rsnd_mod_ops rsnd_mix_ops = {
256 .init = rsnd_mix_init, 256 .init = rsnd_mix_init,
257 .quit = rsnd_mix_quit, 257 .quit = rsnd_mix_quit,
258 .pcm_new = rsnd_mix_pcm_new, 258 .pcm_new = rsnd_mix_pcm_new,
259 .get_status = rsnd_mod_get_status,
259}; 260};
260 261
261struct rsnd_mod *rsnd_mix_mod_get(struct rsnd_priv *priv, int id) 262struct rsnd_mod *rsnd_mix_mod_get(struct rsnd_priv *priv, int id)
@@ -315,7 +316,7 @@ int rsnd_mix_probe(struct rsnd_priv *priv)
315 } 316 }
316 317
317 ret = rsnd_mod_init(priv, rsnd_mod_get(mix), &rsnd_mix_ops, 318 ret = rsnd_mod_init(priv, rsnd_mod_get(mix), &rsnd_mix_ops,
318 clk, rsnd_mod_get_status, RSND_MOD_MIX, i); 319 clk, RSND_MOD_MIX, i);
319 if (ret) { 320 if (ret) {
320 of_node_put(np); 321 of_node_put(np);
321 goto rsnd_mix_probe_done; 322 goto rsnd_mix_probe_done;
diff --git a/sound/soc/sh/rcar/rsnd.h b/sound/soc/sh/rcar/rsnd.h
index 4464d1d0a042..d25fb5c14c2d 100644
--- a/sound/soc/sh/rcar/rsnd.h
+++ b/sound/soc/sh/rcar/rsnd.h
@@ -301,6 +301,9 @@ struct rsnd_mod_ops {
301 int (*cleanup)(struct rsnd_mod *mod, 301 int (*cleanup)(struct rsnd_mod *mod,
302 struct rsnd_dai_stream *io, 302 struct rsnd_dai_stream *io,
303 struct rsnd_priv *priv); 303 struct rsnd_priv *priv);
304 u32 *(*get_status)(struct rsnd_mod *mod,
305 struct rsnd_dai_stream *io,
306 enum rsnd_mod_type type);
304}; 307};
305 308
306struct rsnd_dai_stream; 309struct rsnd_dai_stream;
@@ -310,9 +313,6 @@ struct rsnd_mod {
310 struct rsnd_mod_ops *ops; 313 struct rsnd_mod_ops *ops;
311 struct rsnd_priv *priv; 314 struct rsnd_priv *priv;
312 struct clk *clk; 315 struct clk *clk;
313 u32 *(*get_status)(struct rsnd_dai_stream *io,
314 struct rsnd_mod *mod,
315 enum rsnd_mod_type type);
316 u32 status; 316 u32 status;
317}; 317};
318/* 318/*
@@ -385,9 +385,6 @@ int rsnd_mod_init(struct rsnd_priv *priv,
385 struct rsnd_mod *mod, 385 struct rsnd_mod *mod,
386 struct rsnd_mod_ops *ops, 386 struct rsnd_mod_ops *ops,
387 struct clk *clk, 387 struct clk *clk,
388 u32* (*get_status)(struct rsnd_dai_stream *io,
389 struct rsnd_mod *mod,
390 enum rsnd_mod_type type),
391 enum rsnd_mod_type type, 388 enum rsnd_mod_type type,
392 int id); 389 int id);
393void rsnd_mod_quit(struct rsnd_mod *mod); 390void rsnd_mod_quit(struct rsnd_mod *mod);
@@ -396,8 +393,8 @@ struct dma_chan *rsnd_mod_dma_req(struct rsnd_dai_stream *io,
396void rsnd_mod_interrupt(struct rsnd_mod *mod, 393void rsnd_mod_interrupt(struct rsnd_mod *mod,
397 void (*callback)(struct rsnd_mod *mod, 394 void (*callback)(struct rsnd_mod *mod,
398 struct rsnd_dai_stream *io)); 395 struct rsnd_dai_stream *io));
399u32 *rsnd_mod_get_status(struct rsnd_dai_stream *io, 396u32 *rsnd_mod_get_status(struct rsnd_mod *mod,
400 struct rsnd_mod *mod, 397 struct rsnd_dai_stream *io,
401 enum rsnd_mod_type type); 398 enum rsnd_mod_type type);
402struct rsnd_mod *rsnd_mod_next(int *iterator, 399struct rsnd_mod *rsnd_mod_next(int *iterator,
403 struct rsnd_dai_stream *io, 400 struct rsnd_dai_stream *io,
diff --git a/sound/soc/sh/rcar/src.c b/sound/soc/sh/rcar/src.c
index cd38a43b976f..7de7afd6a3a6 100644
--- a/sound/soc/sh/rcar/src.c
+++ b/sound/soc/sh/rcar/src.c
@@ -527,16 +527,17 @@ static int rsnd_src_pcm_new(struct rsnd_mod *mod,
527} 527}
528 528
529static struct rsnd_mod_ops rsnd_src_ops = { 529static struct rsnd_mod_ops rsnd_src_ops = {
530 .name = SRC_NAME, 530 .name = SRC_NAME,
531 .dma_req = rsnd_src_dma_req, 531 .dma_req = rsnd_src_dma_req,
532 .probe = rsnd_src_probe_, 532 .probe = rsnd_src_probe_,
533 .init = rsnd_src_init, 533 .init = rsnd_src_init,
534 .quit = rsnd_src_quit, 534 .quit = rsnd_src_quit,
535 .start = rsnd_src_start, 535 .start = rsnd_src_start,
536 .stop = rsnd_src_stop, 536 .stop = rsnd_src_stop,
537 .irq = rsnd_src_irq, 537 .irq = rsnd_src_irq,
538 .hw_params = rsnd_src_hw_params, 538 .hw_params = rsnd_src_hw_params,
539 .pcm_new = rsnd_src_pcm_new, 539 .pcm_new = rsnd_src_pcm_new,
540 .get_status = rsnd_mod_get_status,
540}; 541};
541 542
542struct rsnd_mod *rsnd_src_mod_get(struct rsnd_priv *priv, int id) 543struct rsnd_mod *rsnd_src_mod_get(struct rsnd_priv *priv, int id)
@@ -605,8 +606,7 @@ int rsnd_src_probe(struct rsnd_priv *priv)
605 } 606 }
606 607
607 ret = rsnd_mod_init(priv, rsnd_mod_get(src), 608 ret = rsnd_mod_init(priv, rsnd_mod_get(src),
608 &rsnd_src_ops, clk, rsnd_mod_get_status, 609 &rsnd_src_ops, clk, RSND_MOD_SRC, i);
609 RSND_MOD_SRC, i);
610 if (ret) { 610 if (ret) {
611 of_node_put(np); 611 of_node_put(np);
612 goto rsnd_src_probe_done; 612 goto rsnd_src_probe_done;
diff --git a/sound/soc/sh/rcar/ssi.c b/sound/soc/sh/rcar/ssi.c
index fcb4df23248c..cb66986ff776 100644
--- a/sound/soc/sh/rcar/ssi.c
+++ b/sound/soc/sh/rcar/ssi.c
@@ -681,6 +681,41 @@ static irqreturn_t rsnd_ssi_interrupt(int irq, void *data)
681 return IRQ_HANDLED; 681 return IRQ_HANDLED;
682} 682}
683 683
684static u32 *rsnd_ssi_get_status(struct rsnd_mod *mod,
685 struct rsnd_dai_stream *io,
686 enum rsnd_mod_type type)
687{
688 /*
689 * SSIP (= SSI parent) needs to be special, otherwise,
690 * 2nd SSI might doesn't start. see also rsnd_mod_call()
691 *
692 * We can't include parent SSI status on SSI, because we don't know
693 * how many SSI requests parent SSI. Thus, it is localed on "io" now.
694 * ex) trouble case
695 * Playback: SSI0
696 * Capture : SSI1 (needs SSI0)
697 *
698 * 1) start Capture -> SSI0/SSI1 are started.
699 * 2) start Playback -> SSI0 doesn't work, because it is already
700 * marked as "started" on 1)
701 *
702 * OTOH, using each mod's status is good for MUX case.
703 * It doesn't need to start in 2nd start
704 * ex)
705 * IO-0: SRC0 -> CTU1 -+-> MUX -> DVC -> SSIU -> SSI0
706 * |
707 * IO-1: SRC1 -> CTU2 -+
708 *
709 * 1) start IO-0 -> start SSI0
710 * 2) start IO-1 -> SSI0 doesn't need to start, because it is
711 * already started on 1)
712 */
713 if (type == RSND_MOD_SSIP)
714 return &io->parent_ssi_status;
715
716 return rsnd_mod_get_status(mod, io, type);
717}
718
684/* 719/*
685 * SSI PIO 720 * SSI PIO
686 */ 721 */
@@ -876,18 +911,19 @@ static int rsnd_ssi_prepare(struct rsnd_mod *mod,
876} 911}
877 912
878static struct rsnd_mod_ops rsnd_ssi_pio_ops = { 913static struct rsnd_mod_ops rsnd_ssi_pio_ops = {
879 .name = SSI_NAME, 914 .name = SSI_NAME,
880 .probe = rsnd_ssi_common_probe, 915 .probe = rsnd_ssi_common_probe,
881 .remove = rsnd_ssi_common_remove, 916 .remove = rsnd_ssi_common_remove,
882 .init = rsnd_ssi_pio_init, 917 .init = rsnd_ssi_pio_init,
883 .quit = rsnd_ssi_quit, 918 .quit = rsnd_ssi_quit,
884 .start = rsnd_ssi_start, 919 .start = rsnd_ssi_start,
885 .stop = rsnd_ssi_stop, 920 .stop = rsnd_ssi_stop,
886 .irq = rsnd_ssi_irq, 921 .irq = rsnd_ssi_irq,
887 .pointer = rsnd_ssi_pio_pointer, 922 .pointer = rsnd_ssi_pio_pointer,
888 .pcm_new = rsnd_ssi_pcm_new, 923 .pcm_new = rsnd_ssi_pcm_new,
889 .hw_params = rsnd_ssi_hw_params, 924 .hw_params = rsnd_ssi_hw_params,
890 .prepare = rsnd_ssi_prepare, 925 .prepare = rsnd_ssi_prepare,
926 .get_status = rsnd_ssi_get_status,
891}; 927};
892 928
893static int rsnd_ssi_dma_probe(struct rsnd_mod *mod, 929static int rsnd_ssi_dma_probe(struct rsnd_mod *mod,
@@ -951,19 +987,20 @@ static struct dma_chan *rsnd_ssi_dma_req(struct rsnd_dai_stream *io,
951} 987}
952 988
953static struct rsnd_mod_ops rsnd_ssi_dma_ops = { 989static struct rsnd_mod_ops rsnd_ssi_dma_ops = {
954 .name = SSI_NAME, 990 .name = SSI_NAME,
955 .dma_req = rsnd_ssi_dma_req, 991 .dma_req = rsnd_ssi_dma_req,
956 .probe = rsnd_ssi_dma_probe, 992 .probe = rsnd_ssi_dma_probe,
957 .remove = rsnd_ssi_common_remove, 993 .remove = rsnd_ssi_common_remove,
958 .init = rsnd_ssi_init, 994 .init = rsnd_ssi_init,
959 .quit = rsnd_ssi_quit, 995 .quit = rsnd_ssi_quit,
960 .start = rsnd_ssi_start, 996 .start = rsnd_ssi_start,
961 .stop = rsnd_ssi_stop, 997 .stop = rsnd_ssi_stop,
962 .irq = rsnd_ssi_irq, 998 .irq = rsnd_ssi_irq,
963 .pcm_new = rsnd_ssi_pcm_new, 999 .pcm_new = rsnd_ssi_pcm_new,
964 .fallback = rsnd_ssi_fallback, 1000 .fallback = rsnd_ssi_fallback,
965 .hw_params = rsnd_ssi_hw_params, 1001 .hw_params = rsnd_ssi_hw_params,
966 .prepare = rsnd_ssi_prepare, 1002 .prepare = rsnd_ssi_prepare,
1003 .get_status = rsnd_ssi_get_status,
967}; 1004};
968 1005
969int rsnd_ssi_is_dma_mode(struct rsnd_mod *mod) 1006int rsnd_ssi_is_dma_mode(struct rsnd_mod *mod)
@@ -1091,41 +1128,6 @@ int __rsnd_ssi_is_pin_sharing(struct rsnd_mod *mod)
1091 return !!(rsnd_flags_has(rsnd_mod_to_ssi(mod), RSND_SSI_CLK_PIN_SHARE)); 1128 return !!(rsnd_flags_has(rsnd_mod_to_ssi(mod), RSND_SSI_CLK_PIN_SHARE));
1092} 1129}
1093 1130
1094static u32 *rsnd_ssi_get_status(struct rsnd_dai_stream *io,
1095 struct rsnd_mod *mod,
1096 enum rsnd_mod_type type)
1097{
1098 /*
1099 * SSIP (= SSI parent) needs to be special, otherwise,
1100 * 2nd SSI might doesn't start. see also rsnd_mod_call()
1101 *
1102 * We can't include parent SSI status on SSI, because we don't know
1103 * how many SSI requests parent SSI. Thus, it is localed on "io" now.
1104 * ex) trouble case
1105 * Playback: SSI0
1106 * Capture : SSI1 (needs SSI0)
1107 *
1108 * 1) start Capture -> SSI0/SSI1 are started.
1109 * 2) start Playback -> SSI0 doesn't work, because it is already
1110 * marked as "started" on 1)
1111 *
1112 * OTOH, using each mod's status is good for MUX case.
1113 * It doesn't need to start in 2nd start
1114 * ex)
1115 * IO-0: SRC0 -> CTU1 -+-> MUX -> DVC -> SSIU -> SSI0
1116 * |
1117 * IO-1: SRC1 -> CTU2 -+
1118 *
1119 * 1) start IO-0 -> start SSI0
1120 * 2) start IO-1 -> SSI0 doesn't need to start, because it is
1121 * already started on 1)
1122 */
1123 if (type == RSND_MOD_SSIP)
1124 return &io->parent_ssi_status;
1125
1126 return rsnd_mod_get_status(io, mod, type);
1127}
1128
1129int rsnd_ssi_probe(struct rsnd_priv *priv) 1131int rsnd_ssi_probe(struct rsnd_priv *priv)
1130{ 1132{
1131 struct device_node *node; 1133 struct device_node *node;
@@ -1192,7 +1194,7 @@ int rsnd_ssi_probe(struct rsnd_priv *priv)
1192 ops = &rsnd_ssi_dma_ops; 1194 ops = &rsnd_ssi_dma_ops;
1193 1195
1194 ret = rsnd_mod_init(priv, rsnd_mod_get(ssi), ops, clk, 1196 ret = rsnd_mod_init(priv, rsnd_mod_get(ssi), ops, clk,
1195 rsnd_ssi_get_status, RSND_MOD_SSI, i); 1197 RSND_MOD_SSI, i);
1196 if (ret) { 1198 if (ret) {
1197 of_node_put(np); 1199 of_node_put(np);
1198 goto rsnd_ssi_probe_done; 1200 goto rsnd_ssi_probe_done;
diff --git a/sound/soc/sh/rcar/ssiu.c b/sound/soc/sh/rcar/ssiu.c
index 39b67643b5dc..ebcb826b849f 100644
--- a/sound/soc/sh/rcar/ssiu.c
+++ b/sound/soc/sh/rcar/ssiu.c
@@ -22,6 +22,16 @@ struct rsnd_ssiu {
22 ((pos) = ((struct rsnd_ssiu *)(priv)->ssiu + i)); \ 22 ((pos) = ((struct rsnd_ssiu *)(priv)->ssiu + i)); \
23 i++) 23 i++)
24 24
25static u32 *rsnd_ssiu_get_status(struct rsnd_mod *mod,
26 struct rsnd_dai_stream *io,
27 enum rsnd_mod_type type)
28{
29 struct rsnd_ssiu *ssiu = rsnd_mod_to_ssiu(mod);
30 int busif = rsnd_ssi_get_busif(io);
31
32 return &ssiu->busif_status[busif];
33}
34
25static int rsnd_ssiu_init(struct rsnd_mod *mod, 35static int rsnd_ssiu_init(struct rsnd_mod *mod,
26 struct rsnd_dai_stream *io, 36 struct rsnd_dai_stream *io,
27 struct rsnd_priv *priv) 37 struct rsnd_priv *priv)
@@ -115,8 +125,9 @@ static int rsnd_ssiu_init(struct rsnd_mod *mod,
115} 125}
116 126
117static struct rsnd_mod_ops rsnd_ssiu_ops_gen1 = { 127static struct rsnd_mod_ops rsnd_ssiu_ops_gen1 = {
118 .name = SSIU_NAME, 128 .name = SSIU_NAME,
119 .init = rsnd_ssiu_init, 129 .init = rsnd_ssiu_init,
130 .get_status = rsnd_ssiu_get_status,
120}; 131};
121 132
122static int rsnd_ssiu_init_gen2(struct rsnd_mod *mod, 133static int rsnd_ssiu_init_gen2(struct rsnd_mod *mod,
@@ -279,10 +290,11 @@ static int rsnd_ssiu_stop_gen2(struct rsnd_mod *mod,
279} 290}
280 291
281static struct rsnd_mod_ops rsnd_ssiu_ops_gen2 = { 292static struct rsnd_mod_ops rsnd_ssiu_ops_gen2 = {
282 .name = SSIU_NAME, 293 .name = SSIU_NAME,
283 .init = rsnd_ssiu_init_gen2, 294 .init = rsnd_ssiu_init_gen2,
284 .start = rsnd_ssiu_start_gen2, 295 .start = rsnd_ssiu_start_gen2,
285 .stop = rsnd_ssiu_stop_gen2, 296 .stop = rsnd_ssiu_stop_gen2,
297 .get_status = rsnd_ssiu_get_status,
286}; 298};
287 299
288static struct rsnd_mod *rsnd_ssiu_mod_get(struct rsnd_priv *priv, int id) 300static struct rsnd_mod *rsnd_ssiu_mod_get(struct rsnd_priv *priv, int id)
@@ -304,16 +316,6 @@ int rsnd_ssiu_attach(struct rsnd_dai_stream *io,
304 return rsnd_dai_connect(mod, io, mod->type); 316 return rsnd_dai_connect(mod, io, mod->type);
305} 317}
306 318
307static u32 *rsnd_ssiu_get_status(struct rsnd_dai_stream *io,
308 struct rsnd_mod *mod,
309 enum rsnd_mod_type type)
310{
311 struct rsnd_ssiu *ssiu = rsnd_mod_to_ssiu(mod);
312 int busif = rsnd_ssi_get_busif(io);
313
314 return &ssiu->busif_status[busif];
315}
316
317int rsnd_ssiu_probe(struct rsnd_priv *priv) 319int rsnd_ssiu_probe(struct rsnd_priv *priv)
318{ 320{
319 struct device *dev = rsnd_priv_to_dev(priv); 321 struct device *dev = rsnd_priv_to_dev(priv);
@@ -337,8 +339,7 @@ int rsnd_ssiu_probe(struct rsnd_priv *priv)
337 339
338 for_each_rsnd_ssiu(ssiu, priv, i) { 340 for_each_rsnd_ssiu(ssiu, priv, i) {
339 ret = rsnd_mod_init(priv, rsnd_mod_get(ssiu), 341 ret = rsnd_mod_init(priv, rsnd_mod_get(ssiu),
340 ops, NULL, rsnd_ssiu_get_status, 342 ops, NULL, RSND_MOD_SSIU, i);
341 RSND_MOD_SSIU, i);
342 if (ret) 343 if (ret)
343 return ret; 344 return ret;
344 } 345 }