xref: /openbmc/linux/sound/soc/sh/rcar/adg.c (revision 0da85d1e)
1 /*
2  * Helper routines for R-Car sound ADG.
3  *
4  *  Copyright (C) 2013  Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
5  *
6  * This file is subject to the terms and conditions of the GNU General Public
7  * License.  See the file "COPYING" in the main directory of this archive
8  * for more details.
9  */
10 #include <linux/sh_clk.h>
11 #include "rsnd.h"
12 
13 #define CLKA	0
14 #define CLKB	1
15 #define CLKC	2
16 #define CLKI	3
17 #define CLKMAX	4
18 
19 struct rsnd_adg {
20 	struct clk *clk[CLKMAX];
21 
22 	int rbga_rate_for_441khz_div_6;	/* RBGA */
23 	int rbgb_rate_for_48khz_div_6;	/* RBGB */
24 	u32 ckr;
25 };
26 
27 #define for_each_rsnd_clk(pos, adg, i)		\
28 	for (i = 0;				\
29 	     (i < CLKMAX) &&			\
30 	     ((pos) = adg->clk[i]);		\
31 	     i++)
32 #define rsnd_priv_to_adg(priv) ((struct rsnd_adg *)(priv)->adg)
33 
34 
35 static u32 rsnd_adg_ssi_ws_timing_gen2(struct rsnd_dai_stream *io)
36 {
37 	struct rsnd_mod *mod = rsnd_io_to_mod_ssi(io);
38 	struct rsnd_priv *priv = rsnd_mod_to_priv(mod);
39 	int id = rsnd_mod_id(mod);
40 	int ws = id;
41 
42 	if (rsnd_ssi_is_pin_sharing(rsnd_ssi_mod_get(priv, id))) {
43 		switch (id) {
44 		case 1:
45 		case 2:
46 			ws = 0;
47 			break;
48 		case 4:
49 			ws = 3;
50 			break;
51 		case 8:
52 			ws = 7;
53 			break;
54 		}
55 	}
56 
57 	return (0x6 + ws) << 8;
58 }
59 
60 int rsnd_adg_set_cmd_timsel_gen2(struct rsnd_mod *mod,
61 				 struct rsnd_dai_stream *io)
62 {
63 	int id = rsnd_mod_id(mod);
64 	int shift = (id % 2) ? 16 : 0;
65 	u32 mask, val;
66 
67 	val = rsnd_adg_ssi_ws_timing_gen2(io);
68 
69 	val  = val	<< shift;
70 	mask = 0xffff	<< shift;
71 
72 	rsnd_mod_bset(mod, CMDOUT_TIMSEL, mask, val);
73 
74 	return 0;
75 }
76 
77 static int rsnd_adg_set_src_timsel_gen2(struct rsnd_mod *mod,
78 					struct rsnd_dai_stream *io,
79 					u32 timsel)
80 {
81 	int is_play = rsnd_io_is_play(io);
82 	int id = rsnd_mod_id(mod);
83 	int shift = (id % 2) ? 16 : 0;
84 	u32 mask, ws;
85 	u32 in, out;
86 
87 	ws = rsnd_adg_ssi_ws_timing_gen2(io);
88 
89 	in  = (is_play) ? timsel : ws;
90 	out = (is_play) ? ws     : timsel;
91 
92 	in   = in	<< shift;
93 	out  = out	<< shift;
94 	mask = 0xffff	<< shift;
95 
96 	switch (id / 2) {
97 	case 0:
98 		rsnd_mod_bset(mod, SRCIN_TIMSEL0,  mask, in);
99 		rsnd_mod_bset(mod, SRCOUT_TIMSEL0, mask, out);
100 		break;
101 	case 1:
102 		rsnd_mod_bset(mod, SRCIN_TIMSEL1,  mask, in);
103 		rsnd_mod_bset(mod, SRCOUT_TIMSEL1, mask, out);
104 		break;
105 	case 2:
106 		rsnd_mod_bset(mod, SRCIN_TIMSEL2,  mask, in);
107 		rsnd_mod_bset(mod, SRCOUT_TIMSEL2, mask, out);
108 		break;
109 	case 3:
110 		rsnd_mod_bset(mod, SRCIN_TIMSEL3,  mask, in);
111 		rsnd_mod_bset(mod, SRCOUT_TIMSEL3, mask, out);
112 		break;
113 	case 4:
114 		rsnd_mod_bset(mod, SRCIN_TIMSEL4,  mask, in);
115 		rsnd_mod_bset(mod, SRCOUT_TIMSEL4, mask, out);
116 		break;
117 	}
118 
119 	return 0;
120 }
121 
122 int rsnd_adg_set_convert_clk_gen2(struct rsnd_mod *mod,
123 				  struct rsnd_dai_stream *io,
124 				  unsigned int src_rate,
125 				  unsigned int dst_rate)
126 {
127 	struct rsnd_priv *priv = rsnd_mod_to_priv(mod);
128 	struct rsnd_adg *adg = rsnd_priv_to_adg(priv);
129 	struct device *dev = rsnd_priv_to_dev(priv);
130 	int idx, sel, div, step, ret;
131 	u32 val, en;
132 	unsigned int min, diff;
133 	unsigned int sel_rate [] = {
134 		clk_get_rate(adg->clk[CLKA]),	/* 0000: CLKA */
135 		clk_get_rate(adg->clk[CLKB]),	/* 0001: CLKB */
136 		clk_get_rate(adg->clk[CLKC]),	/* 0010: CLKC */
137 		adg->rbga_rate_for_441khz_div_6,/* 0011: RBGA */
138 		adg->rbgb_rate_for_48khz_div_6,	/* 0100: RBGB */
139 	};
140 
141 	min = ~0;
142 	val = 0;
143 	en = 0;
144 	for (sel = 0; sel < ARRAY_SIZE(sel_rate); sel++) {
145 		idx = 0;
146 		step = 2;
147 
148 		if (!sel_rate[sel])
149 			continue;
150 
151 		for (div = 2; div <= 98304; div += step) {
152 			diff = abs(src_rate - sel_rate[sel] / div);
153 			if (min > diff) {
154 				val = (sel << 8) | idx;
155 				min = diff;
156 				en = 1 << (sel + 1); /* fixme */
157 			}
158 
159 			/*
160 			 * step of 0_0000 / 0_0001 / 0_1101
161 			 * are out of order
162 			 */
163 			if ((idx > 2) && (idx % 2))
164 				step *= 2;
165 			if (idx == 0x1c) {
166 				div += step;
167 				step *= 2;
168 			}
169 			idx++;
170 		}
171 	}
172 
173 	if (min == ~0) {
174 		dev_err(dev, "no Input clock\n");
175 		return -EIO;
176 	}
177 
178 	ret = rsnd_adg_set_src_timsel_gen2(mod, io, val);
179 	if (ret < 0) {
180 		dev_err(dev, "timsel error\n");
181 		return ret;
182 	}
183 
184 	rsnd_mod_bset(mod, DIV_EN, en, en);
185 
186 	dev_dbg(dev, "convert rate %d <-> %d\n", src_rate, dst_rate);
187 
188 	return 0;
189 }
190 
191 int rsnd_adg_set_convert_timing_gen2(struct rsnd_mod *mod,
192 				     struct rsnd_dai_stream *io)
193 {
194 	u32 val = rsnd_adg_ssi_ws_timing_gen2(io);
195 
196 	return rsnd_adg_set_src_timsel_gen2(mod, io, val);
197 }
198 
199 int rsnd_adg_set_convert_clk_gen1(struct rsnd_priv *priv,
200 				  struct rsnd_mod *mod,
201 				  unsigned int src_rate,
202 				  unsigned int dst_rate)
203 {
204 	struct rsnd_adg *adg = rsnd_priv_to_adg(priv);
205 	struct device *dev = rsnd_priv_to_dev(priv);
206 	int idx, sel, div, shift;
207 	u32 mask, val;
208 	int id = rsnd_mod_id(mod);
209 	unsigned int sel_rate [] = {
210 		clk_get_rate(adg->clk[CLKA]),	/* 000: CLKA */
211 		clk_get_rate(adg->clk[CLKB]),	/* 001: CLKB */
212 		clk_get_rate(adg->clk[CLKC]),	/* 010: CLKC */
213 		0,				/* 011: MLBCLK (not used) */
214 		adg->rbga_rate_for_441khz_div_6,/* 100: RBGA */
215 		adg->rbgb_rate_for_48khz_div_6,	/* 101: RBGB */
216 	};
217 
218 	/* find div (= 1/128, 1/256, 1/512, 1/1024, 1/2048 */
219 	for (sel = 0; sel < ARRAY_SIZE(sel_rate); sel++) {
220 		for (div  = 128,	idx = 0;
221 		     div <= 2048;
222 		     div *= 2,		idx++) {
223 			if (src_rate == sel_rate[sel] / div) {
224 				val = (idx << 4) | sel;
225 				goto find_rate;
226 			}
227 		}
228 	}
229 	dev_err(dev, "can't find convert src clk\n");
230 	return -EINVAL;
231 
232 find_rate:
233 	shift	= (id % 4) * 8;
234 	mask	= 0xFF << shift;
235 	val	= val << shift;
236 
237 	dev_dbg(dev, "adg convert src clk = %02x\n", val);
238 
239 	switch (id / 4) {
240 	case 0:
241 		rsnd_mod_bset(mod, AUDIO_CLK_SEL3, mask, val);
242 		break;
243 	case 1:
244 		rsnd_mod_bset(mod, AUDIO_CLK_SEL4, mask, val);
245 		break;
246 	case 2:
247 		rsnd_mod_bset(mod, AUDIO_CLK_SEL5, mask, val);
248 		break;
249 	}
250 
251 	/*
252 	 * Gen1 doesn't need dst_rate settings,
253 	 * since it uses SSI WS pin.
254 	 * see also rsnd_src_set_route_if_gen1()
255 	 */
256 
257 	return 0;
258 }
259 
260 static void rsnd_adg_set_ssi_clk(struct rsnd_mod *mod, u32 val)
261 {
262 	int id = rsnd_mod_id(mod);
263 	int shift = (id % 4) * 8;
264 	u32 mask = 0xFF << shift;
265 
266 	val = val << shift;
267 
268 	/*
269 	 * SSI 8 is not connected to ADG.
270 	 * it works with SSI 7
271 	 */
272 	if (id == 8)
273 		return;
274 
275 	switch (id / 4) {
276 	case 0:
277 		rsnd_mod_bset(mod, AUDIO_CLK_SEL0, mask, val);
278 		break;
279 	case 1:
280 		rsnd_mod_bset(mod, AUDIO_CLK_SEL1, mask, val);
281 		break;
282 	case 2:
283 		rsnd_mod_bset(mod, AUDIO_CLK_SEL2, mask, val);
284 		break;
285 	}
286 }
287 
288 int rsnd_adg_ssi_clk_stop(struct rsnd_mod *mod)
289 {
290 	/*
291 	 * "mod" = "ssi" here.
292 	 * we can get "ssi id" from mod
293 	 */
294 	rsnd_adg_set_ssi_clk(mod, 0);
295 
296 	return 0;
297 }
298 
299 int rsnd_adg_ssi_clk_try_start(struct rsnd_mod *mod, unsigned int rate)
300 {
301 	struct rsnd_priv *priv = rsnd_mod_to_priv(mod);
302 	struct rsnd_adg *adg = rsnd_priv_to_adg(priv);
303 	struct device *dev = rsnd_priv_to_dev(priv);
304 	struct clk *clk;
305 	int i;
306 	u32 data;
307 	int sel_table[] = {
308 		[CLKA] = 0x1,
309 		[CLKB] = 0x2,
310 		[CLKC] = 0x3,
311 		[CLKI] = 0x0,
312 	};
313 
314 	dev_dbg(dev, "request clock = %d\n", rate);
315 
316 	/*
317 	 * find suitable clock from
318 	 * AUDIO_CLKA/AUDIO_CLKB/AUDIO_CLKC/AUDIO_CLKI.
319 	 */
320 	data = 0;
321 	for_each_rsnd_clk(clk, adg, i) {
322 		if (rate == clk_get_rate(clk)) {
323 			data = sel_table[i];
324 			goto found_clock;
325 		}
326 	}
327 
328 	/*
329 	 * find 1/6 clock from BRGA/BRGB
330 	 */
331 	if (rate == adg->rbga_rate_for_441khz_div_6) {
332 		data = 0x10;
333 		goto found_clock;
334 	}
335 
336 	if (rate == adg->rbgb_rate_for_48khz_div_6) {
337 		data = 0x20;
338 		goto found_clock;
339 	}
340 
341 	return -EIO;
342 
343 found_clock:
344 
345 	/* see rsnd_adg_ssi_clk_init() */
346 	rsnd_mod_bset(mod, SSICKR, 0x00FF0000, adg->ckr);
347 	rsnd_mod_write(mod, BRRA,  0x00000002); /* 1/6 */
348 	rsnd_mod_write(mod, BRRB,  0x00000002); /* 1/6 */
349 
350 	/*
351 	 * This "mod" = "ssi" here.
352 	 * we can get "ssi id" from mod
353 	 */
354 	rsnd_adg_set_ssi_clk(mod, data);
355 
356 	dev_dbg(dev, "ADG: ssi%d selects clk%d = %d",
357 		rsnd_mod_id(mod), i, rate);
358 
359 	return 0;
360 }
361 
362 static void rsnd_adg_ssi_clk_init(struct rsnd_priv *priv, struct rsnd_adg *adg)
363 {
364 	struct clk *clk;
365 	unsigned long rate;
366 	u32 ckr;
367 	int i;
368 	int brg_table[] = {
369 		[CLKA] = 0x0,
370 		[CLKB] = 0x1,
371 		[CLKC] = 0x4,
372 		[CLKI] = 0x2,
373 	};
374 
375 	/*
376 	 * This driver is assuming that AUDIO_CLKA/AUDIO_CLKB/AUDIO_CLKC
377 	 * have 44.1kHz or 48kHz base clocks for now.
378 	 *
379 	 * SSI itself can divide parent clock by 1/1 - 1/16
380 	 * So,  BRGA outputs 44.1kHz base parent clock 1/32,
381 	 * and, BRGB outputs 48.0kHz base parent clock 1/32 here.
382 	 * see
383 	 *	rsnd_adg_ssi_clk_try_start()
384 	 */
385 	ckr = 0;
386 	adg->rbga_rate_for_441khz_div_6 = 0;
387 	adg->rbgb_rate_for_48khz_div_6  = 0;
388 	for_each_rsnd_clk(clk, adg, i) {
389 		rate = clk_get_rate(clk);
390 
391 		if (0 == rate) /* not used */
392 			continue;
393 
394 		/* RBGA */
395 		if (!adg->rbga_rate_for_441khz_div_6 && (0 == rate % 44100)) {
396 			adg->rbga_rate_for_441khz_div_6 = rate / 6;
397 			ckr |= brg_table[i] << 20;
398 		}
399 
400 		/* RBGB */
401 		if (!adg->rbgb_rate_for_48khz_div_6 && (0 == rate % 48000)) {
402 			adg->rbgb_rate_for_48khz_div_6 = rate / 6;
403 			ckr |= brg_table[i] << 16;
404 		}
405 	}
406 
407 	adg->ckr = ckr;
408 }
409 
410 int rsnd_adg_probe(struct platform_device *pdev,
411 		   const struct rsnd_of_data *of_data,
412 		   struct rsnd_priv *priv)
413 {
414 	struct rsnd_adg *adg;
415 	struct device *dev = rsnd_priv_to_dev(priv);
416 	struct clk *clk;
417 	int i;
418 
419 	adg = devm_kzalloc(dev, sizeof(*adg), GFP_KERNEL);
420 	if (!adg) {
421 		dev_err(dev, "ADG allocate failed\n");
422 		return -ENOMEM;
423 	}
424 
425 	adg->clk[CLKA]	= devm_clk_get(dev, "clk_a");
426 	adg->clk[CLKB]	= devm_clk_get(dev, "clk_b");
427 	adg->clk[CLKC]	= devm_clk_get(dev, "clk_c");
428 	adg->clk[CLKI]	= devm_clk_get(dev, "clk_i");
429 
430 	for_each_rsnd_clk(clk, adg, i)
431 		dev_dbg(dev, "clk %d : %p : %ld\n", i, clk, clk_get_rate(clk));
432 
433 	rsnd_adg_ssi_clk_init(priv, adg);
434 
435 	priv->adg = adg;
436 
437 	return 0;
438 }
439