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