blob: 4ef318ac73d5b77c667dff31cfe16f9aada46c10 [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 Morimotoca16cc62015-11-04 08:44:12 +000076#define rsnd_dvc_get_vrpdr(dvc) (dvc->rup.val << 8 | dvc->rdown.val)
77#define rsnd_dvc_get_vrdbr(dvc) (0x3ff - (dvc->volume.val[0] >> 13))
Kuninori Morimoto3bb3d362015-07-15 07:13:29 +000078
Kuninori Morimotoca16cc62015-11-04 08:44:12 +000079static void rsnd_dvc_volume_parameter(struct rsnd_dai_stream *io,
80 struct rsnd_mod *mod)
Kuninori Morimotobff58ea2014-05-08 17:44:49 -070081{
82 struct rsnd_dvc *dvc = rsnd_mod_to_dvc(mod);
Kuninori Morimotod2240f02016-02-18 08:13:13 +000083 u32 val[RSND_MAX_CHANNELS];
Kuninori Morimotobff58ea2014-05-08 17:44:49 -070084 int i;
85
Kuninori Morimotoca16cc62015-11-04 08:44:12 +000086 /* Enable Ramp */
87 if (dvc->ren.val)
Kuninori Morimotod2240f02016-02-18 08:13:13 +000088 for (i = 0; i < RSND_MAX_CHANNELS; i++)
Kuninori Morimotoca16cc62015-11-04 08:44:12 +000089 val[i] = dvc->volume.cfg.max;
90 else
Kuninori Morimotod2240f02016-02-18 08:13:13 +000091 for (i = 0; i < RSND_MAX_CHANNELS; i++)
Kuninori Morimotoca16cc62015-11-04 08:44:12 +000092 val[i] = dvc->volume.val[i];
Kuninori Morimotobff58ea2014-05-08 17:44:49 -070093
Kuninori Morimotoca16cc62015-11-04 08:44:12 +000094 /* Enable Digital Volume */
95 rsnd_mod_write(mod, DVC_VOL0R, val[0]);
96 rsnd_mod_write(mod, DVC_VOL1R, val[1]);
Kuninori Morimoto42ab9a72015-11-30 08:53:44 +000097 rsnd_mod_write(mod, DVC_VOL2R, val[2]);
98 rsnd_mod_write(mod, DVC_VOL3R, val[3]);
99 rsnd_mod_write(mod, DVC_VOL4R, val[4]);
100 rsnd_mod_write(mod, DVC_VOL5R, val[5]);
101 rsnd_mod_write(mod, DVC_VOL6R, val[6]);
102 rsnd_mod_write(mod, DVC_VOL7R, val[7]);
Kuninori Morimotoca16cc62015-11-04 08:44:12 +0000103}
104
105static void rsnd_dvc_volume_init(struct rsnd_dai_stream *io,
106 struct rsnd_mod *mod)
107{
108 struct rsnd_dvc *dvc = rsnd_mod_to_dvc(mod);
Kuninori Morimotoc45f7262015-11-30 08:49:33 +0000109 u32 adinr = 0;
Kuninori Morimotoca16cc62015-11-04 08:44:12 +0000110 u32 dvucr = 0;
111 u32 vrctr = 0;
112 u32 vrpdr = 0;
113 u32 vrdbr = 0;
114
Kuninori Morimotoc45f7262015-11-30 08:49:33 +0000115 adinr = rsnd_get_adinr_bit(mod, io) |
Kuninori Morimotoeed76bb2016-02-25 05:54:58 +0000116 rsnd_runtime_channel_after_ctu(io);
Kuninori Morimotoc45f7262015-11-30 08:49:33 +0000117
Kuninori Morimotoca16cc62015-11-04 08:44:12 +0000118 /* Enable Digital Volume, Zero Cross Mute Mode */
119 dvucr |= 0x101;
Kuninori Morimoto140bab82014-11-04 20:27:18 -0800120
Kuninori Morimoto3539cac2014-11-09 19:52:06 -0800121 /* Enable Ramp */
122 if (dvc->ren.val) {
123 dvucr |= 0x10;
124
Kuninori Morimoto3539cac2014-11-09 19:52:06 -0800125 /*
126 * FIXME !!
127 * use scale-downed Digital Volume
128 * as Volume Ramp
129 * 7F FFFF -> 3FF
130 */
Kuninori Morimotoca16cc62015-11-04 08:44:12 +0000131 vrctr = 0xff;
132 vrpdr = rsnd_dvc_get_vrpdr(dvc);
133 vrdbr = rsnd_dvc_get_vrdbr(dvc);
Kuninori Morimoto3539cac2014-11-09 19:52:06 -0800134 }
135
Kuninori Morimotoca16cc62015-11-04 08:44:12 +0000136 /* Initialize operation */
137 rsnd_mod_write(mod, DVC_DVUIR, 1);
Kuninori Morimotocd2b6572014-08-01 03:10:55 -0700138
Kuninori Morimotoca16cc62015-11-04 08:44:12 +0000139 /* General Information */
Kuninori Morimotoc45f7262015-11-30 08:49:33 +0000140 rsnd_mod_write(mod, DVC_ADINR, adinr);
Kuninori Morimoto1c5d1c92014-11-04 20:26:53 -0800141 rsnd_mod_write(mod, DVC_DVUCR, dvucr);
Kuninori Morimoto140bab82014-11-04 20:27:18 -0800142
Kuninori Morimotoca16cc62015-11-04 08:44:12 +0000143 /* Volume Ramp Parameter */
144 rsnd_mod_write(mod, DVC_VRCTR, vrctr);
145 rsnd_mod_write(mod, DVC_VRPDR, vrpdr);
146 rsnd_mod_write(mod, DVC_VRDBR, vrdbr);
147
148 /* Digital Volume Function Parameter */
149 rsnd_dvc_volume_parameter(io, mod);
150
151 /* cancel operation */
152 rsnd_mod_write(mod, DVC_DVUIR, 0);
153}
154
155static void rsnd_dvc_volume_update(struct rsnd_dai_stream *io,
156 struct rsnd_mod *mod)
157{
158 struct rsnd_dvc *dvc = rsnd_mod_to_dvc(mod);
159 u32 zcmcr = 0;
160 u32 vrpdr = 0;
161 u32 vrdbr = 0;
162 int i;
163
164 for (i = 0; i < dvc->mute.cfg.size; i++)
165 zcmcr |= (!!dvc->mute.cfg.val[i]) << i;
166
167 if (dvc->ren.val) {
168 vrpdr = rsnd_dvc_get_vrpdr(dvc);
169 vrdbr = rsnd_dvc_get_vrdbr(dvc);
170 }
171
172 /* Disable DVC Register access */
173 rsnd_mod_write(mod, DVC_DVUER, 0);
174
175 /* Zero Cross Mute Function */
176 rsnd_mod_write(mod, DVC_ZCMCR, zcmcr);
177
178 /* Volume Ramp Function */
179 rsnd_mod_write(mod, DVC_VRPDR, vrpdr);
180 rsnd_mod_write(mod, DVC_VRDBR, vrdbr);
181 /* add DVC_VRWTR here */
182
183 /* Digital Volume Function Parameter */
184 rsnd_dvc_volume_parameter(io, mod);
185
Kuninori Morimoto140bab82014-11-04 20:27:18 -0800186 /* Enable DVC Register access */
187 rsnd_mod_write(mod, DVC_DVUER, 1);
Kuninori Morimotobff58ea2014-05-08 17:44:49 -0700188}
189
Kuninori Morimoto1b2ca0a2015-10-26 08:43:21 +0000190static int rsnd_dvc_probe_(struct rsnd_mod *mod,
191 struct rsnd_dai_stream *io,
192 struct rsnd_priv *priv)
193{
194 return rsnd_cmd_attach(io, rsnd_mod_id(mod));
195}
196
Kuninori Morimotoe2c08412015-07-15 07:13:10 +0000197static int rsnd_dvc_init(struct rsnd_mod *mod,
Kuninori Morimoto2c0fac12015-06-15 06:25:20 +0000198 struct rsnd_dai_stream *io,
Kuninori Morimoto690602f2015-01-15 08:07:47 +0000199 struct rsnd_priv *priv)
Kuninori Morimotobff58ea2014-05-08 17:44:49 -0700200{
Kuninori Morimotoc9929342015-10-22 03:15:04 +0000201 rsnd_mod_power_on(mod);
Kuninori Morimotobff58ea2014-05-08 17:44:49 -0700202
Kuninori Morimoto87a6c5a2015-11-30 08:51:15 +0000203 rsnd_dvc_activation(mod);
Kuninori Morimotobff58ea2014-05-08 17:44:49 -0700204
Kuninori Morimotoca16cc62015-11-04 08:44:12 +0000205 rsnd_dvc_volume_init(io, mod);
Kuninori Morimotobff58ea2014-05-08 17:44:49 -0700206
Kuninori Morimotoe2c08412015-07-15 07:13:10 +0000207 rsnd_dvc_volume_update(io, mod);
Kuninori Morimotobff58ea2014-05-08 17:44:49 -0700208
Kuninori Morimotobff58ea2014-05-08 17:44:49 -0700209 return 0;
210}
211
212static int rsnd_dvc_quit(struct rsnd_mod *mod,
Kuninori Morimoto2c0fac12015-06-15 06:25:20 +0000213 struct rsnd_dai_stream *io,
Kuninori Morimoto690602f2015-01-15 08:07:47 +0000214 struct rsnd_priv *priv)
Kuninori Morimotobff58ea2014-05-08 17:44:49 -0700215{
Kuninori Morimotof13edb82015-11-30 08:52:21 +0000216 rsnd_dvc_halt(mod);
217
Kuninori Morimotoc9929342015-10-22 03:15:04 +0000218 rsnd_mod_power_off(mod);
Kuninori Morimotobff58ea2014-05-08 17:44:49 -0700219
220 return 0;
221}
222
Kuninori Morimotobff58ea2014-05-08 17:44:49 -0700223static int rsnd_dvc_pcm_new(struct rsnd_mod *mod,
Kuninori Morimoto2c0fac12015-06-15 06:25:20 +0000224 struct rsnd_dai_stream *io,
Kuninori Morimotobff58ea2014-05-08 17:44:49 -0700225 struct snd_soc_pcm_runtime *rtd)
226{
Kuninori Morimoto486b09c2014-08-01 03:10:47 -0700227 struct rsnd_dvc *dvc = rsnd_mod_to_dvc(mod);
Kuninori Morimoto1ff95932017-06-15 00:49:27 +0000228 struct rsnd_dai *rdai = rsnd_io_to_rdai(io);
Kuninori Morimoto985a4f62015-01-15 08:06:49 +0000229 int is_play = rsnd_io_is_play(io);
Kuninori Morimoto1ff95932017-06-15 00:49:27 +0000230 int channels = rsnd_rdai_channels_get(rdai);
Kuninori Morimotobff58ea2014-05-08 17:44:49 -0700231 int ret;
232
Kuninori Morimotob918f1b2017-10-01 23:48:29 +0000233 if (rsnd_flags_has(dvc, KCTRL_INITIALIZED))
234 return 0;
235
Kuninori Morimoto486b09c2014-08-01 03:10:47 -0700236 /* Volume */
Kuninori Morimotob65a7cc2015-06-15 06:27:28 +0000237 ret = rsnd_kctrl_new_m(mod, io, rtd,
Kuninori Morimoto985a4f62015-01-15 08:06:49 +0000238 is_play ?
Kuninori Morimoto486b09c2014-08-01 03:10:47 -0700239 "DVC Out Playback Volume" : "DVC In Capture Volume",
Kuninori Morimotof0b04d82017-06-07 00:11:48 +0000240 rsnd_kctrl_accept_anytime,
Kuninori Morimoto170a2492014-11-27 08:06:14 +0000241 rsnd_dvc_volume_update,
Kuninori Morimoto1ff95932017-06-15 00:49:27 +0000242 &dvc->volume, channels,
Kuninori Morimoto42ab9a72015-11-30 08:53:44 +0000243 0x00800000 - 1);
Kuninori Morimotobff58ea2014-05-08 17:44:49 -0700244 if (ret < 0)
245 return ret;
246
Kuninori Morimotocd2b6572014-08-01 03:10:55 -0700247 /* Mute */
Kuninori Morimotob65a7cc2015-06-15 06:27:28 +0000248 ret = rsnd_kctrl_new_m(mod, io, rtd,
Kuninori Morimoto985a4f62015-01-15 08:06:49 +0000249 is_play ?
Kuninori Morimotocd2b6572014-08-01 03:10:55 -0700250 "DVC Out Mute Switch" : "DVC In Mute Switch",
Kuninori Morimotof0b04d82017-06-07 00:11:48 +0000251 rsnd_kctrl_accept_anytime,
Kuninori Morimoto170a2492014-11-27 08:06:14 +0000252 rsnd_dvc_volume_update,
Kuninori Morimoto1ff95932017-06-15 00:49:27 +0000253 &dvc->mute, channels,
Kuninori Morimoto42ab9a72015-11-30 08:53:44 +0000254 1);
Kuninori Morimotocd2b6572014-08-01 03:10:55 -0700255 if (ret < 0)
256 return ret;
257
Kuninori Morimoto3539cac2014-11-09 19:52:06 -0800258 /* Ramp */
Kuninori Morimotob65a7cc2015-06-15 06:27:28 +0000259 ret = rsnd_kctrl_new_s(mod, io, rtd,
Kuninori Morimoto985a4f62015-01-15 08:06:49 +0000260 is_play ?
Kuninori Morimoto3539cac2014-11-09 19:52:06 -0800261 "DVC Out Ramp Switch" : "DVC In Ramp Switch",
Kuninori Morimotof0b04d82017-06-07 00:11:48 +0000262 rsnd_kctrl_accept_anytime,
Kuninori Morimoto170a2492014-11-27 08:06:14 +0000263 rsnd_dvc_volume_update,
Kuninori Morimoto3539cac2014-11-09 19:52:06 -0800264 &dvc->ren, 1);
265 if (ret < 0)
266 return ret;
267
Kuninori Morimotob65a7cc2015-06-15 06:27:28 +0000268 ret = rsnd_kctrl_new_e(mod, io, rtd,
Kuninori Morimoto985a4f62015-01-15 08:06:49 +0000269 is_play ?
Kuninori Morimoto3539cac2014-11-09 19:52:06 -0800270 "DVC Out Ramp Up Rate" : "DVC In Ramp Up Rate",
Kuninori Morimotof0b04d82017-06-07 00:11:48 +0000271 rsnd_kctrl_accept_anytime,
Kuninori Morimoto170a2492014-11-27 08:06:14 +0000272 rsnd_dvc_volume_update,
Kuninori Morimoto32973dc2017-04-06 07:25:13 +0000273 &dvc->rup,
Kuninori Morimotof3c26ac2017-10-01 23:49:03 +0000274 volume_ramp_rate,
275 VOLUME_RAMP_MAX_DVC);
Kuninori Morimoto3539cac2014-11-09 19:52:06 -0800276 if (ret < 0)
277 return ret;
278
Kuninori Morimotob65a7cc2015-06-15 06:27:28 +0000279 ret = rsnd_kctrl_new_e(mod, io, rtd,
Kuninori Morimoto985a4f62015-01-15 08:06:49 +0000280 is_play ?
Kuninori Morimoto3539cac2014-11-09 19:52:06 -0800281 "DVC Out Ramp Down Rate" : "DVC In Ramp Down Rate",
Kuninori Morimotof0b04d82017-06-07 00:11:48 +0000282 rsnd_kctrl_accept_anytime,
Kuninori Morimoto170a2492014-11-27 08:06:14 +0000283 rsnd_dvc_volume_update,
Kuninori Morimoto32973dc2017-04-06 07:25:13 +0000284 &dvc->rdown,
Kuninori Morimotof3c26ac2017-10-01 23:49:03 +0000285 volume_ramp_rate,
286 VOLUME_RAMP_MAX_DVC);
Kuninori Morimoto3539cac2014-11-09 19:52:06 -0800287
288 if (ret < 0)
289 return ret;
290
Kuninori Morimotob918f1b2017-10-01 23:48:29 +0000291 rsnd_flags_set(dvc, KCTRL_INITIALIZED);
292
Kuninori Morimotobff58ea2014-05-08 17:44:49 -0700293 return 0;
294}
295
Kuninori Morimoto9b99e9a2015-06-15 06:26:25 +0000296static struct dma_chan *rsnd_dvc_dma_req(struct rsnd_dai_stream *io,
297 struct rsnd_mod *mod)
Kuninori Morimoto72adc612015-02-20 10:31:23 +0000298{
299 struct rsnd_priv *priv = rsnd_mod_to_priv(mod);
300
301 return rsnd_dma_request_channel(rsnd_dvc_of_node(priv),
302 mod, "tx");
303}
304
Kuninori Morimotobff58ea2014-05-08 17:44:49 -0700305static struct rsnd_mod_ops rsnd_dvc_ops = {
Kuninori Morimoto8aefda52014-05-22 23:25:43 -0700306 .name = DVC_NAME,
Kuninori Morimoto72adc612015-02-20 10:31:23 +0000307 .dma_req = rsnd_dvc_dma_req,
Kuninori Morimoto1b2ca0a2015-10-26 08:43:21 +0000308 .probe = rsnd_dvc_probe_,
Kuninori Morimotobff58ea2014-05-08 17:44:49 -0700309 .init = rsnd_dvc_init,
310 .quit = rsnd_dvc_quit,
Kuninori Morimotobff58ea2014-05-08 17:44:49 -0700311 .pcm_new = rsnd_dvc_pcm_new,
312};
313
314struct rsnd_mod *rsnd_dvc_mod_get(struct rsnd_priv *priv, int id)
315{
316 if (WARN_ON(id < 0 || id >= rsnd_dvc_nr(priv)))
317 id = 0;
318
Kuninori Morimoto9eaa1a62015-11-10 05:12:50 +0000319 return rsnd_mod_get(rsnd_dvc_get(priv, id));
Kuninori Morimoto34cb6122014-06-22 17:59:28 -0700320}
321
Kuninori Morimoto2ea6b072015-11-10 05:14:12 +0000322int rsnd_dvc_probe(struct rsnd_priv *priv)
Kuninori Morimotobff58ea2014-05-08 17:44:49 -0700323{
Kuninori Morimoto9eaa1a62015-11-10 05:12:50 +0000324 struct device_node *node;
325 struct device_node *np;
Kuninori Morimotobff58ea2014-05-08 17:44:49 -0700326 struct device *dev = rsnd_priv_to_dev(priv);
327 struct rsnd_dvc *dvc;
328 struct clk *clk;
329 char name[RSND_DVC_NAME_SIZE];
Kuninori Morimoto2f78dd72015-03-26 04:02:09 +0000330 int i, nr, ret;
Kuninori Morimotobff58ea2014-05-08 17:44:49 -0700331
Kuninori Morimotobff58ea2014-05-08 17:44:49 -0700332 /* This driver doesn't support Gen1 at this point */
Kuninori Morimoto8a98b422015-10-15 03:25:28 +0000333 if (rsnd_is_gen1(priv))
334 return 0;
Kuninori Morimotobff58ea2014-05-08 17:44:49 -0700335
Kuninori Morimoto9eaa1a62015-11-10 05:12:50 +0000336 node = rsnd_dvc_of_node(priv);
337 if (!node)
338 return 0; /* not used is not error */
Kuninori Morimoto9469b8b2015-07-15 07:15:47 +0000339
Kuninori Morimoto9eaa1a62015-11-10 05:12:50 +0000340 nr = of_get_child_count(node);
341 if (!nr) {
342 ret = -EINVAL;
343 goto rsnd_dvc_probe_done;
344 }
Kuninori Morimoto9469b8b2015-07-15 07:15:47 +0000345
Kuninori Morimotobff58ea2014-05-08 17:44:49 -0700346 dvc = devm_kzalloc(dev, sizeof(*dvc) * nr, GFP_KERNEL);
Kuninori Morimoto9eaa1a62015-11-10 05:12:50 +0000347 if (!dvc) {
348 ret = -ENOMEM;
349 goto rsnd_dvc_probe_done;
350 }
Kuninori Morimotobff58ea2014-05-08 17:44:49 -0700351
352 priv->dvc_nr = nr;
353 priv->dvc = dvc;
354
Kuninori Morimoto9eaa1a62015-11-10 05:12:50 +0000355 i = 0;
Mark Brown2e4118d2015-12-14 12:05:17 +0000356 ret = 0;
Kuninori Morimoto9eaa1a62015-11-10 05:12:50 +0000357 for_each_child_of_node(node, np) {
358 dvc = rsnd_dvc_get(priv, i);
359
Kuninori Morimoto8aefda52014-05-22 23:25:43 -0700360 snprintf(name, RSND_DVC_NAME_SIZE, "%s.%d",
361 DVC_NAME, i);
Kuninori Morimotobff58ea2014-05-08 17:44:49 -0700362
363 clk = devm_clk_get(dev, name);
Kuninori Morimoto9eaa1a62015-11-10 05:12:50 +0000364 if (IS_ERR(clk)) {
365 ret = PTR_ERR(clk);
Julia Lawall53ba2aa2017-07-15 09:19:07 +0200366 of_node_put(np);
Kuninori Morimoto9eaa1a62015-11-10 05:12:50 +0000367 goto rsnd_dvc_probe_done;
368 }
Kuninori Morimotobff58ea2014-05-08 17:44:49 -0700369
Kuninori Morimotob76e2182015-09-10 07:02:21 +0000370 ret = rsnd_mod_init(priv, rsnd_mod_get(dvc), &rsnd_dvc_ops,
Kuninori Morimoto5ba17b422016-01-21 01:58:07 +0000371 clk, rsnd_mod_get_status, RSND_MOD_DVC, i);
Julia Lawall53ba2aa2017-07-15 09:19:07 +0200372 if (ret) {
373 of_node_put(np);
Kuninori Morimoto9eaa1a62015-11-10 05:12:50 +0000374 goto rsnd_dvc_probe_done;
Julia Lawall53ba2aa2017-07-15 09:19:07 +0200375 }
Kuninori Morimoto9eaa1a62015-11-10 05:12:50 +0000376
377 i++;
Kuninori Morimotobff58ea2014-05-08 17:44:49 -0700378 }
379
Kuninori Morimoto9eaa1a62015-11-10 05:12:50 +0000380rsnd_dvc_probe_done:
381 of_node_put(node);
382
383 return ret;
Kuninori Morimotobff58ea2014-05-08 17:44:49 -0700384}
Kuninori Morimoto2f78dd72015-03-26 04:02:09 +0000385
Kuninori Morimoto2ea6b072015-11-10 05:14:12 +0000386void rsnd_dvc_remove(struct rsnd_priv *priv)
Kuninori Morimoto2f78dd72015-03-26 04:02:09 +0000387{
388 struct rsnd_dvc *dvc;
389 int i;
390
391 for_each_rsnd_dvc(dvc, priv, i) {
Kuninori Morimotob76e2182015-09-10 07:02:21 +0000392 rsnd_mod_quit(rsnd_mod_get(dvc));
Kuninori Morimoto2f78dd72015-03-26 04:02:09 +0000393 }
394}