File Index
Files and directories
Sign in
FILE

adg.c

File preview with syntax highlighting.

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