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