blob: bb22850e8fe6fc1fc6984e116b5e6acf5e4c40dd [file] [log] [blame]
Kuninori Morimotobff58ea2014-05-08 17:44:49 -07001/*
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 */
Kuninori Morimotof1511a12016-03-10 05:29:21 +000011
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
Kuninori Morimotobff58ea2014-05-08 17:44:49 -070034#include "rsnd.h"
35
36#define RSND_DVC_NAME_SIZE 16
Kuninori Morimoto8aefda52014-05-22 23:25:43 -070037
38#define DVC_NAME "dvc"
39
Kuninori Morimotobff58ea2014-05-08 17:44:49 -070040struct rsnd_dvc {
Kuninori Morimotobff58ea2014-05-08 17:44:49 -070041 struct rsnd_mod mod;
Kuninori Morimoto170a2492014-11-27 08:06:14 +000042 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 */
Kuninori Morimotob918f1b2017-10-01 23:48:29 +000047 u32 flags;
Kuninori Morimotobff58ea2014-05-08 17:44:49 -070048};
49
Kuninori Morimotob918f1b2017-10-01 23:48:29 +000050#define KCTRL_INITIALIZED (1 << 0)
51
Kuninori Morimoto9eaa1a62015-11-10 05:12:50 +000052#define rsnd_dvc_get(priv, id) ((struct rsnd_dvc *)(priv->dvc) + id)
Kuninori Morimoto4f35fab2015-07-15 07:11:02 +000053#define rsnd_dvc_nr(priv) ((priv)->dvc_nr)
Kuninori Morimoto93b986e2015-02-20 10:30:41 +000054
Kuninori Morimotobff58ea2014-05-08 17:44:49 -070055#define rsnd_mod_to_dvc(_mod) \
56 container_of((_mod), struct rsnd_dvc, mod)
57
58#define for_each_rsnd_dvc(pos, priv, i) \
59 for ((i) = 0; \
60 ((i) < rsnd_dvc_nr(priv)) && \
61 ((pos) = (struct rsnd_dvc *)(priv)->dvc + i); \
62 i++)
63
Krzysztof Kozlowski2f4b1e62015-03-24 11:47:43 +010064static const char * const dvc_ramp_rate[] = {
Kuninori Morimoto3539cac2014-11-09 19:52:06 -080065 "128 dB/1 step", /* 00000 */
66 "64 dB/1 step", /* 00001 */
67 "32 dB/1 step", /* 00010 */
68 "16 dB/1 step", /* 00011 */
69 "8 dB/1 step", /* 00100 */
70 "4 dB/1 step", /* 00101 */
71 "2 dB/1 step", /* 00110 */
72 "1 dB/1 step", /* 00111 */
73 "0.5 dB/1 step", /* 01000 */
74 "0.25 dB/1 step", /* 01001 */
75 "0.125 dB/1 step", /* 01010 */
76 "0.125 dB/2 steps", /* 01011 */
77 "0.125 dB/4 steps", /* 01100 */
78 "0.125 dB/8 steps", /* 01101 */
79 "0.125 dB/16 steps", /* 01110 */
80 "0.125 dB/32 steps", /* 01111 */
81 "0.125 dB/64 steps", /* 10000 */
82 "0.125 dB/128 steps", /* 10001 */
83 "0.125 dB/256 steps", /* 10010 */
84 "0.125 dB/512 steps", /* 10011 */
85 "0.125 dB/1024 steps", /* 10100 */
86 "0.125 dB/2048 steps", /* 10101 */
87 "0.125 dB/4096 steps", /* 10110 */
88 "0.125 dB/8192 steps", /* 10111 */
89};
90
Kuninori Morimoto87a6c5a2015-11-30 08:51:15 +000091static void rsnd_dvc_activation(struct rsnd_mod *mod)
Kuninori Morimoto636e4ba2015-07-15 07:12:00 +000092{
93 rsnd_mod_write(mod, DVC_SWRSR, 0);
94 rsnd_mod_write(mod, DVC_SWRSR, 1);
95}
96
Kuninori Morimotof13edb82015-11-30 08:52:21 +000097static void rsnd_dvc_halt(struct rsnd_mod *mod)
98{
99 rsnd_mod_write(mod, DVC_DVUIR, 1);
100 rsnd_mod_write(mod, DVC_SWRSR, 0);
101}
102
Kuninori Morimotoca16cc62015-11-04 08:44:12 +0000103#define rsnd_dvc_get_vrpdr(dvc) (dvc->rup.val << 8 | dvc->rdown.val)
104#define rsnd_dvc_get_vrdbr(dvc) (0x3ff - (dvc->volume.val[0] >> 13))
Kuninori Morimoto3bb3d362015-07-15 07:13:29 +0000105
Kuninori Morimotoca16cc62015-11-04 08:44:12 +0000106static void rsnd_dvc_volume_parameter(struct rsnd_dai_stream *io,
107 struct rsnd_mod *mod)
Kuninori Morimotobff58ea2014-05-08 17:44:49 -0700108{
109 struct rsnd_dvc *dvc = rsnd_mod_to_dvc(mod);
Kuninori Morimotod2240f02016-02-18 08:13:13 +0000110 u32 val[RSND_MAX_CHANNELS];
Kuninori Morimotobff58ea2014-05-08 17:44:49 -0700111 int i;
112
Kuninori Morimotoca16cc62015-11-04 08:44:12 +0000113 /* Enable Ramp */
114 if (dvc->ren.val)
Kuninori Morimotod2240f02016-02-18 08:13:13 +0000115 for (i = 0; i < RSND_MAX_CHANNELS; i++)
Kuninori Morimotoca16cc62015-11-04 08:44:12 +0000116 val[i] = dvc->volume.cfg.max;
117 else
Kuninori Morimotod2240f02016-02-18 08:13:13 +0000118 for (i = 0; i < RSND_MAX_CHANNELS; i++)
Kuninori Morimotoca16cc62015-11-04 08:44:12 +0000119 val[i] = dvc->volume.val[i];
Kuninori Morimotobff58ea2014-05-08 17:44:49 -0700120
Kuninori Morimotoca16cc62015-11-04 08:44:12 +0000121 /* Enable Digital Volume */
122 rsnd_mod_write(mod, DVC_VOL0R, val[0]);
123 rsnd_mod_write(mod, DVC_VOL1R, val[1]);
Kuninori Morimoto42ab9a72015-11-30 08:53:44 +0000124 rsnd_mod_write(mod, DVC_VOL2R, val[2]);
125 rsnd_mod_write(mod, DVC_VOL3R, val[3]);
126 rsnd_mod_write(mod, DVC_VOL4R, val[4]);
127 rsnd_mod_write(mod, DVC_VOL5R, val[5]);
128 rsnd_mod_write(mod, DVC_VOL6R, val[6]);
129 rsnd_mod_write(mod, DVC_VOL7R, val[7]);
Kuninori Morimotoca16cc62015-11-04 08:44:12 +0000130}
131
132static void rsnd_dvc_volume_init(struct rsnd_dai_stream *io,
133 struct rsnd_mod *mod)
134{
135 struct rsnd_dvc *dvc = rsnd_mod_to_dvc(mod);
Kuninori Morimotoc45f7262015-11-30 08:49:33 +0000136 u32 adinr = 0;
Kuninori Morimotoca16cc62015-11-04 08:44:12 +0000137 u32 dvucr = 0;
138 u32 vrctr = 0;
139 u32 vrpdr = 0;
140 u32 vrdbr = 0;
141
Kuninori Morimotoc45f7262015-11-30 08:49:33 +0000142 adinr = rsnd_get_adinr_bit(mod, io) |
Kuninori Morimotoeed76bb2016-02-25 05:54:58 +0000143 rsnd_runtime_channel_after_ctu(io);
Kuninori Morimotoc45f7262015-11-30 08:49:33 +0000144
Kuninori Morimotoca16cc62015-11-04 08:44:12 +0000145 /* Enable Digital Volume, Zero Cross Mute Mode */
146 dvucr |= 0x101;
Kuninori Morimoto140bab82014-11-04 20:27:18 -0800147
Kuninori Morimoto3539cac2014-11-09 19:52:06 -0800148 /* Enable Ramp */
149 if (dvc->ren.val) {
150 dvucr |= 0x10;
151
Kuninori Morimoto3539cac2014-11-09 19:52:06 -0800152 /*
153 * FIXME !!
154 * use scale-downed Digital Volume
155 * as Volume Ramp
156 * 7F FFFF -> 3FF
157 */
Kuninori Morimotoca16cc62015-11-04 08:44:12 +0000158 vrctr = 0xff;
159 vrpdr = rsnd_dvc_get_vrpdr(dvc);
160 vrdbr = rsnd_dvc_get_vrdbr(dvc);
Kuninori Morimoto3539cac2014-11-09 19:52:06 -0800161 }
162
Kuninori Morimotoca16cc62015-11-04 08:44:12 +0000163 /* Initialize operation */
164 rsnd_mod_write(mod, DVC_DVUIR, 1);
Kuninori Morimotocd2b6572014-08-01 03:10:55 -0700165
Kuninori Morimotoca16cc62015-11-04 08:44:12 +0000166 /* General Information */
Kuninori Morimotoc45f7262015-11-30 08:49:33 +0000167 rsnd_mod_write(mod, DVC_ADINR, adinr);
Kuninori Morimoto1c5d1c92014-11-04 20:26:53 -0800168 rsnd_mod_write(mod, DVC_DVUCR, dvucr);
Kuninori Morimoto140bab82014-11-04 20:27:18 -0800169
Kuninori Morimotoca16cc62015-11-04 08:44:12 +0000170 /* Volume Ramp Parameter */
171 rsnd_mod_write(mod, DVC_VRCTR, vrctr);
172 rsnd_mod_write(mod, DVC_VRPDR, vrpdr);
173 rsnd_mod_write(mod, DVC_VRDBR, vrdbr);
174
175 /* Digital Volume Function Parameter */
176 rsnd_dvc_volume_parameter(io, mod);
177
178 /* cancel operation */
179 rsnd_mod_write(mod, DVC_DVUIR, 0);
180}
181
182static void rsnd_dvc_volume_update(struct rsnd_dai_stream *io,
183 struct rsnd_mod *mod)
184{
185 struct rsnd_dvc *dvc = rsnd_mod_to_dvc(mod);
186 u32 zcmcr = 0;
187 u32 vrpdr = 0;
188 u32 vrdbr = 0;
189 int i;
190
191 for (i = 0; i < dvc->mute.cfg.size; i++)
192 zcmcr |= (!!dvc->mute.cfg.val[i]) << i;
193
194 if (dvc->ren.val) {
195 vrpdr = rsnd_dvc_get_vrpdr(dvc);
196 vrdbr = rsnd_dvc_get_vrdbr(dvc);
197 }
198
199 /* Disable DVC Register access */
200 rsnd_mod_write(mod, DVC_DVUER, 0);
201
202 /* Zero Cross Mute Function */
203 rsnd_mod_write(mod, DVC_ZCMCR, zcmcr);
204
205 /* Volume Ramp Function */
206 rsnd_mod_write(mod, DVC_VRPDR, vrpdr);
207 rsnd_mod_write(mod, DVC_VRDBR, vrdbr);
208 /* add DVC_VRWTR here */
209
210 /* Digital Volume Function Parameter */
211 rsnd_dvc_volume_parameter(io, mod);
212
Kuninori Morimoto140bab82014-11-04 20:27:18 -0800213 /* Enable DVC Register access */
214 rsnd_mod_write(mod, DVC_DVUER, 1);
Kuninori Morimotobff58ea2014-05-08 17:44:49 -0700215}
216
Kuninori Morimoto1b2ca0a2015-10-26 08:43:21 +0000217static int rsnd_dvc_probe_(struct rsnd_mod *mod,
218 struct rsnd_dai_stream *io,
219 struct rsnd_priv *priv)
220{
221 return rsnd_cmd_attach(io, rsnd_mod_id(mod));
222}
223
Kuninori Morimotoe2c08412015-07-15 07:13:10 +0000224static int rsnd_dvc_init(struct rsnd_mod *mod,
Kuninori Morimoto2c0fac12015-06-15 06:25:20 +0000225 struct rsnd_dai_stream *io,
Kuninori Morimoto690602f2015-01-15 08:07:47 +0000226 struct rsnd_priv *priv)
Kuninori Morimotobff58ea2014-05-08 17:44:49 -0700227{
Kuninori Morimotoc9929342015-10-22 03:15:04 +0000228 rsnd_mod_power_on(mod);
Kuninori Morimotobff58ea2014-05-08 17:44:49 -0700229
Kuninori Morimoto87a6c5a2015-11-30 08:51:15 +0000230 rsnd_dvc_activation(mod);
Kuninori Morimotobff58ea2014-05-08 17:44:49 -0700231
Kuninori Morimotoca16cc62015-11-04 08:44:12 +0000232 rsnd_dvc_volume_init(io, mod);
Kuninori Morimotobff58ea2014-05-08 17:44:49 -0700233
Kuninori Morimotoe2c08412015-07-15 07:13:10 +0000234 rsnd_dvc_volume_update(io, mod);
Kuninori Morimotobff58ea2014-05-08 17:44:49 -0700235
Kuninori Morimotobff58ea2014-05-08 17:44:49 -0700236 return 0;
237}
238
239static int rsnd_dvc_quit(struct rsnd_mod *mod,
Kuninori Morimoto2c0fac12015-06-15 06:25:20 +0000240 struct rsnd_dai_stream *io,
Kuninori Morimoto690602f2015-01-15 08:07:47 +0000241 struct rsnd_priv *priv)
Kuninori Morimotobff58ea2014-05-08 17:44:49 -0700242{
Kuninori Morimotof13edb82015-11-30 08:52:21 +0000243 rsnd_dvc_halt(mod);
244
Kuninori Morimotoc9929342015-10-22 03:15:04 +0000245 rsnd_mod_power_off(mod);
Kuninori Morimotobff58ea2014-05-08 17:44:49 -0700246
247 return 0;
248}
249
Kuninori Morimotobff58ea2014-05-08 17:44:49 -0700250static int rsnd_dvc_pcm_new(struct rsnd_mod *mod,
Kuninori Morimoto2c0fac12015-06-15 06:25:20 +0000251 struct rsnd_dai_stream *io,
Kuninori Morimotobff58ea2014-05-08 17:44:49 -0700252 struct snd_soc_pcm_runtime *rtd)
253{
Kuninori Morimoto486b09c2014-08-01 03:10:47 -0700254 struct rsnd_dvc *dvc = rsnd_mod_to_dvc(mod);
Kuninori Morimoto1ff95932017-06-15 00:49:27 +0000255 struct rsnd_dai *rdai = rsnd_io_to_rdai(io);
Kuninori Morimoto985a4f62015-01-15 08:06:49 +0000256 int is_play = rsnd_io_is_play(io);
Kuninori Morimoto1ff95932017-06-15 00:49:27 +0000257 int channels = rsnd_rdai_channels_get(rdai);
Kuninori Morimotobff58ea2014-05-08 17:44:49 -0700258 int ret;
259
Kuninori Morimotob918f1b2017-10-01 23:48:29 +0000260 if (rsnd_flags_has(dvc, KCTRL_INITIALIZED))
261 return 0;
262
Kuninori Morimoto486b09c2014-08-01 03:10:47 -0700263 /* Volume */
Kuninori Morimotob65a7cc2015-06-15 06:27:28 +0000264 ret = rsnd_kctrl_new_m(mod, io, rtd,
Kuninori Morimoto985a4f62015-01-15 08:06:49 +0000265 is_play ?
Kuninori Morimoto486b09c2014-08-01 03:10:47 -0700266 "DVC Out Playback Volume" : "DVC In Capture Volume",
Kuninori Morimotof0b04d82017-06-07 00:11:48 +0000267 rsnd_kctrl_accept_anytime,
Kuninori Morimoto170a2492014-11-27 08:06:14 +0000268 rsnd_dvc_volume_update,
Kuninori Morimoto1ff95932017-06-15 00:49:27 +0000269 &dvc->volume, channels,
Kuninori Morimoto42ab9a72015-11-30 08:53:44 +0000270 0x00800000 - 1);
Kuninori Morimotobff58ea2014-05-08 17:44:49 -0700271 if (ret < 0)
272 return ret;
273
Kuninori Morimotocd2b6572014-08-01 03:10:55 -0700274 /* Mute */
Kuninori Morimotob65a7cc2015-06-15 06:27:28 +0000275 ret = rsnd_kctrl_new_m(mod, io, rtd,
Kuninori Morimoto985a4f62015-01-15 08:06:49 +0000276 is_play ?
Kuninori Morimotocd2b6572014-08-01 03:10:55 -0700277 "DVC Out Mute Switch" : "DVC In Mute Switch",
Kuninori Morimotof0b04d82017-06-07 00:11:48 +0000278 rsnd_kctrl_accept_anytime,
Kuninori Morimoto170a2492014-11-27 08:06:14 +0000279 rsnd_dvc_volume_update,
Kuninori Morimoto1ff95932017-06-15 00:49:27 +0000280 &dvc->mute, channels,
Kuninori Morimoto42ab9a72015-11-30 08:53:44 +0000281 1);
Kuninori Morimotocd2b6572014-08-01 03:10:55 -0700282 if (ret < 0)
283 return ret;
284
Kuninori Morimoto3539cac2014-11-09 19:52:06 -0800285 /* Ramp */
Kuninori Morimotob65a7cc2015-06-15 06:27:28 +0000286 ret = rsnd_kctrl_new_s(mod, io, rtd,
Kuninori Morimoto985a4f62015-01-15 08:06:49 +0000287 is_play ?
Kuninori Morimoto3539cac2014-11-09 19:52:06 -0800288 "DVC Out Ramp Switch" : "DVC In Ramp Switch",
Kuninori Morimotof0b04d82017-06-07 00:11:48 +0000289 rsnd_kctrl_accept_anytime,
Kuninori Morimoto170a2492014-11-27 08:06:14 +0000290 rsnd_dvc_volume_update,
Kuninori Morimoto3539cac2014-11-09 19:52:06 -0800291 &dvc->ren, 1);
292 if (ret < 0)
293 return ret;
294
Kuninori Morimotob65a7cc2015-06-15 06:27:28 +0000295 ret = rsnd_kctrl_new_e(mod, io, rtd,
Kuninori Morimoto985a4f62015-01-15 08:06:49 +0000296 is_play ?
Kuninori Morimoto3539cac2014-11-09 19:52:06 -0800297 "DVC Out Ramp Up Rate" : "DVC In Ramp Up Rate",
Kuninori Morimotof0b04d82017-06-07 00:11:48 +0000298 rsnd_kctrl_accept_anytime,
Kuninori Morimoto170a2492014-11-27 08:06:14 +0000299 rsnd_dvc_volume_update,
Kuninori Morimoto32973dc2017-04-06 07:25:13 +0000300 &dvc->rup,
301 dvc_ramp_rate);
Kuninori Morimoto3539cac2014-11-09 19:52:06 -0800302 if (ret < 0)
303 return ret;
304
Kuninori Morimotob65a7cc2015-06-15 06:27:28 +0000305 ret = rsnd_kctrl_new_e(mod, io, rtd,
Kuninori Morimoto985a4f62015-01-15 08:06:49 +0000306 is_play ?
Kuninori Morimoto3539cac2014-11-09 19:52:06 -0800307 "DVC Out Ramp Down Rate" : "DVC In Ramp Down Rate",
Kuninori Morimotof0b04d82017-06-07 00:11:48 +0000308 rsnd_kctrl_accept_anytime,
Kuninori Morimoto170a2492014-11-27 08:06:14 +0000309 rsnd_dvc_volume_update,
Kuninori Morimoto32973dc2017-04-06 07:25:13 +0000310 &dvc->rdown,
311 dvc_ramp_rate);
Kuninori Morimoto3539cac2014-11-09 19:52:06 -0800312
313 if (ret < 0)
314 return ret;
315
Kuninori Morimotob918f1b2017-10-01 23:48:29 +0000316 rsnd_flags_set(dvc, KCTRL_INITIALIZED);
317
Kuninori Morimotobff58ea2014-05-08 17:44:49 -0700318 return 0;
319}
320
Kuninori Morimoto9b99e9a2015-06-15 06:26:25 +0000321static struct dma_chan *rsnd_dvc_dma_req(struct rsnd_dai_stream *io,
322 struct rsnd_mod *mod)
Kuninori Morimoto72adc612015-02-20 10:31:23 +0000323{
324 struct rsnd_priv *priv = rsnd_mod_to_priv(mod);
325
326 return rsnd_dma_request_channel(rsnd_dvc_of_node(priv),
327 mod, "tx");
328}
329
Kuninori Morimotobff58ea2014-05-08 17:44:49 -0700330static struct rsnd_mod_ops rsnd_dvc_ops = {
Kuninori Morimoto8aefda52014-05-22 23:25:43 -0700331 .name = DVC_NAME,
Kuninori Morimoto72adc612015-02-20 10:31:23 +0000332 .dma_req = rsnd_dvc_dma_req,
Kuninori Morimoto1b2ca0a2015-10-26 08:43:21 +0000333 .probe = rsnd_dvc_probe_,
Kuninori Morimotobff58ea2014-05-08 17:44:49 -0700334 .init = rsnd_dvc_init,
335 .quit = rsnd_dvc_quit,
Kuninori Morimotobff58ea2014-05-08 17:44:49 -0700336 .pcm_new = rsnd_dvc_pcm_new,
337};
338
339struct rsnd_mod *rsnd_dvc_mod_get(struct rsnd_priv *priv, int id)
340{
341 if (WARN_ON(id < 0 || id >= rsnd_dvc_nr(priv)))
342 id = 0;
343
Kuninori Morimoto9eaa1a62015-11-10 05:12:50 +0000344 return rsnd_mod_get(rsnd_dvc_get(priv, id));
Kuninori Morimoto34cb6122014-06-22 17:59:28 -0700345}
346
Kuninori Morimoto2ea6b072015-11-10 05:14:12 +0000347int rsnd_dvc_probe(struct rsnd_priv *priv)
Kuninori Morimotobff58ea2014-05-08 17:44:49 -0700348{
Kuninori Morimoto9eaa1a62015-11-10 05:12:50 +0000349 struct device_node *node;
350 struct device_node *np;
Kuninori Morimotobff58ea2014-05-08 17:44:49 -0700351 struct device *dev = rsnd_priv_to_dev(priv);
352 struct rsnd_dvc *dvc;
353 struct clk *clk;
354 char name[RSND_DVC_NAME_SIZE];
Kuninori Morimoto2f78dd72015-03-26 04:02:09 +0000355 int i, nr, ret;
Kuninori Morimotobff58ea2014-05-08 17:44:49 -0700356
Kuninori Morimotobff58ea2014-05-08 17:44:49 -0700357 /* This driver doesn't support Gen1 at this point */
Kuninori Morimoto8a98b422015-10-15 03:25:28 +0000358 if (rsnd_is_gen1(priv))
359 return 0;
Kuninori Morimotobff58ea2014-05-08 17:44:49 -0700360
Kuninori Morimoto9eaa1a62015-11-10 05:12:50 +0000361 node = rsnd_dvc_of_node(priv);
362 if (!node)
363 return 0; /* not used is not error */
Kuninori Morimoto9469b8b2015-07-15 07:15:47 +0000364
Kuninori Morimoto9eaa1a62015-11-10 05:12:50 +0000365 nr = of_get_child_count(node);
366 if (!nr) {
367 ret = -EINVAL;
368 goto rsnd_dvc_probe_done;
369 }
Kuninori Morimoto9469b8b2015-07-15 07:15:47 +0000370
Kuninori Morimotobff58ea2014-05-08 17:44:49 -0700371 dvc = devm_kzalloc(dev, sizeof(*dvc) * nr, GFP_KERNEL);
Kuninori Morimoto9eaa1a62015-11-10 05:12:50 +0000372 if (!dvc) {
373 ret = -ENOMEM;
374 goto rsnd_dvc_probe_done;
375 }
Kuninori Morimotobff58ea2014-05-08 17:44:49 -0700376
377 priv->dvc_nr = nr;
378 priv->dvc = dvc;
379
Kuninori Morimoto9eaa1a62015-11-10 05:12:50 +0000380 i = 0;
Mark Brown2e4118d2015-12-14 12:05:17 +0000381 ret = 0;
Kuninori Morimoto9eaa1a62015-11-10 05:12:50 +0000382 for_each_child_of_node(node, np) {
383 dvc = rsnd_dvc_get(priv, i);
384
Kuninori Morimoto8aefda52014-05-22 23:25:43 -0700385 snprintf(name, RSND_DVC_NAME_SIZE, "%s.%d",
386 DVC_NAME, i);
Kuninori Morimotobff58ea2014-05-08 17:44:49 -0700387
388 clk = devm_clk_get(dev, name);
Kuninori Morimoto9eaa1a62015-11-10 05:12:50 +0000389 if (IS_ERR(clk)) {
390 ret = PTR_ERR(clk);
Julia Lawall53ba2aa2017-07-15 09:19:07 +0200391 of_node_put(np);
Kuninori Morimoto9eaa1a62015-11-10 05:12:50 +0000392 goto rsnd_dvc_probe_done;
393 }
Kuninori Morimotobff58ea2014-05-08 17:44:49 -0700394
Kuninori Morimotob76e2182015-09-10 07:02:21 +0000395 ret = rsnd_mod_init(priv, rsnd_mod_get(dvc), &rsnd_dvc_ops,
Kuninori Morimoto5ba17b422016-01-21 01:58:07 +0000396 clk, rsnd_mod_get_status, RSND_MOD_DVC, i);
Julia Lawall53ba2aa2017-07-15 09:19:07 +0200397 if (ret) {
398 of_node_put(np);
Kuninori Morimoto9eaa1a62015-11-10 05:12:50 +0000399 goto rsnd_dvc_probe_done;
Julia Lawall53ba2aa2017-07-15 09:19:07 +0200400 }
Kuninori Morimoto9eaa1a62015-11-10 05:12:50 +0000401
402 i++;
Kuninori Morimotobff58ea2014-05-08 17:44:49 -0700403 }
404
Kuninori Morimoto9eaa1a62015-11-10 05:12:50 +0000405rsnd_dvc_probe_done:
406 of_node_put(node);
407
408 return ret;
Kuninori Morimotobff58ea2014-05-08 17:44:49 -0700409}
Kuninori Morimoto2f78dd72015-03-26 04:02:09 +0000410
Kuninori Morimoto2ea6b072015-11-10 05:14:12 +0000411void rsnd_dvc_remove(struct rsnd_priv *priv)
Kuninori Morimoto2f78dd72015-03-26 04:02:09 +0000412{
413 struct rsnd_dvc *dvc;
414 int i;
415
416 for_each_rsnd_dvc(dvc, priv, i) {
Kuninori Morimotob76e2182015-09-10 07:02:21 +0000417 rsnd_mod_quit(rsnd_mod_get(dvc));
Kuninori Morimoto2f78dd72015-03-26 04:02:09 +0000418 }
419}