xref: /openbmc/linux/sound/soc/sh/rcar/dvc.c (revision 6d99a79c)
1 // SPDX-License-Identifier: GPL-2.0
2 //
3 // Renesas R-Car DVC support
4 //
5 // Copyright (C) 2014 Renesas Solutions Corp.
6 // Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
7 
8 /*
9  * Playback Volume
10  *	amixer set "DVC Out" 100%
11  *
12  * Capture Volume
13  *	amixer set "DVC In" 100%
14  *
15  * Playback Mute
16  *	amixer set "DVC Out Mute" on
17  *
18  * Capture Mute
19  *	amixer set "DVC In Mute" on
20  *
21  * Volume Ramp
22  *	amixer set "DVC Out Ramp Up Rate"   "0.125 dB/64 steps"
23  *	amixer set "DVC Out Ramp Down Rate" "0.125 dB/512 steps"
24  *	amixer set "DVC Out Ramp" on
25  *	aplay xxx.wav &
26  *	amixer set "DVC Out"  80%  // Volume Down
27  *	amixer set "DVC Out" 100%  // Volume Up
28  */
29 
30 #include "rsnd.h"
31 
32 #define RSND_DVC_NAME_SIZE	16
33 
34 #define DVC_NAME "dvc"
35 
36 struct rsnd_dvc {
37 	struct rsnd_mod mod;
38 	struct rsnd_kctrl_cfg_m volume;
39 	struct rsnd_kctrl_cfg_m mute;
40 	struct rsnd_kctrl_cfg_s ren;	/* Ramp Enable */
41 	struct rsnd_kctrl_cfg_s rup;	/* Ramp Rate Up */
42 	struct rsnd_kctrl_cfg_s rdown;	/* Ramp Rate Down */
43 	u32 flags;
44 };
45 
46 #define KCTRL_INITIALIZED	(1 << 0)
47 
48 #define rsnd_dvc_get(priv, id) ((struct rsnd_dvc *)(priv->dvc) + id)
49 #define rsnd_dvc_nr(priv) ((priv)->dvc_nr)
50 
51 #define rsnd_mod_to_dvc(_mod)	\
52 	container_of((_mod), struct rsnd_dvc, mod)
53 
54 #define for_each_rsnd_dvc(pos, priv, i)				\
55 	for ((i) = 0;						\
56 	     ((i) < rsnd_dvc_nr(priv)) &&			\
57 	     ((pos) = (struct rsnd_dvc *)(priv)->dvc + i);	\
58 	     i++)
59 
60 static void rsnd_dvc_activation(struct rsnd_mod *mod)
61 {
62 	rsnd_mod_write(mod, DVC_SWRSR, 0);
63 	rsnd_mod_write(mod, DVC_SWRSR, 1);
64 }
65 
66 static void rsnd_dvc_halt(struct rsnd_mod *mod)
67 {
68 	rsnd_mod_write(mod, DVC_DVUIR, 1);
69 	rsnd_mod_write(mod, DVC_SWRSR, 0);
70 }
71 
72 #define rsnd_dvc_get_vrpdr(dvc) (rsnd_kctrl_vals(dvc->rup) << 8 | \
73 				 rsnd_kctrl_vals(dvc->rdown))
74 #define rsnd_dvc_get_vrdbr(dvc) (0x3ff - (rsnd_kctrl_valm(dvc->volume, 0) >> 13))
75 
76 static void rsnd_dvc_volume_parameter(struct rsnd_dai_stream *io,
77 					      struct rsnd_mod *mod)
78 {
79 	struct rsnd_dvc *dvc = rsnd_mod_to_dvc(mod);
80 	u32 val[RSND_MAX_CHANNELS];
81 	int i;
82 
83 	/* Enable Ramp */
84 	if (rsnd_kctrl_vals(dvc->ren))
85 		for (i = 0; i < RSND_MAX_CHANNELS; i++)
86 			val[i] = rsnd_kctrl_max(dvc->volume);
87 	else
88 		for (i = 0; i < RSND_MAX_CHANNELS; i++)
89 			val[i] = rsnd_kctrl_valm(dvc->volume, i);
90 
91 	/* Enable Digital Volume */
92 	rsnd_mod_write(mod, DVC_VOL0R, val[0]);
93 	rsnd_mod_write(mod, DVC_VOL1R, val[1]);
94 	rsnd_mod_write(mod, DVC_VOL2R, val[2]);
95 	rsnd_mod_write(mod, DVC_VOL3R, val[3]);
96 	rsnd_mod_write(mod, DVC_VOL4R, val[4]);
97 	rsnd_mod_write(mod, DVC_VOL5R, val[5]);
98 	rsnd_mod_write(mod, DVC_VOL6R, val[6]);
99 	rsnd_mod_write(mod, DVC_VOL7R, val[7]);
100 }
101 
102 static void rsnd_dvc_volume_init(struct rsnd_dai_stream *io,
103 				 struct rsnd_mod *mod)
104 {
105 	struct rsnd_dvc *dvc = rsnd_mod_to_dvc(mod);
106 	u32 adinr = 0;
107 	u32 dvucr = 0;
108 	u32 vrctr = 0;
109 	u32 vrpdr = 0;
110 	u32 vrdbr = 0;
111 
112 	adinr = rsnd_get_adinr_bit(mod, io) |
113 		rsnd_runtime_channel_after_ctu(io);
114 
115 	/* Enable Digital Volume, Zero Cross Mute Mode */
116 	dvucr |= 0x101;
117 
118 	/* Enable Ramp */
119 	if (rsnd_kctrl_vals(dvc->ren)) {
120 		dvucr |= 0x10;
121 
122 		/*
123 		 * FIXME !!
124 		 * use scale-downed Digital Volume
125 		 * as Volume Ramp
126 		 * 7F FFFF -> 3FF
127 		 */
128 		vrctr = 0xff;
129 		vrpdr = rsnd_dvc_get_vrpdr(dvc);
130 		vrdbr = rsnd_dvc_get_vrdbr(dvc);
131 	}
132 
133 	/* Initialize operation */
134 	rsnd_mod_write(mod, DVC_DVUIR, 1);
135 
136 	/* General Information */
137 	rsnd_mod_write(mod, DVC_ADINR, adinr);
138 	rsnd_mod_write(mod, DVC_DVUCR, dvucr);
139 
140 	/* Volume Ramp Parameter */
141 	rsnd_mod_write(mod, DVC_VRCTR, vrctr);
142 	rsnd_mod_write(mod, DVC_VRPDR, vrpdr);
143 	rsnd_mod_write(mod, DVC_VRDBR, vrdbr);
144 
145 	/* Digital Volume Function Parameter */
146 	rsnd_dvc_volume_parameter(io, mod);
147 
148 	/* cancel operation */
149 	rsnd_mod_write(mod, DVC_DVUIR, 0);
150 }
151 
152 static void rsnd_dvc_volume_update(struct rsnd_dai_stream *io,
153 				   struct rsnd_mod *mod)
154 {
155 	struct rsnd_dvc *dvc = rsnd_mod_to_dvc(mod);
156 	u32 zcmcr = 0;
157 	u32 vrpdr = 0;
158 	u32 vrdbr = 0;
159 	int i;
160 
161 	for (i = 0; i < rsnd_kctrl_size(dvc->mute); i++)
162 		zcmcr |= (!!rsnd_kctrl_valm(dvc->mute, i)) << i;
163 
164 	if (rsnd_kctrl_vals(dvc->ren)) {
165 		vrpdr = rsnd_dvc_get_vrpdr(dvc);
166 		vrdbr = rsnd_dvc_get_vrdbr(dvc);
167 	}
168 
169 	/* Disable DVC Register access */
170 	rsnd_mod_write(mod, DVC_DVUER, 0);
171 
172 	/* Zero Cross Mute Function */
173 	rsnd_mod_write(mod, DVC_ZCMCR, zcmcr);
174 
175 	/* Volume Ramp Function */
176 	rsnd_mod_write(mod, DVC_VRPDR, vrpdr);
177 	rsnd_mod_write(mod, DVC_VRDBR, vrdbr);
178 	/* add DVC_VRWTR here */
179 
180 	/* Digital Volume Function Parameter */
181 	rsnd_dvc_volume_parameter(io, mod);
182 
183 	/* Enable DVC Register access */
184 	rsnd_mod_write(mod, DVC_DVUER, 1);
185 }
186 
187 static int rsnd_dvc_probe_(struct rsnd_mod *mod,
188 			   struct rsnd_dai_stream *io,
189 			   struct rsnd_priv *priv)
190 {
191 	return rsnd_cmd_attach(io, rsnd_mod_id(mod));
192 }
193 
194 static int rsnd_dvc_init(struct rsnd_mod *mod,
195 			 struct rsnd_dai_stream *io,
196 			 struct rsnd_priv *priv)
197 {
198 	rsnd_mod_power_on(mod);
199 
200 	rsnd_dvc_activation(mod);
201 
202 	rsnd_dvc_volume_init(io, mod);
203 
204 	rsnd_dvc_volume_update(io, mod);
205 
206 	return 0;
207 }
208 
209 static int rsnd_dvc_quit(struct rsnd_mod *mod,
210 			 struct rsnd_dai_stream *io,
211 			 struct rsnd_priv *priv)
212 {
213 	rsnd_dvc_halt(mod);
214 
215 	rsnd_mod_power_off(mod);
216 
217 	return 0;
218 }
219 
220 static int rsnd_dvc_pcm_new(struct rsnd_mod *mod,
221 			    struct rsnd_dai_stream *io,
222 			    struct snd_soc_pcm_runtime *rtd)
223 {
224 	struct rsnd_dvc *dvc = rsnd_mod_to_dvc(mod);
225 	struct rsnd_dai *rdai = rsnd_io_to_rdai(io);
226 	int is_play = rsnd_io_is_play(io);
227 	int channels = rsnd_rdai_channels_get(rdai);
228 	int ret;
229 
230 	if (rsnd_flags_has(dvc, KCTRL_INITIALIZED))
231 		return 0;
232 
233 	/* Volume */
234 	ret = rsnd_kctrl_new_m(mod, io, rtd,
235 			is_play ?
236 			"DVC Out Playback Volume" : "DVC In Capture Volume",
237 			rsnd_kctrl_accept_anytime,
238 			rsnd_dvc_volume_update,
239 			&dvc->volume, channels,
240 			0x00800000 - 1);
241 	if (ret < 0)
242 		return ret;
243 
244 	/* Mute */
245 	ret = rsnd_kctrl_new_m(mod, io, rtd,
246 			is_play ?
247 			"DVC Out Mute Switch" : "DVC In Mute Switch",
248 			rsnd_kctrl_accept_anytime,
249 			rsnd_dvc_volume_update,
250 			&dvc->mute, channels,
251 			1);
252 	if (ret < 0)
253 		return ret;
254 
255 	/* Ramp */
256 	ret = rsnd_kctrl_new_s(mod, io, rtd,
257 			is_play ?
258 			"DVC Out Ramp Switch" : "DVC In Ramp Switch",
259 			rsnd_kctrl_accept_anytime,
260 			rsnd_dvc_volume_update,
261 			&dvc->ren, 1);
262 	if (ret < 0)
263 		return ret;
264 
265 	ret = rsnd_kctrl_new_e(mod, io, rtd,
266 			is_play ?
267 			"DVC Out Ramp Up Rate" : "DVC In Ramp Up Rate",
268 			rsnd_kctrl_accept_anytime,
269 			rsnd_dvc_volume_update,
270 			&dvc->rup,
271 			volume_ramp_rate,
272 			VOLUME_RAMP_MAX_DVC);
273 	if (ret < 0)
274 		return ret;
275 
276 	ret = rsnd_kctrl_new_e(mod, io, rtd,
277 			is_play ?
278 			"DVC Out Ramp Down Rate" : "DVC In Ramp Down Rate",
279 			rsnd_kctrl_accept_anytime,
280 			rsnd_dvc_volume_update,
281 			&dvc->rdown,
282 			volume_ramp_rate,
283 			VOLUME_RAMP_MAX_DVC);
284 
285 	if (ret < 0)
286 		return ret;
287 
288 	rsnd_flags_set(dvc, KCTRL_INITIALIZED);
289 
290 	return 0;
291 }
292 
293 static struct dma_chan *rsnd_dvc_dma_req(struct rsnd_dai_stream *io,
294 					 struct rsnd_mod *mod)
295 {
296 	struct rsnd_priv *priv = rsnd_mod_to_priv(mod);
297 
298 	return rsnd_dma_request_channel(rsnd_dvc_of_node(priv),
299 					mod, "tx");
300 }
301 
302 static struct rsnd_mod_ops rsnd_dvc_ops = {
303 	.name		= DVC_NAME,
304 	.dma_req	= rsnd_dvc_dma_req,
305 	.probe		= rsnd_dvc_probe_,
306 	.init		= rsnd_dvc_init,
307 	.quit		= rsnd_dvc_quit,
308 	.pcm_new	= rsnd_dvc_pcm_new,
309 };
310 
311 struct rsnd_mod *rsnd_dvc_mod_get(struct rsnd_priv *priv, int id)
312 {
313 	if (WARN_ON(id < 0 || id >= rsnd_dvc_nr(priv)))
314 		id = 0;
315 
316 	return rsnd_mod_get(rsnd_dvc_get(priv, id));
317 }
318 
319 int rsnd_dvc_probe(struct rsnd_priv *priv)
320 {
321 	struct device_node *node;
322 	struct device_node *np;
323 	struct device *dev = rsnd_priv_to_dev(priv);
324 	struct rsnd_dvc *dvc;
325 	struct clk *clk;
326 	char name[RSND_DVC_NAME_SIZE];
327 	int i, nr, ret;
328 
329 	/* This driver doesn't support Gen1 at this point */
330 	if (rsnd_is_gen1(priv))
331 		return 0;
332 
333 	node = rsnd_dvc_of_node(priv);
334 	if (!node)
335 		return 0; /* not used is not error */
336 
337 	nr = of_get_child_count(node);
338 	if (!nr) {
339 		ret = -EINVAL;
340 		goto rsnd_dvc_probe_done;
341 	}
342 
343 	dvc	= devm_kcalloc(dev, nr, sizeof(*dvc), GFP_KERNEL);
344 	if (!dvc) {
345 		ret = -ENOMEM;
346 		goto rsnd_dvc_probe_done;
347 	}
348 
349 	priv->dvc_nr	= nr;
350 	priv->dvc	= dvc;
351 
352 	i = 0;
353 	ret = 0;
354 	for_each_child_of_node(node, np) {
355 		dvc = rsnd_dvc_get(priv, i);
356 
357 		snprintf(name, RSND_DVC_NAME_SIZE, "%s.%d",
358 			 DVC_NAME, i);
359 
360 		clk = devm_clk_get(dev, name);
361 		if (IS_ERR(clk)) {
362 			ret = PTR_ERR(clk);
363 			of_node_put(np);
364 			goto rsnd_dvc_probe_done;
365 		}
366 
367 		ret = rsnd_mod_init(priv, rsnd_mod_get(dvc), &rsnd_dvc_ops,
368 				    clk, rsnd_mod_get_status, RSND_MOD_DVC, i);
369 		if (ret) {
370 			of_node_put(np);
371 			goto rsnd_dvc_probe_done;
372 		}
373 
374 		i++;
375 	}
376 
377 rsnd_dvc_probe_done:
378 	of_node_put(node);
379 
380 	return ret;
381 }
382 
383 void rsnd_dvc_remove(struct rsnd_priv *priv)
384 {
385 	struct rsnd_dvc *dvc;
386 	int i;
387 
388 	for_each_rsnd_dvc(dvc, priv, i) {
389 		rsnd_mod_quit(rsnd_mod_get(dvc));
390 	}
391 }
392