1 // SPDX-License-Identifier: GPL-2.0
2 //
3 // Helper routines for R-Car sound ADG.
4 //
5 // Copyright (C) 2013 Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
6 #include <linux/clk-provider.h>
7 #include <linux/clkdev.h>
8 #include "rsnd.h"
9
10 #define CLKA 0
11 #define CLKB 1
12 #define CLKC 2
13 #define CLKI 3
14 #define CLKMAX 4
15
16 #define CLKOUT 0
17 #define CLKOUT1 1
18 #define CLKOUT2 2
19 #define CLKOUT3 3
20 #define CLKOUTMAX 4
21
22 #define BRRx_MASK(x) (0x3FF & x)
23
24 static struct rsnd_mod_ops adg_ops = {
25 .name = "adg",
26 };
27
28 struct rsnd_adg {
29 struct clk *clk[CLKMAX];
30 struct clk *clkout[CLKOUTMAX];
31 struct clk *null_clk;
32 struct clk_onecell_data onecell;
33 struct rsnd_mod mod;
34 int clk_rate[CLKMAX];
35 u32 flags;
36 u32 ckr;
37 u32 rbga;
38 u32 rbgb;
39
40 int rbga_rate_for_441khz; /* RBGA */
41 int rbgb_rate_for_48khz; /* RBGB */
42 };
43
44 #define LRCLK_ASYNC (1 << 0)
45 #define AUDIO_OUT_48 (1 << 1)
46
47 #define for_each_rsnd_clk(pos, adg, i) \
48 for (i = 0; \
49 (i < CLKMAX) && \
50 ((pos) = adg->clk[i]); \
51 i++)
52 #define for_each_rsnd_clkout(pos, adg, i) \
53 for (i = 0; \
54 (i < CLKOUTMAX) && \
55 ((pos) = adg->clkout[i]); \
56 i++)
57 #define rsnd_priv_to_adg(priv) ((struct rsnd_adg *)(priv)->adg)
58
59 static const char * const clk_name[] = {
60 [CLKA] = "clk_a",
61 [CLKB] = "clk_b",
62 [CLKC] = "clk_c",
63 [CLKI] = "clk_i",
64 };
65
rsnd_adg_calculate_rbgx(unsigned long div)66 static u32 rsnd_adg_calculate_rbgx(unsigned long div)
67 {
68 int i;
69
70 if (!div)
71 return 0;
72
73 for (i = 3; i >= 0; i--) {
74 int ratio = 2 << (i * 2);
75 if (0 == (div % ratio))
76 return (u32)((i << 8) | ((div / ratio) - 1));
77 }
78
79 return ~0;
80 }
81
rsnd_adg_ssi_ws_timing_gen2(struct rsnd_dai_stream * io)82 static u32 rsnd_adg_ssi_ws_timing_gen2(struct rsnd_dai_stream *io)
83 {
84 struct rsnd_mod *ssi_mod = rsnd_io_to_mod_ssi(io);
85 int id = rsnd_mod_id(ssi_mod);
86 int ws = id;
87
88 if (rsnd_ssi_is_pin_sharing(io)) {
89 switch (id) {
90 case 1:
91 case 2:
92 case 9:
93 ws = 0;
94 break;
95 case 4:
96 ws = 3;
97 break;
98 case 8:
99 ws = 7;
100 break;
101 }
102 }
103
104 return (0x6 + ws) << 8;
105 }
106
__rsnd_adg_get_timesel_ratio(struct rsnd_priv * priv,struct rsnd_dai_stream * io,unsigned int target_rate,unsigned int * target_val,unsigned int * target_en)107 static void __rsnd_adg_get_timesel_ratio(struct rsnd_priv *priv,
108 struct rsnd_dai_stream *io,
109 unsigned int target_rate,
110 unsigned int *target_val,
111 unsigned int *target_en)
112 {
113 struct rsnd_adg *adg = rsnd_priv_to_adg(priv);
114 struct device *dev = rsnd_priv_to_dev(priv);
115 int sel;
116 unsigned int val, en;
117 unsigned int min, diff;
118 unsigned int sel_rate[] = {
119 adg->clk_rate[CLKA], /* 0000: CLKA */
120 adg->clk_rate[CLKB], /* 0001: CLKB */
121 adg->clk_rate[CLKC], /* 0010: CLKC */
122 adg->rbga_rate_for_441khz, /* 0011: RBGA */
123 adg->rbgb_rate_for_48khz, /* 0100: RBGB */
124 };
125
126 min = ~0;
127 val = 0;
128 en = 0;
129 for (sel = 0; sel < ARRAY_SIZE(sel_rate); sel++) {
130 int idx = 0;
131 int step = 2;
132 int div;
133
134 if (!sel_rate[sel])
135 continue;
136
137 for (div = 2; div <= 98304; div += step) {
138 diff = abs(target_rate - sel_rate[sel] / div);
139 if (min > diff) {
140 val = (sel << 8) | idx;
141 min = diff;
142 en = 1 << (sel + 1); /* fixme */
143 }
144
145 /*
146 * step of 0_0000 / 0_0001 / 0_1101
147 * are out of order
148 */
149 if ((idx > 2) && (idx % 2))
150 step *= 2;
151 if (idx == 0x1c) {
152 div += step;
153 step *= 2;
154 }
155 idx++;
156 }
157 }
158
159 if (min == ~0) {
160 dev_err(dev, "no Input clock\n");
161 return;
162 }
163
164 *target_val = val;
165 if (target_en)
166 *target_en = en;
167 }
168
rsnd_adg_get_timesel_ratio(struct rsnd_priv * priv,struct rsnd_dai_stream * io,unsigned int in_rate,unsigned int out_rate,u32 * in,u32 * out,u32 * en)169 static void rsnd_adg_get_timesel_ratio(struct rsnd_priv *priv,
170 struct rsnd_dai_stream *io,
171 unsigned int in_rate,
172 unsigned int out_rate,
173 u32 *in, u32 *out, u32 *en)
174 {
175 struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io);
176 unsigned int target_rate;
177 u32 *target_val;
178 u32 _in;
179 u32 _out;
180 u32 _en;
181
182 /* default = SSI WS */
183 _in =
184 _out = rsnd_adg_ssi_ws_timing_gen2(io);
185
186 target_rate = 0;
187 target_val = NULL;
188 _en = 0;
189 if (runtime->rate != in_rate) {
190 target_rate = out_rate;
191 target_val = &_out;
192 } else if (runtime->rate != out_rate) {
193 target_rate = in_rate;
194 target_val = &_in;
195 }
196
197 if (target_rate)
198 __rsnd_adg_get_timesel_ratio(priv, io,
199 target_rate,
200 target_val, &_en);
201
202 if (in)
203 *in = _in;
204 if (out)
205 *out = _out;
206 if (en)
207 *en = _en;
208 }
209
rsnd_adg_set_cmd_timsel_gen2(struct rsnd_mod * cmd_mod,struct rsnd_dai_stream * io)210 int rsnd_adg_set_cmd_timsel_gen2(struct rsnd_mod *cmd_mod,
211 struct rsnd_dai_stream *io)
212 {
213 struct rsnd_priv *priv = rsnd_mod_to_priv(cmd_mod);
214 struct rsnd_adg *adg = rsnd_priv_to_adg(priv);
215 struct rsnd_mod *adg_mod = rsnd_mod_get(adg);
216 int id = rsnd_mod_id(cmd_mod);
217 int shift = (id % 2) ? 16 : 0;
218 u32 mask, val;
219
220 rsnd_adg_get_timesel_ratio(priv, io,
221 rsnd_src_get_in_rate(priv, io),
222 rsnd_src_get_out_rate(priv, io),
223 NULL, &val, NULL);
224
225 val = val << shift;
226 mask = 0x0f1f << shift;
227
228 rsnd_mod_bset(adg_mod, CMDOUT_TIMSEL, mask, val);
229
230 return 0;
231 }
232
rsnd_adg_set_src_timesel_gen2(struct rsnd_mod * src_mod,struct rsnd_dai_stream * io,unsigned int in_rate,unsigned int out_rate)233 int rsnd_adg_set_src_timesel_gen2(struct rsnd_mod *src_mod,
234 struct rsnd_dai_stream *io,
235 unsigned int in_rate,
236 unsigned int out_rate)
237 {
238 struct rsnd_priv *priv = rsnd_mod_to_priv(src_mod);
239 struct rsnd_adg *adg = rsnd_priv_to_adg(priv);
240 struct rsnd_mod *adg_mod = rsnd_mod_get(adg);
241 u32 in, out;
242 u32 mask, en;
243 int id = rsnd_mod_id(src_mod);
244 int shift = (id % 2) ? 16 : 0;
245
246 rsnd_mod_confirm_src(src_mod);
247
248 rsnd_adg_get_timesel_ratio(priv, io,
249 in_rate, out_rate,
250 &in, &out, &en);
251
252 in = in << shift;
253 out = out << shift;
254 mask = 0x0f1f << shift;
255
256 rsnd_mod_bset(adg_mod, SRCIN_TIMSEL(id / 2), mask, in);
257 rsnd_mod_bset(adg_mod, SRCOUT_TIMSEL(id / 2), mask, out);
258
259 if (en)
260 rsnd_mod_bset(adg_mod, DIV_EN, en, en);
261
262 return 0;
263 }
264
rsnd_adg_set_ssi_clk(struct rsnd_mod * ssi_mod,u32 val)265 static void rsnd_adg_set_ssi_clk(struct rsnd_mod *ssi_mod, u32 val)
266 {
267 struct rsnd_priv *priv = rsnd_mod_to_priv(ssi_mod);
268 struct rsnd_adg *adg = rsnd_priv_to_adg(priv);
269 struct rsnd_mod *adg_mod = rsnd_mod_get(adg);
270 struct device *dev = rsnd_priv_to_dev(priv);
271 int id = rsnd_mod_id(ssi_mod);
272 int shift = (id % 4) * 8;
273 u32 mask = 0xFF << shift;
274
275 rsnd_mod_confirm_ssi(ssi_mod);
276
277 val = val << shift;
278
279 /*
280 * SSI 8 is not connected to ADG.
281 * it works with SSI 7
282 */
283 if (id == 8)
284 return;
285
286 rsnd_mod_bset(adg_mod, AUDIO_CLK_SEL(id / 4), mask, val);
287
288 dev_dbg(dev, "AUDIO_CLK_SEL is 0x%x\n", val);
289 }
290
rsnd_adg_clk_query(struct rsnd_priv * priv,unsigned int rate)291 int rsnd_adg_clk_query(struct rsnd_priv *priv, unsigned int rate)
292 {
293 struct rsnd_adg *adg = rsnd_priv_to_adg(priv);
294 int i;
295 int sel_table[] = {
296 [CLKA] = 0x1,
297 [CLKB] = 0x2,
298 [CLKC] = 0x3,
299 [CLKI] = 0x0,
300 };
301
302 /*
303 * find suitable clock from
304 * AUDIO_CLKA/AUDIO_CLKB/AUDIO_CLKC/AUDIO_CLKI.
305 */
306 for (i = 0; i < CLKMAX; i++)
307 if (rate == adg->clk_rate[i])
308 return sel_table[i];
309
310 /*
311 * find divided clock from BRGA/BRGB
312 */
313 if (rate == adg->rbga_rate_for_441khz)
314 return 0x10;
315
316 if (rate == adg->rbgb_rate_for_48khz)
317 return 0x20;
318
319 return -EIO;
320 }
321
rsnd_adg_ssi_clk_stop(struct rsnd_mod * ssi_mod)322 int rsnd_adg_ssi_clk_stop(struct rsnd_mod *ssi_mod)
323 {
324 rsnd_adg_set_ssi_clk(ssi_mod, 0);
325
326 return 0;
327 }
328
rsnd_adg_ssi_clk_try_start(struct rsnd_mod * ssi_mod,unsigned int rate)329 int rsnd_adg_ssi_clk_try_start(struct rsnd_mod *ssi_mod, unsigned int rate)
330 {
331 struct rsnd_priv *priv = rsnd_mod_to_priv(ssi_mod);
332 struct rsnd_adg *adg = rsnd_priv_to_adg(priv);
333 struct device *dev = rsnd_priv_to_dev(priv);
334 struct rsnd_mod *adg_mod = rsnd_mod_get(adg);
335 int data;
336 u32 ckr = 0;
337
338 data = rsnd_adg_clk_query(priv, rate);
339 if (data < 0)
340 return data;
341
342 rsnd_adg_set_ssi_clk(ssi_mod, data);
343
344 if (rsnd_flags_has(adg, LRCLK_ASYNC)) {
345 if (rsnd_flags_has(adg, AUDIO_OUT_48))
346 ckr = 0x80000000;
347 } else {
348 if (0 == (rate % 8000))
349 ckr = 0x80000000;
350 }
351
352 rsnd_mod_bset(adg_mod, BRGCKR, 0x80770000, adg->ckr | ckr);
353 rsnd_mod_write(adg_mod, BRRA, adg->rbga);
354 rsnd_mod_write(adg_mod, BRRB, adg->rbgb);
355
356 dev_dbg(dev, "CLKOUT is based on BRG%c (= %dHz)\n",
357 (ckr) ? 'B' : 'A',
358 (ckr) ? adg->rbgb_rate_for_48khz :
359 adg->rbga_rate_for_441khz);
360
361 return 0;
362 }
363
rsnd_adg_clk_control(struct rsnd_priv * priv,int enable)364 void rsnd_adg_clk_control(struct rsnd_priv *priv, int enable)
365 {
366 struct rsnd_adg *adg = rsnd_priv_to_adg(priv);
367 struct clk *clk;
368 int i;
369
370 for_each_rsnd_clk(clk, adg, i) {
371 if (enable) {
372 clk_prepare_enable(clk);
373
374 /*
375 * We shouldn't use clk_get_rate() under
376 * atomic context. Let's keep it when
377 * rsnd_adg_clk_enable() was called
378 */
379 adg->clk_rate[i] = clk_get_rate(clk);
380 } else {
381 clk_disable_unprepare(clk);
382 }
383 }
384 }
385
rsnd_adg_create_null_clk(struct rsnd_priv * priv,const char * const name,const char * parent)386 static struct clk *rsnd_adg_create_null_clk(struct rsnd_priv *priv,
387 const char * const name,
388 const char *parent)
389 {
390 struct device *dev = rsnd_priv_to_dev(priv);
391 struct clk *clk;
392
393 clk = clk_register_fixed_rate(dev, name, parent, 0, 0);
394 if (IS_ERR_OR_NULL(clk)) {
395 dev_err(dev, "create null clk error\n");
396 return ERR_CAST(clk);
397 }
398
399 return clk;
400 }
401
rsnd_adg_null_clk_get(struct rsnd_priv * priv)402 static struct clk *rsnd_adg_null_clk_get(struct rsnd_priv *priv)
403 {
404 struct rsnd_adg *adg = priv->adg;
405
406 if (!adg->null_clk) {
407 static const char * const name = "rsnd_adg_null";
408
409 adg->null_clk = rsnd_adg_create_null_clk(priv, name, NULL);
410 }
411
412 return adg->null_clk;
413 }
414
rsnd_adg_null_clk_clean(struct rsnd_priv * priv)415 static void rsnd_adg_null_clk_clean(struct rsnd_priv *priv)
416 {
417 struct rsnd_adg *adg = priv->adg;
418
419 if (adg->null_clk)
420 clk_unregister_fixed_rate(adg->null_clk);
421 }
422
rsnd_adg_get_clkin(struct rsnd_priv * priv)423 static int rsnd_adg_get_clkin(struct rsnd_priv *priv)
424 {
425 struct rsnd_adg *adg = priv->adg;
426 struct device *dev = rsnd_priv_to_dev(priv);
427 struct clk *clk;
428 int i;
429
430 for (i = 0; i < CLKMAX; i++) {
431 clk = devm_clk_get(dev, clk_name[i]);
432
433 if (IS_ERR_OR_NULL(clk))
434 clk = rsnd_adg_null_clk_get(priv);
435 if (IS_ERR_OR_NULL(clk))
436 goto err;
437
438 adg->clk[i] = clk;
439 }
440
441 return 0;
442
443 err:
444 dev_err(dev, "adg clock IN get failed\n");
445
446 rsnd_adg_null_clk_clean(priv);
447
448 return -EIO;
449 }
450
rsnd_adg_unregister_clkout(struct rsnd_priv * priv)451 static void rsnd_adg_unregister_clkout(struct rsnd_priv *priv)
452 {
453 struct rsnd_adg *adg = priv->adg;
454 struct clk *clk;
455 int i;
456
457 for_each_rsnd_clkout(clk, adg, i)
458 clk_unregister_fixed_rate(clk);
459 }
460
rsnd_adg_get_clkout(struct rsnd_priv * priv)461 static int rsnd_adg_get_clkout(struct rsnd_priv *priv)
462 {
463 struct rsnd_adg *adg = priv->adg;
464 struct clk *clk;
465 struct device *dev = rsnd_priv_to_dev(priv);
466 struct device_node *np = dev->of_node;
467 struct property *prop;
468 u32 ckr, rbgx, rbga, rbgb;
469 u32 rate, div;
470 #define REQ_SIZE 2
471 u32 req_rate[REQ_SIZE] = {};
472 uint32_t count = 0;
473 unsigned long req_48kHz_rate, req_441kHz_rate;
474 int i, req_size;
475 const char *parent_clk_name = NULL;
476 static const char * const clkout_name[] = {
477 [CLKOUT] = "audio_clkout",
478 [CLKOUT1] = "audio_clkout1",
479 [CLKOUT2] = "audio_clkout2",
480 [CLKOUT3] = "audio_clkout3",
481 };
482 int brg_table[] = {
483 [CLKA] = 0x0,
484 [CLKB] = 0x1,
485 [CLKC] = 0x4,
486 [CLKI] = 0x2,
487 };
488
489 ckr = 0;
490 rbga = 2; /* default 1/6 */
491 rbgb = 2; /* default 1/6 */
492
493 /*
494 * ADG supports BRRA/BRRB output only
495 * this means all clkout0/1/2/3 will be same rate
496 */
497 prop = of_find_property(np, "clock-frequency", NULL);
498 if (!prop)
499 goto rsnd_adg_get_clkout_end;
500
501 req_size = prop->length / sizeof(u32);
502 if (req_size > REQ_SIZE) {
503 dev_err(dev, "too many clock-frequency\n");
504 return -EINVAL;
505 }
506
507 of_property_read_u32_array(np, "clock-frequency", req_rate, req_size);
508 req_48kHz_rate = 0;
509 req_441kHz_rate = 0;
510 for (i = 0; i < req_size; i++) {
511 if (0 == (req_rate[i] % 44100))
512 req_441kHz_rate = req_rate[i];
513 if (0 == (req_rate[i] % 48000))
514 req_48kHz_rate = req_rate[i];
515 }
516
517 if (req_rate[0] % 48000 == 0)
518 rsnd_flags_set(adg, AUDIO_OUT_48);
519
520 if (of_get_property(np, "clkout-lr-asynchronous", NULL))
521 rsnd_flags_set(adg, LRCLK_ASYNC);
522
523 /*
524 * This driver is assuming that AUDIO_CLKA/AUDIO_CLKB/AUDIO_CLKC
525 * have 44.1kHz or 48kHz base clocks for now.
526 *
527 * SSI itself can divide parent clock by 1/1 - 1/16
528 * see
529 * rsnd_adg_ssi_clk_try_start()
530 * rsnd_ssi_master_clk_start()
531 */
532 adg->rbga_rate_for_441khz = 0;
533 adg->rbgb_rate_for_48khz = 0;
534 for_each_rsnd_clk(clk, adg, i) {
535 rate = clk_get_rate(clk);
536
537 if (0 == rate) /* not used */
538 continue;
539
540 /* RBGA */
541 if (!adg->rbga_rate_for_441khz && (0 == rate % 44100)) {
542 div = 6;
543 if (req_441kHz_rate)
544 div = rate / req_441kHz_rate;
545 rbgx = rsnd_adg_calculate_rbgx(div);
546 if (BRRx_MASK(rbgx) == rbgx) {
547 rbga = rbgx;
548 adg->rbga_rate_for_441khz = rate / div;
549 ckr |= brg_table[i] << 20;
550 if (req_441kHz_rate &&
551 !rsnd_flags_has(adg, AUDIO_OUT_48))
552 parent_clk_name = __clk_get_name(clk);
553 }
554 }
555
556 /* RBGB */
557 if (!adg->rbgb_rate_for_48khz && (0 == rate % 48000)) {
558 div = 6;
559 if (req_48kHz_rate)
560 div = rate / req_48kHz_rate;
561 rbgx = rsnd_adg_calculate_rbgx(div);
562 if (BRRx_MASK(rbgx) == rbgx) {
563 rbgb = rbgx;
564 adg->rbgb_rate_for_48khz = rate / div;
565 ckr |= brg_table[i] << 16;
566 if (req_48kHz_rate &&
567 rsnd_flags_has(adg, AUDIO_OUT_48))
568 parent_clk_name = __clk_get_name(clk);
569 }
570 }
571 }
572
573 /*
574 * ADG supports BRRA/BRRB output only.
575 * this means all clkout0/1/2/3 will be * same rate
576 */
577
578 of_property_read_u32(np, "#clock-cells", &count);
579 /*
580 * for clkout
581 */
582 if (!count) {
583 clk = clk_register_fixed_rate(dev, clkout_name[CLKOUT],
584 parent_clk_name, 0, req_rate[0]);
585 if (IS_ERR_OR_NULL(clk))
586 goto err;
587
588 adg->clkout[CLKOUT] = clk;
589 of_clk_add_provider(np, of_clk_src_simple_get, clk);
590 }
591 /*
592 * for clkout0/1/2/3
593 */
594 else {
595 for (i = 0; i < CLKOUTMAX; i++) {
596 clk = clk_register_fixed_rate(dev, clkout_name[i],
597 parent_clk_name, 0,
598 req_rate[0]);
599 if (IS_ERR_OR_NULL(clk))
600 goto err;
601
602 adg->clkout[i] = clk;
603 }
604 adg->onecell.clks = adg->clkout;
605 adg->onecell.clk_num = CLKOUTMAX;
606 of_clk_add_provider(np, of_clk_src_onecell_get,
607 &adg->onecell);
608 }
609
610 rsnd_adg_get_clkout_end:
611 adg->ckr = ckr;
612 adg->rbga = rbga;
613 adg->rbgb = rbgb;
614
615 return 0;
616
617 err:
618 dev_err(dev, "adg clock OUT get failed\n");
619
620 rsnd_adg_unregister_clkout(priv);
621
622 return -EIO;
623 }
624
625 #if defined(DEBUG) || defined(CONFIG_DEBUG_FS)
626 __printf(3, 4)
dbg_msg(struct device * dev,struct seq_file * m,const char * fmt,...)627 static void dbg_msg(struct device *dev, struct seq_file *m,
628 const char *fmt, ...)
629 {
630 char msg[128];
631 va_list args;
632
633 va_start(args, fmt);
634 vsnprintf(msg, sizeof(msg), fmt, args);
635 va_end(args);
636
637 if (m)
638 seq_puts(m, msg);
639 else
640 dev_dbg(dev, "%s", msg);
641 }
642
rsnd_adg_clk_dbg_info(struct rsnd_priv * priv,struct seq_file * m)643 void rsnd_adg_clk_dbg_info(struct rsnd_priv *priv, struct seq_file *m)
644 {
645 struct rsnd_adg *adg = rsnd_priv_to_adg(priv);
646 struct device *dev = rsnd_priv_to_dev(priv);
647 struct clk *clk;
648 int i;
649
650 for_each_rsnd_clk(clk, adg, i)
651 dbg_msg(dev, m, "%s : %pa : %ld\n",
652 clk_name[i], clk, clk_get_rate(clk));
653
654 dbg_msg(dev, m, "BRGCKR = 0x%08x, BRRA/BRRB = 0x%x/0x%x\n",
655 adg->ckr, adg->rbga, adg->rbgb);
656 dbg_msg(dev, m, "BRGA (for 44100 base) = %d\n", adg->rbga_rate_for_441khz);
657 dbg_msg(dev, m, "BRGB (for 48000 base) = %d\n", adg->rbgb_rate_for_48khz);
658
659 /*
660 * Actual CLKOUT will be exchanged in rsnd_adg_ssi_clk_try_start()
661 * by BRGCKR::BRGCKR_31
662 */
663 for_each_rsnd_clkout(clk, adg, i)
664 dbg_msg(dev, m, "clkout %d : %pa : %ld\n", i,
665 clk, clk_get_rate(clk));
666 }
667 #else
668 #define rsnd_adg_clk_dbg_info(priv, m)
669 #endif
670
rsnd_adg_probe(struct rsnd_priv * priv)671 int rsnd_adg_probe(struct rsnd_priv *priv)
672 {
673 struct rsnd_adg *adg;
674 struct device *dev = rsnd_priv_to_dev(priv);
675 int ret;
676
677 adg = devm_kzalloc(dev, sizeof(*adg), GFP_KERNEL);
678 if (!adg)
679 return -ENOMEM;
680
681 ret = rsnd_mod_init(priv, &adg->mod, &adg_ops,
682 NULL, 0, 0);
683 if (ret)
684 return ret;
685
686 priv->adg = adg;
687
688 ret = rsnd_adg_get_clkin(priv);
689 if (ret)
690 return ret;
691
692 ret = rsnd_adg_get_clkout(priv);
693 if (ret)
694 return ret;
695
696 rsnd_adg_clk_enable(priv);
697 rsnd_adg_clk_dbg_info(priv, NULL);
698
699 return 0;
700 }
701
rsnd_adg_remove(struct rsnd_priv * priv)702 void rsnd_adg_remove(struct rsnd_priv *priv)
703 {
704 struct device *dev = rsnd_priv_to_dev(priv);
705 struct device_node *np = dev->of_node;
706
707 rsnd_adg_unregister_clkout(priv);
708
709 of_clk_del_provider(np);
710
711 rsnd_adg_clk_disable(priv);
712
713 /* It should be called after rsnd_adg_clk_disable() */
714 rsnd_adg_null_clk_clean(priv);
715 }
716