aboutsummaryrefslogtreecommitdiffstats
path: root/sound/soc/sh/rcar/scu.c
diff options
context:
space:
mode:
authorKuninori Morimoto <kuninori.morimoto.gx@renesas.com>2013-12-19 22:28:51 -0500
committerMark Brown <broonie@linaro.org>2013-12-31 08:35:31 -0500
commitef749400434cefd14fe02fe3de9e9f0125b2256d (patch)
tree2cd4dbdb054ad59d84e5eaefb75484aa6be8ac96 /sound/soc/sh/rcar/scu.c
parentadcf7d5e7605e8134a99d415b7afd13f03c4bf23 (diff)
ASoC: rsnd: add SRC (Sampling Rate Converter) support
This patch adds SRC support to Renesas sound driver. SRC converts sampling rate between codec <-> cpu. It needs special codec chip, or very simple DA/AD converter to use it. This patch was tested via ak4554 codec, and supports Gen1 only at this point. Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com> Signed-off-by: Mark Brown <broonie@linaro.org>
Diffstat (limited to 'sound/soc/sh/rcar/scu.c')
-rw-r--r--sound/soc/sh/rcar/scu.c152
1 files changed, 145 insertions, 7 deletions
diff --git a/sound/soc/sh/rcar/scu.c b/sound/soc/sh/rcar/scu.c
index 5f4f57206faf..1406dd8d9ed2 100644
--- a/sound/soc/sh/rcar/scu.c
+++ b/sound/soc/sh/rcar/scu.c
@@ -13,9 +13,13 @@
13struct rsnd_scu { 13struct rsnd_scu {
14 struct rsnd_scu_platform_info *info; /* rcar_snd.h */ 14 struct rsnd_scu_platform_info *info; /* rcar_snd.h */
15 struct rsnd_mod mod; 15 struct rsnd_mod mod;
16 struct clk *clk;
16}; 17};
17 18
18#define rsnd_scu_mode_flags(p) ((p)->info->flags) 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
19 23
20/* 24/*
21 * ADINR 25 * ADINR
@@ -26,6 +30,15 @@ struct rsnd_scu {
26#define OTBL_18 (6 << 16) 30#define OTBL_18 (6 << 16)
27#define OTBL_16 (8 << 16) 31#define OTBL_16 (8 << 16)
28 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 */
29 42
30#define rsnd_mod_to_scu(_mod) \ 43#define rsnd_mod_to_scu(_mod) \
31 container_of((_mod), struct rsnd_scu, mod) 44 container_of((_mod), struct rsnd_scu, mod)
@@ -56,7 +69,7 @@ static int rsnd_src_set_route_if_gen1(struct rsnd_priv *priv,
56 { 0x3, 28, }, /* 7 */ 69 { 0x3, 28, }, /* 7 */
57 { 0x3, 30, }, /* 8 */ 70 { 0x3, 30, }, /* 8 */
58 }; 71 };
59 72 struct rsnd_scu *scu = rsnd_mod_to_scu(mod);
60 u32 mask; 73 u32 mask;
61 u32 val; 74 u32 val;
62 int shift; 75 int shift;
@@ -86,9 +99,18 @@ static int rsnd_src_set_route_if_gen1(struct rsnd_priv *priv,
86 */ 99 */
87 shift = (id % 4) * 8; 100 shift = (id % 4) * 8;
88 mask = 0x1F << shift; 101 mask = 0x1F << shift;
89 if (8 == id) /* SRU8 is very special */ 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 */
90 val = id << shift; 112 val = id << shift;
91 else 113 else /* use SSI WS */
92 val = (id + 1) << shift; 114 val = (id + 1) << shift;
93 115
94 switch (id / 4) { 116 switch (id / 4) {
@@ -106,14 +128,45 @@ static int rsnd_src_set_route_if_gen1(struct rsnd_priv *priv,
106 return 0; 128 return 0;
107} 129}
108 130
109static int rsnd_scu_rate_ctrl(struct rsnd_priv *priv, 131unsigned 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
152static int rsnd_scu_convert_rate_ctrl(struct rsnd_priv *priv,
110 struct rsnd_mod *mod, 153 struct rsnd_mod *mod,
111 struct rsnd_dai *rdai, 154 struct rsnd_dai *rdai,
112 struct rsnd_dai_stream *io) 155 struct rsnd_dai_stream *io)
113{ 156{
114 struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io); 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);
115 u32 adinr = runtime->channels; 160 u32 adinr = runtime->channels;
116 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 */
117 switch (runtime->sample_bits) { 170 switch (runtime->sample_bits) {
118 case 16: 171 case 16:
119 adinr |= OTBL_16; 172 adinr |= OTBL_16;
@@ -124,9 +177,42 @@ static int rsnd_scu_rate_ctrl(struct rsnd_priv *priv,
124 default: 177 default:
125 return -EIO; 178 return -EIO;
126 } 179 }
127
128 rsnd_mod_write(mod, SRC_ADINR, adinr); 180 rsnd_mod_write(mod, SRC_ADINR, adinr);
129 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
130 return 0; 216 return 0;
131} 217}
132 218
@@ -135,6 +221,7 @@ static int rsnd_scu_transfer_start(struct rsnd_priv *priv,
135 struct rsnd_dai *rdai, 221 struct rsnd_dai *rdai,
136 struct rsnd_dai_stream *io) 222 struct rsnd_dai_stream *io)
137{ 223{
224 struct rsnd_scu *scu = rsnd_mod_to_scu(mod);
138 int id = rsnd_mod_id(mod); 225 int id = rsnd_mod_id(mod);
139 u32 val; 226 u32 val;
140 227
@@ -143,7 +230,28 @@ static int rsnd_scu_transfer_start(struct rsnd_priv *priv,
143 rsnd_mod_bset(mod, SRC_ROUTE_CTRL, val, val); 230 rsnd_mod_bset(mod, SRC_ROUTE_CTRL, val, val);
144 } 231 }
145 232
146 rsnd_mod_write(mod, BUSIF_MODE, 1); 233 if (rsnd_scu_convert_rate(scu))
234 rsnd_mod_write(mod, SRC_ROUTE_MODE0, 1);
235
236 return 0;
237}
238
239static 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);
147 255
148 return 0; 256 return 0;
149} 257}
@@ -161,6 +269,7 @@ static int rsnd_scu_start(struct rsnd_mod *mod,
161 struct rsnd_dai_stream *io) 269 struct rsnd_dai_stream *io)
162{ 270{
163 struct rsnd_priv *priv = rsnd_mod_to_priv(mod); 271 struct rsnd_priv *priv = rsnd_mod_to_priv(mod);
272 struct rsnd_scu *scu = rsnd_mod_to_scu(mod);
164 struct device *dev = rsnd_priv_to_dev(priv); 273 struct device *dev = rsnd_priv_to_dev(priv);
165 int ret; 274 int ret;
166 275
@@ -175,13 +284,15 @@ static int rsnd_scu_start(struct rsnd_mod *mod,
175 return 0; 284 return 0;
176 } 285 }
177 286
287 clk_enable(scu->clk);
288
178 /* it use DMA transter */ 289 /* it use DMA transter */
179 290
180 ret = rsnd_src_set_route_if_gen1(priv, mod, rdai, io); 291 ret = rsnd_src_set_route_if_gen1(priv, mod, rdai, io);
181 if (ret < 0) 292 if (ret < 0)
182 return ret; 293 return ret;
183 294
184 ret = rsnd_scu_rate_ctrl(priv, mod, rdai, io); 295 ret = rsnd_scu_convert_rate_ctrl(priv, mod, rdai, io);
185 if (ret < 0) 296 if (ret < 0)
186 return ret; 297 return ret;
187 298
@@ -194,9 +305,27 @@ static int rsnd_scu_start(struct rsnd_mod *mod,
194 return 0; 305 return 0;
195} 306}
196 307
308static 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
197static struct rsnd_mod_ops rsnd_scu_ops = { 325static struct rsnd_mod_ops rsnd_scu_ops = {
198 .name = "scu", 326 .name = "scu",
199 .start = rsnd_scu_start, 327 .start = rsnd_scu_start,
328 .stop = rsnd_scu_stop,
200}; 329};
201 330
202struct rsnd_mod *rsnd_scu_mod_get(struct rsnd_priv *priv, int id) 331struct rsnd_mod *rsnd_scu_mod_get(struct rsnd_priv *priv, int id)
@@ -212,6 +341,8 @@ int rsnd_scu_probe(struct platform_device *pdev,
212{ 341{
213 struct device *dev = rsnd_priv_to_dev(priv); 342 struct device *dev = rsnd_priv_to_dev(priv);
214 struct rsnd_scu *scu; 343 struct rsnd_scu *scu;
344 struct clk *clk;
345 char name[RSND_SCU_NAME_SIZE];
215 int i, nr; 346 int i, nr;
216 347
217 /* 348 /*
@@ -228,9 +359,16 @@ int rsnd_scu_probe(struct platform_device *pdev,
228 priv->scu = scu; 359 priv->scu = scu;
229 360
230 for_each_rsnd_scu(scu, priv, i) { 361 for_each_rsnd_scu(scu, priv, i) {
362 snprintf(name, RSND_SCU_NAME_SIZE, "scu.%d", i);
363
364 clk = devm_clk_get(dev, name);
365 if (IS_ERR(clk))
366 return PTR_ERR(clk);
367
231 rsnd_mod_init(priv, &scu->mod, 368 rsnd_mod_init(priv, &scu->mod,
232 &rsnd_scu_ops, i); 369 &rsnd_scu_ops, i);
233 scu->info = &info->scu_info[i]; 370 scu->info = &info->scu_info[i];
371 scu->clk = clk;
234 372
235 dev_dbg(dev, "SCU%d probed\n", i); 373 dev_dbg(dev, "SCU%d probed\n", i);
236 } 374 }