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