1/*
2 * Renesas R-Car DVC support
3 *
4 * Copyright (C) 2014 Renesas Solutions Corp.
5 * Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 */
11#include "rsnd.h"
12
13#define RSND_DVC_NAME_SIZE	16
14
15#define DVC_NAME "dvc"
16
17struct rsnd_dvc {
18	struct rsnd_dvc_platform_info *info; /* rcar_snd.h */
19	struct rsnd_mod mod;
20	struct rsnd_kctrl_cfg_m volume;
21	struct rsnd_kctrl_cfg_m mute;
22	struct rsnd_kctrl_cfg_s ren;	/* Ramp Enable */
23	struct rsnd_kctrl_cfg_s rup;	/* Ramp Rate Up */
24	struct rsnd_kctrl_cfg_s rdown;	/* Ramp Rate Down */
25};
26
27#define rsnd_dvc_of_node(priv) \
28	of_get_child_by_name(rsnd_priv_to_dev(priv)->of_node, "rcar_sound,dvc")
29
30#define rsnd_mod_to_dvc(_mod)	\
31	container_of((_mod), struct rsnd_dvc, mod)
32
33#define for_each_rsnd_dvc(pos, priv, i)				\
34	for ((i) = 0;						\
35	     ((i) < rsnd_dvc_nr(priv)) &&			\
36	     ((pos) = (struct rsnd_dvc *)(priv)->dvc + i);	\
37	     i++)
38
39static const char * const dvc_ramp_rate[] = {
40	"128 dB/1 step",	 /* 00000 */
41	"64 dB/1 step",		 /* 00001 */
42	"32 dB/1 step",		 /* 00010 */
43	"16 dB/1 step",		 /* 00011 */
44	"8 dB/1 step",		 /* 00100 */
45	"4 dB/1 step",		 /* 00101 */
46	"2 dB/1 step",		 /* 00110 */
47	"1 dB/1 step",		 /* 00111 */
48	"0.5 dB/1 step",	 /* 01000 */
49	"0.25 dB/1 step",	 /* 01001 */
50	"0.125 dB/1 step",	 /* 01010 */
51	"0.125 dB/2 steps",	 /* 01011 */
52	"0.125 dB/4 steps",	 /* 01100 */
53	"0.125 dB/8 steps",	 /* 01101 */
54	"0.125 dB/16 steps",	 /* 01110 */
55	"0.125 dB/32 steps",	 /* 01111 */
56	"0.125 dB/64 steps",	 /* 10000 */
57	"0.125 dB/128 steps",	 /* 10001 */
58	"0.125 dB/256 steps",	 /* 10010 */
59	"0.125 dB/512 steps",	 /* 10011 */
60	"0.125 dB/1024 steps",	 /* 10100 */
61	"0.125 dB/2048 steps",	 /* 10101 */
62	"0.125 dB/4096 steps",	 /* 10110 */
63	"0.125 dB/8192 steps",	 /* 10111 */
64};
65
66static void rsnd_dvc_volume_update(struct rsnd_mod *mod)
67{
68	struct rsnd_dvc *dvc = rsnd_mod_to_dvc(mod);
69	u32 val[RSND_DVC_CHANNELS];
70	u32 dvucr = 0;
71	u32 mute = 0;
72	int i;
73
74	for (i = 0; i < dvc->mute.cfg.size; i++)
75		mute |= (!!dvc->mute.cfg.val[i]) << i;
76
77	/* Disable DVC Register access */
78	rsnd_mod_write(mod, DVC_DVUER, 0);
79
80	/* Enable Ramp */
81	if (dvc->ren.val) {
82		dvucr |= 0x10;
83
84		/* Digital Volume Max */
85		for (i = 0; i < RSND_DVC_CHANNELS; i++)
86			val[i] = dvc->volume.cfg.max;
87
88		rsnd_mod_write(mod, DVC_VRCTR, 0xff);
89		rsnd_mod_write(mod, DVC_VRPDR, dvc->rup.val << 8 |
90					       dvc->rdown.val);
91		/*
92		 * FIXME !!
93		 * use scale-downed Digital Volume
94		 * as Volume Ramp
95		 * 7F FFFF -> 3FF
96		 */
97		rsnd_mod_write(mod, DVC_VRDBR,
98			       0x3ff - (dvc->volume.val[0] >> 13));
99
100	} else {
101		for (i = 0; i < RSND_DVC_CHANNELS; i++)
102			val[i] = dvc->volume.val[i];
103	}
104
105	/* Enable Digital Volume */
106	dvucr |= 0x100;
107	rsnd_mod_write(mod, DVC_VOL0R, val[0]);
108	rsnd_mod_write(mod, DVC_VOL1R, val[1]);
109
110	/*  Enable Mute */
111	if (mute) {
112		dvucr |= 0x1;
113		rsnd_mod_write(mod, DVC_ZCMCR, mute);
114	}
115
116	rsnd_mod_write(mod, DVC_DVUCR, dvucr);
117
118	/* Enable DVC Register access */
119	rsnd_mod_write(mod, DVC_DVUER, 1);
120}
121
122static int rsnd_dvc_remove_gen2(struct rsnd_mod *mod,
123				struct rsnd_priv *priv)
124{
125	struct rsnd_dvc *dvc = rsnd_mod_to_dvc(mod);
126
127	rsnd_kctrl_remove(dvc->volume);
128	rsnd_kctrl_remove(dvc->mute);
129	rsnd_kctrl_remove(dvc->ren);
130	rsnd_kctrl_remove(dvc->rup);
131	rsnd_kctrl_remove(dvc->rdown);
132
133	return 0;
134}
135
136static int rsnd_dvc_init(struct rsnd_mod *dvc_mod,
137			 struct rsnd_priv *priv)
138{
139	struct rsnd_dai_stream *io = rsnd_mod_to_io(dvc_mod);
140	struct rsnd_mod *src_mod = rsnd_io_to_mod_src(io);
141	struct device *dev = rsnd_priv_to_dev(priv);
142	int dvc_id = rsnd_mod_id(dvc_mod);
143	int src_id = rsnd_mod_id(src_mod);
144	u32 route[] = {
145		[0] = 0x30000,
146		[1] = 0x30001,
147		[2] = 0x40000,
148		[3] = 0x10000,
149		[4] = 0x20000,
150		[5] = 0x40100
151	};
152
153	if (src_id >= ARRAY_SIZE(route)) {
154		dev_err(dev, "DVC%d isn't connected to SRC%d\n", dvc_id, src_id);
155		return -EINVAL;
156	}
157
158	rsnd_mod_hw_start(dvc_mod);
159
160	/*
161	 * fixme
162	 * it doesn't support CTU/MIX
163	 */
164	rsnd_mod_write(dvc_mod, CMD_ROUTE_SLCT, route[src_id]);
165
166	rsnd_mod_write(dvc_mod, DVC_SWRSR, 0);
167	rsnd_mod_write(dvc_mod, DVC_SWRSR, 1);
168
169	rsnd_mod_write(dvc_mod, DVC_DVUIR, 1);
170
171	rsnd_mod_write(dvc_mod, DVC_ADINR, rsnd_get_adinr(dvc_mod));
172
173	/* ch0/ch1 Volume */
174	rsnd_dvc_volume_update(dvc_mod);
175
176	rsnd_mod_write(dvc_mod, DVC_DVUIR, 0);
177
178	rsnd_adg_set_cmd_timsel_gen2(dvc_mod, io);
179
180	return 0;
181}
182
183static int rsnd_dvc_quit(struct rsnd_mod *mod,
184			 struct rsnd_priv *priv)
185{
186	rsnd_mod_hw_stop(mod);
187
188	return 0;
189}
190
191static int rsnd_dvc_start(struct rsnd_mod *mod,
192			  struct rsnd_priv *priv)
193{
194	rsnd_mod_write(mod, CMD_CTRL, 0x10);
195
196	return 0;
197}
198
199static int rsnd_dvc_stop(struct rsnd_mod *mod,
200			 struct rsnd_priv *priv)
201{
202	rsnd_mod_write(mod, CMD_CTRL, 0);
203
204	return 0;
205}
206
207static int rsnd_dvc_pcm_new(struct rsnd_mod *mod,
208			    struct snd_soc_pcm_runtime *rtd)
209{
210	struct rsnd_dai_stream *io = rsnd_mod_to_io(mod);
211	struct rsnd_dvc *dvc = rsnd_mod_to_dvc(mod);
212	int is_play = rsnd_io_is_play(io);
213	int ret;
214
215	/* Volume */
216	ret = rsnd_kctrl_new_m(mod, rtd,
217			is_play ?
218			"DVC Out Playback Volume" : "DVC In Capture Volume",
219			rsnd_dvc_volume_update,
220			&dvc->volume, 0x00800000 - 1);
221	if (ret < 0)
222		return ret;
223
224	/* Mute */
225	ret = rsnd_kctrl_new_m(mod, rtd,
226			is_play ?
227			"DVC Out Mute Switch" : "DVC In Mute Switch",
228			rsnd_dvc_volume_update,
229			&dvc->mute, 1);
230	if (ret < 0)
231		return ret;
232
233	/* Ramp */
234	ret = rsnd_kctrl_new_s(mod, rtd,
235			is_play ?
236			"DVC Out Ramp Switch" : "DVC In Ramp Switch",
237			rsnd_dvc_volume_update,
238			&dvc->ren, 1);
239	if (ret < 0)
240		return ret;
241
242	ret = rsnd_kctrl_new_e(mod, rtd,
243			is_play ?
244			"DVC Out Ramp Up Rate" : "DVC In Ramp Up Rate",
245			&dvc->rup,
246			rsnd_dvc_volume_update,
247			dvc_ramp_rate, ARRAY_SIZE(dvc_ramp_rate));
248	if (ret < 0)
249		return ret;
250
251	ret = rsnd_kctrl_new_e(mod, rtd,
252			is_play ?
253			"DVC Out Ramp Down Rate" : "DVC In Ramp Down Rate",
254			&dvc->rdown,
255			rsnd_dvc_volume_update,
256			dvc_ramp_rate, ARRAY_SIZE(dvc_ramp_rate));
257
258	if (ret < 0)
259		return ret;
260
261	return 0;
262}
263
264static struct dma_chan *rsnd_dvc_dma_req(struct rsnd_mod *mod)
265{
266	struct rsnd_priv *priv = rsnd_mod_to_priv(mod);
267
268	return rsnd_dma_request_channel(rsnd_dvc_of_node(priv),
269					mod, "tx");
270}
271
272static struct rsnd_mod_ops rsnd_dvc_ops = {
273	.name		= DVC_NAME,
274	.dma_req	= rsnd_dvc_dma_req,
275	.remove		= rsnd_dvc_remove_gen2,
276	.init		= rsnd_dvc_init,
277	.quit		= rsnd_dvc_quit,
278	.start		= rsnd_dvc_start,
279	.stop		= rsnd_dvc_stop,
280	.pcm_new	= rsnd_dvc_pcm_new,
281};
282
283struct rsnd_mod *rsnd_dvc_mod_get(struct rsnd_priv *priv, int id)
284{
285	if (WARN_ON(id < 0 || id >= rsnd_dvc_nr(priv)))
286		id = 0;
287
288	return &((struct rsnd_dvc *)(priv->dvc) + id)->mod;
289}
290
291static void rsnd_of_parse_dvc(struct platform_device *pdev,
292			      const struct rsnd_of_data *of_data,
293			      struct rsnd_priv *priv)
294{
295	struct device_node *node;
296	struct rsnd_dvc_platform_info *dvc_info;
297	struct rcar_snd_info *info = rsnd_priv_to_info(priv);
298	struct device *dev = &pdev->dev;
299	int nr;
300
301	if (!of_data)
302		return;
303
304	node = of_get_child_by_name(dev->of_node, "rcar_sound,dvc");
305	if (!node)
306		return;
307
308	nr = of_get_child_count(node);
309	if (!nr)
310		goto rsnd_of_parse_dvc_end;
311
312	dvc_info = devm_kzalloc(dev,
313				sizeof(struct rsnd_dvc_platform_info) * nr,
314				GFP_KERNEL);
315	if (!dvc_info) {
316		dev_err(dev, "dvc info allocation error\n");
317		goto rsnd_of_parse_dvc_end;
318	}
319
320	info->dvc_info		= dvc_info;
321	info->dvc_info_nr	= nr;
322
323rsnd_of_parse_dvc_end:
324	of_node_put(node);
325}
326
327int rsnd_dvc_probe(struct platform_device *pdev,
328		   const struct rsnd_of_data *of_data,
329		   struct rsnd_priv *priv)
330{
331	struct rcar_snd_info *info = rsnd_priv_to_info(priv);
332	struct device *dev = rsnd_priv_to_dev(priv);
333	struct rsnd_dvc *dvc;
334	struct clk *clk;
335	char name[RSND_DVC_NAME_SIZE];
336	int i, nr, ret;
337
338	rsnd_of_parse_dvc(pdev, of_data, priv);
339
340	nr = info->dvc_info_nr;
341	if (!nr)
342		return 0;
343
344	/* This driver doesn't support Gen1 at this point */
345	if (rsnd_is_gen1(priv)) {
346		dev_warn(dev, "CMD is not supported on Gen1\n");
347		return -EINVAL;
348	}
349
350	dvc	= devm_kzalloc(dev, sizeof(*dvc) * nr, GFP_KERNEL);
351	if (!dvc) {
352		dev_err(dev, "CMD allocate failed\n");
353		return -ENOMEM;
354	}
355
356	priv->dvc_nr	= nr;
357	priv->dvc	= dvc;
358
359	for_each_rsnd_dvc(dvc, priv, i) {
360		snprintf(name, RSND_DVC_NAME_SIZE, "%s.%d",
361			 DVC_NAME, i);
362
363		clk = devm_clk_get(dev, name);
364		if (IS_ERR(clk))
365			return PTR_ERR(clk);
366
367		dvc->info = &info->dvc_info[i];
368
369		ret = rsnd_mod_init(&dvc->mod, &rsnd_dvc_ops,
370			      clk, RSND_MOD_DVC, i);
371		if (ret)
372			return ret;
373	}
374
375	return 0;
376}
377
378void rsnd_dvc_remove(struct platform_device *pdev,
379		     struct rsnd_priv *priv)
380{
381	struct rsnd_dvc *dvc;
382	int i;
383
384	for_each_rsnd_dvc(dvc, priv, i) {
385		rsnd_mod_quit(&dvc->mod);
386	}
387}
388