]> Pileus Git - ~andy/linux/blob - sound/soc/sh/rcar/scu.c
Merge remote-tracking branches 'asoc/topic/ad1836', 'asoc/topic/ad193x', 'asoc/topic...
[~andy/linux] / sound / soc / sh / rcar / scu.c
1 /*
2  * Renesas R-Car SCU support
3  *
4  * Copyright (C) 2013 Renesas Solutions Corp.
5  * Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
6  *
7  * This program is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License version 2 as
9  * published by the Free Software Foundation.
10  */
11 #include "rsnd.h"
12
13 struct rsnd_scu {
14         struct rsnd_scu_platform_info *info; /* rcar_snd.h */
15         struct rsnd_mod mod;
16         struct clk *clk;
17 };
18
19 #define rsnd_scu_mode_flags(p) ((p)->info->flags)
20 #define rsnd_scu_convert_rate(p) ((p)->info->convert_rate)
21
22 #define RSND_SCU_NAME_SIZE 16
23
24 /*
25  * ADINR
26  */
27 #define OTBL_24         (0 << 16)
28 #define OTBL_22         (2 << 16)
29 #define OTBL_20         (4 << 16)
30 #define OTBL_18         (6 << 16)
31 #define OTBL_16         (8 << 16)
32
33 /*
34  *              image of SRC (Sampling Rate Converter)
35  *
36  * 96kHz   <-> +-----+  48kHz   +-----+  48kHz  +-------+
37  * 48kHz   <-> | SRC | <------> | SSI | <-----> | codec |
38  * 44.1kHz <-> +-----+          +-----+         +-------+
39  * ...
40  *
41  */
42
43 #define rsnd_mod_to_scu(_mod)   \
44         container_of((_mod), struct rsnd_scu, mod)
45
46 #define for_each_rsnd_scu(pos, priv, i)                                 \
47         for ((i) = 0;                                                   \
48              ((i) < rsnd_scu_nr(priv)) &&                               \
49                      ((pos) = (struct rsnd_scu *)(priv)->scu + i);      \
50              i++)
51
52 /* Gen1 only */
53 static int rsnd_src_set_route_if_gen1(struct rsnd_priv *priv,
54                               struct rsnd_mod *mod,
55                               struct rsnd_dai *rdai,
56                               struct rsnd_dai_stream *io)
57 {
58         struct scu_route_config {
59                 u32 mask;
60                 int shift;
61         } routes[] = {
62                 { 0xF,  0, }, /* 0 */
63                 { 0xF,  4, }, /* 1 */
64                 { 0xF,  8, }, /* 2 */
65                 { 0x7, 12, }, /* 3 */
66                 { 0x7, 16, }, /* 4 */
67                 { 0x7, 20, }, /* 5 */
68                 { 0x7, 24, }, /* 6 */
69                 { 0x3, 28, }, /* 7 */
70                 { 0x3, 30, }, /* 8 */
71         };
72         struct rsnd_scu *scu = rsnd_mod_to_scu(mod);
73         u32 mask;
74         u32 val;
75         int shift;
76         int id;
77
78         /*
79          * Gen1 only
80          */
81         if (!rsnd_is_gen1(priv))
82                 return 0;
83
84         id = rsnd_mod_id(mod);
85         if (id < 0 || id >= ARRAY_SIZE(routes))
86                 return -EIO;
87
88         /*
89          * SRC_ROUTE_SELECT
90          */
91         val = rsnd_dai_is_play(rdai, io) ? 0x1 : 0x2;
92         val = val               << routes[id].shift;
93         mask = routes[id].mask  << routes[id].shift;
94
95         rsnd_mod_bset(mod, SRC_ROUTE_SEL, mask, val);
96
97         /*
98          * SRC_TIMING_SELECT
99          */
100         shift   = (id % 4) * 8;
101         mask    = 0x1F << shift;
102
103         /*
104          * ADG is used as source clock if SRC was used,
105          * then, SSI WS is used as destination clock.
106          * SSI WS is used as source clock if SRC is not used
107          * (when playback, source/destination become reverse when capture)
108          */
109         if (rsnd_scu_convert_rate(scu)) /* use ADG */
110                 val = 0;
111         else if (8 == id)               /* use SSI WS, but SRU8 is special */
112                 val = id << shift;
113         else                            /* use SSI WS */
114                 val = (id + 1) << shift;
115
116         switch (id / 4) {
117         case 0:
118                 rsnd_mod_bset(mod, SRC_TMG_SEL0, mask, val);
119                 break;
120         case 1:
121                 rsnd_mod_bset(mod, SRC_TMG_SEL1, mask, val);
122                 break;
123         case 2:
124                 rsnd_mod_bset(mod, SRC_TMG_SEL2, mask, val);
125                 break;
126         }
127
128         return 0;
129 }
130
131 unsigned int rsnd_scu_get_ssi_rate(struct rsnd_priv *priv,
132                                    struct rsnd_mod *ssi_mod,
133                                    struct snd_pcm_runtime *runtime)
134 {
135         struct rsnd_scu *scu;
136         unsigned int rate;
137
138         /* this function is assuming SSI id = SCU id here */
139         scu = rsnd_mod_to_scu(rsnd_scu_mod_get(priv, rsnd_mod_id(ssi_mod)));
140
141         /*
142          * return convert rate if SRC is used,
143          * otherwise, return runtime->rate as usual
144          */
145         rate = rsnd_scu_convert_rate(scu);
146         if (!rate)
147                 rate = runtime->rate;
148
149         return rate;
150 }
151
152 static int rsnd_scu_convert_rate_ctrl(struct rsnd_priv *priv,
153                               struct rsnd_mod *mod,
154                               struct rsnd_dai *rdai,
155                               struct rsnd_dai_stream *io)
156 {
157         struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io);
158         struct rsnd_scu *scu = rsnd_mod_to_scu(mod);
159         u32 convert_rate = rsnd_scu_convert_rate(scu);
160         u32 adinr = runtime->channels;
161
162         /* set/clear soft reset */
163         rsnd_mod_write(mod, SRC_SWRSR, 0);
164         rsnd_mod_write(mod, SRC_SWRSR, 1);
165
166         /* Initialize the operation of the SRC internal circuits */
167         rsnd_mod_write(mod, SRC_SRCIR, 1);
168
169         /* Set channel number and output bit length */
170         switch (runtime->sample_bits) {
171         case 16:
172                 adinr |= OTBL_16;
173                 break;
174         case 32:
175                 adinr |= OTBL_24;
176                 break;
177         default:
178                 return -EIO;
179         }
180         rsnd_mod_write(mod, SRC_ADINR, adinr);
181
182         if (convert_rate) {
183                 u32 fsrate = 0x0400000 / convert_rate * runtime->rate;
184                 int ret;
185
186                 /* Enable the initial value of IFS */
187                 rsnd_mod_write(mod, SRC_IFSCR, 1);
188
189                 /* Set initial value of IFS */
190                 rsnd_mod_write(mod, SRC_IFSVR, fsrate);
191
192                 /* Select SRC mode (fixed value) */
193                 rsnd_mod_write(mod, SRC_SRCCR, 0x00010110);
194
195                 /* Set the restriction value of the FS ratio (98%) */
196                 rsnd_mod_write(mod, SRC_MNFSR, fsrate / 100 * 98);
197
198                 if (rsnd_is_gen1(priv)) {
199                         /* no SRC_BFSSR settings, since SRC_SRCCR::BUFMD is 0 */
200                 }
201
202                 /* set convert clock */
203                 ret = rsnd_adg_set_convert_clk(priv, mod,
204                                                runtime->rate,
205                                                convert_rate);
206                 if (ret < 0)
207                         return ret;
208         }
209
210         /* Cancel the initialization and operate the SRC function */
211         rsnd_mod_write(mod, SRC_SRCIR, 0);
212
213         /* use DMA transfer */
214         rsnd_mod_write(mod, BUSIF_MODE, 1);
215
216         return 0;
217 }
218
219 static int rsnd_scu_transfer_start(struct rsnd_priv *priv,
220                                    struct rsnd_mod *mod,
221                                    struct rsnd_dai *rdai,
222                                    struct rsnd_dai_stream *io)
223 {
224         struct rsnd_scu *scu = rsnd_mod_to_scu(mod);
225         int id = rsnd_mod_id(mod);
226         u32 val;
227
228         if (rsnd_is_gen1(priv)) {
229                 val = (1 << id);
230                 rsnd_mod_bset(mod, SRC_ROUTE_CTRL, val, val);
231         }
232
233         if (rsnd_scu_convert_rate(scu))
234                 rsnd_mod_write(mod, SRC_ROUTE_MODE0, 1);
235
236         return 0;
237 }
238
239 static int rsnd_scu_transfer_stop(struct rsnd_priv *priv,
240                                   struct rsnd_mod *mod,
241                                   struct rsnd_dai *rdai,
242                                   struct rsnd_dai_stream *io)
243 {
244         struct rsnd_scu *scu = rsnd_mod_to_scu(mod);
245         int id = rsnd_mod_id(mod);
246         u32 mask;
247
248         if (rsnd_is_gen1(priv)) {
249                 mask = (1 << id);
250                 rsnd_mod_bset(mod, SRC_ROUTE_CTRL, mask, 0);
251         }
252
253         if (rsnd_scu_convert_rate(scu))
254                 rsnd_mod_write(mod, SRC_ROUTE_MODE0, 0);
255
256         return 0;
257 }
258
259 bool rsnd_scu_hpbif_is_enable(struct rsnd_mod *mod)
260 {
261         struct rsnd_scu *scu = rsnd_mod_to_scu(mod);
262         u32 flags = rsnd_scu_mode_flags(scu);
263
264         return !!(flags & RSND_SCU_USE_HPBIF);
265 }
266
267 static int rsnd_scu_start(struct rsnd_mod *mod,
268                           struct rsnd_dai *rdai,
269                           struct rsnd_dai_stream *io)
270 {
271         struct rsnd_priv *priv = rsnd_mod_to_priv(mod);
272         struct rsnd_scu *scu = rsnd_mod_to_scu(mod);
273         struct device *dev = rsnd_priv_to_dev(priv);
274         int ret;
275
276         /*
277          * SCU will be used if it has RSND_SCU_USE_HPBIF flags
278          */
279         if (!rsnd_scu_hpbif_is_enable(mod)) {
280                 /* it use PIO transter */
281                 dev_dbg(dev, "%s%d is not used\n",
282                         rsnd_mod_name(mod), rsnd_mod_id(mod));
283
284                 return 0;
285         }
286
287         clk_enable(scu->clk);
288
289         /* it use DMA transter */
290
291         ret = rsnd_src_set_route_if_gen1(priv, mod, rdai, io);
292         if (ret < 0)
293                 return ret;
294
295         ret = rsnd_scu_convert_rate_ctrl(priv, mod, rdai, io);
296         if (ret < 0)
297                 return ret;
298
299         ret = rsnd_scu_transfer_start(priv, mod, rdai, io);
300         if (ret < 0)
301                 return ret;
302
303         dev_dbg(dev, "%s%d start\n", rsnd_mod_name(mod), rsnd_mod_id(mod));
304
305         return 0;
306 }
307
308 static int rsnd_scu_stop(struct rsnd_mod *mod,
309                           struct rsnd_dai *rdai,
310                           struct rsnd_dai_stream *io)
311 {
312         struct rsnd_priv *priv = rsnd_mod_to_priv(mod);
313         struct rsnd_scu *scu = rsnd_mod_to_scu(mod);
314
315         if (!rsnd_scu_hpbif_is_enable(mod))
316                 return 0;
317
318         rsnd_scu_transfer_stop(priv, mod, rdai, io);
319
320         clk_disable(scu->clk);
321
322         return 0;
323 }
324
325 static struct rsnd_mod_ops rsnd_scu_ops = {
326         .name   = "scu",
327         .start  = rsnd_scu_start,
328         .stop   = rsnd_scu_stop,
329 };
330
331 struct rsnd_mod *rsnd_scu_mod_get(struct rsnd_priv *priv, int id)
332 {
333         if (WARN_ON(id < 0 || id >= rsnd_scu_nr(priv)))
334                 id = 0;
335
336         return &((struct rsnd_scu *)(priv->scu) + id)->mod;
337 }
338
339 int rsnd_scu_probe(struct platform_device *pdev,
340                    struct rcar_snd_info *info,
341                    struct rsnd_priv *priv)
342 {
343         struct device *dev = rsnd_priv_to_dev(priv);
344         struct rsnd_scu *scu;
345         struct clk *clk;
346         char name[RSND_SCU_NAME_SIZE];
347         int i, nr;
348
349         /*
350          * init SCU
351          */
352         nr      = info->scu_info_nr;
353         scu     = devm_kzalloc(dev, sizeof(*scu) * nr, GFP_KERNEL);
354         if (!scu) {
355                 dev_err(dev, "SCU allocate failed\n");
356                 return -ENOMEM;
357         }
358
359         priv->scu_nr    = nr;
360         priv->scu       = scu;
361
362         for_each_rsnd_scu(scu, priv, i) {
363                 snprintf(name, RSND_SCU_NAME_SIZE, "scu.%d", i);
364
365                 clk = devm_clk_get(dev, name);
366                 if (IS_ERR(clk))
367                         return PTR_ERR(clk);
368
369                 rsnd_mod_init(priv, &scu->mod,
370                               &rsnd_scu_ops, i);
371                 scu->info = &info->scu_info[i];
372                 scu->clk = clk;
373
374                 dev_dbg(dev, "SCU%d probed\n", i);
375         }
376         dev_dbg(dev, "scu probed\n");
377
378         return 0;
379 }
380
381 void rsnd_scu_remove(struct platform_device *pdev,
382                      struct rsnd_priv *priv)
383 {
384 }