xref: /linux/sound/soc/renesas/rcar/ssiu.c (revision ef19ecf042b448a69ee3bd9b3e35689b0b7892ac)
1 // SPDX-License-Identifier: GPL-2.0
2 //
3 // Renesas R-Car SSIU support
4 //
5 // Copyright (c) 2015 Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
6 
7 #include "rsnd.h"
8 
9 #define SSIU_NAME "ssiu"
10 
11 struct rsnd_ssiu {
12 	struct rsnd_mod mod;
13 	u32 busif_status[8]; /* for BUSIF0 - BUSIF7 */
14 	unsigned int usrcnt;
15 	int id;
16 	int id_sub;
17 };
18 
19 /* SSI_MODE */
20 #define TDM_EXT		(1 << 0)
21 #define TDM_SPLIT	(1 << 8)
22 
23 #define rsnd_ssiu_nr(priv) ((priv)->ssiu_nr)
24 #define rsnd_mod_to_ssiu(_mod) container_of((_mod), struct rsnd_ssiu, mod)
25 #define for_each_rsnd_ssiu(pos, priv, i)				\
26 	for (i = 0;							\
27 	     (i < rsnd_ssiu_nr(priv)) &&				\
28 		     ((pos) = ((struct rsnd_ssiu *)(priv)->ssiu + i));	\
29 	     i++)
30 
31 /*
32  *	SSI	Gen2		Gen3		Gen4		RZ/G3E
33  *	0	BUSIF0-3	BUSIF0-7	BUSIF0-7	BUSIF0-3
34  *	1	BUSIF0-3	BUSIF0-7			BUSIF0-3
35  *	2	BUSIF0-3	BUSIF0-7			BUSIF0-3
36  *	3	BUSIF0		BUSIF0-7			BUSIF0-3
37  *	4	BUSIF0		BUSIF0-7			BUSIF0-3
38  *	5	BUSIF0		BUSIF0				BUSIF0
39  *	6	BUSIF0		BUSIF0				BUSIF0
40  *	7	BUSIF0		BUSIF0				BUSIF0
41  *	8	BUSIF0		BUSIF0				BUSIF0
42  *	9	BUSIF0-3	BUSIF0-7			BUSIF0-3
43  *	total	22		52		8		28
44  */
45 static const int gen2_id[] = { 0, 4,  8, 12, 13, 14, 15, 16, 17, 18 };
46 static const int gen3_id[] = { 0, 8, 16, 24, 32, 40, 41, 42, 43, 44 };
47 static const int gen4_id[] = { 0 };
48 static const int rzg3e_id[] = { 0, 4, 8, 12, 16, 20, 21, 22, 23, 24 };
49 
50 struct rsnd_ssiu_ctrl {
51 	unsigned int busif_status_count;
52 };
53 
54 #define rsnd_priv_to_ssiu_ctrl(priv) \
55 	((struct rsnd_ssiu_ctrl *)(priv)->ssiu_ctrl)
56 
57 /* enable busif buffer over/under run interrupt. */
58 #define rsnd_ssiu_busif_err_irq_enable(mod)  rsnd_ssiu_busif_err_irq_ctrl(mod, 1)
59 #define rsnd_ssiu_busif_err_irq_disable(mod) rsnd_ssiu_busif_err_irq_ctrl(mod, 0)
60 static void rsnd_ssiu_busif_err_irq_ctrl(struct rsnd_mod *mod, int enable)
61 {
62 	struct rsnd_priv *priv = rsnd_mod_to_priv(mod);
63 	int id = rsnd_mod_id(mod);
64 	int shift, offset;
65 
66 	switch (id) {
67 	case 0:
68 	case 1:
69 	case 2:
70 	case 3:
71 	case 4:
72 		shift  = id;
73 		offset = 0;
74 		break;
75 	case 9:
76 		shift  = 1;
77 		offset = 1;
78 		break;
79 	default:
80 		return;
81 	}
82 
83 	for (unsigned int i = 0; i < rsnd_priv_to_ssiu_ctrl(priv)->busif_status_count; i++) {
84 		enum rsnd_reg reg = SSI_SYS_INT_ENABLE((i * 2) + offset);
85 		u32 val = 0xf << (shift * 4);
86 		u32 sys_int_enable = rsnd_mod_read(mod, reg);
87 
88 		if (enable)
89 			sys_int_enable |= val;
90 		else
91 			sys_int_enable &= ~val;
92 		rsnd_mod_write(mod, reg, sys_int_enable);
93 	}
94 }
95 
96 bool rsnd_ssiu_busif_err_status_clear(struct rsnd_mod *mod)
97 {
98 	struct rsnd_priv *priv = rsnd_mod_to_priv(mod);
99 	bool error = false;
100 	int id = rsnd_mod_id(mod);
101 	int shift, offset;
102 
103 	switch (id) {
104 	case 0:
105 	case 1:
106 	case 2:
107 	case 3:
108 	case 4:
109 		shift  = id;
110 		offset = 0;
111 		break;
112 	case 9:
113 		shift  = 1;
114 		offset = 1;
115 		break;
116 	default:
117 		goto out;
118 	}
119 
120 	for (unsigned int i = 0; i < rsnd_priv_to_ssiu_ctrl(priv)->busif_status_count; i++) {
121 		u32 reg = SSI_SYS_STATUS(i * 2) + offset;
122 		u32 status = rsnd_mod_read(mod, reg);
123 		u32 val = 0xf << (shift * 4);
124 
125 		status &= val;
126 		if (status) {
127 			struct device *dev = rsnd_priv_to_dev(priv);
128 
129 			rsnd_print_irq_status(dev, "%s err status : 0x%08x\n",
130 					      rsnd_mod_name(mod), status);
131 			error = true;
132 		}
133 		rsnd_mod_write(mod, reg, val);
134 	}
135 out:
136 	return error;
137 }
138 
139 static u32 *rsnd_ssiu_get_status(struct rsnd_mod *mod,
140 				 struct rsnd_dai_stream *io,
141 				 enum rsnd_mod_type type)
142 {
143 	struct rsnd_ssiu *ssiu = rsnd_mod_to_ssiu(mod);
144 	int busif = rsnd_mod_id_sub(mod);
145 
146 	return &ssiu->busif_status[busif];
147 }
148 
149 static int rsnd_ssiu_init(struct rsnd_mod *mod,
150 			  struct rsnd_dai_stream *io,
151 			  struct rsnd_priv *priv)
152 {
153 	struct rsnd_dai *rdai = rsnd_io_to_rdai(io);
154 	u32 ssis = rsnd_ssi_multi_secondaries_runtime(io);
155 	int use_busif = rsnd_ssi_use_busif(io);
156 	int id = rsnd_mod_id(mod);
157 	int is_clk_master = rsnd_rdai_is_clk_master(rdai);
158 	u32 val1, val2;
159 
160 	/* clear status */
161 	rsnd_ssiu_busif_err_status_clear(mod);
162 
163 	/* Gen4 doesn't have SSI_MODE */
164 	if (rsnd_is_gen4(priv))
165 		goto ssi_mode_setting_end;
166 
167 	/*
168 	 * SSI_MODE0
169 	 */
170 	if (!rsnd_is_rzg3e(priv))
171 		rsnd_mod_bset(mod, SSI_MODE0, (1 << id), !use_busif << id);
172 
173 	/*
174 	 * SSI_MODE1 / SSI_MODE2
175 	 *
176 	 * FIXME
177 	 * sharing/multi with SSI0 are mainly supported
178 	 */
179 	val1 = rsnd_mod_read(mod, SSI_MODE1);
180 	val2 = rsnd_mod_read(mod, SSI_MODE2);
181 	if (rsnd_ssi_is_pin_sharing(io)) {
182 
183 		ssis |= (1 << id);
184 
185 	} else if (ssis) {
186 		/*
187 		 * Multi SSI
188 		 *
189 		 * set synchronized bit here
190 		 */
191 
192 		/* SSI4 is synchronized with SSI3 */
193 		if (ssis & (1 << 4))
194 			val1 |= (1 << 20);
195 		/* SSI012 are synchronized */
196 		if (ssis == 0x0006)
197 			val1 |= (1 << 4);
198 		/* SSI0129 are synchronized */
199 		if (ssis == 0x0206)
200 			val2 |= (1 << 4);
201 	}
202 
203 	/* SSI1 is sharing pin with SSI0 */
204 	if (ssis & (1 << 1))
205 		val1 |= is_clk_master ? 0x2 : 0x1;
206 
207 	/* SSI2 is sharing pin with SSI0 */
208 	if (ssis & (1 << 2))
209 		val1 |= is_clk_master ?	0x2 << 2 :
210 					0x1 << 2;
211 	/* SSI4 is sharing pin with SSI3 */
212 	if (ssis & (1 << 4))
213 		val1 |= is_clk_master ? 0x2 << 16 :
214 					0x1 << 16;
215 	/* SSI9 is sharing pin with SSI0 */
216 	if (ssis & (1 << 9))
217 		val2 |= is_clk_master ? 0x2 : 0x1;
218 
219 	rsnd_mod_bset(mod, SSI_MODE1, 0x0013001f, val1);
220 	rsnd_mod_bset(mod, SSI_MODE2, 0x00000017, val2);
221 
222 ssi_mode_setting_end:
223 	/*
224 	 * Enable busif buffer over/under run interrupt.
225 	 * It will be handled from ssi.c
226 	 * see
227 	 *	__rsnd_ssi_interrupt()
228 	 */
229 	rsnd_ssiu_busif_err_irq_enable(mod);
230 
231 	return 0;
232 }
233 
234 static int rsnd_ssiu_quit(struct rsnd_mod *mod,
235 			  struct rsnd_dai_stream *io,
236 			  struct rsnd_priv *priv)
237 {
238 	/* disable busif buffer over/under run interrupt. */
239 	rsnd_ssiu_busif_err_irq_disable(mod);
240 
241 	return 0;
242 }
243 
244 static struct rsnd_mod_ops rsnd_ssiu_ops_gen1 = {
245 	.name		= SSIU_NAME,
246 	.init		= rsnd_ssiu_init,
247 	.quit		= rsnd_ssiu_quit,
248 	.get_status	= rsnd_ssiu_get_status,
249 };
250 
251 static int rsnd_ssiu_init_gen2(struct rsnd_mod *mod,
252 			       struct rsnd_dai_stream *io,
253 			       struct rsnd_priv *priv)
254 {
255 	struct rsnd_ssiu *ssiu = rsnd_mod_to_ssiu(mod);
256 	u32 has_hdmi0 = rsnd_flags_has(io, RSND_STREAM_HDMI0);
257 	u32 has_hdmi1 = rsnd_flags_has(io, RSND_STREAM_HDMI1);
258 	int ret;
259 	u32 mode = 0;
260 
261 	ret = rsnd_ssiu_init(mod, io, priv);
262 	if (ret < 0)
263 		return ret;
264 
265 	ssiu->usrcnt++;
266 
267 	/*
268 	 * TDM Extend/Split Mode
269 	 * see
270 	 *	rsnd_ssi_config_init()
271 	 */
272 	if (rsnd_runtime_is_tdm(io))
273 		mode = TDM_EXT;
274 	else if (rsnd_runtime_is_tdm_split(io))
275 		mode = TDM_SPLIT;
276 
277 	rsnd_mod_write(mod, SSI_MODE, mode);
278 
279 	if (rsnd_ssi_use_busif(io)) {
280 		int id = rsnd_mod_id(mod);
281 		int busif = rsnd_mod_id_sub(mod);
282 		enum rsnd_reg adinr_reg, mode_reg, dalign_reg;
283 
284 		if ((id == 9) && (busif >= 4)) {
285 			adinr_reg = SSI9_BUSIF_ADINR(busif);
286 			mode_reg = SSI9_BUSIF_MODE(busif);
287 			dalign_reg = SSI9_BUSIF_DALIGN(busif);
288 		} else {
289 			adinr_reg = SSI_BUSIF_ADINR(busif);
290 			mode_reg = SSI_BUSIF_MODE(busif);
291 			dalign_reg = SSI_BUSIF_DALIGN(busif);
292 		}
293 
294 		rsnd_mod_write(mod, adinr_reg,
295 			       rsnd_get_adinr_bit(mod, io) |
296 			       (rsnd_io_is_play(io) ?
297 				rsnd_runtime_channel_after_ctu(io) :
298 				rsnd_runtime_channel_original(io)));
299 		rsnd_mod_write(mod, mode_reg,
300 			       rsnd_get_busif_shift(io, mod) | 1);
301 		rsnd_mod_write(mod, dalign_reg,
302 			       rsnd_get_dalign(mod, io));
303 	}
304 
305 	if (has_hdmi0 || has_hdmi1) {
306 		enum rsnd_mod_type rsnd_ssi_array[] = {
307 			RSND_MOD_SSIM1,
308 			RSND_MOD_SSIM2,
309 			RSND_MOD_SSIM3,
310 		};
311 		struct rsnd_mod *ssi_mod = rsnd_io_to_mod_ssi(io);
312 		struct rsnd_mod *pos;
313 		u32 val;
314 		int i;
315 
316 		i = rsnd_mod_id(ssi_mod);
317 
318 		/* output all same SSI as default */
319 		val =	i << 16 |
320 			i << 20 |
321 			i << 24 |
322 			i << 28 |
323 			i;
324 
325 		for_each_rsnd_mod_array(i, pos, io, rsnd_ssi_array) {
326 			int shift = (i * 4) + 20;
327 
328 			val	= (val & ~(0xF << shift)) |
329 				rsnd_mod_id(pos) << shift;
330 		}
331 
332 		if (has_hdmi0)
333 			rsnd_mod_write(mod, HDMI0_SEL, val);
334 		if (has_hdmi1)
335 			rsnd_mod_write(mod, HDMI1_SEL, val);
336 	}
337 
338 	return 0;
339 }
340 
341 static int rsnd_ssiu_start_gen2(struct rsnd_mod *mod,
342 				struct rsnd_dai_stream *io,
343 				struct rsnd_priv *priv)
344 {
345 	int busif = rsnd_mod_id_sub(mod);
346 
347 	if (!rsnd_ssi_use_busif(io))
348 		return 0;
349 
350 	rsnd_mod_bset(mod, SSI_CTRL, 1 << (busif * 4), 1 << (busif * 4));
351 
352 	if (rsnd_ssi_multi_secondaries_runtime(io))
353 		rsnd_mod_write(mod, SSI_CONTROL, 0x1);
354 
355 	return 0;
356 }
357 
358 static int rsnd_ssiu_stop_gen2(struct rsnd_mod *mod,
359 			       struct rsnd_dai_stream *io,
360 			       struct rsnd_priv *priv)
361 {
362 	struct rsnd_ssiu *ssiu = rsnd_mod_to_ssiu(mod);
363 	int busif = rsnd_mod_id_sub(mod);
364 
365 	if (!rsnd_ssi_use_busif(io))
366 		return 0;
367 
368 	rsnd_mod_bset(mod, SSI_CTRL, 1 << (busif * 4), 0);
369 
370 	if (--ssiu->usrcnt)
371 		return 0;
372 
373 	if (rsnd_ssi_multi_secondaries_runtime(io))
374 		rsnd_mod_write(mod, SSI_CONTROL, 0);
375 
376 	return 0;
377 }
378 
379 static int rsnd_ssiu_id(struct rsnd_mod *mod)
380 {
381 	struct rsnd_ssiu *ssiu = rsnd_mod_to_ssiu(mod);
382 
383 	/* see rsnd_ssiu_probe() */
384 	return ssiu->id;
385 }
386 
387 static int rsnd_ssiu_id_sub(struct rsnd_mod *mod)
388 {
389 	struct rsnd_ssiu *ssiu = rsnd_mod_to_ssiu(mod);
390 
391 	/* see rsnd_ssiu_probe() */
392 	return ssiu->id_sub;
393 }
394 
395 static struct dma_chan *rsnd_ssiu_dma_req(struct rsnd_dai_stream *io,
396 					  struct rsnd_mod *mod)
397 {
398 	struct rsnd_priv *priv = rsnd_mod_to_priv(mod);
399 	int is_play = rsnd_io_is_play(io);
400 	char *name;
401 
402 	/*
403 	 * It should use "rcar_sound,ssiu" (R-Car) or "ssiu" (RZ/G3E) on DT.
404 	 * We need to keep compatibility for old versions.
405 	 *
406 	 * If it has "rcar_sound.ssiu" or "ssiu", it will be used.
407 	 * If not, "rcar_sound.ssi" or "ssi" will be used.
408 	 * see
409 	 *	rsnd_ssi_dma_req()
410 	 *	rsnd_dma_of_path()
411 	 */
412 
413 	name = is_play ? "rx" : "tx";
414 
415 	return rsnd_dma_request_channel(rsnd_ssiu_of_node(priv),
416 					SSIU_NAME, mod, name);
417 }
418 
419 #ifdef CONFIG_DEBUG_FS
420 static void rsnd_ssiu_debug_info(struct seq_file *m,
421 				 struct rsnd_dai_stream *io,
422 				struct rsnd_mod *mod)
423 {
424 	rsnd_debugfs_mod_reg_show(m, mod, RSND_BASE_SSIU,
425 				  rsnd_mod_id(mod) * 0x80, 0x80);
426 }
427 #define DEBUG_INFO .debug_info = rsnd_ssiu_debug_info
428 #else
429 #define DEBUG_INFO
430 #endif
431 
432 static struct rsnd_mod_ops rsnd_ssiu_ops_gen2 = {
433 	.name		= SSIU_NAME,
434 	.dma_req	= rsnd_ssiu_dma_req,
435 	.init		= rsnd_ssiu_init_gen2,
436 	.quit		= rsnd_ssiu_quit,
437 	.start		= rsnd_ssiu_start_gen2,
438 	.stop		= rsnd_ssiu_stop_gen2,
439 	.get_status	= rsnd_ssiu_get_status,
440 	DEBUG_INFO
441 };
442 
443 static struct rsnd_mod *rsnd_ssiu_mod_get(struct rsnd_priv *priv, int id)
444 {
445 	if (WARN_ON(id < 0 || id >= rsnd_ssiu_nr(priv)))
446 		id = 0;
447 
448 	return rsnd_mod_get((struct rsnd_ssiu *)(priv->ssiu) + id);
449 }
450 
451 static void rsnd_parse_connect_ssiu_compatible(struct rsnd_priv *priv,
452 					       struct rsnd_dai_stream *io)
453 {
454 	struct rsnd_mod *ssi_mod = rsnd_io_to_mod_ssi(io);
455 	struct rsnd_ssiu *ssiu;
456 	int is_dma_mode;
457 	int i;
458 
459 	if (!ssi_mod)
460 		return;
461 
462 	is_dma_mode = rsnd_ssi_is_dma_mode(ssi_mod);
463 
464 	/* select BUSIF0 */
465 	for_each_rsnd_ssiu(ssiu, priv, i) {
466 		struct rsnd_mod *mod = rsnd_mod_get(ssiu);
467 
468 		if (is_dma_mode &&
469 		    (rsnd_mod_id(ssi_mod) == rsnd_mod_id(mod)) &&
470 		    (rsnd_mod_id_sub(mod) == 0)) {
471 			rsnd_dai_connect(mod, io, mod->type);
472 			return;
473 		}
474 	}
475 }
476 
477 void rsnd_parse_connect_ssiu(struct rsnd_dai *rdai,
478 			     struct device_node *playback,
479 			     struct device_node *capture)
480 {
481 	struct rsnd_priv *priv = rsnd_rdai_to_priv(rdai);
482 	struct device *dev = rsnd_priv_to_dev(priv);
483 	struct device_node *node = rsnd_ssiu_of_node(priv);
484 	struct rsnd_dai_stream *io_p = &rdai->playback;
485 	struct rsnd_dai_stream *io_c = &rdai->capture;
486 
487 	/* use rcar_sound,ssiu if exist */
488 	if (node) {
489 		int i = 0;
490 
491 		for_each_child_of_node_scoped(node, np) {
492 			struct rsnd_mod *mod;
493 
494 			i = rsnd_node_fixed_index(dev, np, SSIU_NAME, i);
495 			if (i < 0)
496 				break;
497 
498 			mod = rsnd_ssiu_mod_get(priv, i);
499 
500 			if (np == playback)
501 				rsnd_dai_connect(mod, io_p, mod->type);
502 			if (np == capture)
503 				rsnd_dai_connect(mod, io_c, mod->type);
504 			i++;
505 		}
506 
507 		of_node_put(node);
508 	}
509 
510 	/* Keep DT compatibility */
511 	if (!rsnd_io_to_mod_ssiu(io_p))
512 		rsnd_parse_connect_ssiu_compatible(priv, io_p);
513 	if (!rsnd_io_to_mod_ssiu(io_c))
514 		rsnd_parse_connect_ssiu_compatible(priv, io_c);
515 }
516 
517 int rsnd_ssiu_probe(struct rsnd_priv *priv)
518 {
519 	struct device *dev = rsnd_priv_to_dev(priv);
520 	struct device_node *node __free(device_node) = rsnd_ssiu_of_node(priv);
521 	struct reset_control *rstc;
522 	struct rsnd_ssiu_ctrl *ctrl;
523 	struct rsnd_ssiu *ssiu;
524 	struct rsnd_mod_ops *ops;
525 	const int *list = NULL;
526 	int i, nr;
527 
528 	/*
529 	 * Keep DT compatibility.
530 	 * if it has "rcar_sound,ssiu", use it.
531 	 * if not, use "rcar_sound,ssi"
532 	 * see
533 	 *	rsnd_ssiu_bufsif_to_id()
534 	 */
535 	if (node)
536 		nr = rsnd_node_count(priv, node, SSIU_NAME);
537 	else
538 		nr = priv->ssi_nr;
539 
540 	if (!nr)
541 		return -EINVAL;
542 
543 	ssiu	= devm_kcalloc(dev, nr, sizeof(*ssiu), GFP_KERNEL);
544 	if (!ssiu)
545 		return -ENOMEM;
546 
547 	ctrl = devm_kzalloc(dev, sizeof(*ctrl), GFP_KERNEL);
548 	if (!ctrl)
549 		return -ENOMEM;
550 
551 	ctrl->busif_status_count = rsnd_flags_has(priv, RSND_SSIU_BUSIF_STATUS_COUNT_2) ? 2 : 4;
552 
553 	priv->ssiu	= ssiu;
554 	priv->ssiu_nr	= nr;
555 	priv->ssiu_ctrl	= ctrl;
556 
557 	if (rsnd_is_gen1(priv))
558 		ops = &rsnd_ssiu_ops_gen1;
559 	else
560 		ops = &rsnd_ssiu_ops_gen2;
561 
562 	/* Keep compatibility */
563 	nr = 0;
564 	if ((node) &&
565 	    (ops == &rsnd_ssiu_ops_gen2)) {
566 		ops->id		= rsnd_ssiu_id;
567 		ops->id_sub	= rsnd_ssiu_id_sub;
568 
569 		if (rsnd_is_gen2(priv)) {
570 			list	= gen2_id;
571 			nr	= ARRAY_SIZE(gen2_id);
572 		} else if (rsnd_is_gen3(priv)) {
573 			list	= gen3_id;
574 			nr	= ARRAY_SIZE(gen3_id);
575 		} else if (rsnd_is_gen4(priv)) {
576 			list	= gen4_id;
577 			nr	= ARRAY_SIZE(gen4_id);
578 		} else if (rsnd_is_rzg3e(priv)) {
579 			list	= rzg3e_id;
580 			nr	= ARRAY_SIZE(rzg3e_id);
581 		} else {
582 			dev_err(dev, "unknown SSIU\n");
583 			return -ENODEV;
584 		}
585 	}
586 
587 	/* Acquire shared reset once for all SSIU modules */
588 	rstc = devm_reset_control_get_optional_shared(dev, "ssi-all");
589 	if (IS_ERR(rstc))
590 		return dev_err_probe(dev, PTR_ERR(rstc),
591 				     "failed to get ssi-all reset\n");
592 
593 	for_each_rsnd_ssiu(ssiu, priv, i) {
594 		int ret;
595 
596 		if (node) {
597 			int j;
598 
599 			/*
600 			 * see
601 			 *	rsnd_ssiu_get_id()
602 			 *	rsnd_ssiu_get_id_sub()
603 			 */
604 			for (j = 0; j < nr; j++) {
605 				if (list[j] > i)
606 					break;
607 				ssiu->id	= j;
608 				ssiu->id_sub	= i - list[ssiu->id];
609 			}
610 		} else {
611 			ssiu->id = i;
612 		}
613 
614 		ret = rsnd_mod_init(priv, rsnd_mod_get(ssiu),
615 				    ops, NULL, rstc, RSND_MOD_SSIU, i);
616 		if (ret)
617 			return ret;
618 	}
619 
620 	return 0;
621 }
622 
623 void rsnd_ssiu_remove(struct rsnd_priv *priv)
624 {
625 	struct rsnd_ssiu *ssiu;
626 	int i;
627 
628 	for_each_rsnd_ssiu(ssiu, priv, i) {
629 		rsnd_mod_quit(rsnd_mod_get(ssiu));
630 	}
631 }
632 
633 void rsnd_ssiu_suspend(struct rsnd_priv *priv)
634 {
635 	struct rsnd_ssiu *ssiu;
636 	int i;
637 
638 	for_each_rsnd_ssiu(ssiu, priv, i)
639 		rsnd_suspend_clk_reset(rsnd_mod_get(ssiu)->clk,
640 				       rsnd_mod_get(ssiu)->rstc);
641 }
642 
643 void rsnd_ssiu_resume(struct rsnd_priv *priv)
644 {
645 	struct rsnd_ssiu *ssiu;
646 	int i;
647 
648 	for_each_rsnd_ssiu(ssiu, priv, i)
649 		rsnd_resume_clk_reset(rsnd_mod_get(ssiu)->clk,
650 				      rsnd_mod_get(ssiu)->rstc);
651 }
652