Linux 3.14.25
[platform/adaptation/renesas_rcar/renesas_kernel.git] / sound / soc / sh / rcar / adg.c
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, (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
33 static int rsnd_adg_set_convert_clk_gen1(struct rsnd_priv *priv,
34                                          struct rsnd_mod *mod,
35                                          unsigned int src_rate,
36                                          unsigned int dst_rate)
37 {
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;
41         u32 mask, val;
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 */
50         };
51
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;
55                      div <= 2048;
56                      div *= 2,          idx++) {
57                         if (src_rate == sel_rate[sel] / div) {
58                                 val = (idx << 4) | sel;
59                                 goto find_rate;
60                         }
61                 }
62         }
63         dev_err(dev, "can't find convert src clk\n");
64         return -EINVAL;
65
66 find_rate:
67         shift   = (id % 4) * 8;
68         mask    = 0xFF << shift;
69         val     = val << shift;
70
71         dev_dbg(dev, "adg convert src clk = %02x\n", val);
72
73         switch (id / 4) {
74         case 0:
75                 rsnd_mod_bset(mod, AUDIO_CLK_SEL3, mask, val);
76                 break;
77         case 1:
78                 rsnd_mod_bset(mod, AUDIO_CLK_SEL4, mask, val);
79                 break;
80         case 2:
81                 rsnd_mod_bset(mod, AUDIO_CLK_SEL5, mask, val);
82                 break;
83         }
84
85         /*
86          * Gen1 doesn't need dst_rate settings,
87          * since it uses SSI WS pin.
88          * see also rsnd_src_set_route_if_gen1()
89          */
90
91         return 0;
92 }
93
94 int rsnd_adg_set_convert_clk(struct rsnd_priv *priv,
95                              struct rsnd_mod *mod,
96                              unsigned int src_rate,
97                              unsigned int dst_rate)
98 {
99         if (rsnd_is_gen1(priv))
100                 return rsnd_adg_set_convert_clk_gen1(priv, mod,
101                                                      src_rate, dst_rate);
102
103         return -EINVAL;
104 }
105
106 static void rsnd_adg_set_ssi_clk(struct rsnd_mod *mod, u32 val)
107 {
108         int id = rsnd_mod_id(mod);
109         int shift = (id % 4) * 8;
110         u32 mask = 0xFF << shift;
111
112         val = val << shift;
113
114         /*
115          * SSI 8 is not connected to ADG.
116          * it works with SSI 7
117          */
118         if (id == 8)
119                 return;
120
121         switch (id / 4) {
122         case 0:
123                 rsnd_mod_bset(mod, AUDIO_CLK_SEL0, mask, val);
124                 break;
125         case 1:
126                 rsnd_mod_bset(mod, AUDIO_CLK_SEL1, mask, val);
127                 break;
128         case 2:
129                 rsnd_mod_bset(mod, AUDIO_CLK_SEL2, mask, val);
130                 break;
131         }
132 }
133
134 int rsnd_adg_ssi_clk_stop(struct rsnd_mod *mod)
135 {
136         /*
137          * "mod" = "ssi" here.
138          * we can get "ssi id" from mod
139          */
140         rsnd_adg_set_ssi_clk(mod, 0);
141
142         return 0;
143 }
144
145 int rsnd_adg_ssi_clk_try_start(struct rsnd_mod *mod, unsigned int rate)
146 {
147         struct rsnd_priv *priv = rsnd_mod_to_priv(mod);
148         struct rsnd_adg *adg = rsnd_priv_to_adg(priv);
149         struct device *dev = rsnd_priv_to_dev(priv);
150         struct clk *clk;
151         int i;
152         u32 data;
153         int sel_table[] = {
154                 [CLKA] = 0x1,
155                 [CLKB] = 0x2,
156                 [CLKC] = 0x3,
157                 [CLKI] = 0x0,
158         };
159
160         dev_dbg(dev, "request clock = %d\n", rate);
161
162         /*
163          * find suitable clock from
164          * AUDIO_CLKA/AUDIO_CLKB/AUDIO_CLKC/AUDIO_CLKI.
165          */
166         data = 0;
167         for_each_rsnd_clk(clk, adg, i) {
168                 if (rate == clk_get_rate(clk)) {
169                         data = sel_table[i];
170                         goto found_clock;
171                 }
172         }
173
174         /*
175          * find 1/6 clock from BRGA/BRGB
176          */
177         if (rate == adg->rbga_rate_for_441khz_div_6) {
178                 data = 0x10;
179                 goto found_clock;
180         }
181
182         if (rate == adg->rbgb_rate_for_48khz_div_6) {
183                 data = 0x20;
184                 goto found_clock;
185         }
186
187         return -EIO;
188
189 found_clock:
190
191         /* see rsnd_adg_ssi_clk_init() */
192         rsnd_mod_bset(mod, SSICKR, 0x00FF0000, adg->ckr);
193         rsnd_mod_write(mod, BRRA,  0x00000002); /* 1/6 */
194         rsnd_mod_write(mod, BRRB,  0x00000002); /* 1/6 */
195
196         /*
197          * This "mod" = "ssi" here.
198          * we can get "ssi id" from mod
199          */
200         rsnd_adg_set_ssi_clk(mod, data);
201
202         dev_dbg(dev, "ADG: ssi%d selects clk%d = %d",
203                 rsnd_mod_id(mod), i, rate);
204
205         return 0;
206 }
207
208 static void rsnd_adg_ssi_clk_init(struct rsnd_priv *priv, struct rsnd_adg *adg)
209 {
210         struct clk *clk;
211         unsigned long rate;
212         u32 ckr;
213         int i;
214         int brg_table[] = {
215                 [CLKA] = 0x0,
216                 [CLKB] = 0x1,
217                 [CLKC] = 0x4,
218                 [CLKI] = 0x2,
219         };
220
221         /*
222          * This driver is assuming that AUDIO_CLKA/AUDIO_CLKB/AUDIO_CLKC
223          * have 44.1kHz or 48kHz base clocks for now.
224          *
225          * SSI itself can divide parent clock by 1/1 - 1/16
226          * So,  BRGA outputs 44.1kHz base parent clock 1/32,
227          * and, BRGB outputs 48.0kHz base parent clock 1/32 here.
228          * see
229          *      rsnd_adg_ssi_clk_try_start()
230          */
231         ckr = 0;
232         adg->rbga_rate_for_441khz_div_6 = 0;
233         adg->rbgb_rate_for_48khz_div_6  = 0;
234         for_each_rsnd_clk(clk, adg, i) {
235                 rate = clk_get_rate(clk);
236
237                 if (0 == rate) /* not used */
238                         continue;
239
240                 /* RBGA */
241                 if (!adg->rbga_rate_for_441khz_div_6 && (0 == rate % 44100)) {
242                         adg->rbga_rate_for_441khz_div_6 = rate / 6;
243                         ckr |= brg_table[i] << 20;
244                 }
245
246                 /* RBGB */
247                 if (!adg->rbgb_rate_for_48khz_div_6 && (0 == rate % 48000)) {
248                         adg->rbgb_rate_for_48khz_div_6 = rate / 6;
249                         ckr |= brg_table[i] << 16;
250                 }
251         }
252
253         adg->ckr = ckr;
254 }
255
256 int rsnd_adg_probe(struct platform_device *pdev,
257                    struct rcar_snd_info *info,
258                    struct rsnd_priv *priv)
259 {
260         struct rsnd_adg *adg;
261         struct device *dev = rsnd_priv_to_dev(priv);
262         struct clk *clk;
263         int i;
264
265         adg = devm_kzalloc(dev, sizeof(*adg), GFP_KERNEL);
266         if (!adg) {
267                 dev_err(dev, "ADG allocate failed\n");
268                 return -ENOMEM;
269         }
270
271         adg->clk[CLKA] = clk_get(NULL, "audio_clk_a");
272         adg->clk[CLKB] = clk_get(NULL, "audio_clk_b");
273         adg->clk[CLKC] = clk_get(NULL, "audio_clk_c");
274         adg->clk[CLKI] = clk_get(NULL, "audio_clk_internal");
275         for_each_rsnd_clk(clk, adg, i) {
276                 if (IS_ERR(clk)) {
277                         dev_err(dev, "Audio clock failed\n");
278                         return -EIO;
279                 }
280         }
281
282         rsnd_adg_ssi_clk_init(priv, adg);
283
284         priv->adg = adg;
285
286         dev_dbg(dev, "adg probed\n");
287
288         return 0;
289 }
290
291 void rsnd_adg_remove(struct platform_device *pdev,
292                      struct rsnd_priv *priv)
293 {
294         struct rsnd_adg *adg = priv->adg;
295         struct clk *clk;
296         int i;
297
298         for_each_rsnd_clk(clk, adg, i)
299                 clk_put(clk);
300 }