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
19struct 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
35static 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
60int 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
77static 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
122int 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
191int 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
199int 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
232find_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
260static 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
288int 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
299int 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
343found_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
362static 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
410int 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