xref: /openbmc/linux/sound/soc/sh/rcar/src.c (revision ba9c949f797aa3af56303445812a452144c61c35)
1*ba9c949fSKuninori Morimoto /*
2*ba9c949fSKuninori Morimoto  * Renesas R-Car SRC support
3*ba9c949fSKuninori Morimoto  *
4*ba9c949fSKuninori Morimoto  * Copyright (C) 2013 Renesas Solutions Corp.
5*ba9c949fSKuninori Morimoto  * Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
6*ba9c949fSKuninori Morimoto  *
7*ba9c949fSKuninori Morimoto  * This program is free software; you can redistribute it and/or modify
8*ba9c949fSKuninori Morimoto  * it under the terms of the GNU General Public License version 2 as
9*ba9c949fSKuninori Morimoto  * published by the Free Software Foundation.
10*ba9c949fSKuninori Morimoto  */
11*ba9c949fSKuninori Morimoto #include "rsnd.h"
12*ba9c949fSKuninori Morimoto 
13*ba9c949fSKuninori Morimoto struct rsnd_src {
14*ba9c949fSKuninori Morimoto 	struct rsnd_src_platform_info *info; /* rcar_snd.h */
15*ba9c949fSKuninori Morimoto 	struct rsnd_mod mod;
16*ba9c949fSKuninori Morimoto 	struct clk *clk;
17*ba9c949fSKuninori Morimoto };
18*ba9c949fSKuninori Morimoto 
19*ba9c949fSKuninori Morimoto #define RSND_SRC_NAME_SIZE 16
20*ba9c949fSKuninori Morimoto 
21*ba9c949fSKuninori Morimoto /*
22*ba9c949fSKuninori Morimoto  * ADINR
23*ba9c949fSKuninori Morimoto  */
24*ba9c949fSKuninori Morimoto #define OTBL_24		(0 << 16)
25*ba9c949fSKuninori Morimoto #define OTBL_22		(2 << 16)
26*ba9c949fSKuninori Morimoto #define OTBL_20		(4 << 16)
27*ba9c949fSKuninori Morimoto #define OTBL_18		(6 << 16)
28*ba9c949fSKuninori Morimoto #define OTBL_16		(8 << 16)
29*ba9c949fSKuninori Morimoto 
30*ba9c949fSKuninori Morimoto #define rsnd_src_mode_flags(p) ((p)->info->flags)
31*ba9c949fSKuninori Morimoto #define rsnd_src_convert_rate(p) ((p)->info->convert_rate)
32*ba9c949fSKuninori Morimoto #define rsnd_mod_to_src(_mod)				\
33*ba9c949fSKuninori Morimoto 	container_of((_mod), struct rsnd_src, mod)
34*ba9c949fSKuninori Morimoto #define rsnd_src_hpbif_is_enable(src)	\
35*ba9c949fSKuninori Morimoto 	(rsnd_src_mode_flags(src) & RSND_SCU_USE_HPBIF)
36*ba9c949fSKuninori Morimoto #define rsnd_src_dma_available(src) \
37*ba9c949fSKuninori Morimoto 	rsnd_dma_available(rsnd_mod_to_dma(&(src)->mod))
38*ba9c949fSKuninori Morimoto 
39*ba9c949fSKuninori Morimoto #define for_each_rsnd_src(pos, priv, i)				\
40*ba9c949fSKuninori Morimoto 	for ((i) = 0;						\
41*ba9c949fSKuninori Morimoto 	     ((i) < rsnd_src_nr(priv)) &&			\
42*ba9c949fSKuninori Morimoto 	     ((pos) = (struct rsnd_src *)(priv)->src + i);	\
43*ba9c949fSKuninori Morimoto 	     i++)
44*ba9c949fSKuninori Morimoto 
45*ba9c949fSKuninori Morimoto 
46*ba9c949fSKuninori Morimoto /*
47*ba9c949fSKuninori Morimoto  *		image of SRC (Sampling Rate Converter)
48*ba9c949fSKuninori Morimoto  *
49*ba9c949fSKuninori Morimoto  * 96kHz   <-> +-----+	48kHz	+-----+	 48kHz	+-------+
50*ba9c949fSKuninori Morimoto  * 48kHz   <-> | SRC | <------>	| SSI |	<----->	| codec |
51*ba9c949fSKuninori Morimoto  * 44.1kHz <-> +-----+		+-----+		+-------+
52*ba9c949fSKuninori Morimoto  * ...
53*ba9c949fSKuninori Morimoto  *
54*ba9c949fSKuninori Morimoto  */
55*ba9c949fSKuninori Morimoto 
56*ba9c949fSKuninori Morimoto /*
57*ba9c949fSKuninori Morimoto  * src.c is caring...
58*ba9c949fSKuninori Morimoto  *
59*ba9c949fSKuninori Morimoto  * Gen1
60*ba9c949fSKuninori Morimoto  *
61*ba9c949fSKuninori Morimoto  * [mem] -> [SRU] -> [SSI]
62*ba9c949fSKuninori Morimoto  *        |--------|
63*ba9c949fSKuninori Morimoto  *
64*ba9c949fSKuninori Morimoto  * Gen2
65*ba9c949fSKuninori Morimoto  *
66*ba9c949fSKuninori Morimoto  * [mem] -> [SRC] -> [SSIU] -> [SSI]
67*ba9c949fSKuninori Morimoto  *        |-----------------|
68*ba9c949fSKuninori Morimoto  */
69*ba9c949fSKuninori Morimoto 
70*ba9c949fSKuninori Morimoto /*
71*ba9c949fSKuninori Morimoto  *	How to use SRC bypass mode for debugging
72*ba9c949fSKuninori Morimoto  *
73*ba9c949fSKuninori Morimoto  * SRC has bypass mode, and it is useful for debugging.
74*ba9c949fSKuninori Morimoto  * In Gen2 case,
75*ba9c949fSKuninori Morimoto  * SRCm_MODE controls whether SRC is used or not
76*ba9c949fSKuninori Morimoto  * SSI_MODE0 controls whether SSIU which receives SRC data
77*ba9c949fSKuninori Morimoto  * is used or not.
78*ba9c949fSKuninori Morimoto  * Both SRCm_MODE/SSI_MODE0 settings are needed if you use SRC,
79*ba9c949fSKuninori Morimoto  * but SRC bypass mode needs SSI_MODE0 only.
80*ba9c949fSKuninori Morimoto  *
81*ba9c949fSKuninori Morimoto  * This driver request
82*ba9c949fSKuninori Morimoto  * struct rsnd_src_platform_info {
83*ba9c949fSKuninori Morimoto  *	u32 flags;
84*ba9c949fSKuninori Morimoto  *	u32 convert_rate;
85*ba9c949fSKuninori Morimoto  * }
86*ba9c949fSKuninori Morimoto  *
87*ba9c949fSKuninori Morimoto  * rsnd_src_hpbif_is_enable() will be true
88*ba9c949fSKuninori Morimoto  * if flags had RSND_SRC_USE_HPBIF,
89*ba9c949fSKuninori Morimoto  * and it controls whether SSIU is used or not.
90*ba9c949fSKuninori Morimoto  *
91*ba9c949fSKuninori Morimoto  * rsnd_src_convert_rate() indicates
92*ba9c949fSKuninori Morimoto  * above convert_rate, and it controls
93*ba9c949fSKuninori Morimoto  * whether SRC is used or not.
94*ba9c949fSKuninori Morimoto  *
95*ba9c949fSKuninori Morimoto  * ex) doesn't use SRC
96*ba9c949fSKuninori Morimoto  * struct rsnd_src_platform_info info = {
97*ba9c949fSKuninori Morimoto  *	.flags = 0,
98*ba9c949fSKuninori Morimoto  *	.convert_rate = 0,
99*ba9c949fSKuninori Morimoto  * };
100*ba9c949fSKuninori Morimoto  *
101*ba9c949fSKuninori Morimoto  * ex) uses SRC
102*ba9c949fSKuninori Morimoto  * struct rsnd_src_platform_info info = {
103*ba9c949fSKuninori Morimoto  *	.flags = RSND_SRC_USE_HPBIF,
104*ba9c949fSKuninori Morimoto  *	.convert_rate = 48000,
105*ba9c949fSKuninori Morimoto  * };
106*ba9c949fSKuninori Morimoto  *
107*ba9c949fSKuninori Morimoto  * ex) uses SRC bypass mode
108*ba9c949fSKuninori Morimoto  * struct rsnd_src_platform_info info = {
109*ba9c949fSKuninori Morimoto  *	.flags = RSND_SRC_USE_HPBIF,
110*ba9c949fSKuninori Morimoto  *	.convert_rate = 0,
111*ba9c949fSKuninori Morimoto  * };
112*ba9c949fSKuninori Morimoto  *
113*ba9c949fSKuninori Morimoto  */
114*ba9c949fSKuninori Morimoto 
115*ba9c949fSKuninori Morimoto /*
116*ba9c949fSKuninori Morimoto  *		Gen1/Gen2 common functions
117*ba9c949fSKuninori Morimoto  */
118*ba9c949fSKuninori Morimoto int rsnd_src_ssi_mode_init(struct rsnd_mod *ssi_mod,
119*ba9c949fSKuninori Morimoto 			   struct rsnd_dai *rdai,
120*ba9c949fSKuninori Morimoto 			   struct rsnd_dai_stream *io)
121*ba9c949fSKuninori Morimoto {
122*ba9c949fSKuninori Morimoto 	struct rsnd_priv *priv = rsnd_mod_to_priv(ssi_mod);
123*ba9c949fSKuninori Morimoto 	struct rsnd_mod *src_mod = rsnd_io_to_mod_src(io);
124*ba9c949fSKuninori Morimoto 	struct rcar_snd_info *info = rsnd_priv_to_info(priv);
125*ba9c949fSKuninori Morimoto 	int ssi_id = rsnd_mod_id(ssi_mod);
126*ba9c949fSKuninori Morimoto 	int has_src = 0;
127*ba9c949fSKuninori Morimoto 
128*ba9c949fSKuninori Morimoto 	/*
129*ba9c949fSKuninori Morimoto 	 * SSI_MODE0
130*ba9c949fSKuninori Morimoto 	 */
131*ba9c949fSKuninori Morimoto 	if (info->dai_info) {
132*ba9c949fSKuninori Morimoto 		has_src = !!src_mod;
133*ba9c949fSKuninori Morimoto 	} else {
134*ba9c949fSKuninori Morimoto 		struct rsnd_src *src = rsnd_mod_to_src(src_mod);
135*ba9c949fSKuninori Morimoto 		has_src = rsnd_src_hpbif_is_enable(src);
136*ba9c949fSKuninori Morimoto 	}
137*ba9c949fSKuninori Morimoto 
138*ba9c949fSKuninori Morimoto 	rsnd_mod_bset(ssi_mod, SSI_MODE0, (1 << ssi_id),
139*ba9c949fSKuninori Morimoto 		      has_src ? 0 : (1 << ssi_id));
140*ba9c949fSKuninori Morimoto 
141*ba9c949fSKuninori Morimoto 	/*
142*ba9c949fSKuninori Morimoto 	 * SSI_MODE1
143*ba9c949fSKuninori Morimoto 	 */
144*ba9c949fSKuninori Morimoto 	if (rsnd_ssi_is_pin_sharing(ssi_mod)) {
145*ba9c949fSKuninori Morimoto 		int shift = -1;
146*ba9c949fSKuninori Morimoto 		switch (ssi_id) {
147*ba9c949fSKuninori Morimoto 		case 1:
148*ba9c949fSKuninori Morimoto 			shift = 0;
149*ba9c949fSKuninori Morimoto 			break;
150*ba9c949fSKuninori Morimoto 		case 2:
151*ba9c949fSKuninori Morimoto 			shift = 2;
152*ba9c949fSKuninori Morimoto 			break;
153*ba9c949fSKuninori Morimoto 		case 4:
154*ba9c949fSKuninori Morimoto 			shift = 16;
155*ba9c949fSKuninori Morimoto 			break;
156*ba9c949fSKuninori Morimoto 		}
157*ba9c949fSKuninori Morimoto 
158*ba9c949fSKuninori Morimoto 		if (shift >= 0)
159*ba9c949fSKuninori Morimoto 			rsnd_mod_bset(ssi_mod, SSI_MODE1,
160*ba9c949fSKuninori Morimoto 				      0x3 << shift,
161*ba9c949fSKuninori Morimoto 				      rsnd_dai_is_clk_master(rdai) ?
162*ba9c949fSKuninori Morimoto 				      0x2 << shift : 0x1 << shift);
163*ba9c949fSKuninori Morimoto 	}
164*ba9c949fSKuninori Morimoto 
165*ba9c949fSKuninori Morimoto 	return 0;
166*ba9c949fSKuninori Morimoto }
167*ba9c949fSKuninori Morimoto 
168*ba9c949fSKuninori Morimoto int rsnd_src_enable_ssi_irq(struct rsnd_mod *ssi_mod,
169*ba9c949fSKuninori Morimoto 			    struct rsnd_dai *rdai,
170*ba9c949fSKuninori Morimoto 			    struct rsnd_dai_stream *io)
171*ba9c949fSKuninori Morimoto {
172*ba9c949fSKuninori Morimoto 	struct rsnd_priv *priv = rsnd_mod_to_priv(ssi_mod);
173*ba9c949fSKuninori Morimoto 
174*ba9c949fSKuninori Morimoto 	/* enable PIO interrupt if Gen2 */
175*ba9c949fSKuninori Morimoto 	if (rsnd_is_gen2(priv))
176*ba9c949fSKuninori Morimoto 		rsnd_mod_write(ssi_mod, INT_ENABLE, 0x0f000000);
177*ba9c949fSKuninori Morimoto 
178*ba9c949fSKuninori Morimoto 	return 0;
179*ba9c949fSKuninori Morimoto }
180*ba9c949fSKuninori Morimoto 
181*ba9c949fSKuninori Morimoto unsigned int rsnd_src_get_ssi_rate(struct rsnd_priv *priv,
182*ba9c949fSKuninori Morimoto 				   struct rsnd_dai_stream *io,
183*ba9c949fSKuninori Morimoto 				   struct snd_pcm_runtime *runtime)
184*ba9c949fSKuninori Morimoto {
185*ba9c949fSKuninori Morimoto 	struct rsnd_src *src;
186*ba9c949fSKuninori Morimoto 	unsigned int rate;
187*ba9c949fSKuninori Morimoto 
188*ba9c949fSKuninori Morimoto 	src = rsnd_mod_to_src(rsnd_io_to_mod_src(io));
189*ba9c949fSKuninori Morimoto 
190*ba9c949fSKuninori Morimoto 	/*
191*ba9c949fSKuninori Morimoto 	 * return convert rate if SRC is used,
192*ba9c949fSKuninori Morimoto 	 * otherwise, return runtime->rate as usual
193*ba9c949fSKuninori Morimoto 	 */
194*ba9c949fSKuninori Morimoto 	rate = rsnd_src_convert_rate(src);
195*ba9c949fSKuninori Morimoto 	if (!rate)
196*ba9c949fSKuninori Morimoto 		rate = runtime->rate;
197*ba9c949fSKuninori Morimoto 
198*ba9c949fSKuninori Morimoto 	return rate;
199*ba9c949fSKuninori Morimoto }
200*ba9c949fSKuninori Morimoto 
201*ba9c949fSKuninori Morimoto static int rsnd_src_set_convert_rate(struct rsnd_mod *mod,
202*ba9c949fSKuninori Morimoto 				     struct rsnd_dai *rdai,
203*ba9c949fSKuninori Morimoto 				     struct rsnd_dai_stream *io)
204*ba9c949fSKuninori Morimoto {
205*ba9c949fSKuninori Morimoto 	struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io);
206*ba9c949fSKuninori Morimoto 	struct rsnd_src *src = rsnd_mod_to_src(mod);
207*ba9c949fSKuninori Morimoto 	u32 convert_rate = rsnd_src_convert_rate(src);
208*ba9c949fSKuninori Morimoto 	u32 adinr = runtime->channels;
209*ba9c949fSKuninori Morimoto 	u32 fsrate = 0;
210*ba9c949fSKuninori Morimoto 
211*ba9c949fSKuninori Morimoto 	if (convert_rate)
212*ba9c949fSKuninori Morimoto 		fsrate = 0x0400000 / convert_rate * runtime->rate;
213*ba9c949fSKuninori Morimoto 
214*ba9c949fSKuninori Morimoto 	/* set/clear soft reset */
215*ba9c949fSKuninori Morimoto 	rsnd_mod_write(mod, SRC_SWRSR, 0);
216*ba9c949fSKuninori Morimoto 	rsnd_mod_write(mod, SRC_SWRSR, 1);
217*ba9c949fSKuninori Morimoto 
218*ba9c949fSKuninori Morimoto 	/*
219*ba9c949fSKuninori Morimoto 	 * Initialize the operation of the SRC internal circuits
220*ba9c949fSKuninori Morimoto 	 * see rsnd_src_start()
221*ba9c949fSKuninori Morimoto 	 */
222*ba9c949fSKuninori Morimoto 	rsnd_mod_write(mod, SRC_SRCIR, 1);
223*ba9c949fSKuninori Morimoto 
224*ba9c949fSKuninori Morimoto 	/* Set channel number and output bit length */
225*ba9c949fSKuninori Morimoto 	switch (runtime->sample_bits) {
226*ba9c949fSKuninori Morimoto 	case 16:
227*ba9c949fSKuninori Morimoto 		adinr |= OTBL_16;
228*ba9c949fSKuninori Morimoto 		break;
229*ba9c949fSKuninori Morimoto 	case 32:
230*ba9c949fSKuninori Morimoto 		adinr |= OTBL_24;
231*ba9c949fSKuninori Morimoto 		break;
232*ba9c949fSKuninori Morimoto 	default:
233*ba9c949fSKuninori Morimoto 		return -EIO;
234*ba9c949fSKuninori Morimoto 	}
235*ba9c949fSKuninori Morimoto 	rsnd_mod_write(mod, SRC_ADINR, adinr);
236*ba9c949fSKuninori Morimoto 
237*ba9c949fSKuninori Morimoto 	/* Enable the initial value of IFS */
238*ba9c949fSKuninori Morimoto 	if (fsrate) {
239*ba9c949fSKuninori Morimoto 		rsnd_mod_write(mod, SRC_IFSCR, 1);
240*ba9c949fSKuninori Morimoto 
241*ba9c949fSKuninori Morimoto 		/* Set initial value of IFS */
242*ba9c949fSKuninori Morimoto 		rsnd_mod_write(mod, SRC_IFSVR, fsrate);
243*ba9c949fSKuninori Morimoto 	}
244*ba9c949fSKuninori Morimoto 
245*ba9c949fSKuninori Morimoto 	/* use DMA transfer */
246*ba9c949fSKuninori Morimoto 	rsnd_mod_write(mod, SRC_BUSIF_MODE, 1);
247*ba9c949fSKuninori Morimoto 
248*ba9c949fSKuninori Morimoto 	return 0;
249*ba9c949fSKuninori Morimoto }
250*ba9c949fSKuninori Morimoto 
251*ba9c949fSKuninori Morimoto static int rsnd_src_init(struct rsnd_mod *mod,
252*ba9c949fSKuninori Morimoto 			 struct rsnd_dai *rdai,
253*ba9c949fSKuninori Morimoto 			 struct rsnd_dai_stream *io)
254*ba9c949fSKuninori Morimoto {
255*ba9c949fSKuninori Morimoto 	struct rsnd_src *src = rsnd_mod_to_src(mod);
256*ba9c949fSKuninori Morimoto 
257*ba9c949fSKuninori Morimoto 	clk_enable(src->clk);
258*ba9c949fSKuninori Morimoto 
259*ba9c949fSKuninori Morimoto 	return 0;
260*ba9c949fSKuninori Morimoto }
261*ba9c949fSKuninori Morimoto 
262*ba9c949fSKuninori Morimoto static int rsnd_src_quit(struct rsnd_mod *mod,
263*ba9c949fSKuninori Morimoto 			 struct rsnd_dai *rdai,
264*ba9c949fSKuninori Morimoto 			 struct rsnd_dai_stream *io)
265*ba9c949fSKuninori Morimoto {
266*ba9c949fSKuninori Morimoto 	struct rsnd_src *src = rsnd_mod_to_src(mod);
267*ba9c949fSKuninori Morimoto 
268*ba9c949fSKuninori Morimoto 	clk_disable(src->clk);
269*ba9c949fSKuninori Morimoto 
270*ba9c949fSKuninori Morimoto 	return 0;
271*ba9c949fSKuninori Morimoto }
272*ba9c949fSKuninori Morimoto 
273*ba9c949fSKuninori Morimoto static int rsnd_src_start(struct rsnd_mod *mod,
274*ba9c949fSKuninori Morimoto 			  struct rsnd_dai *rdai,
275*ba9c949fSKuninori Morimoto 			  struct rsnd_dai_stream *io)
276*ba9c949fSKuninori Morimoto {
277*ba9c949fSKuninori Morimoto 	struct rsnd_src *src = rsnd_mod_to_src(mod);
278*ba9c949fSKuninori Morimoto 
279*ba9c949fSKuninori Morimoto 	/*
280*ba9c949fSKuninori Morimoto 	 * Cancel the initialization and operate the SRC function
281*ba9c949fSKuninori Morimoto 	 * see rsnd_src_set_convert_rate()
282*ba9c949fSKuninori Morimoto 	 */
283*ba9c949fSKuninori Morimoto 	rsnd_mod_write(mod, SRC_SRCIR, 0);
284*ba9c949fSKuninori Morimoto 
285*ba9c949fSKuninori Morimoto 	if (rsnd_src_convert_rate(src))
286*ba9c949fSKuninori Morimoto 		rsnd_mod_write(mod, SRC_ROUTE_MODE0, 1);
287*ba9c949fSKuninori Morimoto 
288*ba9c949fSKuninori Morimoto 	return 0;
289*ba9c949fSKuninori Morimoto }
290*ba9c949fSKuninori Morimoto 
291*ba9c949fSKuninori Morimoto 
292*ba9c949fSKuninori Morimoto static int rsnd_src_stop(struct rsnd_mod *mod,
293*ba9c949fSKuninori Morimoto 			 struct rsnd_dai *rdai,
294*ba9c949fSKuninori Morimoto 			 struct rsnd_dai_stream *io)
295*ba9c949fSKuninori Morimoto {
296*ba9c949fSKuninori Morimoto 	struct rsnd_src *src = rsnd_mod_to_src(mod);
297*ba9c949fSKuninori Morimoto 
298*ba9c949fSKuninori Morimoto 	if (rsnd_src_convert_rate(src))
299*ba9c949fSKuninori Morimoto 		rsnd_mod_write(mod, SRC_ROUTE_MODE0, 0);
300*ba9c949fSKuninori Morimoto 
301*ba9c949fSKuninori Morimoto 	return 0;
302*ba9c949fSKuninori Morimoto }
303*ba9c949fSKuninori Morimoto 
304*ba9c949fSKuninori Morimoto static struct rsnd_mod_ops rsnd_src_non_ops = {
305*ba9c949fSKuninori Morimoto 	.name	= "src (non)",
306*ba9c949fSKuninori Morimoto };
307*ba9c949fSKuninori Morimoto 
308*ba9c949fSKuninori Morimoto /*
309*ba9c949fSKuninori Morimoto  *		Gen1 functions
310*ba9c949fSKuninori Morimoto  */
311*ba9c949fSKuninori Morimoto static int rsnd_src_set_route_gen1(struct rsnd_mod *mod,
312*ba9c949fSKuninori Morimoto 				   struct rsnd_dai *rdai,
313*ba9c949fSKuninori Morimoto 				   struct rsnd_dai_stream *io)
314*ba9c949fSKuninori Morimoto {
315*ba9c949fSKuninori Morimoto 	struct src_route_config {
316*ba9c949fSKuninori Morimoto 		u32 mask;
317*ba9c949fSKuninori Morimoto 		int shift;
318*ba9c949fSKuninori Morimoto 	} routes[] = {
319*ba9c949fSKuninori Morimoto 		{ 0xF,  0, }, /* 0 */
320*ba9c949fSKuninori Morimoto 		{ 0xF,  4, }, /* 1 */
321*ba9c949fSKuninori Morimoto 		{ 0xF,  8, }, /* 2 */
322*ba9c949fSKuninori Morimoto 		{ 0x7, 12, }, /* 3 */
323*ba9c949fSKuninori Morimoto 		{ 0x7, 16, }, /* 4 */
324*ba9c949fSKuninori Morimoto 		{ 0x7, 20, }, /* 5 */
325*ba9c949fSKuninori Morimoto 		{ 0x7, 24, }, /* 6 */
326*ba9c949fSKuninori Morimoto 		{ 0x3, 28, }, /* 7 */
327*ba9c949fSKuninori Morimoto 		{ 0x3, 30, }, /* 8 */
328*ba9c949fSKuninori Morimoto 	};
329*ba9c949fSKuninori Morimoto 	u32 mask;
330*ba9c949fSKuninori Morimoto 	u32 val;
331*ba9c949fSKuninori Morimoto 	int id;
332*ba9c949fSKuninori Morimoto 
333*ba9c949fSKuninori Morimoto 	id = rsnd_mod_id(mod);
334*ba9c949fSKuninori Morimoto 	if (id < 0 || id >= ARRAY_SIZE(routes))
335*ba9c949fSKuninori Morimoto 		return -EIO;
336*ba9c949fSKuninori Morimoto 
337*ba9c949fSKuninori Morimoto 	/*
338*ba9c949fSKuninori Morimoto 	 * SRC_ROUTE_SELECT
339*ba9c949fSKuninori Morimoto 	 */
340*ba9c949fSKuninori Morimoto 	val = rsnd_dai_is_play(rdai, io) ? 0x1 : 0x2;
341*ba9c949fSKuninori Morimoto 	val = val		<< routes[id].shift;
342*ba9c949fSKuninori Morimoto 	mask = routes[id].mask	<< routes[id].shift;
343*ba9c949fSKuninori Morimoto 
344*ba9c949fSKuninori Morimoto 	rsnd_mod_bset(mod, SRC_ROUTE_SEL, mask, val);
345*ba9c949fSKuninori Morimoto 
346*ba9c949fSKuninori Morimoto 	return 0;
347*ba9c949fSKuninori Morimoto }
348*ba9c949fSKuninori Morimoto 
349*ba9c949fSKuninori Morimoto static int rsnd_src_set_convert_timing_gen1(struct rsnd_mod *mod,
350*ba9c949fSKuninori Morimoto 					    struct rsnd_dai *rdai,
351*ba9c949fSKuninori Morimoto 					    struct rsnd_dai_stream *io)
352*ba9c949fSKuninori Morimoto {
353*ba9c949fSKuninori Morimoto 	struct rsnd_priv *priv = rsnd_mod_to_priv(mod);
354*ba9c949fSKuninori Morimoto 	struct rsnd_src *src = rsnd_mod_to_src(mod);
355*ba9c949fSKuninori Morimoto 	struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io);
356*ba9c949fSKuninori Morimoto 	u32 convert_rate = rsnd_src_convert_rate(src);
357*ba9c949fSKuninori Morimoto 	u32 mask;
358*ba9c949fSKuninori Morimoto 	u32 val;
359*ba9c949fSKuninori Morimoto 	int shift;
360*ba9c949fSKuninori Morimoto 	int id = rsnd_mod_id(mod);
361*ba9c949fSKuninori Morimoto 	int ret;
362*ba9c949fSKuninori Morimoto 
363*ba9c949fSKuninori Morimoto 	/*
364*ba9c949fSKuninori Morimoto 	 * SRC_TIMING_SELECT
365*ba9c949fSKuninori Morimoto 	 */
366*ba9c949fSKuninori Morimoto 	shift	= (id % 4) * 8;
367*ba9c949fSKuninori Morimoto 	mask	= 0x1F << shift;
368*ba9c949fSKuninori Morimoto 
369*ba9c949fSKuninori Morimoto 	/*
370*ba9c949fSKuninori Morimoto 	 * ADG is used as source clock if SRC was used,
371*ba9c949fSKuninori Morimoto 	 * then, SSI WS is used as destination clock.
372*ba9c949fSKuninori Morimoto 	 * SSI WS is used as source clock if SRC is not used
373*ba9c949fSKuninori Morimoto 	 * (when playback, source/destination become reverse when capture)
374*ba9c949fSKuninori Morimoto 	 */
375*ba9c949fSKuninori Morimoto 	ret = 0;
376*ba9c949fSKuninori Morimoto 	if (convert_rate) {
377*ba9c949fSKuninori Morimoto 		/* use ADG */
378*ba9c949fSKuninori Morimoto 		val = 0;
379*ba9c949fSKuninori Morimoto 		ret = rsnd_adg_set_convert_clk_gen1(priv, mod,
380*ba9c949fSKuninori Morimoto 						    runtime->rate,
381*ba9c949fSKuninori Morimoto 						    convert_rate);
382*ba9c949fSKuninori Morimoto 	} else if (8 == id) {
383*ba9c949fSKuninori Morimoto 		/* use SSI WS, but SRU8 is special */
384*ba9c949fSKuninori Morimoto 		val = id << shift;
385*ba9c949fSKuninori Morimoto 	} else {
386*ba9c949fSKuninori Morimoto 		/* use SSI WS */
387*ba9c949fSKuninori Morimoto 		val = (id + 1) << shift;
388*ba9c949fSKuninori Morimoto 	}
389*ba9c949fSKuninori Morimoto 
390*ba9c949fSKuninori Morimoto 	if (ret < 0)
391*ba9c949fSKuninori Morimoto 		return ret;
392*ba9c949fSKuninori Morimoto 
393*ba9c949fSKuninori Morimoto 	switch (id / 4) {
394*ba9c949fSKuninori Morimoto 	case 0:
395*ba9c949fSKuninori Morimoto 		rsnd_mod_bset(mod, SRC_TMG_SEL0, mask, val);
396*ba9c949fSKuninori Morimoto 		break;
397*ba9c949fSKuninori Morimoto 	case 1:
398*ba9c949fSKuninori Morimoto 		rsnd_mod_bset(mod, SRC_TMG_SEL1, mask, val);
399*ba9c949fSKuninori Morimoto 		break;
400*ba9c949fSKuninori Morimoto 	case 2:
401*ba9c949fSKuninori Morimoto 		rsnd_mod_bset(mod, SRC_TMG_SEL2, mask, val);
402*ba9c949fSKuninori Morimoto 		break;
403*ba9c949fSKuninori Morimoto 	}
404*ba9c949fSKuninori Morimoto 
405*ba9c949fSKuninori Morimoto 	return 0;
406*ba9c949fSKuninori Morimoto }
407*ba9c949fSKuninori Morimoto 
408*ba9c949fSKuninori Morimoto static int rsnd_src_set_convert_rate_gen1(struct rsnd_mod *mod,
409*ba9c949fSKuninori Morimoto 					  struct rsnd_dai *rdai,
410*ba9c949fSKuninori Morimoto 					  struct rsnd_dai_stream *io)
411*ba9c949fSKuninori Morimoto {
412*ba9c949fSKuninori Morimoto 	int ret;
413*ba9c949fSKuninori Morimoto 
414*ba9c949fSKuninori Morimoto 	ret = rsnd_src_set_convert_rate(mod, rdai, io);
415*ba9c949fSKuninori Morimoto 	if (ret < 0)
416*ba9c949fSKuninori Morimoto 		return ret;
417*ba9c949fSKuninori Morimoto 
418*ba9c949fSKuninori Morimoto 	/* Select SRC mode (fixed value) */
419*ba9c949fSKuninori Morimoto 	rsnd_mod_write(mod, SRC_SRCCR, 0x00010110);
420*ba9c949fSKuninori Morimoto 
421*ba9c949fSKuninori Morimoto 	/* Set the restriction value of the FS ratio (98%) */
422*ba9c949fSKuninori Morimoto 	rsnd_mod_write(mod, SRC_MNFSR,
423*ba9c949fSKuninori Morimoto 		       rsnd_mod_read(mod, SRC_IFSVR) / 100 * 98);
424*ba9c949fSKuninori Morimoto 
425*ba9c949fSKuninori Morimoto 	/* no SRC_BFSSR settings, since SRC_SRCCR::BUFMD is 0 */
426*ba9c949fSKuninori Morimoto 
427*ba9c949fSKuninori Morimoto 	return 0;
428*ba9c949fSKuninori Morimoto }
429*ba9c949fSKuninori Morimoto 
430*ba9c949fSKuninori Morimoto static int rsnd_src_init_gen1(struct rsnd_mod *mod,
431*ba9c949fSKuninori Morimoto 			      struct rsnd_dai *rdai,
432*ba9c949fSKuninori Morimoto 			      struct rsnd_dai_stream *io)
433*ba9c949fSKuninori Morimoto {
434*ba9c949fSKuninori Morimoto 	int ret;
435*ba9c949fSKuninori Morimoto 
436*ba9c949fSKuninori Morimoto 	ret = rsnd_src_init(mod, rdai, io);
437*ba9c949fSKuninori Morimoto 	if (ret < 0)
438*ba9c949fSKuninori Morimoto 		return ret;
439*ba9c949fSKuninori Morimoto 
440*ba9c949fSKuninori Morimoto 	ret = rsnd_src_set_route_gen1(mod, rdai, io);
441*ba9c949fSKuninori Morimoto 	if (ret < 0)
442*ba9c949fSKuninori Morimoto 		return ret;
443*ba9c949fSKuninori Morimoto 
444*ba9c949fSKuninori Morimoto 	ret = rsnd_src_set_convert_rate_gen1(mod, rdai, io);
445*ba9c949fSKuninori Morimoto 	if (ret < 0)
446*ba9c949fSKuninori Morimoto 		return ret;
447*ba9c949fSKuninori Morimoto 
448*ba9c949fSKuninori Morimoto 	ret = rsnd_src_set_convert_timing_gen1(mod, rdai, io);
449*ba9c949fSKuninori Morimoto 	if (ret < 0)
450*ba9c949fSKuninori Morimoto 		return ret;
451*ba9c949fSKuninori Morimoto 
452*ba9c949fSKuninori Morimoto 	return 0;
453*ba9c949fSKuninori Morimoto }
454*ba9c949fSKuninori Morimoto 
455*ba9c949fSKuninori Morimoto static int rsnd_src_start_gen1(struct rsnd_mod *mod,
456*ba9c949fSKuninori Morimoto 			       struct rsnd_dai *rdai,
457*ba9c949fSKuninori Morimoto 			       struct rsnd_dai_stream *io)
458*ba9c949fSKuninori Morimoto {
459*ba9c949fSKuninori Morimoto 	int id = rsnd_mod_id(mod);
460*ba9c949fSKuninori Morimoto 
461*ba9c949fSKuninori Morimoto 	rsnd_mod_bset(mod, SRC_ROUTE_CTRL, (1 << id), (1 << id));
462*ba9c949fSKuninori Morimoto 
463*ba9c949fSKuninori Morimoto 	return rsnd_src_start(mod, rdai, io);
464*ba9c949fSKuninori Morimoto }
465*ba9c949fSKuninori Morimoto 
466*ba9c949fSKuninori Morimoto static int rsnd_src_stop_gen1(struct rsnd_mod *mod,
467*ba9c949fSKuninori Morimoto 			      struct rsnd_dai *rdai,
468*ba9c949fSKuninori Morimoto 			      struct rsnd_dai_stream *io)
469*ba9c949fSKuninori Morimoto {
470*ba9c949fSKuninori Morimoto 	int id = rsnd_mod_id(mod);
471*ba9c949fSKuninori Morimoto 
472*ba9c949fSKuninori Morimoto 	rsnd_mod_bset(mod, SRC_ROUTE_CTRL, (1 << id), 0);
473*ba9c949fSKuninori Morimoto 
474*ba9c949fSKuninori Morimoto 	return rsnd_src_stop(mod, rdai, io);
475*ba9c949fSKuninori Morimoto }
476*ba9c949fSKuninori Morimoto 
477*ba9c949fSKuninori Morimoto static struct rsnd_mod_ops rsnd_src_gen1_ops = {
478*ba9c949fSKuninori Morimoto 	.name	= "sru (gen1)",
479*ba9c949fSKuninori Morimoto 	.init	= rsnd_src_init_gen1,
480*ba9c949fSKuninori Morimoto 	.quit	= rsnd_src_quit,
481*ba9c949fSKuninori Morimoto 	.start	= rsnd_src_start_gen1,
482*ba9c949fSKuninori Morimoto 	.stop	= rsnd_src_stop_gen1,
483*ba9c949fSKuninori Morimoto };
484*ba9c949fSKuninori Morimoto 
485*ba9c949fSKuninori Morimoto /*
486*ba9c949fSKuninori Morimoto  *		Gen2 functions
487*ba9c949fSKuninori Morimoto  */
488*ba9c949fSKuninori Morimoto static int rsnd_src_set_convert_rate_gen2(struct rsnd_mod *mod,
489*ba9c949fSKuninori Morimoto 					  struct rsnd_dai *rdai,
490*ba9c949fSKuninori Morimoto 					  struct rsnd_dai_stream *io)
491*ba9c949fSKuninori Morimoto {
492*ba9c949fSKuninori Morimoto 	int ret;
493*ba9c949fSKuninori Morimoto 
494*ba9c949fSKuninori Morimoto 	ret = rsnd_src_set_convert_rate(mod, rdai, io);
495*ba9c949fSKuninori Morimoto 	if (ret < 0)
496*ba9c949fSKuninori Morimoto 		return ret;
497*ba9c949fSKuninori Morimoto 
498*ba9c949fSKuninori Morimoto 	rsnd_mod_write(mod, SSI_BUSIF_ADINR, rsnd_mod_read(mod, SRC_ADINR));
499*ba9c949fSKuninori Morimoto 	rsnd_mod_write(mod, SSI_BUSIF_MODE,  rsnd_mod_read(mod, SRC_BUSIF_MODE));
500*ba9c949fSKuninori Morimoto 
501*ba9c949fSKuninori Morimoto 	rsnd_mod_write(mod, SRC_SRCCR, 0x00011110);
502*ba9c949fSKuninori Morimoto 
503*ba9c949fSKuninori Morimoto 	rsnd_mod_write(mod, SRC_BSDSR, 0x01800000);
504*ba9c949fSKuninori Morimoto 	rsnd_mod_write(mod, SRC_BSISR, 0x00100060);
505*ba9c949fSKuninori Morimoto 
506*ba9c949fSKuninori Morimoto 	return 0;
507*ba9c949fSKuninori Morimoto }
508*ba9c949fSKuninori Morimoto 
509*ba9c949fSKuninori Morimoto static int rsnd_src_set_convert_timing_gen2(struct rsnd_mod *mod,
510*ba9c949fSKuninori Morimoto 					    struct rsnd_dai *rdai,
511*ba9c949fSKuninori Morimoto 					    struct rsnd_dai_stream *io)
512*ba9c949fSKuninori Morimoto {
513*ba9c949fSKuninori Morimoto 	struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io);
514*ba9c949fSKuninori Morimoto 	struct rsnd_src *src = rsnd_mod_to_src(mod);
515*ba9c949fSKuninori Morimoto 	u32 convert_rate = rsnd_src_convert_rate(src);
516*ba9c949fSKuninori Morimoto 	int ret;
517*ba9c949fSKuninori Morimoto 
518*ba9c949fSKuninori Morimoto 	if (convert_rate)
519*ba9c949fSKuninori Morimoto 		ret = rsnd_adg_set_convert_clk_gen2(mod, rdai, io,
520*ba9c949fSKuninori Morimoto 						    runtime->rate,
521*ba9c949fSKuninori Morimoto 						    convert_rate);
522*ba9c949fSKuninori Morimoto 	else
523*ba9c949fSKuninori Morimoto 		ret = rsnd_adg_set_convert_timing_gen2(mod, rdai, io);
524*ba9c949fSKuninori Morimoto 
525*ba9c949fSKuninori Morimoto 	return ret;
526*ba9c949fSKuninori Morimoto }
527*ba9c949fSKuninori Morimoto 
528*ba9c949fSKuninori Morimoto static int rsnd_src_probe_gen2(struct rsnd_mod *mod,
529*ba9c949fSKuninori Morimoto 			       struct rsnd_dai *rdai,
530*ba9c949fSKuninori Morimoto 			       struct rsnd_dai_stream *io)
531*ba9c949fSKuninori Morimoto {
532*ba9c949fSKuninori Morimoto 	struct rsnd_priv *priv = rsnd_mod_to_priv(mod);
533*ba9c949fSKuninori Morimoto 	struct rcar_snd_info *info = rsnd_priv_to_info(priv);
534*ba9c949fSKuninori Morimoto 	struct rsnd_src *src = rsnd_mod_to_src(mod);
535*ba9c949fSKuninori Morimoto 	struct rsnd_mod *ssi = rsnd_ssi_mod_get(priv, rsnd_mod_id(mod));
536*ba9c949fSKuninori Morimoto 	struct device *dev = rsnd_priv_to_dev(priv);
537*ba9c949fSKuninori Morimoto 	int ret;
538*ba9c949fSKuninori Morimoto 	int is_play;
539*ba9c949fSKuninori Morimoto 
540*ba9c949fSKuninori Morimoto 	if (info->dai_info)
541*ba9c949fSKuninori Morimoto 		is_play = rsnd_info_is_playback(priv, src);
542*ba9c949fSKuninori Morimoto 	else
543*ba9c949fSKuninori Morimoto 		is_play = rsnd_ssi_is_play(ssi);
544*ba9c949fSKuninori Morimoto 
545*ba9c949fSKuninori Morimoto 	ret = rsnd_dma_init(priv,
546*ba9c949fSKuninori Morimoto 			    rsnd_mod_to_dma(mod),
547*ba9c949fSKuninori Morimoto 			    is_play,
548*ba9c949fSKuninori Morimoto 			    src->info->dma_id);
549*ba9c949fSKuninori Morimoto 	if (ret < 0)
550*ba9c949fSKuninori Morimoto 		dev_err(dev, "SRC DMA failed\n");
551*ba9c949fSKuninori Morimoto 
552*ba9c949fSKuninori Morimoto 	return ret;
553*ba9c949fSKuninori Morimoto }
554*ba9c949fSKuninori Morimoto 
555*ba9c949fSKuninori Morimoto static int rsnd_src_remove_gen2(struct rsnd_mod *mod,
556*ba9c949fSKuninori Morimoto 				struct rsnd_dai *rdai,
557*ba9c949fSKuninori Morimoto 				struct rsnd_dai_stream *io)
558*ba9c949fSKuninori Morimoto {
559*ba9c949fSKuninori Morimoto 	rsnd_dma_quit(rsnd_mod_to_priv(mod), rsnd_mod_to_dma(mod));
560*ba9c949fSKuninori Morimoto 
561*ba9c949fSKuninori Morimoto 	return 0;
562*ba9c949fSKuninori Morimoto }
563*ba9c949fSKuninori Morimoto 
564*ba9c949fSKuninori Morimoto static int rsnd_src_init_gen2(struct rsnd_mod *mod,
565*ba9c949fSKuninori Morimoto 			      struct rsnd_dai *rdai,
566*ba9c949fSKuninori Morimoto 			      struct rsnd_dai_stream *io)
567*ba9c949fSKuninori Morimoto {
568*ba9c949fSKuninori Morimoto 	int ret;
569*ba9c949fSKuninori Morimoto 
570*ba9c949fSKuninori Morimoto 	ret = rsnd_src_init(mod, rdai, io);
571*ba9c949fSKuninori Morimoto 	if (ret < 0)
572*ba9c949fSKuninori Morimoto 		return ret;
573*ba9c949fSKuninori Morimoto 
574*ba9c949fSKuninori Morimoto 	ret = rsnd_src_set_convert_rate_gen2(mod, rdai, io);
575*ba9c949fSKuninori Morimoto 	if (ret < 0)
576*ba9c949fSKuninori Morimoto 		return ret;
577*ba9c949fSKuninori Morimoto 
578*ba9c949fSKuninori Morimoto 	ret = rsnd_src_set_convert_timing_gen2(mod, rdai, io);
579*ba9c949fSKuninori Morimoto 	if (ret < 0)
580*ba9c949fSKuninori Morimoto 		return ret;
581*ba9c949fSKuninori Morimoto 
582*ba9c949fSKuninori Morimoto 	return 0;
583*ba9c949fSKuninori Morimoto }
584*ba9c949fSKuninori Morimoto 
585*ba9c949fSKuninori Morimoto static int rsnd_src_start_gen2(struct rsnd_mod *mod,
586*ba9c949fSKuninori Morimoto 			       struct rsnd_dai *rdai,
587*ba9c949fSKuninori Morimoto 			       struct rsnd_dai_stream *io)
588*ba9c949fSKuninori Morimoto {
589*ba9c949fSKuninori Morimoto 	struct rsnd_src *src = rsnd_mod_to_src(mod);
590*ba9c949fSKuninori Morimoto 
591*ba9c949fSKuninori Morimoto 	rsnd_dma_start(rsnd_mod_to_dma(&src->mod));
592*ba9c949fSKuninori Morimoto 
593*ba9c949fSKuninori Morimoto 	rsnd_mod_write(mod, SSI_CTRL, 0x1);
594*ba9c949fSKuninori Morimoto 	rsnd_mod_write(mod, SRC_CTRL, 0x11);
595*ba9c949fSKuninori Morimoto 
596*ba9c949fSKuninori Morimoto 	return rsnd_src_start(mod, rdai, io);
597*ba9c949fSKuninori Morimoto }
598*ba9c949fSKuninori Morimoto 
599*ba9c949fSKuninori Morimoto static int rsnd_src_stop_gen2(struct rsnd_mod *mod,
600*ba9c949fSKuninori Morimoto 			      struct rsnd_dai *rdai,
601*ba9c949fSKuninori Morimoto 			      struct rsnd_dai_stream *io)
602*ba9c949fSKuninori Morimoto {
603*ba9c949fSKuninori Morimoto 	struct rsnd_src *src = rsnd_mod_to_src(mod);
604*ba9c949fSKuninori Morimoto 
605*ba9c949fSKuninori Morimoto 	rsnd_mod_write(mod, SSI_CTRL, 0);
606*ba9c949fSKuninori Morimoto 	rsnd_mod_write(mod, SRC_CTRL, 0);
607*ba9c949fSKuninori Morimoto 
608*ba9c949fSKuninori Morimoto 	rsnd_dma_stop(rsnd_mod_to_dma(&src->mod));
609*ba9c949fSKuninori Morimoto 
610*ba9c949fSKuninori Morimoto 	return rsnd_src_stop(mod, rdai, io);
611*ba9c949fSKuninori Morimoto }
612*ba9c949fSKuninori Morimoto 
613*ba9c949fSKuninori Morimoto static struct rsnd_mod_ops rsnd_src_gen2_ops = {
614*ba9c949fSKuninori Morimoto 	.name	= "src (gen2)",
615*ba9c949fSKuninori Morimoto 	.probe	= rsnd_src_probe_gen2,
616*ba9c949fSKuninori Morimoto 	.remove	= rsnd_src_remove_gen2,
617*ba9c949fSKuninori Morimoto 	.init	= rsnd_src_init_gen2,
618*ba9c949fSKuninori Morimoto 	.quit	= rsnd_src_quit,
619*ba9c949fSKuninori Morimoto 	.start	= rsnd_src_start_gen2,
620*ba9c949fSKuninori Morimoto 	.stop	= rsnd_src_stop_gen2,
621*ba9c949fSKuninori Morimoto };
622*ba9c949fSKuninori Morimoto 
623*ba9c949fSKuninori Morimoto struct rsnd_mod *rsnd_src_mod_get(struct rsnd_priv *priv, int id)
624*ba9c949fSKuninori Morimoto {
625*ba9c949fSKuninori Morimoto 	if (WARN_ON(id < 0 || id >= rsnd_src_nr(priv)))
626*ba9c949fSKuninori Morimoto 		id = 0;
627*ba9c949fSKuninori Morimoto 
628*ba9c949fSKuninori Morimoto 	return &((struct rsnd_src *)(priv->src) + id)->mod;
629*ba9c949fSKuninori Morimoto }
630*ba9c949fSKuninori Morimoto 
631*ba9c949fSKuninori Morimoto int rsnd_src_probe(struct platform_device *pdev,
632*ba9c949fSKuninori Morimoto 		   struct rsnd_priv *priv)
633*ba9c949fSKuninori Morimoto {
634*ba9c949fSKuninori Morimoto 	struct rcar_snd_info *info = rsnd_priv_to_info(priv);
635*ba9c949fSKuninori Morimoto 	struct device *dev = rsnd_priv_to_dev(priv);
636*ba9c949fSKuninori Morimoto 	struct rsnd_src *src;
637*ba9c949fSKuninori Morimoto 	struct rsnd_mod_ops *ops;
638*ba9c949fSKuninori Morimoto 	struct clk *clk;
639*ba9c949fSKuninori Morimoto 	char name[RSND_SRC_NAME_SIZE];
640*ba9c949fSKuninori Morimoto 	int i, nr;
641*ba9c949fSKuninori Morimoto 
642*ba9c949fSKuninori Morimoto 	/*
643*ba9c949fSKuninori Morimoto 	 * init SRC
644*ba9c949fSKuninori Morimoto 	 */
645*ba9c949fSKuninori Morimoto 	nr	= info->src_info_nr;
646*ba9c949fSKuninori Morimoto 	if (!nr)
647*ba9c949fSKuninori Morimoto 		return 0;
648*ba9c949fSKuninori Morimoto 
649*ba9c949fSKuninori Morimoto 	src	= devm_kzalloc(dev, sizeof(*src) * nr, GFP_KERNEL);
650*ba9c949fSKuninori Morimoto 	if (!src) {
651*ba9c949fSKuninori Morimoto 		dev_err(dev, "SRC allocate failed\n");
652*ba9c949fSKuninori Morimoto 		return -ENOMEM;
653*ba9c949fSKuninori Morimoto 	}
654*ba9c949fSKuninori Morimoto 
655*ba9c949fSKuninori Morimoto 	priv->src_nr	= nr;
656*ba9c949fSKuninori Morimoto 	priv->src	= src;
657*ba9c949fSKuninori Morimoto 
658*ba9c949fSKuninori Morimoto 	for_each_rsnd_src(src, priv, i) {
659*ba9c949fSKuninori Morimoto 		snprintf(name, RSND_SRC_NAME_SIZE, "src.%d", i);
660*ba9c949fSKuninori Morimoto 
661*ba9c949fSKuninori Morimoto 		clk = devm_clk_get(dev, name);
662*ba9c949fSKuninori Morimoto 		if (IS_ERR(clk)) {
663*ba9c949fSKuninori Morimoto 			snprintf(name, RSND_SRC_NAME_SIZE, "scu.%d", i);
664*ba9c949fSKuninori Morimoto 			clk = devm_clk_get(dev, name);
665*ba9c949fSKuninori Morimoto 		}
666*ba9c949fSKuninori Morimoto 
667*ba9c949fSKuninori Morimoto 		if (IS_ERR(clk))
668*ba9c949fSKuninori Morimoto 			return PTR_ERR(clk);
669*ba9c949fSKuninori Morimoto 
670*ba9c949fSKuninori Morimoto 		src->info = &info->src_info[i];
671*ba9c949fSKuninori Morimoto 		src->clk = clk;
672*ba9c949fSKuninori Morimoto 
673*ba9c949fSKuninori Morimoto 		ops = &rsnd_src_non_ops;
674*ba9c949fSKuninori Morimoto 		if (rsnd_src_hpbif_is_enable(src)) {
675*ba9c949fSKuninori Morimoto 			if (rsnd_is_gen1(priv))
676*ba9c949fSKuninori Morimoto 				ops = &rsnd_src_gen1_ops;
677*ba9c949fSKuninori Morimoto 			if (rsnd_is_gen2(priv))
678*ba9c949fSKuninori Morimoto 				ops = &rsnd_src_gen2_ops;
679*ba9c949fSKuninori Morimoto 		}
680*ba9c949fSKuninori Morimoto 
681*ba9c949fSKuninori Morimoto 		rsnd_mod_init(priv, &src->mod, ops, RSND_MOD_SRC, i);
682*ba9c949fSKuninori Morimoto 
683*ba9c949fSKuninori Morimoto 		dev_dbg(dev, "SRC%d probed\n", i);
684*ba9c949fSKuninori Morimoto 	}
685*ba9c949fSKuninori Morimoto 
686*ba9c949fSKuninori Morimoto 	return 0;
687*ba9c949fSKuninori Morimoto }
688