2 * Helper routines for R-Car sound ADG.
4 * Copyright (C) 2013 Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
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
10 #include <linux/sh_clk.h>
20 struct clk
*clk
[CLKMAX
];
22 int rbga_rate_for_441khz_div_6
; /* RBGA */
23 int rbgb_rate_for_48khz_div_6
; /* RBGB */
27 #define for_each_rsnd_clk(pos, adg, i) \
28 for (i = 0, (pos) = adg->clk[i]; \
30 i++, (pos) = adg->clk[i])
31 #define rsnd_priv_to_adg(priv) ((struct rsnd_adg *)(priv)->adg)
33 int rsnd_adg_set_convert_clk_gen1(struct rsnd_priv
*priv
,
35 unsigned int src_rate
,
36 unsigned int dst_rate
)
38 struct rsnd_adg
*adg
= rsnd_priv_to_adg(priv
);
39 struct device
*dev
= rsnd_priv_to_dev(priv
);
40 int idx
, sel
, div
, shift
;
42 int id
= rsnd_mod_id(mod
);
43 unsigned int sel_rate
[] = {
44 clk_get_rate(adg
->clk
[CLKA
]), /* 000: CLKA */
45 clk_get_rate(adg
->clk
[CLKB
]), /* 001: CLKB */
46 clk_get_rate(adg
->clk
[CLKC
]), /* 010: CLKC */
47 0, /* 011: MLBCLK (not used) */
48 adg
->rbga_rate_for_441khz_div_6
,/* 100: RBGA */
49 adg
->rbgb_rate_for_48khz_div_6
, /* 101: RBGB */
52 /* find div (= 1/128, 1/256, 1/512, 1/1024, 1/2048 */
53 for (sel
= 0; sel
< ARRAY_SIZE(sel_rate
); sel
++) {
54 for (div
= 128, idx
= 0;
57 if (src_rate
== sel_rate
[sel
] / div
) {
58 val
= (idx
<< 4) | sel
;
63 dev_err(dev
, "can't find convert src clk\n");
71 dev_dbg(dev
, "adg convert src clk = %02x\n", val
);
75 rsnd_mod_bset(mod
, AUDIO_CLK_SEL3
, mask
, val
);
78 rsnd_mod_bset(mod
, AUDIO_CLK_SEL4
, mask
, val
);
81 rsnd_mod_bset(mod
, AUDIO_CLK_SEL5
, mask
, val
);
86 * Gen1 doesn't need dst_rate settings,
87 * since it uses SSI WS pin.
88 * see also rsnd_src_set_route_if_gen1()
94 static void rsnd_adg_set_ssi_clk(struct rsnd_mod
*mod
, u32 val
)
96 int id
= rsnd_mod_id(mod
);
97 int shift
= (id
% 4) * 8;
98 u32 mask
= 0xFF << shift
;
103 * SSI 8 is not connected to ADG.
104 * it works with SSI 7
111 rsnd_mod_bset(mod
, AUDIO_CLK_SEL0
, mask
, val
);
114 rsnd_mod_bset(mod
, AUDIO_CLK_SEL1
, mask
, val
);
117 rsnd_mod_bset(mod
, AUDIO_CLK_SEL2
, mask
, val
);
122 int rsnd_adg_ssi_clk_stop(struct rsnd_mod
*mod
)
125 * "mod" = "ssi" here.
126 * we can get "ssi id" from mod
128 rsnd_adg_set_ssi_clk(mod
, 0);
133 int rsnd_adg_ssi_clk_try_start(struct rsnd_mod
*mod
, unsigned int rate
)
135 struct rsnd_priv
*priv
= rsnd_mod_to_priv(mod
);
136 struct rsnd_adg
*adg
= rsnd_priv_to_adg(priv
);
137 struct device
*dev
= rsnd_priv_to_dev(priv
);
148 dev_dbg(dev
, "request clock = %d\n", rate
);
151 * find suitable clock from
152 * AUDIO_CLKA/AUDIO_CLKB/AUDIO_CLKC/AUDIO_CLKI.
155 for_each_rsnd_clk(clk
, adg
, i
) {
156 if (rate
== clk_get_rate(clk
)) {
163 * find 1/6 clock from BRGA/BRGB
165 if (rate
== adg
->rbga_rate_for_441khz_div_6
) {
170 if (rate
== adg
->rbgb_rate_for_48khz_div_6
) {
179 /* see rsnd_adg_ssi_clk_init() */
180 rsnd_mod_bset(mod
, SSICKR
, 0x00FF0000, adg
->ckr
);
181 rsnd_mod_write(mod
, BRRA
, 0x00000002); /* 1/6 */
182 rsnd_mod_write(mod
, BRRB
, 0x00000002); /* 1/6 */
185 * This "mod" = "ssi" here.
186 * we can get "ssi id" from mod
188 rsnd_adg_set_ssi_clk(mod
, data
);
190 dev_dbg(dev
, "ADG: ssi%d selects clk%d = %d",
191 rsnd_mod_id(mod
), i
, rate
);
196 static void rsnd_adg_ssi_clk_init(struct rsnd_priv
*priv
, struct rsnd_adg
*adg
)
210 * This driver is assuming that AUDIO_CLKA/AUDIO_CLKB/AUDIO_CLKC
211 * have 44.1kHz or 48kHz base clocks for now.
213 * SSI itself can divide parent clock by 1/1 - 1/16
214 * So, BRGA outputs 44.1kHz base parent clock 1/32,
215 * and, BRGB outputs 48.0kHz base parent clock 1/32 here.
217 * rsnd_adg_ssi_clk_try_start()
220 adg
->rbga_rate_for_441khz_div_6
= 0;
221 adg
->rbgb_rate_for_48khz_div_6
= 0;
222 for_each_rsnd_clk(clk
, adg
, i
) {
223 rate
= clk_get_rate(clk
);
225 if (0 == rate
) /* not used */
229 if (!adg
->rbga_rate_for_441khz_div_6
&& (0 == rate
% 44100)) {
230 adg
->rbga_rate_for_441khz_div_6
= rate
/ 6;
231 ckr
|= brg_table
[i
] << 20;
235 if (!adg
->rbgb_rate_for_48khz_div_6
&& (0 == rate
% 48000)) {
236 adg
->rbgb_rate_for_48khz_div_6
= rate
/ 6;
237 ckr
|= brg_table
[i
] << 16;
244 int rsnd_adg_probe(struct platform_device
*pdev
,
245 struct rcar_snd_info
*info
,
246 struct rsnd_priv
*priv
)
248 struct rsnd_adg
*adg
;
249 struct device
*dev
= rsnd_priv_to_dev(priv
);
253 adg
= devm_kzalloc(dev
, sizeof(*adg
), GFP_KERNEL
);
255 dev_err(dev
, "ADG allocate failed\n");
259 adg
->clk
[CLKA
] = clk_get(NULL
, "audio_clk_a");
260 adg
->clk
[CLKB
] = clk_get(NULL
, "audio_clk_b");
261 adg
->clk
[CLKC
] = clk_get(NULL
, "audio_clk_c");
262 adg
->clk
[CLKI
] = clk_get(NULL
, "audio_clk_internal");
263 for_each_rsnd_clk(clk
, adg
, i
) {
265 dev_err(dev
, "Audio clock failed\n");
270 rsnd_adg_ssi_clk_init(priv
, adg
);
274 dev_dbg(dev
, "adg probed\n");
279 void rsnd_adg_remove(struct platform_device
*pdev
,
280 struct rsnd_priv
*priv
)
282 struct rsnd_adg
*adg
= priv
->adg
;
286 for_each_rsnd_clk(clk
, adg
, i
)