diff options
Diffstat (limited to 'sound/soc/sh/rcar/src.c')
-rw-r--r-- | sound/soc/sh/rcar/src.c | 232 |
1 files changed, 96 insertions, 136 deletions
diff --git a/sound/soc/sh/rcar/src.c b/sound/soc/sh/rcar/src.c index 4d0720ed5a90..200eda019bc7 100644 --- a/sound/soc/sh/rcar/src.c +++ b/sound/soc/sh/rcar/src.c | |||
@@ -10,6 +10,8 @@ | |||
10 | */ | 10 | */ |
11 | #include "rsnd.h" | 11 | #include "rsnd.h" |
12 | 12 | ||
13 | #define SRC_NAME "src" | ||
14 | |||
13 | struct rsnd_src { | 15 | struct rsnd_src { |
14 | struct rsnd_src_platform_info *info; /* rcar_snd.h */ | 16 | struct rsnd_src_platform_info *info; /* rcar_snd.h */ |
15 | struct rsnd_mod mod; | 17 | struct rsnd_mod mod; |
@@ -18,21 +20,9 @@ struct rsnd_src { | |||
18 | 20 | ||
19 | #define RSND_SRC_NAME_SIZE 16 | 21 | #define RSND_SRC_NAME_SIZE 16 |
20 | 22 | ||
21 | /* | ||
22 | * ADINR | ||
23 | */ | ||
24 | #define OTBL_24 (0 << 16) | ||
25 | #define OTBL_22 (2 << 16) | ||
26 | #define OTBL_20 (4 << 16) | ||
27 | #define OTBL_18 (6 << 16) | ||
28 | #define OTBL_16 (8 << 16) | ||
29 | |||
30 | #define rsnd_src_mode_flags(p) ((p)->info->flags) | ||
31 | #define rsnd_src_convert_rate(p) ((p)->info->convert_rate) | 23 | #define rsnd_src_convert_rate(p) ((p)->info->convert_rate) |
32 | #define rsnd_mod_to_src(_mod) \ | 24 | #define rsnd_mod_to_src(_mod) \ |
33 | container_of((_mod), struct rsnd_src, mod) | 25 | container_of((_mod), struct rsnd_src, mod) |
34 | #define rsnd_src_hpbif_is_enable(src) \ | ||
35 | (rsnd_src_mode_flags(src) & RSND_SCU_USE_HPBIF) | ||
36 | #define rsnd_src_dma_available(src) \ | 26 | #define rsnd_src_dma_available(src) \ |
37 | rsnd_dma_available(rsnd_mod_to_dma(&(src)->mod)) | 27 | rsnd_dma_available(rsnd_mod_to_dma(&(src)->mod)) |
38 | 28 | ||
@@ -80,34 +70,35 @@ struct rsnd_src { | |||
80 | * | 70 | * |
81 | * This driver request | 71 | * This driver request |
82 | * struct rsnd_src_platform_info { | 72 | * struct rsnd_src_platform_info { |
83 | * u32 flags; | ||
84 | * u32 convert_rate; | 73 | * u32 convert_rate; |
74 | * int dma_id; | ||
85 | * } | 75 | * } |
86 | * | 76 | * |
87 | * rsnd_src_hpbif_is_enable() will be true | ||
88 | * if flags had RSND_SRC_USE_HPBIF, | ||
89 | * and it controls whether SSIU is used or not. | ||
90 | * | ||
91 | * rsnd_src_convert_rate() indicates | 77 | * rsnd_src_convert_rate() indicates |
92 | * above convert_rate, and it controls | 78 | * above convert_rate, and it controls |
93 | * whether SRC is used or not. | 79 | * whether SRC is used or not. |
94 | * | 80 | * |
95 | * ex) doesn't use SRC | 81 | * ex) doesn't use SRC |
96 | * struct rsnd_src_platform_info info = { | 82 | * static struct rsnd_dai_platform_info rsnd_dai = { |
97 | * .flags = 0, | 83 | * .playback = { .ssi = &rsnd_ssi[0], }, |
98 | * .convert_rate = 0, | ||
99 | * }; | 84 | * }; |
100 | * | 85 | * |
101 | * ex) uses SRC | 86 | * ex) uses SRC |
102 | * struct rsnd_src_platform_info info = { | 87 | * static struct rsnd_src_platform_info rsnd_src[] = { |
103 | * .flags = RSND_SRC_USE_HPBIF, | 88 | * RSND_SCU(48000, 0), |
104 | * .convert_rate = 48000, | 89 | * ... |
90 | * }; | ||
91 | * static struct rsnd_dai_platform_info rsnd_dai = { | ||
92 | * .playback = { .ssi = &rsnd_ssi[0], .src = &rsnd_src[0] }, | ||
105 | * }; | 93 | * }; |
106 | * | 94 | * |
107 | * ex) uses SRC bypass mode | 95 | * ex) uses SRC bypass mode |
108 | * struct rsnd_src_platform_info info = { | 96 | * static struct rsnd_src_platform_info rsnd_src[] = { |
109 | * .flags = RSND_SRC_USE_HPBIF, | 97 | * RSND_SCU(0, 0), |
110 | * .convert_rate = 0, | 98 | * ... |
99 | * }; | ||
100 | * static struct rsnd_dai_platform_info rsnd_dai = { | ||
101 | * .playback = { .ssi = &rsnd_ssi[0], .src = &rsnd_src[0] }, | ||
111 | * }; | 102 | * }; |
112 | * | 103 | * |
113 | */ | 104 | */ |
@@ -116,27 +107,17 @@ struct rsnd_src { | |||
116 | * Gen1/Gen2 common functions | 107 | * Gen1/Gen2 common functions |
117 | */ | 108 | */ |
118 | int rsnd_src_ssi_mode_init(struct rsnd_mod *ssi_mod, | 109 | int rsnd_src_ssi_mode_init(struct rsnd_mod *ssi_mod, |
119 | struct rsnd_dai *rdai, | 110 | struct rsnd_dai *rdai) |
120 | struct rsnd_dai_stream *io) | ||
121 | { | 111 | { |
122 | struct rsnd_priv *priv = rsnd_mod_to_priv(ssi_mod); | 112 | struct rsnd_dai_stream *io = rsnd_mod_to_io(ssi_mod); |
123 | struct rsnd_mod *src_mod = rsnd_io_to_mod_src(io); | 113 | struct rsnd_mod *src_mod = rsnd_io_to_mod_src(io); |
124 | struct rcar_snd_info *info = rsnd_priv_to_info(priv); | ||
125 | int ssi_id = rsnd_mod_id(ssi_mod); | 114 | int ssi_id = rsnd_mod_id(ssi_mod); |
126 | int has_src = 0; | ||
127 | 115 | ||
128 | /* | 116 | /* |
129 | * SSI_MODE0 | 117 | * SSI_MODE0 |
130 | */ | 118 | */ |
131 | if (info->dai_info) { | ||
132 | has_src = !!src_mod; | ||
133 | } else { | ||
134 | struct rsnd_src *src = rsnd_mod_to_src(src_mod); | ||
135 | has_src = rsnd_src_hpbif_is_enable(src); | ||
136 | } | ||
137 | |||
138 | rsnd_mod_bset(ssi_mod, SSI_MODE0, (1 << ssi_id), | 119 | rsnd_mod_bset(ssi_mod, SSI_MODE0, (1 << ssi_id), |
139 | has_src ? 0 : (1 << ssi_id)); | 120 | src_mod ? 0 : (1 << ssi_id)); |
140 | 121 | ||
141 | /* | 122 | /* |
142 | * SSI_MODE1 | 123 | * SSI_MODE1 |
@@ -166,8 +147,7 @@ int rsnd_src_ssi_mode_init(struct rsnd_mod *ssi_mod, | |||
166 | } | 147 | } |
167 | 148 | ||
168 | int rsnd_src_enable_ssi_irq(struct rsnd_mod *ssi_mod, | 149 | int rsnd_src_enable_ssi_irq(struct rsnd_mod *ssi_mod, |
169 | struct rsnd_dai *rdai, | 150 | struct rsnd_dai *rdai) |
170 | struct rsnd_dai_stream *io) | ||
171 | { | 151 | { |
172 | struct rsnd_priv *priv = rsnd_mod_to_priv(ssi_mod); | 152 | struct rsnd_priv *priv = rsnd_mod_to_priv(ssi_mod); |
173 | 153 | ||
@@ -203,13 +183,12 @@ unsigned int rsnd_src_get_ssi_rate(struct rsnd_priv *priv, | |||
203 | } | 183 | } |
204 | 184 | ||
205 | static int rsnd_src_set_convert_rate(struct rsnd_mod *mod, | 185 | static int rsnd_src_set_convert_rate(struct rsnd_mod *mod, |
206 | struct rsnd_dai *rdai, | 186 | struct rsnd_dai *rdai) |
207 | struct rsnd_dai_stream *io) | ||
208 | { | 187 | { |
188 | struct rsnd_dai_stream *io = rsnd_mod_to_io(mod); | ||
209 | struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io); | 189 | struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io); |
210 | struct rsnd_src *src = rsnd_mod_to_src(mod); | 190 | struct rsnd_src *src = rsnd_mod_to_src(mod); |
211 | u32 convert_rate = rsnd_src_convert_rate(src); | 191 | u32 convert_rate = rsnd_src_convert_rate(src); |
212 | u32 adinr = runtime->channels; | ||
213 | u32 fsrate = 0; | 192 | u32 fsrate = 0; |
214 | 193 | ||
215 | if (convert_rate) | 194 | if (convert_rate) |
@@ -226,17 +205,7 @@ static int rsnd_src_set_convert_rate(struct rsnd_mod *mod, | |||
226 | rsnd_mod_write(mod, SRC_SRCIR, 1); | 205 | rsnd_mod_write(mod, SRC_SRCIR, 1); |
227 | 206 | ||
228 | /* Set channel number and output bit length */ | 207 | /* Set channel number and output bit length */ |
229 | switch (runtime->sample_bits) { | 208 | rsnd_mod_write(mod, SRC_ADINR, rsnd_get_adinr(mod)); |
230 | case 16: | ||
231 | adinr |= OTBL_16; | ||
232 | break; | ||
233 | case 32: | ||
234 | adinr |= OTBL_24; | ||
235 | break; | ||
236 | default: | ||
237 | return -EIO; | ||
238 | } | ||
239 | rsnd_mod_write(mod, SRC_ADINR, adinr); | ||
240 | 209 | ||
241 | /* Enable the initial value of IFS */ | 210 | /* Enable the initial value of IFS */ |
242 | if (fsrate) { | 211 | if (fsrate) { |
@@ -253,8 +222,7 @@ static int rsnd_src_set_convert_rate(struct rsnd_mod *mod, | |||
253 | } | 222 | } |
254 | 223 | ||
255 | static int rsnd_src_init(struct rsnd_mod *mod, | 224 | static int rsnd_src_init(struct rsnd_mod *mod, |
256 | struct rsnd_dai *rdai, | 225 | struct rsnd_dai *rdai) |
257 | struct rsnd_dai_stream *io) | ||
258 | { | 226 | { |
259 | struct rsnd_src *src = rsnd_mod_to_src(mod); | 227 | struct rsnd_src *src = rsnd_mod_to_src(mod); |
260 | 228 | ||
@@ -264,8 +232,7 @@ static int rsnd_src_init(struct rsnd_mod *mod, | |||
264 | } | 232 | } |
265 | 233 | ||
266 | static int rsnd_src_quit(struct rsnd_mod *mod, | 234 | static int rsnd_src_quit(struct rsnd_mod *mod, |
267 | struct rsnd_dai *rdai, | 235 | struct rsnd_dai *rdai) |
268 | struct rsnd_dai_stream *io) | ||
269 | { | 236 | { |
270 | struct rsnd_src *src = rsnd_mod_to_src(mod); | 237 | struct rsnd_src *src = rsnd_mod_to_src(mod); |
271 | 238 | ||
@@ -275,8 +242,7 @@ static int rsnd_src_quit(struct rsnd_mod *mod, | |||
275 | } | 242 | } |
276 | 243 | ||
277 | static int rsnd_src_start(struct rsnd_mod *mod, | 244 | static int rsnd_src_start(struct rsnd_mod *mod, |
278 | struct rsnd_dai *rdai, | 245 | struct rsnd_dai *rdai) |
279 | struct rsnd_dai_stream *io) | ||
280 | { | 246 | { |
281 | struct rsnd_src *src = rsnd_mod_to_src(mod); | 247 | struct rsnd_src *src = rsnd_mod_to_src(mod); |
282 | 248 | ||
@@ -294,8 +260,7 @@ static int rsnd_src_start(struct rsnd_mod *mod, | |||
294 | 260 | ||
295 | 261 | ||
296 | static int rsnd_src_stop(struct rsnd_mod *mod, | 262 | static int rsnd_src_stop(struct rsnd_mod *mod, |
297 | struct rsnd_dai *rdai, | 263 | struct rsnd_dai *rdai) |
298 | struct rsnd_dai_stream *io) | ||
299 | { | 264 | { |
300 | struct rsnd_src *src = rsnd_mod_to_src(mod); | 265 | struct rsnd_src *src = rsnd_mod_to_src(mod); |
301 | 266 | ||
@@ -305,17 +270,13 @@ static int rsnd_src_stop(struct rsnd_mod *mod, | |||
305 | return 0; | 270 | return 0; |
306 | } | 271 | } |
307 | 272 | ||
308 | static struct rsnd_mod_ops rsnd_src_non_ops = { | ||
309 | .name = "src (non)", | ||
310 | }; | ||
311 | |||
312 | /* | 273 | /* |
313 | * Gen1 functions | 274 | * Gen1 functions |
314 | */ | 275 | */ |
315 | static int rsnd_src_set_route_gen1(struct rsnd_mod *mod, | 276 | static int rsnd_src_set_route_gen1(struct rsnd_mod *mod, |
316 | struct rsnd_dai *rdai, | 277 | struct rsnd_dai *rdai) |
317 | struct rsnd_dai_stream *io) | ||
318 | { | 278 | { |
279 | struct rsnd_dai_stream *io = rsnd_mod_to_io(mod); | ||
319 | struct src_route_config { | 280 | struct src_route_config { |
320 | u32 mask; | 281 | u32 mask; |
321 | int shift; | 282 | int shift; |
@@ -351,9 +312,9 @@ static int rsnd_src_set_route_gen1(struct rsnd_mod *mod, | |||
351 | } | 312 | } |
352 | 313 | ||
353 | static int rsnd_src_set_convert_timing_gen1(struct rsnd_mod *mod, | 314 | static int rsnd_src_set_convert_timing_gen1(struct rsnd_mod *mod, |
354 | struct rsnd_dai *rdai, | 315 | struct rsnd_dai *rdai) |
355 | struct rsnd_dai_stream *io) | ||
356 | { | 316 | { |
317 | struct rsnd_dai_stream *io = rsnd_mod_to_io(mod); | ||
357 | struct rsnd_priv *priv = rsnd_mod_to_priv(mod); | 318 | struct rsnd_priv *priv = rsnd_mod_to_priv(mod); |
358 | struct rsnd_src *src = rsnd_mod_to_src(mod); | 319 | struct rsnd_src *src = rsnd_mod_to_src(mod); |
359 | struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io); | 320 | struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io); |
@@ -410,12 +371,11 @@ static int rsnd_src_set_convert_timing_gen1(struct rsnd_mod *mod, | |||
410 | } | 371 | } |
411 | 372 | ||
412 | static int rsnd_src_set_convert_rate_gen1(struct rsnd_mod *mod, | 373 | static int rsnd_src_set_convert_rate_gen1(struct rsnd_mod *mod, |
413 | struct rsnd_dai *rdai, | 374 | struct rsnd_dai *rdai) |
414 | struct rsnd_dai_stream *io) | ||
415 | { | 375 | { |
416 | int ret; | 376 | int ret; |
417 | 377 | ||
418 | ret = rsnd_src_set_convert_rate(mod, rdai, io); | 378 | ret = rsnd_src_set_convert_rate(mod, rdai); |
419 | if (ret < 0) | 379 | if (ret < 0) |
420 | return ret; | 380 | return ret; |
421 | 381 | ||
@@ -431,25 +391,35 @@ static int rsnd_src_set_convert_rate_gen1(struct rsnd_mod *mod, | |||
431 | return 0; | 391 | return 0; |
432 | } | 392 | } |
433 | 393 | ||
394 | static int rsnd_src_probe_gen1(struct rsnd_mod *mod, | ||
395 | struct rsnd_dai *rdai) | ||
396 | { | ||
397 | struct rsnd_priv *priv = rsnd_mod_to_priv(mod); | ||
398 | struct device *dev = rsnd_priv_to_dev(priv); | ||
399 | |||
400 | dev_dbg(dev, "%s (Gen1) is probed\n", rsnd_mod_name(mod)); | ||
401 | |||
402 | return 0; | ||
403 | } | ||
404 | |||
434 | static int rsnd_src_init_gen1(struct rsnd_mod *mod, | 405 | static int rsnd_src_init_gen1(struct rsnd_mod *mod, |
435 | struct rsnd_dai *rdai, | 406 | struct rsnd_dai *rdai) |
436 | struct rsnd_dai_stream *io) | ||
437 | { | 407 | { |
438 | int ret; | 408 | int ret; |
439 | 409 | ||
440 | ret = rsnd_src_init(mod, rdai, io); | 410 | ret = rsnd_src_init(mod, rdai); |
441 | if (ret < 0) | 411 | if (ret < 0) |
442 | return ret; | 412 | return ret; |
443 | 413 | ||
444 | ret = rsnd_src_set_route_gen1(mod, rdai, io); | 414 | ret = rsnd_src_set_route_gen1(mod, rdai); |
445 | if (ret < 0) | 415 | if (ret < 0) |
446 | return ret; | 416 | return ret; |
447 | 417 | ||
448 | ret = rsnd_src_set_convert_rate_gen1(mod, rdai, io); | 418 | ret = rsnd_src_set_convert_rate_gen1(mod, rdai); |
449 | if (ret < 0) | 419 | if (ret < 0) |
450 | return ret; | 420 | return ret; |
451 | 421 | ||
452 | ret = rsnd_src_set_convert_timing_gen1(mod, rdai, io); | 422 | ret = rsnd_src_set_convert_timing_gen1(mod, rdai); |
453 | if (ret < 0) | 423 | if (ret < 0) |
454 | return ret; | 424 | return ret; |
455 | 425 | ||
@@ -457,29 +427,28 @@ static int rsnd_src_init_gen1(struct rsnd_mod *mod, | |||
457 | } | 427 | } |
458 | 428 | ||
459 | static int rsnd_src_start_gen1(struct rsnd_mod *mod, | 429 | static int rsnd_src_start_gen1(struct rsnd_mod *mod, |
460 | struct rsnd_dai *rdai, | 430 | struct rsnd_dai *rdai) |
461 | struct rsnd_dai_stream *io) | ||
462 | { | 431 | { |
463 | int id = rsnd_mod_id(mod); | 432 | int id = rsnd_mod_id(mod); |
464 | 433 | ||
465 | rsnd_mod_bset(mod, SRC_ROUTE_CTRL, (1 << id), (1 << id)); | 434 | rsnd_mod_bset(mod, SRC_ROUTE_CTRL, (1 << id), (1 << id)); |
466 | 435 | ||
467 | return rsnd_src_start(mod, rdai, io); | 436 | return rsnd_src_start(mod, rdai); |
468 | } | 437 | } |
469 | 438 | ||
470 | static int rsnd_src_stop_gen1(struct rsnd_mod *mod, | 439 | static int rsnd_src_stop_gen1(struct rsnd_mod *mod, |
471 | struct rsnd_dai *rdai, | 440 | struct rsnd_dai *rdai) |
472 | struct rsnd_dai_stream *io) | ||
473 | { | 441 | { |
474 | int id = rsnd_mod_id(mod); | 442 | int id = rsnd_mod_id(mod); |
475 | 443 | ||
476 | rsnd_mod_bset(mod, SRC_ROUTE_CTRL, (1 << id), 0); | 444 | rsnd_mod_bset(mod, SRC_ROUTE_CTRL, (1 << id), 0); |
477 | 445 | ||
478 | return rsnd_src_stop(mod, rdai, io); | 446 | return rsnd_src_stop(mod, rdai); |
479 | } | 447 | } |
480 | 448 | ||
481 | static struct rsnd_mod_ops rsnd_src_gen1_ops = { | 449 | static struct rsnd_mod_ops rsnd_src_gen1_ops = { |
482 | .name = "sru (gen1)", | 450 | .name = SRC_NAME, |
451 | .probe = rsnd_src_probe_gen1, | ||
483 | .init = rsnd_src_init_gen1, | 452 | .init = rsnd_src_init_gen1, |
484 | .quit = rsnd_src_quit, | 453 | .quit = rsnd_src_quit, |
485 | .start = rsnd_src_start_gen1, | 454 | .start = rsnd_src_start_gen1, |
@@ -490,17 +459,16 @@ static struct rsnd_mod_ops rsnd_src_gen1_ops = { | |||
490 | * Gen2 functions | 459 | * Gen2 functions |
491 | */ | 460 | */ |
492 | static int rsnd_src_set_convert_rate_gen2(struct rsnd_mod *mod, | 461 | static int rsnd_src_set_convert_rate_gen2(struct rsnd_mod *mod, |
493 | struct rsnd_dai *rdai, | 462 | struct rsnd_dai *rdai) |
494 | struct rsnd_dai_stream *io) | ||
495 | { | 463 | { |
496 | int ret; | 464 | int ret; |
497 | 465 | ||
498 | ret = rsnd_src_set_convert_rate(mod, rdai, io); | 466 | ret = rsnd_src_set_convert_rate(mod, rdai); |
499 | if (ret < 0) | 467 | if (ret < 0) |
500 | return ret; | 468 | return ret; |
501 | 469 | ||
502 | rsnd_mod_write(mod, SSI_BUSIF_ADINR, rsnd_mod_read(mod, SRC_ADINR)); | 470 | rsnd_mod_write(mod, SSI_BUSIF_ADINR, rsnd_get_adinr(mod)); |
503 | rsnd_mod_write(mod, SSI_BUSIF_MODE, rsnd_mod_read(mod, SRC_BUSIF_MODE)); | 471 | rsnd_mod_write(mod, SSI_BUSIF_MODE, 1); |
504 | 472 | ||
505 | rsnd_mod_write(mod, SRC_SRCCR, 0x00011110); | 473 | rsnd_mod_write(mod, SRC_SRCCR, 0x00011110); |
506 | 474 | ||
@@ -511,9 +479,9 @@ static int rsnd_src_set_convert_rate_gen2(struct rsnd_mod *mod, | |||
511 | } | 479 | } |
512 | 480 | ||
513 | static int rsnd_src_set_convert_timing_gen2(struct rsnd_mod *mod, | 481 | static int rsnd_src_set_convert_timing_gen2(struct rsnd_mod *mod, |
514 | struct rsnd_dai *rdai, | 482 | struct rsnd_dai *rdai) |
515 | struct rsnd_dai_stream *io) | ||
516 | { | 483 | { |
484 | struct rsnd_dai_stream *io = rsnd_mod_to_io(mod); | ||
517 | struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io); | 485 | struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io); |
518 | struct rsnd_src *src = rsnd_mod_to_src(mod); | 486 | struct rsnd_src *src = rsnd_mod_to_src(mod); |
519 | u32 convert_rate = rsnd_src_convert_rate(src); | 487 | u32 convert_rate = rsnd_src_convert_rate(src); |
@@ -530,35 +498,27 @@ static int rsnd_src_set_convert_timing_gen2(struct rsnd_mod *mod, | |||
530 | } | 498 | } |
531 | 499 | ||
532 | static int rsnd_src_probe_gen2(struct rsnd_mod *mod, | 500 | static int rsnd_src_probe_gen2(struct rsnd_mod *mod, |
533 | struct rsnd_dai *rdai, | 501 | struct rsnd_dai *rdai) |
534 | struct rsnd_dai_stream *io) | ||
535 | { | 502 | { |
536 | struct rsnd_priv *priv = rsnd_mod_to_priv(mod); | 503 | struct rsnd_priv *priv = rsnd_mod_to_priv(mod); |
537 | struct rcar_snd_info *info = rsnd_priv_to_info(priv); | ||
538 | struct rsnd_src *src = rsnd_mod_to_src(mod); | 504 | struct rsnd_src *src = rsnd_mod_to_src(mod); |
539 | struct rsnd_mod *ssi = rsnd_ssi_mod_get(priv, rsnd_mod_id(mod)); | ||
540 | struct device *dev = rsnd_priv_to_dev(priv); | 505 | struct device *dev = rsnd_priv_to_dev(priv); |
541 | int ret; | 506 | int ret; |
542 | int is_play; | ||
543 | |||
544 | if (info->dai_info) | ||
545 | is_play = rsnd_info_is_playback(priv, src); | ||
546 | else | ||
547 | is_play = rsnd_ssi_is_play(ssi); | ||
548 | 507 | ||
549 | ret = rsnd_dma_init(priv, | 508 | ret = rsnd_dma_init(priv, |
550 | rsnd_mod_to_dma(mod), | 509 | rsnd_mod_to_dma(mod), |
551 | is_play, | 510 | rsnd_info_is_playback(priv, src), |
552 | src->info->dma_id); | 511 | src->info->dma_id); |
553 | if (ret < 0) | 512 | if (ret < 0) |
554 | dev_err(dev, "SRC DMA failed\n"); | 513 | dev_err(dev, "SRC DMA failed\n"); |
555 | 514 | ||
515 | dev_dbg(dev, "%s (Gen2) is probed\n", rsnd_mod_name(mod)); | ||
516 | |||
556 | return ret; | 517 | return ret; |
557 | } | 518 | } |
558 | 519 | ||
559 | static int rsnd_src_remove_gen2(struct rsnd_mod *mod, | 520 | static int rsnd_src_remove_gen2(struct rsnd_mod *mod, |
560 | struct rsnd_dai *rdai, | 521 | struct rsnd_dai *rdai) |
561 | struct rsnd_dai_stream *io) | ||
562 | { | 522 | { |
563 | rsnd_dma_quit(rsnd_mod_to_priv(mod), rsnd_mod_to_dma(mod)); | 523 | rsnd_dma_quit(rsnd_mod_to_priv(mod), rsnd_mod_to_dma(mod)); |
564 | 524 | ||
@@ -566,20 +526,19 @@ static int rsnd_src_remove_gen2(struct rsnd_mod *mod, | |||
566 | } | 526 | } |
567 | 527 | ||
568 | static int rsnd_src_init_gen2(struct rsnd_mod *mod, | 528 | static int rsnd_src_init_gen2(struct rsnd_mod *mod, |
569 | struct rsnd_dai *rdai, | 529 | struct rsnd_dai *rdai) |
570 | struct rsnd_dai_stream *io) | ||
571 | { | 530 | { |
572 | int ret; | 531 | int ret; |
573 | 532 | ||
574 | ret = rsnd_src_init(mod, rdai, io); | 533 | ret = rsnd_src_init(mod, rdai); |
575 | if (ret < 0) | 534 | if (ret < 0) |
576 | return ret; | 535 | return ret; |
577 | 536 | ||
578 | ret = rsnd_src_set_convert_rate_gen2(mod, rdai, io); | 537 | ret = rsnd_src_set_convert_rate_gen2(mod, rdai); |
579 | if (ret < 0) | 538 | if (ret < 0) |
580 | return ret; | 539 | return ret; |
581 | 540 | ||
582 | ret = rsnd_src_set_convert_timing_gen2(mod, rdai, io); | 541 | ret = rsnd_src_set_convert_timing_gen2(mod, rdai); |
583 | if (ret < 0) | 542 | if (ret < 0) |
584 | return ret; | 543 | return ret; |
585 | 544 | ||
@@ -587,22 +546,22 @@ static int rsnd_src_init_gen2(struct rsnd_mod *mod, | |||
587 | } | 546 | } |
588 | 547 | ||
589 | static int rsnd_src_start_gen2(struct rsnd_mod *mod, | 548 | static int rsnd_src_start_gen2(struct rsnd_mod *mod, |
590 | struct rsnd_dai *rdai, | 549 | struct rsnd_dai *rdai) |
591 | struct rsnd_dai_stream *io) | ||
592 | { | 550 | { |
551 | struct rsnd_dai_stream *io = rsnd_mod_to_io(mod); | ||
593 | struct rsnd_src *src = rsnd_mod_to_src(mod); | 552 | struct rsnd_src *src = rsnd_mod_to_src(mod); |
553 | u32 val = rsnd_io_to_mod_dvc(io) ? 0x01 : 0x11; | ||
594 | 554 | ||
595 | rsnd_dma_start(rsnd_mod_to_dma(&src->mod)); | 555 | rsnd_dma_start(rsnd_mod_to_dma(&src->mod)); |
596 | 556 | ||
597 | rsnd_mod_write(mod, SSI_CTRL, 0x1); | 557 | rsnd_mod_write(mod, SSI_CTRL, 0x1); |
598 | rsnd_mod_write(mod, SRC_CTRL, 0x11); | 558 | rsnd_mod_write(mod, SRC_CTRL, val); |
599 | 559 | ||
600 | return rsnd_src_start(mod, rdai, io); | 560 | return rsnd_src_start(mod, rdai); |
601 | } | 561 | } |
602 | 562 | ||
603 | static int rsnd_src_stop_gen2(struct rsnd_mod *mod, | 563 | static int rsnd_src_stop_gen2(struct rsnd_mod *mod, |
604 | struct rsnd_dai *rdai, | 564 | struct rsnd_dai *rdai) |
605 | struct rsnd_dai_stream *io) | ||
606 | { | 565 | { |
607 | struct rsnd_src *src = rsnd_mod_to_src(mod); | 566 | struct rsnd_src *src = rsnd_mod_to_src(mod); |
608 | 567 | ||
@@ -611,11 +570,11 @@ static int rsnd_src_stop_gen2(struct rsnd_mod *mod, | |||
611 | 570 | ||
612 | rsnd_dma_stop(rsnd_mod_to_dma(&src->mod)); | 571 | rsnd_dma_stop(rsnd_mod_to_dma(&src->mod)); |
613 | 572 | ||
614 | return rsnd_src_stop(mod, rdai, io); | 573 | return rsnd_src_stop(mod, rdai); |
615 | } | 574 | } |
616 | 575 | ||
617 | static struct rsnd_mod_ops rsnd_src_gen2_ops = { | 576 | static struct rsnd_mod_ops rsnd_src_gen2_ops = { |
618 | .name = "src (gen2)", | 577 | .name = SRC_NAME, |
619 | .probe = rsnd_src_probe_gen2, | 578 | .probe = rsnd_src_probe_gen2, |
620 | .remove = rsnd_src_remove_gen2, | 579 | .remove = rsnd_src_remove_gen2, |
621 | .init = rsnd_src_init_gen2, | 580 | .init = rsnd_src_init_gen2, |
@@ -651,18 +610,21 @@ static void rsnd_of_parse_src(struct platform_device *pdev, | |||
651 | 610 | ||
652 | nr = of_get_child_count(src_node); | 611 | nr = of_get_child_count(src_node); |
653 | if (!nr) | 612 | if (!nr) |
654 | return; | 613 | goto rsnd_of_parse_src_end; |
655 | 614 | ||
656 | src_info = devm_kzalloc(dev, | 615 | src_info = devm_kzalloc(dev, |
657 | sizeof(struct rsnd_src_platform_info) * nr, | 616 | sizeof(struct rsnd_src_platform_info) * nr, |
658 | GFP_KERNEL); | 617 | GFP_KERNEL); |
659 | if (!src_info) { | 618 | if (!src_info) { |
660 | dev_err(dev, "src info allocation error\n"); | 619 | dev_err(dev, "src info allocation error\n"); |
661 | return; | 620 | goto rsnd_of_parse_src_end; |
662 | } | 621 | } |
663 | 622 | ||
664 | info->src_info = src_info; | 623 | info->src_info = src_info; |
665 | info->src_info_nr = nr; | 624 | info->src_info_nr = nr; |
625 | |||
626 | rsnd_of_parse_src_end: | ||
627 | of_node_put(src_node); | ||
666 | } | 628 | } |
667 | 629 | ||
668 | int rsnd_src_probe(struct platform_device *pdev, | 630 | int rsnd_src_probe(struct platform_device *pdev, |
@@ -677,6 +639,16 @@ int rsnd_src_probe(struct platform_device *pdev, | |||
677 | char name[RSND_SRC_NAME_SIZE]; | 639 | char name[RSND_SRC_NAME_SIZE]; |
678 | int i, nr; | 640 | int i, nr; |
679 | 641 | ||
642 | ops = NULL; | ||
643 | if (rsnd_is_gen1(priv)) | ||
644 | ops = &rsnd_src_gen1_ops; | ||
645 | if (rsnd_is_gen2(priv)) | ||
646 | ops = &rsnd_src_gen2_ops; | ||
647 | if (!ops) { | ||
648 | dev_err(dev, "unknown Generation\n"); | ||
649 | return -EIO; | ||
650 | } | ||
651 | |||
680 | rsnd_of_parse_src(pdev, of_data, priv); | 652 | rsnd_of_parse_src(pdev, of_data, priv); |
681 | 653 | ||
682 | /* | 654 | /* |
@@ -696,28 +668,16 @@ int rsnd_src_probe(struct platform_device *pdev, | |||
696 | priv->src = src; | 668 | priv->src = src; |
697 | 669 | ||
698 | for_each_rsnd_src(src, priv, i) { | 670 | for_each_rsnd_src(src, priv, i) { |
699 | snprintf(name, RSND_SRC_NAME_SIZE, "src.%d", i); | 671 | snprintf(name, RSND_SRC_NAME_SIZE, "%s.%d", |
672 | SRC_NAME, i); | ||
700 | 673 | ||
701 | clk = devm_clk_get(dev, name); | 674 | clk = devm_clk_get(dev, name); |
702 | if (IS_ERR(clk)) { | ||
703 | snprintf(name, RSND_SRC_NAME_SIZE, "scu.%d", i); | ||
704 | clk = devm_clk_get(dev, name); | ||
705 | } | ||
706 | |||
707 | if (IS_ERR(clk)) | 675 | if (IS_ERR(clk)) |
708 | return PTR_ERR(clk); | 676 | return PTR_ERR(clk); |
709 | 677 | ||
710 | src->info = &info->src_info[i]; | 678 | src->info = &info->src_info[i]; |
711 | src->clk = clk; | 679 | src->clk = clk; |
712 | 680 | ||
713 | ops = &rsnd_src_non_ops; | ||
714 | if (rsnd_src_hpbif_is_enable(src)) { | ||
715 | if (rsnd_is_gen1(priv)) | ||
716 | ops = &rsnd_src_gen1_ops; | ||
717 | if (rsnd_is_gen2(priv)) | ||
718 | ops = &rsnd_src_gen2_ops; | ||
719 | } | ||
720 | |||
721 | rsnd_mod_init(priv, &src->mod, ops, RSND_MOD_SRC, i); | 681 | rsnd_mod_init(priv, &src->mod, ops, RSND_MOD_SRC, i); |
722 | 682 | ||
723 | dev_dbg(dev, "SRC%d probed\n", i); | 683 | dev_dbg(dev, "SRC%d probed\n", i); |