xref: /linux/sound/soc/renesas/rcar/ctu.c (revision b2128290c29902315e632ea59e0504d6bc9e9b42)
1 // SPDX-License-Identifier: GPL-2.0
2 //
3 // ctu.c
4 //
5 // Copyright (c) 2015 Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
6 
7 #include "rsnd.h"
8 
9 #define CTU_NAME "ctu"
10 
11 /*
12  * User needs to setup CTU by amixer, and its settings are
13  * based on below registers
14  *
15  * CTUn_CPMDR : amixser set "CTU Pass"
16  * CTUn_SV0xR : amixser set "CTU SV0"
17  * CTUn_SV1xR : amixser set "CTU SV1"
18  * CTUn_SV2xR : amixser set "CTU SV2"
19  * CTUn_SV3xR : amixser set "CTU SV3"
20  *
21  * [CTU Pass]
22  * 0000: default
23  * 0001: Connect input data of channel 0
24  * 0010: Connect input data of channel 1
25  * 0011: Connect input data of channel 2
26  * 0100: Connect input data of channel 3
27  * 0101: Connect input data of channel 4
28  * 0110: Connect input data of channel 5
29  * 0111: Connect input data of channel 6
30  * 1000: Connect input data of channel 7
31  * 1001: Connect calculated data by scale values of matrix row 0
32  * 1010: Connect calculated data by scale values of matrix row 1
33  * 1011: Connect calculated data by scale values of matrix row 2
34  * 1100: Connect calculated data by scale values of matrix row 3
35  *
36  * [CTU SVx]
37  * [Output0] = [SV00, SV01, SV02, SV03, SV04, SV05, SV06, SV07]
38  * [Output1] = [SV10, SV11, SV12, SV13, SV14, SV15, SV16, SV17]
39  * [Output2] = [SV20, SV21, SV22, SV23, SV24, SV25, SV26, SV27]
40  * [Output3] = [SV30, SV31, SV32, SV33, SV34, SV35, SV36, SV37]
41  * [Output4] = [ 0,   0,    0,    0,    0,    0,    0,    0   ]
42  * [Output5] = [ 0,   0,    0,    0,    0,    0,    0,    0   ]
43  * [Output6] = [ 0,   0,    0,    0,    0,    0,    0,    0   ]
44  * [Output7] = [ 0,   0,    0,    0,    0,    0,    0,    0   ]
45  *
46  * [SVxx]
47  * Plus					Minus
48  * value	time		dB	value		time		dB
49  * -----------------------------------------------------------------------
50  * H'7F_FFFF	2		6	H'80_0000	2		6
51  * ...
52  * H'40_0000	1		0	H'C0_0000	1		0
53  * ...
54  * H'00_0001	2.38 x 10^-7	-132
55  * H'00_0000	0		Mute	H'FF_FFFF	2.38 x 10^-7	-132
56  *
57  *
58  * Ex) Input ch -> Output ch
59  *	1ch     ->  0ch
60  *	0ch     ->  1ch
61  *
62  *	amixer set "CTU Reset" on
63  *	amixer set "CTU Pass" 9,10
64  *	amixer set "CTU SV0" 0,4194304
65  *	amixer set "CTU SV1" 4194304,0
66  * or
67  *	amixer set "CTU Reset" on
68  *	amixer set "CTU Pass" 2,1
69  */
70 
71 struct rsnd_ctu {
72 	struct rsnd_mod mod;
73 	struct rsnd_kctrl_cfg_m pass;
74 	struct rsnd_kctrl_cfg_m sv[4];
75 	struct rsnd_kctrl_cfg_s reset;
76 	int channels;
77 	u32 flags;
78 };
79 
80 #define KCTRL_INITIALIZED	(1 << 0)
81 
82 #define rsnd_ctu_nr(priv) ((priv)->ctu_nr)
83 #define for_each_rsnd_ctu(pos, priv, i)					\
84 	for ((i) = 0;							\
85 	     ((i) < rsnd_ctu_nr(priv)) &&				\
86 		     ((pos) = (struct rsnd_ctu *)(priv)->ctu + i);	\
87 	     i++)
88 
89 #define rsnd_mod_to_ctu(_mod)	\
90 	container_of((_mod), struct rsnd_ctu, mod)
91 
92 #define rsnd_ctu_get(priv, id) ((struct rsnd_ctu *)(priv->ctu) + id)
93 
94 static void rsnd_ctu_activation(struct rsnd_mod *mod)
95 {
96 	rsnd_mod_write(mod, CTU_SWRSR, 0);
97 	rsnd_mod_write(mod, CTU_SWRSR, 1);
98 }
99 
100 static void rsnd_ctu_halt(struct rsnd_mod *mod)
101 {
102 	rsnd_mod_write(mod, CTU_CTUIR, 1);
103 	rsnd_mod_write(mod, CTU_SWRSR, 0);
104 }
105 
106 static int rsnd_ctu_probe_(struct rsnd_mod *mod,
107 			   struct rsnd_dai_stream *io,
108 			   struct rsnd_priv *priv)
109 {
110 	return rsnd_cmd_attach(io, rsnd_mod_id(mod));
111 }
112 
113 static void rsnd_ctu_value_init(struct rsnd_dai_stream *io,
114 			       struct rsnd_mod *mod)
115 {
116 	struct rsnd_ctu *ctu = rsnd_mod_to_ctu(mod);
117 	u32 cpmdr = 0;
118 	u32 scmdr = 0;
119 	int i, j;
120 
121 	for (i = 0; i < RSND_MAX_CHANNELS; i++) {
122 		u32 val = rsnd_kctrl_valm(ctu->pass, i);
123 
124 		cpmdr |= val << (28 - (i * 4));
125 
126 		if ((val > 0x8) && (scmdr < (val - 0x8)))
127 			scmdr = val - 0x8;
128 	}
129 
130 	rsnd_mod_write(mod, CTU_CTUIR, 1);
131 
132 	rsnd_mod_write(mod, CTU_ADINR, rsnd_runtime_channel_original(io));
133 
134 	rsnd_mod_write(mod, CTU_CPMDR, cpmdr);
135 
136 	rsnd_mod_write(mod, CTU_SCMDR, scmdr);
137 
138 	for (i = 0; i < 4; i++) {
139 
140 		if (i >= scmdr)
141 			break;
142 
143 		for (j = 0; j < RSND_MAX_CHANNELS; j++)
144 			rsnd_mod_write(mod, CTU_SVxxR(i, j), rsnd_kctrl_valm(ctu->sv[i], j));
145 	}
146 
147 	rsnd_mod_write(mod, CTU_CTUIR, 0);
148 }
149 
150 static void rsnd_ctu_value_reset(struct rsnd_dai_stream *io,
151 				 struct rsnd_mod *mod)
152 {
153 	struct rsnd_ctu *ctu = rsnd_mod_to_ctu(mod);
154 	int i;
155 
156 	if (!rsnd_kctrl_vals(ctu->reset))
157 		return;
158 
159 	for (i = 0; i < RSND_MAX_CHANNELS; i++) {
160 		rsnd_kctrl_valm(ctu->pass, i) = 0;
161 		rsnd_kctrl_valm(ctu->sv[0],  i) = 0;
162 		rsnd_kctrl_valm(ctu->sv[1],  i) = 0;
163 		rsnd_kctrl_valm(ctu->sv[2],  i) = 0;
164 		rsnd_kctrl_valm(ctu->sv[3],  i) = 0;
165 	}
166 	rsnd_kctrl_vals(ctu->reset) = 0;
167 }
168 
169 static int rsnd_ctu_init(struct rsnd_mod *mod,
170 			 struct rsnd_dai_stream *io,
171 			 struct rsnd_priv *priv)
172 {
173 	int ret;
174 
175 	ret = rsnd_mod_power_on(mod);
176 	if (ret < 0)
177 		return ret;
178 
179 	rsnd_ctu_activation(mod);
180 
181 	rsnd_ctu_value_init(io, mod);
182 
183 	return 0;
184 }
185 
186 static int rsnd_ctu_quit(struct rsnd_mod *mod,
187 			 struct rsnd_dai_stream *io,
188 			 struct rsnd_priv *priv)
189 {
190 	rsnd_ctu_halt(mod);
191 
192 	rsnd_mod_power_off(mod);
193 
194 	return 0;
195 }
196 
197 static int rsnd_ctu_pcm_new(struct rsnd_mod *mod,
198 			    struct rsnd_dai_stream *io,
199 			    struct snd_soc_pcm_runtime *rtd)
200 {
201 	struct rsnd_ctu *ctu = rsnd_mod_to_ctu(mod);
202 	int ret;
203 
204 	if (rsnd_flags_has(ctu, KCTRL_INITIALIZED))
205 		return 0;
206 
207 	/* CTU Pass */
208 	ret = rsnd_kctrl_new_m(mod, io, rtd, "CTU Pass",
209 			       rsnd_kctrl_accept_anytime,
210 			       NULL,
211 			       &ctu->pass, RSND_MAX_CHANNELS,
212 			       0xC);
213 	if (ret < 0)
214 		return ret;
215 
216 	/* ROW0 */
217 	ret = rsnd_kctrl_new_m(mod, io, rtd, "CTU SV0",
218 			       rsnd_kctrl_accept_anytime,
219 			       NULL,
220 			       &ctu->sv[0], RSND_MAX_CHANNELS,
221 			       0x00FFFFFF);
222 	if (ret < 0)
223 		return ret;
224 
225 	/* ROW1 */
226 	ret = rsnd_kctrl_new_m(mod, io, rtd, "CTU SV1",
227 			       rsnd_kctrl_accept_anytime,
228 			       NULL,
229 			       &ctu->sv[1], RSND_MAX_CHANNELS,
230 			       0x00FFFFFF);
231 	if (ret < 0)
232 		return ret;
233 
234 	/* ROW2 */
235 	ret = rsnd_kctrl_new_m(mod, io, rtd, "CTU SV2",
236 			       rsnd_kctrl_accept_anytime,
237 			       NULL,
238 			       &ctu->sv[2], RSND_MAX_CHANNELS,
239 			       0x00FFFFFF);
240 	if (ret < 0)
241 		return ret;
242 
243 	/* ROW3 */
244 	ret = rsnd_kctrl_new_m(mod, io, rtd, "CTU SV3",
245 			       rsnd_kctrl_accept_anytime,
246 			       NULL,
247 			       &ctu->sv[3], RSND_MAX_CHANNELS,
248 			       0x00FFFFFF);
249 	if (ret < 0)
250 		return ret;
251 
252 	/* Reset */
253 	ret = rsnd_kctrl_new_s(mod, io, rtd, "CTU Reset",
254 			       rsnd_kctrl_accept_anytime,
255 			       rsnd_ctu_value_reset,
256 			       &ctu->reset, 1);
257 
258 	rsnd_flags_set(ctu, KCTRL_INITIALIZED);
259 
260 	return ret;
261 }
262 
263 static int rsnd_ctu_id(struct rsnd_mod *mod)
264 {
265 	/*
266 	 * ctu00: -> 0, ctu01: -> 0, ctu02: -> 0, ctu03: -> 0
267 	 * ctu10: -> 1, ctu11: -> 1, ctu12: -> 1, ctu13: -> 1
268 	 */
269 	return mod->id / 4;
270 }
271 
272 static int rsnd_ctu_id_sub(struct rsnd_mod *mod)
273 {
274 	/*
275 	 * ctu00: -> 0, ctu01: -> 1, ctu02: -> 2, ctu03: -> 3
276 	 * ctu10: -> 0, ctu11: -> 1, ctu12: -> 2, ctu13: -> 3
277 	 */
278 	return mod->id % 4;
279 }
280 
281 #ifdef CONFIG_DEBUG_FS
282 static void rsnd_ctu_debug_info(struct seq_file *m,
283 				struct rsnd_dai_stream *io,
284 				struct rsnd_mod *mod)
285 {
286 	rsnd_debugfs_mod_reg_show(m, mod, RSND_BASE_SCU,
287 				  0x500 + rsnd_mod_id_raw(mod) * 0x100, 0x100);
288 }
289 #define DEBUG_INFO .debug_info = rsnd_ctu_debug_info
290 #else
291 #define DEBUG_INFO
292 #endif
293 
294 static struct rsnd_mod_ops rsnd_ctu_ops = {
295 	.name		= CTU_NAME,
296 	.probe		= rsnd_ctu_probe_,
297 	.init		= rsnd_ctu_init,
298 	.quit		= rsnd_ctu_quit,
299 	.pcm_new	= rsnd_ctu_pcm_new,
300 	.get_status	= rsnd_mod_get_status,
301 	.id		= rsnd_ctu_id,
302 	.id_sub		= rsnd_ctu_id_sub,
303 	.id_cmd		= rsnd_mod_id_raw,
304 	DEBUG_INFO
305 };
306 
307 struct rsnd_mod *rsnd_ctu_mod_get(struct rsnd_priv *priv, int id)
308 {
309 	if (WARN_ON(id < 0 || id >= rsnd_ctu_nr(priv)))
310 		id = 0;
311 
312 	return rsnd_mod_get(rsnd_ctu_get(priv, id));
313 }
314 
315 int rsnd_ctu_probe(struct rsnd_priv *priv)
316 {
317 	struct device_node *node;
318 	struct device *dev = rsnd_priv_to_dev(priv);
319 	struct rsnd_ctu *ctu;
320 	struct clk *clk;
321 	int i, nr, ret;
322 
323 	node = rsnd_ctu_of_node(priv);
324 	if (!node)
325 		return 0; /* not used is not error */
326 
327 	nr = of_get_child_count(node);
328 	if (!nr) {
329 		ret = -EINVAL;
330 		goto rsnd_ctu_probe_done;
331 	}
332 
333 	ctu = devm_kcalloc(dev, nr, sizeof(*ctu), GFP_KERNEL);
334 	if (!ctu) {
335 		ret = -ENOMEM;
336 		goto rsnd_ctu_probe_done;
337 	}
338 
339 	priv->ctu_nr	= nr;
340 	priv->ctu	= ctu;
341 
342 	i = 0;
343 	ret = 0;
344 	for_each_child_of_node_scoped(node, np) {
345 		ctu = rsnd_ctu_get(priv, i);
346 
347 		/*
348 		 * CTU00, CTU01, CTU02, CTU03 => CTU0
349 		 * CTU10, CTU11, CTU12, CTU13 => CTU1
350 		 */
351 		clk = rsnd_devm_clk_get_indexed(dev, CTU_NAME, i / 4);
352 		if (IS_ERR(clk)) {
353 			ret = PTR_ERR(clk);
354 			goto rsnd_ctu_probe_done;
355 		}
356 
357 		ret = rsnd_mod_init(priv, rsnd_mod_get(ctu), &rsnd_ctu_ops,
358 				    clk, NULL, RSND_MOD_CTU, i);
359 		if (ret)
360 			goto rsnd_ctu_probe_done;
361 
362 		i++;
363 	}
364 
365 
366 rsnd_ctu_probe_done:
367 	of_node_put(node);
368 
369 	return ret;
370 }
371 
372 void rsnd_ctu_remove(struct rsnd_priv *priv)
373 {
374 	struct rsnd_ctu *ctu;
375 	int i;
376 
377 	for_each_rsnd_ctu(ctu, priv, i) {
378 		rsnd_mod_quit(rsnd_mod_get(ctu));
379 	}
380 }
381 
382 void rsnd_ctu_suspend(struct rsnd_priv *priv)
383 {
384 	struct rsnd_ctu *ctu;
385 	int i;
386 
387 	for_each_rsnd_ctu(ctu, priv, i)
388 		rsnd_suspend_clk_reset(rsnd_mod_get(ctu)->clk,
389 				       rsnd_mod_get(ctu)->rstc);
390 }
391 
392 void rsnd_ctu_resume(struct rsnd_priv *priv)
393 {
394 	struct rsnd_ctu *ctu;
395 	int i;
396 
397 	for_each_rsnd_ctu(ctu, priv, i)
398 		rsnd_resume_clk_reset(rsnd_mod_get(ctu)->clk,
399 				      rsnd_mod_get(ctu)->rstc);
400 }
401