blob: ca1780e0b8304afc0567585d002b965fc978682b [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
Kuninori Morimoto87a6c5a2015-11-30 08:51:15 +000064static void rsnd_dvc_activation(struct rsnd_mod *mod)
Kuninori Morimoto636e4ba2015-07-15 07:12:00 +000065{
66 rsnd_mod_write(mod, DVC_SWRSR, 0);
67 rsnd_mod_write(mod, DVC_SWRSR, 1);
68}
69
Kuninori Morimotof13edb82015-11-30 08:52:21 +000070static void rsnd_dvc_halt(struct rsnd_mod *mod)
71{
72 rsnd_mod_write(mod, DVC_DVUIR, 1);
73 rsnd_mod_write(mod, DVC_SWRSR, 0);
74}
75
Kuninori Morimoto3a9fa272017-10-11 04:42:34 +000076#define rsnd_dvc_get_vrpdr(dvc) (rsnd_kctrl_vals(dvc->rup) << 8 | \
77 rsnd_kctrl_vals(dvc->rdown))
78#define rsnd_dvc_get_vrdbr(dvc) (0x3ff - (rsnd_kctrl_valm(dvc->volume, 0) >> 13))
Kuninori Morimoto3bb3d362015-07-15 07:13:29 +000079
Kuninori Morimotoca16cc62015-11-04 08:44:12 +000080static void rsnd_dvc_volume_parameter(struct rsnd_dai_stream *io,
81 struct rsnd_mod *mod)
Kuninori Morimotobff58ea2014-05-08 17:44:49 -070082{
83 struct rsnd_dvc *dvc = rsnd_mod_to_dvc(mod);
Kuninori Morimotod2240f02016-02-18 08:13:13 +000084 u32 val[RSND_MAX_CHANNELS];
Kuninori Morimotobff58ea2014-05-08 17:44:49 -070085 int i;
86
Kuninori Morimotoca16cc62015-11-04 08:44:12 +000087 /* Enable Ramp */
Kuninori Morimoto3a9fa272017-10-11 04:42:34 +000088 if (rsnd_kctrl_vals(dvc->ren))
Kuninori Morimotod2240f02016-02-18 08:13:13 +000089 for (i = 0; i < RSND_MAX_CHANNELS; i++)
Kuninori Morimoto3a9fa272017-10-11 04:42:34 +000090 val[i] = rsnd_kctrl_max(dvc->volume);
Kuninori Morimotoca16cc62015-11-04 08:44:12 +000091 else
Kuninori Morimotod2240f02016-02-18 08:13:13 +000092 for (i = 0; i < RSND_MAX_CHANNELS; i++)
Kuninori Morimoto3a9fa272017-10-11 04:42:34 +000093 val[i] = rsnd_kctrl_valm(dvc->volume, i);
Kuninori Morimotobff58ea2014-05-08 17:44:49 -070094
Kuninori Morimotoca16cc62015-11-04 08:44:12 +000095 /* Enable Digital Volume */
96 rsnd_mod_write(mod, DVC_VOL0R, val[0]);
97 rsnd_mod_write(mod, DVC_VOL1R, val[1]);
Kuninori Morimoto42ab9a72015-11-30 08:53:44 +000098 rsnd_mod_write(mod, DVC_VOL2R, val[2]);
99 rsnd_mod_write(mod, DVC_VOL3R, val[3]);
100 rsnd_mod_write(mod, DVC_VOL4R, val[4]);
101 rsnd_mod_write(mod, DVC_VOL5R, val[5]);
102 rsnd_mod_write(mod, DVC_VOL6R, val[6]);
103 rsnd_mod_write(mod, DVC_VOL7R, val[7]);
Kuninori Morimotoca16cc62015-11-04 08:44:12 +0000104}
105
106static void rsnd_dvc_volume_init(struct rsnd_dai_stream *io,
107 struct rsnd_mod *mod)
108{
109 struct rsnd_dvc *dvc = rsnd_mod_to_dvc(mod);
Kuninori Morimotoc45f7262015-11-30 08:49:33 +0000110 u32 adinr = 0;
Kuninori Morimotoca16cc62015-11-04 08:44:12 +0000111 u32 dvucr = 0;
112 u32 vrctr = 0;
113 u32 vrpdr = 0;
114 u32 vrdbr = 0;
115
Kuninori Morimotoc45f7262015-11-30 08:49:33 +0000116 adinr = rsnd_get_adinr_bit(mod, io) |
Kuninori Morimotoeed76bb2016-02-25 05:54:58 +0000117 rsnd_runtime_channel_after_ctu(io);
Kuninori Morimotoc45f7262015-11-30 08:49:33 +0000118
Kuninori Morimotoca16cc62015-11-04 08:44:12 +0000119 /* Enable Digital Volume, Zero Cross Mute Mode */
120 dvucr |= 0x101;
Kuninori Morimoto140bab82014-11-04 20:27:18 -0800121
Kuninori Morimoto3539cac2014-11-09 19:52:06 -0800122 /* Enable Ramp */
Kuninori Morimoto3a9fa272017-10-11 04:42:34 +0000123 if (rsnd_kctrl_vals(dvc->ren)) {
Kuninori Morimoto3539cac2014-11-09 19:52:06 -0800124 dvucr |= 0x10;
125
Kuninori Morimoto3539cac2014-11-09 19:52:06 -0800126 /*
127 * FIXME !!
128 * use scale-downed Digital Volume
129 * as Volume Ramp
130 * 7F FFFF -> 3FF
131 */
Kuninori Morimotoca16cc62015-11-04 08:44:12 +0000132 vrctr = 0xff;
133 vrpdr = rsnd_dvc_get_vrpdr(dvc);
134 vrdbr = rsnd_dvc_get_vrdbr(dvc);
Kuninori Morimoto3539cac2014-11-09 19:52:06 -0800135 }
136
Kuninori Morimotoca16cc62015-11-04 08:44:12 +0000137 /* Initialize operation */
138 rsnd_mod_write(mod, DVC_DVUIR, 1);
Kuninori Morimotocd2b6572014-08-01 03:10:55 -0700139
Kuninori Morimotoca16cc62015-11-04 08:44:12 +0000140 /* General Information */
Kuninori Morimotoc45f7262015-11-30 08:49:33 +0000141 rsnd_mod_write(mod, DVC_ADINR, adinr);
Kuninori Morimoto1c5d1c92014-11-04 20:26:53 -0800142 rsnd_mod_write(mod, DVC_DVUCR, dvucr);
Kuninori Morimoto140bab82014-11-04 20:27:18 -0800143
Kuninori Morimotoca16cc62015-11-04 08:44:12 +0000144 /* Volume Ramp Parameter */
145 rsnd_mod_write(mod, DVC_VRCTR, vrctr);
146 rsnd_mod_write(mod, DVC_VRPDR, vrpdr);
147 rsnd_mod_write(mod, DVC_VRDBR, vrdbr);
148
149 /* Digital Volume Function Parameter */
150 rsnd_dvc_volume_parameter(io, mod);
151
152 /* cancel operation */
153 rsnd_mod_write(mod, DVC_DVUIR, 0);
154}
155
156static void rsnd_dvc_volume_update(struct rsnd_dai_stream *io,
157 struct rsnd_mod *mod)
158{
159 struct rsnd_dvc *dvc = rsnd_mod_to_dvc(mod);
160 u32 zcmcr = 0;
161 u32 vrpdr = 0;
162 u32 vrdbr = 0;
163 int i;
164
Kuninori Morimoto3a9fa272017-10-11 04:42:34 +0000165 for (i = 0; i < rsnd_kctrl_size(dvc->mute); i++)
166 zcmcr |= (!!rsnd_kctrl_valm(dvc->mute, i)) << i;
Kuninori Morimotoca16cc62015-11-04 08:44:12 +0000167
Kuninori Morimoto3a9fa272017-10-11 04:42:34 +0000168 if (rsnd_kctrl_vals(dvc->ren)) {
Kuninori Morimotoca16cc62015-11-04 08:44:12 +0000169 vrpdr = rsnd_dvc_get_vrpdr(dvc);
170 vrdbr = rsnd_dvc_get_vrdbr(dvc);
171 }
172
173 /* Disable DVC Register access */
174 rsnd_mod_write(mod, DVC_DVUER, 0);
175
176 /* Zero Cross Mute Function */
177 rsnd_mod_write(mod, DVC_ZCMCR, zcmcr);
178
179 /* Volume Ramp Function */
180 rsnd_mod_write(mod, DVC_VRPDR, vrpdr);
181 rsnd_mod_write(mod, DVC_VRDBR, vrdbr);
182 /* add DVC_VRWTR here */
183
184 /* Digital Volume Function Parameter */
185 rsnd_dvc_volume_parameter(io, mod);
186
Kuninori Morimoto140bab82014-11-04 20:27:18 -0800187 /* Enable DVC Register access */
188 rsnd_mod_write(mod, DVC_DVUER, 1);
Kuninori Morimotobff58ea2014-05-08 17:44:49 -0700189}
190
Kuninori Morimoto1b2ca0a2015-10-26 08:43:21 +0000191static int rsnd_dvc_probe_(struct rsnd_mod *mod,
192 struct rsnd_dai_stream *io,
193 struct rsnd_priv *priv)
194{
195 return rsnd_cmd_attach(io, rsnd_mod_id(mod));
196}
197
Kuninori Morimotoe2c08412015-07-15 07:13:10 +0000198static int rsnd_dvc_init(struct rsnd_mod *mod,
Kuninori Morimoto2c0fac12015-06-15 06:25:20 +0000199 struct rsnd_dai_stream *io,
Kuninori Morimoto690602f2015-01-15 08:07:47 +0000200 struct rsnd_priv *priv)
Kuninori Morimotobff58ea2014-05-08 17:44:49 -0700201{
Kuninori Morimotoc9929342015-10-22 03:15:04 +0000202 rsnd_mod_power_on(mod);
Kuninori Morimotobff58ea2014-05-08 17:44:49 -0700203
Kuninori Morimoto87a6c5a2015-11-30 08:51:15 +0000204 rsnd_dvc_activation(mod);
Kuninori Morimotobff58ea2014-05-08 17:44:49 -0700205
Kuninori Morimotoca16cc62015-11-04 08:44:12 +0000206 rsnd_dvc_volume_init(io, mod);
Kuninori Morimotobff58ea2014-05-08 17:44:49 -0700207
Kuninori Morimotoe2c08412015-07-15 07:13:10 +0000208 rsnd_dvc_volume_update(io, mod);
Kuninori Morimotobff58ea2014-05-08 17:44:49 -0700209
Kuninori Morimotobff58ea2014-05-08 17:44:49 -0700210 return 0;
211}
212
213static int rsnd_dvc_quit(struct rsnd_mod *mod,
Kuninori Morimoto2c0fac12015-06-15 06:25:20 +0000214 struct rsnd_dai_stream *io,
Kuninori Morimoto690602f2015-01-15 08:07:47 +0000215 struct rsnd_priv *priv)
Kuninori Morimotobff58ea2014-05-08 17:44:49 -0700216{
Kuninori Morimotof13edb82015-11-30 08:52:21 +0000217 rsnd_dvc_halt(mod);
218
Kuninori Morimotoc9929342015-10-22 03:15:04 +0000219 rsnd_mod_power_off(mod);
Kuninori Morimotobff58ea2014-05-08 17:44:49 -0700220
221 return 0;
222}
223
Kuninori Morimotobff58ea2014-05-08 17:44:49 -0700224static int rsnd_dvc_pcm_new(struct rsnd_mod *mod,
Kuninori Morimoto2c0fac12015-06-15 06:25:20 +0000225 struct rsnd_dai_stream *io,
Kuninori Morimotobff58ea2014-05-08 17:44:49 -0700226 struct snd_soc_pcm_runtime *rtd)
227{
Kuninori Morimoto486b09c2014-08-01 03:10:47 -0700228 struct rsnd_dvc *dvc = rsnd_mod_to_dvc(mod);
Kuninori Morimoto1ff95932017-06-15 00:49:27 +0000229 struct rsnd_dai *rdai = rsnd_io_to_rdai(io);
Kuninori Morimoto985a4f62015-01-15 08:06:49 +0000230 int is_play = rsnd_io_is_play(io);
Kuninori Morimoto1ff95932017-06-15 00:49:27 +0000231 int channels = rsnd_rdai_channels_get(rdai);
Kuninori Morimotobff58ea2014-05-08 17:44:49 -0700232 int ret;
233
Kuninori Morimotob918f1b2017-10-01 23:48:29 +0000234 if (rsnd_flags_has(dvc, KCTRL_INITIALIZED))
235 return 0;
236
Kuninori Morimoto486b09c2014-08-01 03:10:47 -0700237 /* Volume */
Kuninori Morimotob65a7cc2015-06-15 06:27:28 +0000238 ret = rsnd_kctrl_new_m(mod, io, rtd,
Kuninori Morimoto985a4f62015-01-15 08:06:49 +0000239 is_play ?
Kuninori Morimoto486b09c2014-08-01 03:10:47 -0700240 "DVC Out Playback Volume" : "DVC In Capture Volume",
Kuninori Morimotof0b04d82017-06-07 00:11:48 +0000241 rsnd_kctrl_accept_anytime,
Kuninori Morimoto170a2492014-11-27 08:06:14 +0000242 rsnd_dvc_volume_update,
Kuninori Morimoto1ff95932017-06-15 00:49:27 +0000243 &dvc->volume, channels,
Kuninori Morimoto42ab9a72015-11-30 08:53:44 +0000244 0x00800000 - 1);
Kuninori Morimotobff58ea2014-05-08 17:44:49 -0700245 if (ret < 0)
246 return ret;
247
Kuninori Morimotocd2b6572014-08-01 03:10:55 -0700248 /* Mute */
Kuninori Morimotob65a7cc2015-06-15 06:27:28 +0000249 ret = rsnd_kctrl_new_m(mod, io, rtd,
Kuninori Morimoto985a4f62015-01-15 08:06:49 +0000250 is_play ?
Kuninori Morimotocd2b6572014-08-01 03:10:55 -0700251 "DVC Out Mute Switch" : "DVC In Mute Switch",
Kuninori Morimotof0b04d82017-06-07 00:11:48 +0000252 rsnd_kctrl_accept_anytime,
Kuninori Morimoto170a2492014-11-27 08:06:14 +0000253 rsnd_dvc_volume_update,
Kuninori Morimoto1ff95932017-06-15 00:49:27 +0000254 &dvc->mute, channels,
Kuninori Morimoto42ab9a72015-11-30 08:53:44 +0000255 1);
Kuninori Morimotocd2b6572014-08-01 03:10:55 -0700256 if (ret < 0)
257 return ret;
258
Kuninori Morimoto3539cac2014-11-09 19:52:06 -0800259 /* Ramp */
Kuninori Morimotob65a7cc2015-06-15 06:27:28 +0000260 ret = rsnd_kctrl_new_s(mod, io, rtd,
Kuninori Morimoto985a4f62015-01-15 08:06:49 +0000261 is_play ?
Kuninori Morimoto3539cac2014-11-09 19:52:06 -0800262 "DVC Out Ramp Switch" : "DVC In Ramp Switch",
Kuninori Morimotof0b04d82017-06-07 00:11:48 +0000263 rsnd_kctrl_accept_anytime,
Kuninori Morimoto170a2492014-11-27 08:06:14 +0000264 rsnd_dvc_volume_update,
Kuninori Morimoto3539cac2014-11-09 19:52:06 -0800265 &dvc->ren, 1);
266 if (ret < 0)
267 return ret;
268
Kuninori Morimotob65a7cc2015-06-15 06:27:28 +0000269 ret = rsnd_kctrl_new_e(mod, io, rtd,
Kuninori Morimoto985a4f62015-01-15 08:06:49 +0000270 is_play ?
Kuninori Morimoto3539cac2014-11-09 19:52:06 -0800271 "DVC Out Ramp Up Rate" : "DVC In Ramp Up Rate",
Kuninori Morimotof0b04d82017-06-07 00:11:48 +0000272 rsnd_kctrl_accept_anytime,
Kuninori Morimoto170a2492014-11-27 08:06:14 +0000273 rsnd_dvc_volume_update,
Kuninori Morimoto32973dc2017-04-06 07:25:13 +0000274 &dvc->rup,
Kuninori Morimotof3c26ac2017-10-01 23:49:03 +0000275 volume_ramp_rate,
276 VOLUME_RAMP_MAX_DVC);
Kuninori Morimoto3539cac2014-11-09 19:52:06 -0800277 if (ret < 0)
278 return ret;
279
Kuninori Morimotob65a7cc2015-06-15 06:27:28 +0000280 ret = rsnd_kctrl_new_e(mod, io, rtd,
Kuninori Morimoto985a4f62015-01-15 08:06:49 +0000281 is_play ?
Kuninori Morimoto3539cac2014-11-09 19:52:06 -0800282 "DVC Out Ramp Down Rate" : "DVC In Ramp Down Rate",
Kuninori Morimotof0b04d82017-06-07 00:11:48 +0000283 rsnd_kctrl_accept_anytime,
Kuninori Morimoto170a2492014-11-27 08:06:14 +0000284 rsnd_dvc_volume_update,
Kuninori Morimoto32973dc2017-04-06 07:25:13 +0000285 &dvc->rdown,
Kuninori Morimotof3c26ac2017-10-01 23:49:03 +0000286 volume_ramp_rate,
287 VOLUME_RAMP_MAX_DVC);
Kuninori Morimoto3539cac2014-11-09 19:52:06 -0800288
289 if (ret < 0)
290 return ret;
291
Kuninori Morimotob918f1b2017-10-01 23:48:29 +0000292 rsnd_flags_set(dvc, KCTRL_INITIALIZED);
293
Kuninori Morimotobff58ea2014-05-08 17:44:49 -0700294 return 0;
295}
296
Kuninori Morimoto9b99e9a2015-06-15 06:26:25 +0000297static struct dma_chan *rsnd_dvc_dma_req(struct rsnd_dai_stream *io,
298 struct rsnd_mod *mod)
Kuninori Morimoto72adc612015-02-20 10:31:23 +0000299{
300 struct rsnd_priv *priv = rsnd_mod_to_priv(mod);
301
302 return rsnd_dma_request_channel(rsnd_dvc_of_node(priv),
303 mod, "tx");
304}
305
Kuninori Morimotobff58ea2014-05-08 17:44:49 -0700306static struct rsnd_mod_ops rsnd_dvc_ops = {
Kuninori Morimoto8aefda52014-05-22 23:25:43 -0700307 .name = DVC_NAME,
Kuninori Morimoto72adc612015-02-20 10:31:23 +0000308 .dma_req = rsnd_dvc_dma_req,
Kuninori Morimoto1b2ca0a2015-10-26 08:43:21 +0000309 .probe = rsnd_dvc_probe_,
Kuninori Morimotobff58ea2014-05-08 17:44:49 -0700310 .init = rsnd_dvc_init,
311 .quit = rsnd_dvc_quit,
Kuninori Morimotobff58ea2014-05-08 17:44:49 -0700312 .pcm_new = rsnd_dvc_pcm_new,
313};
314
315struct rsnd_mod *rsnd_dvc_mod_get(struct rsnd_priv *priv, int id)
316{
317 if (WARN_ON(id < 0 || id >= rsnd_dvc_nr(priv)))
318 id = 0;
319
Kuninori Morimoto9eaa1a62015-11-10 05:12:50 +0000320 return rsnd_mod_get(rsnd_dvc_get(priv, id));
Kuninori Morimoto34cb6122014-06-22 17:59:28 -0700321}
322
Kuninori Morimoto2ea6b072015-11-10 05:14:12 +0000323int rsnd_dvc_probe(struct rsnd_priv *priv)
Kuninori Morimotobff58ea2014-05-08 17:44:49 -0700324{
Kuninori Morimoto9eaa1a62015-11-10 05:12:50 +0000325 struct device_node *node;
326 struct device_node *np;
Kuninori Morimotobff58ea2014-05-08 17:44:49 -0700327 struct device *dev = rsnd_priv_to_dev(priv);
328 struct rsnd_dvc *dvc;
329 struct clk *clk;
330 char name[RSND_DVC_NAME_SIZE];
Kuninori Morimoto2f78dd72015-03-26 04:02:09 +0000331 int i, nr, ret;
Kuninori Morimotobff58ea2014-05-08 17:44:49 -0700332
Kuninori Morimotobff58ea2014-05-08 17:44:49 -0700333 /* This driver doesn't support Gen1 at this point */
Kuninori Morimoto8a98b422015-10-15 03:25:28 +0000334 if (rsnd_is_gen1(priv))
335 return 0;
Kuninori Morimotobff58ea2014-05-08 17:44:49 -0700336
Kuninori Morimoto9eaa1a62015-11-10 05:12:50 +0000337 node = rsnd_dvc_of_node(priv);
338 if (!node)
339 return 0; /* not used is not error */
Kuninori Morimoto9469b8b2015-07-15 07:15:47 +0000340
Kuninori Morimoto9eaa1a62015-11-10 05:12:50 +0000341 nr = of_get_child_count(node);
342 if (!nr) {
343 ret = -EINVAL;
344 goto rsnd_dvc_probe_done;
345 }
Kuninori Morimoto9469b8b2015-07-15 07:15:47 +0000346
Kees Cooka86854d2018-06-12 14:07:58 -0700347 dvc = devm_kcalloc(dev, nr, sizeof(*dvc), GFP_KERNEL);
Kuninori Morimoto9eaa1a62015-11-10 05:12:50 +0000348 if (!dvc) {
349 ret = -ENOMEM;
350 goto rsnd_dvc_probe_done;
351 }
Kuninori Morimotobff58ea2014-05-08 17:44:49 -0700352
353 priv->dvc_nr = nr;
354 priv->dvc = dvc;
355
Kuninori Morimoto9eaa1a62015-11-10 05:12:50 +0000356 i = 0;
Mark Brown2e4118d2015-12-14 12:05:17 +0000357 ret = 0;
Kuninori Morimoto9eaa1a62015-11-10 05:12:50 +0000358 for_each_child_of_node(node, np) {
359 dvc = rsnd_dvc_get(priv, i);
360
Kuninori Morimoto8aefda52014-05-22 23:25:43 -0700361 snprintf(name, RSND_DVC_NAME_SIZE, "%s.%d",
362 DVC_NAME, i);
Kuninori Morimotobff58ea2014-05-08 17:44:49 -0700363
364 clk = devm_clk_get(dev, name);
Kuninori Morimoto9eaa1a62015-11-10 05:12:50 +0000365 if (IS_ERR(clk)) {
366 ret = PTR_ERR(clk);
Julia Lawall53ba2aa2017-07-15 09:19:07 +0200367 of_node_put(np);
Kuninori Morimoto9eaa1a62015-11-10 05:12:50 +0000368 goto rsnd_dvc_probe_done;
369 }
Kuninori Morimotobff58ea2014-05-08 17:44:49 -0700370
Kuninori Morimotob76e2182015-09-10 07:02:21 +0000371 ret = rsnd_mod_init(priv, rsnd_mod_get(dvc), &rsnd_dvc_ops,
Kuninori Morimoto5ba17b422016-01-21 01:58:07 +0000372 clk, rsnd_mod_get_status, RSND_MOD_DVC, i);
Julia Lawall53ba2aa2017-07-15 09:19:07 +0200373 if (ret) {
374 of_node_put(np);
Kuninori Morimoto9eaa1a62015-11-10 05:12:50 +0000375 goto rsnd_dvc_probe_done;
Julia Lawall53ba2aa2017-07-15 09:19:07 +0200376 }
Kuninori Morimoto9eaa1a62015-11-10 05:12:50 +0000377
378 i++;
Kuninori Morimotobff58ea2014-05-08 17:44:49 -0700379 }
380
Kuninori Morimoto9eaa1a62015-11-10 05:12:50 +0000381rsnd_dvc_probe_done:
382 of_node_put(node);
383
384 return ret;
Kuninori Morimotobff58ea2014-05-08 17:44:49 -0700385}
Kuninori Morimoto2f78dd72015-03-26 04:02:09 +0000386
Kuninori Morimoto2ea6b072015-11-10 05:14:12 +0000387void rsnd_dvc_remove(struct rsnd_priv *priv)
Kuninori Morimoto2f78dd72015-03-26 04:02:09 +0000388{
389 struct rsnd_dvc *dvc;
390 int i;
391
392 for_each_rsnd_dvc(dvc, priv, i) {
Kuninori Morimotob76e2182015-09-10 07:02:21 +0000393 rsnd_mod_quit(rsnd_mod_get(dvc));
Kuninori Morimoto2f78dd72015-03-26 04:02:09 +0000394 }
395}