aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKuninori Morimoto <kuninori.morimoto.gx@renesas.com>2014-01-23 21:42:00 -0500
committerMark Brown <broonie@linaro.org>2014-02-03 07:41:38 -0500
commit629509c5bc478c0343d94c8c70812396f44447fb (patch)
treecdeab0938f68fe265bdd54b219c369213988f0b4
parenteb854f6dff24a59378acc8d8eda57a3543a25acc (diff)
ASoC: rsnd: add Gen2 SRC and DMAEngine support
Renesas sound Gen2 has SRC (= Sampling Rate Converter) which needs 2 DMAC. The data path image when you use SRC on Gen2 is [mem] -> Audio-DMAC -> SRC -> Audio-DMAC-peri-peri -> SSIU -> SSI This patch support SRC and DMAEnine. It is tested on R-Car H2 Lager board Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com> Signed-off-by: Mark Brown <broonie@linaro.org>
-rw-r--r--include/sound/rcar_snd.h6
-rw-r--r--sound/soc/sh/rcar/adg.c138
-rw-r--r--sound/soc/sh/rcar/gen.c26
-rw-r--r--sound/soc/sh/rcar/rsnd.h25
-rw-r--r--sound/soc/sh/rcar/scu.c117
5 files changed, 312 insertions, 0 deletions
diff --git a/include/sound/rcar_snd.h b/include/sound/rcar_snd.h
index 1d19bfc2486d..2be05aea54f9 100644
--- a/include/sound/rcar_snd.h
+++ b/include/sound/rcar_snd.h
@@ -56,9 +56,15 @@ struct rsnd_ssi_platform_info {
56 */ 56 */
57#define RSND_SCU_USE_HPBIF (1 << 31) /* it needs RSND_SSI_DEPENDENT */ 57#define RSND_SCU_USE_HPBIF (1 << 31) /* it needs RSND_SSI_DEPENDENT */
58 58
59#define RSND_SCU_SET(rate, _dma_id) \
60 { .flags = RSND_SCU_USE_HPBIF, .convert_rate = rate, .dma_id = _dma_id, }
61#define RSND_SCU_UNUSED \
62 { .flags = 0, .convert_rate = 0, .dma_id = 0, }
63
59struct rsnd_scu_platform_info { 64struct rsnd_scu_platform_info {
60 u32 flags; 65 u32 flags;
61 u32 convert_rate; /* sampling rate convert */ 66 u32 convert_rate; /* sampling rate convert */
67 int dma_id; /* for Gen2 SCU */
62}; 68};
63 69
64/* 70/*
diff --git a/sound/soc/sh/rcar/adg.c b/sound/soc/sh/rcar/adg.c
index 5bdffa480245..821791e15d04 100644
--- a/sound/soc/sh/rcar/adg.c
+++ b/sound/soc/sh/rcar/adg.c
@@ -30,6 +30,144 @@ struct rsnd_adg {
30 i++, (pos) = adg->clk[i]) 30 i++, (pos) = adg->clk[i])
31#define rsnd_priv_to_adg(priv) ((struct rsnd_adg *)(priv)->adg) 31#define rsnd_priv_to_adg(priv) ((struct rsnd_adg *)(priv)->adg)
32 32
33
34static u32 rsnd_adg_ssi_ws_timing_gen2(struct rsnd_mod *mod)
35{
36 struct rsnd_priv *priv = rsnd_mod_to_priv(mod);
37 int id = rsnd_mod_id(mod);
38 int ws = id;
39
40 if (rsnd_ssi_is_pin_sharing(rsnd_ssi_mod_get(priv, id))) {
41 switch (id) {
42 case 1:
43 case 2:
44 ws = 0;
45 break;
46 case 4:
47 ws = 3;
48 break;
49 case 8:
50 ws = 7;
51 break;
52 }
53 }
54
55 return (0x6 + ws) << 8;
56}
57
58static int rsnd_adg_set_src_timsel_gen2(struct rsnd_dai *rdai,
59 struct rsnd_mod *mod,
60 struct rsnd_dai_stream *io,
61 u32 timsel)
62{
63 int is_play = rsnd_dai_is_play(rdai, io);
64 int id = rsnd_mod_id(mod);
65 int shift = (id % 2) ? 16 : 0;
66 u32 mask, ws;
67 u32 in, out;
68
69 ws = rsnd_adg_ssi_ws_timing_gen2(mod);
70
71 in = (is_play) ? timsel : ws;
72 out = (is_play) ? ws : timsel;
73
74 in = in << shift;
75 out = out << shift;
76 mask = 0xffff << shift;
77
78 switch (id / 2) {
79 case 0:
80 rsnd_mod_bset(mod, SRCIN_TIMSEL0, mask, in);
81 rsnd_mod_bset(mod, SRCOUT_TIMSEL0, mask, out);
82 break;
83 case 1:
84 rsnd_mod_bset(mod, SRCIN_TIMSEL1, mask, in);
85 rsnd_mod_bset(mod, SRCOUT_TIMSEL1, mask, out);
86 break;
87 case 2:
88 rsnd_mod_bset(mod, SRCIN_TIMSEL2, mask, in);
89 rsnd_mod_bset(mod, SRCOUT_TIMSEL2, mask, out);
90 break;
91 case 3:
92 rsnd_mod_bset(mod, SRCIN_TIMSEL3, mask, in);
93 rsnd_mod_bset(mod, SRCOUT_TIMSEL3, mask, out);
94 break;
95 case 4:
96 rsnd_mod_bset(mod, SRCIN_TIMSEL4, mask, in);
97 rsnd_mod_bset(mod, SRCOUT_TIMSEL4, mask, out);
98 break;
99 }
100
101 return 0;
102}
103
104int rsnd_adg_set_convert_clk_gen2(struct rsnd_mod *mod,
105 struct rsnd_dai *rdai,
106 struct rsnd_dai_stream *io,
107 unsigned int src_rate,
108 unsigned int dst_rate)
109{
110 struct rsnd_priv *priv = rsnd_mod_to_priv(mod);
111 struct rsnd_adg *adg = rsnd_priv_to_adg(priv);
112 struct device *dev = rsnd_priv_to_dev(priv);
113 int idx, sel, div, step;
114 u32 val;
115 unsigned int min, diff;
116 unsigned int sel_rate [] = {
117 clk_get_rate(adg->clk[CLKA]), /* 0000: CLKA */
118 clk_get_rate(adg->clk[CLKB]), /* 0001: CLKB */
119 clk_get_rate(adg->clk[CLKC]), /* 0010: CLKC */
120 adg->rbga_rate_for_441khz_div_6,/* 0011: RBGA */
121 adg->rbgb_rate_for_48khz_div_6, /* 0100: RBGB */
122 };
123
124 min = ~0;
125 val = 0;
126 for (sel = 0; sel < ARRAY_SIZE(sel_rate); sel++) {
127 idx = 0;
128 step = 2;
129
130 if (!sel_rate[sel])
131 continue;
132
133 for (div = 2; div <= 98304; div += step) {
134 diff = abs(src_rate - sel_rate[sel] / div);
135 if (min > diff) {
136 val = (sel << 8) | idx;
137 min = diff;
138 }
139
140 /*
141 * step of 0_0000 / 0_0001 / 0_1101
142 * are out of order
143 */
144 if ((idx > 2) && (idx % 2))
145 step *= 2;
146 if (idx == 0x1c) {
147 div += step;
148 step *= 2;
149 }
150 idx++;
151 }
152 }
153
154 if (min == ~0) {
155 dev_err(dev, "no Input clock\n");
156 return -EIO;
157 }
158
159 return rsnd_adg_set_src_timsel_gen2(rdai, mod, io, val);
160}
161
162int rsnd_adg_set_convert_timing_gen2(struct rsnd_mod *mod,
163 struct rsnd_dai *rdai,
164 struct rsnd_dai_stream *io)
165{
166 u32 val = rsnd_adg_ssi_ws_timing_gen2(mod);
167
168 return rsnd_adg_set_src_timsel_gen2(rdai, mod, io, val);
169}
170
33int rsnd_adg_set_convert_clk_gen1(struct rsnd_priv *priv, 171int rsnd_adg_set_convert_clk_gen1(struct rsnd_priv *priv,
34 struct rsnd_mod *mod, 172 struct rsnd_mod *mod,
35 unsigned int src_rate, 173 unsigned int src_rate,
diff --git a/sound/soc/sh/rcar/gen.c b/sound/soc/sh/rcar/gen.c
index db486aae6b8b..3e03a8bc4f75 100644
--- a/sound/soc/sh/rcar/gen.c
+++ b/sound/soc/sh/rcar/gen.c
@@ -229,14 +229,40 @@ static int rsnd_gen2_regmap_init(struct rsnd_priv *priv, struct rsnd_gen *gen)
229 RSND_GEN2_S_REG(gen, SSIU, SSI_MODE0, 0x800), 229 RSND_GEN2_S_REG(gen, SSIU, SSI_MODE0, 0x800),
230 RSND_GEN2_S_REG(gen, SSIU, SSI_MODE1, 0x804), 230 RSND_GEN2_S_REG(gen, SSIU, SSI_MODE1, 0x804),
231 /* FIXME: it needs SSI_MODE2/3 in the future */ 231 /* FIXME: it needs SSI_MODE2/3 in the future */
232 RSND_GEN2_S_REG(gen, SSIU, SSI_CONTROL, 0x810),
233 RSND_GEN2_M_REG(gen, SSIU, SSI_BUSIF_MODE, 0x0, 0x80),
234 RSND_GEN2_M_REG(gen, SSIU, SSI_BUSIF_ADINR,0x4, 0x80),
235 RSND_GEN2_M_REG(gen, SSIU, SSI_CTRL, 0x10, 0x80),
232 RSND_GEN2_M_REG(gen, SSIU, INT_ENABLE, 0x18, 0x80), 236 RSND_GEN2_M_REG(gen, SSIU, INT_ENABLE, 0x18, 0x80),
233 237
238 RSND_GEN2_M_REG(gen, SCU, SRC_BUSIF_MODE, 0x0, 0x20),
239 RSND_GEN2_M_REG(gen, SCU, SRC_ROUTE_MODE0,0xc, 0x20),
240 RSND_GEN2_M_REG(gen, SCU, SRC_CTRL, 0x10, 0x20),
241 RSND_GEN2_M_REG(gen, SCU, SRC_SWRSR, 0x200, 0x40),
242 RSND_GEN2_M_REG(gen, SCU, SRC_SRCIR, 0x204, 0x40),
243 RSND_GEN2_M_REG(gen, SCU, SRC_ADINR, 0x214, 0x40),
244 RSND_GEN2_M_REG(gen, SCU, SRC_IFSCR, 0x21c, 0x40),
245 RSND_GEN2_M_REG(gen, SCU, SRC_IFSVR, 0x220, 0x40),
246 RSND_GEN2_M_REG(gen, SCU, SRC_SRCCR, 0x224, 0x40),
247 RSND_GEN2_M_REG(gen, SCU, SRC_BSDSR, 0x22c, 0x40),
248 RSND_GEN2_M_REG(gen, SCU, SRC_BSISR, 0x238, 0x40),
249
234 RSND_GEN2_S_REG(gen, ADG, BRRA, 0x00), 250 RSND_GEN2_S_REG(gen, ADG, BRRA, 0x00),
235 RSND_GEN2_S_REG(gen, ADG, BRRB, 0x04), 251 RSND_GEN2_S_REG(gen, ADG, BRRB, 0x04),
236 RSND_GEN2_S_REG(gen, ADG, SSICKR, 0x08), 252 RSND_GEN2_S_REG(gen, ADG, SSICKR, 0x08),
237 RSND_GEN2_S_REG(gen, ADG, AUDIO_CLK_SEL0, 0x0c), 253 RSND_GEN2_S_REG(gen, ADG, AUDIO_CLK_SEL0, 0x0c),
238 RSND_GEN2_S_REG(gen, ADG, AUDIO_CLK_SEL1, 0x10), 254 RSND_GEN2_S_REG(gen, ADG, AUDIO_CLK_SEL1, 0x10),
239 RSND_GEN2_S_REG(gen, ADG, AUDIO_CLK_SEL2, 0x14), 255 RSND_GEN2_S_REG(gen, ADG, AUDIO_CLK_SEL2, 0x14),
256 RSND_GEN2_S_REG(gen, ADG, SRCIN_TIMSEL0, 0x34),
257 RSND_GEN2_S_REG(gen, ADG, SRCIN_TIMSEL1, 0x38),
258 RSND_GEN2_S_REG(gen, ADG, SRCIN_TIMSEL2, 0x3c),
259 RSND_GEN2_S_REG(gen, ADG, SRCIN_TIMSEL3, 0x40),
260 RSND_GEN2_S_REG(gen, ADG, SRCIN_TIMSEL4, 0x44),
261 RSND_GEN2_S_REG(gen, ADG, SRCOUT_TIMSEL0, 0x48),
262 RSND_GEN2_S_REG(gen, ADG, SRCOUT_TIMSEL1, 0x4c),
263 RSND_GEN2_S_REG(gen, ADG, SRCOUT_TIMSEL2, 0x50),
264 RSND_GEN2_S_REG(gen, ADG, SRCOUT_TIMSEL3, 0x54),
265 RSND_GEN2_S_REG(gen, ADG, SRCOUT_TIMSEL4, 0x58),
240 266
241 RSND_GEN2_M_REG(gen, SSI, SSICR, 0x00, 0x40), 267 RSND_GEN2_M_REG(gen, SSI, SSICR, 0x00, 0x40),
242 RSND_GEN2_M_REG(gen, SSI, SSISR, 0x04, 0x40), 268 RSND_GEN2_M_REG(gen, SSI, SSISR, 0x04, 0x40),
diff --git a/sound/soc/sh/rcar/rsnd.h b/sound/soc/sh/rcar/rsnd.h
index b2c717d2ba7e..8b66dc15fa73 100644
--- a/sound/soc/sh/rcar/rsnd.h
+++ b/sound/soc/sh/rcar/rsnd.h
@@ -37,6 +37,11 @@ enum rsnd_reg {
37 RSND_REG_SRC_TMG_SEL1, /* for Gen1 */ 37 RSND_REG_SRC_TMG_SEL1, /* for Gen1 */
38 RSND_REG_SRC_TMG_SEL2, /* for Gen1 */ 38 RSND_REG_SRC_TMG_SEL2, /* for Gen1 */
39 RSND_REG_SRC_ROUTE_CTRL, /* for Gen1 */ 39 RSND_REG_SRC_ROUTE_CTRL, /* for Gen1 */
40 RSND_REG_SRC_CTRL, /* for Gen2 */
41 RSND_REG_SSI_CTRL, /* for Gen2 */
42 RSND_REG_SSI_CONTROL,
43 RSND_REG_SSI_BUSIF_MODE, /* for Gen2 */
44 RSND_REG_SSI_BUSIF_ADINR, /* for Gen2 */
40 RSND_REG_SSI_MODE0, 45 RSND_REG_SSI_MODE0,
41 RSND_REG_SSI_MODE1, 46 RSND_REG_SSI_MODE1,
42 RSND_REG_INT_ENABLE, /* for Gen2 */ 47 RSND_REG_INT_ENABLE, /* for Gen2 */
@@ -49,6 +54,8 @@ enum rsnd_reg {
49 RSND_REG_SRC_IFSVR, 54 RSND_REG_SRC_IFSVR,
50 RSND_REG_SRC_SRCCR, 55 RSND_REG_SRC_SRCCR,
51 RSND_REG_SRC_MNFSR, /* for Gen1 */ 56 RSND_REG_SRC_MNFSR, /* for Gen1 */
57 RSND_REG_SRC_BSDSR, /* for Gen2 */
58 RSND_REG_SRC_BSISR, /* for Gen2 */
52 59
53 /* ADG */ 60 /* ADG */
54 RSND_REG_BRRA, 61 RSND_REG_BRRA,
@@ -60,6 +67,16 @@ enum rsnd_reg {
60 RSND_REG_AUDIO_CLK_SEL3, /* for Gen1 */ 67 RSND_REG_AUDIO_CLK_SEL3, /* for Gen1 */
61 RSND_REG_AUDIO_CLK_SEL4, /* for Gen1 */ 68 RSND_REG_AUDIO_CLK_SEL4, /* for Gen1 */
62 RSND_REG_AUDIO_CLK_SEL5, /* for Gen1 */ 69 RSND_REG_AUDIO_CLK_SEL5, /* for Gen1 */
70 RSND_REG_SRCIN_TIMSEL0, /* for Gen2 */
71 RSND_REG_SRCIN_TIMSEL1, /* for Gen2 */
72 RSND_REG_SRCIN_TIMSEL2, /* for Gen2 */
73 RSND_REG_SRCIN_TIMSEL3, /* for Gen2 */
74 RSND_REG_SRCIN_TIMSEL4, /* for Gen2 */
75 RSND_REG_SRCOUT_TIMSEL0, /* for Gen2 */
76 RSND_REG_SRCOUT_TIMSEL1, /* for Gen2 */
77 RSND_REG_SRCOUT_TIMSEL2, /* for Gen2 */
78 RSND_REG_SRCOUT_TIMSEL3, /* for Gen2 */
79 RSND_REG_SRCOUT_TIMSEL4, /* for Gen2 */
63 80
64 /* SSI */ 81 /* SSI */
65 RSND_REG_SSICR, 82 RSND_REG_SSICR,
@@ -250,6 +267,14 @@ int rsnd_adg_set_convert_clk_gen1(struct rsnd_priv *priv,
250 struct rsnd_mod *mod, 267 struct rsnd_mod *mod,
251 unsigned int src_rate, 268 unsigned int src_rate,
252 unsigned int dst_rate); 269 unsigned int dst_rate);
270int rsnd_adg_set_convert_clk_gen2(struct rsnd_mod *mod,
271 struct rsnd_dai *rdai,
272 struct rsnd_dai_stream *io,
273 unsigned int src_rate,
274 unsigned int dst_rate);
275int rsnd_adg_set_convert_timing_gen2(struct rsnd_mod *mod,
276 struct rsnd_dai *rdai,
277 struct rsnd_dai_stream *io);
253 278
254/* 279/*
255 * R-Car sound priv 280 * R-Car sound priv
diff --git a/sound/soc/sh/rcar/scu.c b/sound/soc/sh/rcar/scu.c
index 29d8990e3f0f..6e5c763e1040 100644
--- a/sound/soc/sh/rcar/scu.c
+++ b/sound/soc/sh/rcar/scu.c
@@ -33,6 +33,8 @@ struct rsnd_scu {
33 container_of((_mod), struct rsnd_scu, mod) 33 container_of((_mod), struct rsnd_scu, mod)
34#define rsnd_scu_hpbif_is_enable(scu) \ 34#define rsnd_scu_hpbif_is_enable(scu) \
35 (rsnd_scu_mode_flags(scu) & RSND_SCU_USE_HPBIF) 35 (rsnd_scu_mode_flags(scu) & RSND_SCU_USE_HPBIF)
36#define rsnd_scu_dma_available(scu) \
37 rsnd_dma_available(rsnd_mod_to_dma(&(scu)->mod))
36 38
37#define for_each_rsnd_scu(pos, priv, i) \ 39#define for_each_rsnd_scu(pos, priv, i) \
38 for ((i) = 0; \ 40 for ((i) = 0; \
@@ -472,6 +474,103 @@ static struct rsnd_mod_ops rsnd_scu_non_gen1_ops = {
472/* 474/*
473 * Gen2 functions 475 * Gen2 functions
474 */ 476 */
477static int rsnd_scu_set_convert_rate_gen2(struct rsnd_mod *mod,
478 struct rsnd_dai *rdai,
479 struct rsnd_dai_stream *io)
480{
481 int ret;
482
483 ret = rsnd_scu_set_convert_rate(mod, rdai, io);
484 if (ret < 0)
485 return ret;
486
487 rsnd_mod_write(mod, SSI_BUSIF_ADINR, rsnd_mod_read(mod, SRC_ADINR));
488 rsnd_mod_write(mod, SSI_BUSIF_MODE, rsnd_mod_read(mod, SRC_BUSIF_MODE));
489
490 rsnd_mod_write(mod, SRC_SRCCR, 0x00011110);
491
492 rsnd_mod_write(mod, SRC_BSDSR, 0x01800000);
493 rsnd_mod_write(mod, SRC_BSISR, 0x00100060);
494
495 return 0;
496}
497
498static int rsnd_scu_set_convert_timing_gen2(struct rsnd_mod *mod,
499 struct rsnd_dai *rdai,
500 struct rsnd_dai_stream *io)
501{
502 struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io);
503 struct rsnd_scu *scu = rsnd_mod_to_scu(mod);
504 u32 convert_rate = rsnd_scu_convert_rate(scu);
505 int ret;
506
507 if (convert_rate)
508 ret = rsnd_adg_set_convert_clk_gen2(mod, rdai, io,
509 runtime->rate,
510 convert_rate);
511 else
512 ret = rsnd_adg_set_convert_timing_gen2(mod, rdai, io);
513
514 return ret;
515}
516
517static int rsnd_scu_init_gen2(struct rsnd_mod *mod,
518 struct rsnd_dai *rdai,
519 struct rsnd_dai_stream *io)
520{
521 int ret;
522
523 ret = rsnd_scu_init(mod, rdai, io);
524 if (ret < 0)
525 return ret;
526
527 ret = rsnd_scu_set_convert_rate_gen2(mod, rdai, io);
528 if (ret < 0)
529 return ret;
530
531 ret = rsnd_scu_set_convert_timing_gen2(mod, rdai, io);
532 if (ret < 0)
533 return ret;
534
535 return 0;
536}
537
538static int rsnd_scu_start_gen2(struct rsnd_mod *mod,
539 struct rsnd_dai *rdai,
540 struct rsnd_dai_stream *io)
541{
542 struct rsnd_scu *scu = rsnd_mod_to_scu(mod);
543
544 rsnd_dma_start(rsnd_mod_to_dma(&scu->mod));
545
546 rsnd_mod_write(mod, SSI_CTRL, 0x1);
547 rsnd_mod_write(mod, SRC_CTRL, 0x11);
548
549 return rsnd_scu_start(mod, rdai, io);
550}
551
552static int rsnd_scu_stop_gen2(struct rsnd_mod *mod,
553 struct rsnd_dai *rdai,
554 struct rsnd_dai_stream *io)
555{
556 struct rsnd_scu *scu = rsnd_mod_to_scu(mod);
557
558 rsnd_mod_write(mod, SSI_CTRL, 0);
559 rsnd_mod_write(mod, SRC_CTRL, 0);
560
561 rsnd_dma_stop(rsnd_mod_to_dma(&scu->mod));
562
563 return rsnd_scu_stop(mod, rdai, io);
564}
565
566static struct rsnd_mod_ops rsnd_scu_gen2_ops = {
567 .name = "scu (gen2)",
568 .init = rsnd_scu_init_gen2,
569 .quit = rsnd_scu_quit,
570 .start = rsnd_scu_start_gen2,
571 .stop = rsnd_scu_stop_gen2,
572};
573
475static int rsnd_scu_start_non_gen2(struct rsnd_mod *mod, 574static int rsnd_scu_start_non_gen2(struct rsnd_mod *mod,
476 struct rsnd_dai *rdai, 575 struct rsnd_dai *rdai,
477 struct rsnd_dai_stream *io) 576 struct rsnd_dai_stream *io)
@@ -534,6 +633,17 @@ int rsnd_scu_probe(struct platform_device *pdev,
534 if (rsnd_scu_hpbif_is_enable(scu)) { 633 if (rsnd_scu_hpbif_is_enable(scu)) {
535 if (rsnd_is_gen1(priv)) 634 if (rsnd_is_gen1(priv))
536 ops = &rsnd_scu_gen1_ops; 635 ops = &rsnd_scu_gen1_ops;
636 if (rsnd_is_gen2(priv)) {
637 struct rsnd_mod *ssi = rsnd_ssi_mod_get(priv, i);
638 int ret = rsnd_dma_init(priv,
639 rsnd_mod_to_dma(&scu->mod),
640 rsnd_ssi_is_play(ssi),
641 scu->info->dma_id);
642 if (ret < 0)
643 return ret;
644
645 ops = &rsnd_scu_gen2_ops;
646 }
537 } else { 647 } else {
538 if (rsnd_is_gen1(priv)) 648 if (rsnd_is_gen1(priv))
539 ops = &rsnd_scu_non_gen1_ops; 649 ops = &rsnd_scu_non_gen1_ops;
@@ -553,4 +663,11 @@ int rsnd_scu_probe(struct platform_device *pdev,
553void rsnd_scu_remove(struct platform_device *pdev, 663void rsnd_scu_remove(struct platform_device *pdev,
554 struct rsnd_priv *priv) 664 struct rsnd_priv *priv)
555{ 665{
666 struct rsnd_scu *scu;
667 int i;
668
669 for_each_rsnd_scu(scu, priv, i) {
670 if (rsnd_scu_dma_available(scu))
671 rsnd_dma_quit(priv, rsnd_mod_to_dma(&scu->mod));
672 }
556} 673}