Linux Audio

Check our new training course

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