ASoC: rsnd: add rsnd_path_parse() macro
[deliverable/linux.git] / sound / soc / sh / rcar / src.c
CommitLineData
07539c1d 1/*
ba9c949f 2 * Renesas R-Car SRC support
07539c1d
KM
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
ba9c949f
KM
13struct rsnd_src {
14 struct rsnd_src_platform_info *info; /* rcar_snd.h */
07539c1d 15 struct rsnd_mod mod;
ef749400 16 struct clk *clk;
07539c1d
KM
17};
18
ba9c949f 19#define RSND_SRC_NAME_SIZE 16
374a5281
KM
20
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
ba9c949f
KM
30#define rsnd_src_convert_rate(p) ((p)->info->convert_rate)
31#define rsnd_mod_to_src(_mod) \
32 container_of((_mod), struct rsnd_src, mod)
ba9c949f
KM
33#define rsnd_src_dma_available(src) \
34 rsnd_dma_available(rsnd_mod_to_dma(&(src)->mod))
39cf3c40 35
ba9c949f 36#define for_each_rsnd_src(pos, priv, i) \
39cf3c40 37 for ((i) = 0; \
ba9c949f
KM
38 ((i) < rsnd_src_nr(priv)) && \
39 ((pos) = (struct rsnd_src *)(priv)->src + i); \
39cf3c40
KM
40 i++)
41
42
ef749400
KM
43/*
44 * image of SRC (Sampling Rate Converter)
45 *
46 * 96kHz <-> +-----+ 48kHz +-----+ 48kHz +-------+
47 * 48kHz <-> | SRC | <------> | SSI | <-----> | codec |
48 * 44.1kHz <-> +-----+ +-----+ +-------+
49 * ...
50 *
51 */
374a5281 52
c926b746 53/*
ba9c949f 54 * src.c is caring...
c926b746
KM
55 *
56 * Gen1
57 *
58 * [mem] -> [SRU] -> [SSI]
59 * |--------|
60 *
61 * Gen2
62 *
ba9c949f 63 * [mem] -> [SRC] -> [SSIU] -> [SSI]
c926b746
KM
64 * |-----------------|
65 */
66
41c6221c
KM
67/*
68 * How to use SRC bypass mode for debugging
69 *
70 * SRC has bypass mode, and it is useful for debugging.
71 * In Gen2 case,
72 * SRCm_MODE controls whether SRC is used or not
73 * SSI_MODE0 controls whether SSIU which receives SRC data
74 * is used or not.
75 * Both SRCm_MODE/SSI_MODE0 settings are needed if you use SRC,
76 * but SRC bypass mode needs SSI_MODE0 only.
77 *
78 * This driver request
ba9c949f 79 * struct rsnd_src_platform_info {
41c6221c 80 * u32 convert_rate;
29e69fd2 81 * int dma_id;
41c6221c
KM
82 * }
83 *
ba9c949f 84 * rsnd_src_convert_rate() indicates
41c6221c
KM
85 * above convert_rate, and it controls
86 * whether SRC is used or not.
87 *
88 * ex) doesn't use SRC
29e69fd2
KM
89 * static struct rsnd_dai_platform_info rsnd_dai = {
90 * .playback = { .ssi = &rsnd_ssi[0], },
41c6221c
KM
91 * };
92 *
93 * ex) uses SRC
29e69fd2
KM
94 * static struct rsnd_src_platform_info rsnd_src[] = {
95 * RSND_SCU(48000, 0),
96 * ...
97 * };
98 * static struct rsnd_dai_platform_info rsnd_dai = {
99 * .playback = { .ssi = &rsnd_ssi[0], .src = &rsnd_src[0] },
41c6221c
KM
100 * };
101 *
102 * ex) uses SRC bypass mode
29e69fd2
KM
103 * static struct rsnd_src_platform_info rsnd_src[] = {
104 * RSND_SCU(0, 0),
105 * ...
106 * };
107 * static struct rsnd_dai_platform_info rsnd_dai = {
108 * .playback = { .ssi = &rsnd_ssi[0], .src = &rsnd_src[0] },
41c6221c
KM
109 * };
110 *
111 */
112
1b7b08ef
KM
113/*
114 * Gen1/Gen2 common functions
115 */
ba9c949f 116int rsnd_src_ssi_mode_init(struct rsnd_mod *ssi_mod,
221bf523
KM
117 struct rsnd_dai *rdai,
118 struct rsnd_dai_stream *io)
7b5ce975 119{
ba9c949f 120 struct rsnd_mod *src_mod = rsnd_io_to_mod_src(io);
374e5426 121 int ssi_id = rsnd_mod_id(ssi_mod);
7b5ce975
KM
122
123 /*
124 * SSI_MODE0
125 */
221bf523 126 rsnd_mod_bset(ssi_mod, SSI_MODE0, (1 << ssi_id),
29e69fd2 127 src_mod ? 0 : (1 << ssi_id));
7b5ce975
KM
128
129 /*
130 * SSI_MODE1
131 */
374e5426 132 if (rsnd_ssi_is_pin_sharing(ssi_mod)) {
7b5ce975 133 int shift = -1;
374e5426 134 switch (ssi_id) {
7b5ce975
KM
135 case 1:
136 shift = 0;
137 break;
138 case 2:
139 shift = 2;
140 break;
141 case 4:
142 shift = 16;
143 break;
144 }
145
146 if (shift >= 0)
221bf523 147 rsnd_mod_bset(ssi_mod, SSI_MODE1,
7b5ce975
KM
148 0x3 << shift,
149 rsnd_dai_is_clk_master(rdai) ?
150 0x2 << shift : 0x1 << shift);
151 }
152
153 return 0;
154}
155
ba9c949f 156int rsnd_src_enable_ssi_irq(struct rsnd_mod *ssi_mod,
b8cc41e9
KM
157 struct rsnd_dai *rdai,
158 struct rsnd_dai_stream *io)
159{
160 struct rsnd_priv *priv = rsnd_mod_to_priv(ssi_mod);
161
162 /* enable PIO interrupt if Gen2 */
163 if (rsnd_is_gen2(priv))
164 rsnd_mod_write(ssi_mod, INT_ENABLE, 0x0f000000);
165
166 return 0;
167}
168
ba9c949f 169unsigned int rsnd_src_get_ssi_rate(struct rsnd_priv *priv,
374e5426 170 struct rsnd_dai_stream *io,
1b7b08ef
KM
171 struct snd_pcm_runtime *runtime)
172{
b1eac430 173 struct rsnd_mod *src_mod = rsnd_io_to_mod_src(io);
ba9c949f 174 struct rsnd_src *src;
b1eac430 175 unsigned int rate = 0;
1b7b08ef 176
b1eac430
KM
177 if (src_mod) {
178 src = rsnd_mod_to_src(src_mod);
179
180 /*
181 * return convert rate if SRC is used,
182 * otherwise, return runtime->rate as usual
183 */
184 rate = rsnd_src_convert_rate(src);
185 }
1b7b08ef 186
1b7b08ef
KM
187 if (!rate)
188 rate = runtime->rate;
189
190 return rate;
191}
192
ba9c949f 193static int rsnd_src_set_convert_rate(struct rsnd_mod *mod,
1b7b08ef
KM
194 struct rsnd_dai *rdai,
195 struct rsnd_dai_stream *io)
196{
197 struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io);
ba9c949f
KM
198 struct rsnd_src *src = rsnd_mod_to_src(mod);
199 u32 convert_rate = rsnd_src_convert_rate(src);
1b7b08ef
KM
200 u32 adinr = runtime->channels;
201 u32 fsrate = 0;
202
203 if (convert_rate)
204 fsrate = 0x0400000 / convert_rate * runtime->rate;
205
206 /* set/clear soft reset */
207 rsnd_mod_write(mod, SRC_SWRSR, 0);
208 rsnd_mod_write(mod, SRC_SWRSR, 1);
209
210 /*
211 * Initialize the operation of the SRC internal circuits
ba9c949f 212 * see rsnd_src_start()
1b7b08ef
KM
213 */
214 rsnd_mod_write(mod, SRC_SRCIR, 1);
215
216 /* Set channel number and output bit length */
217 switch (runtime->sample_bits) {
218 case 16:
219 adinr |= OTBL_16;
220 break;
221 case 32:
222 adinr |= OTBL_24;
223 break;
224 default:
225 return -EIO;
226 }
227 rsnd_mod_write(mod, SRC_ADINR, adinr);
228
229 /* Enable the initial value of IFS */
230 if (fsrate) {
231 rsnd_mod_write(mod, SRC_IFSCR, 1);
232
233 /* Set initial value of IFS */
234 rsnd_mod_write(mod, SRC_IFSVR, fsrate);
235 }
236
237 /* use DMA transfer */
238 rsnd_mod_write(mod, SRC_BUSIF_MODE, 1);
239
240 return 0;
241}
242
ba9c949f 243static int rsnd_src_init(struct rsnd_mod *mod,
1b7b08ef
KM
244 struct rsnd_dai *rdai,
245 struct rsnd_dai_stream *io)
246{
ba9c949f 247 struct rsnd_src *src = rsnd_mod_to_src(mod);
1b7b08ef 248
ba9c949f 249 clk_enable(src->clk);
1b7b08ef 250
1b7b08ef
KM
251 return 0;
252}
253
ba9c949f 254static int rsnd_src_quit(struct rsnd_mod *mod,
1b7b08ef
KM
255 struct rsnd_dai *rdai,
256 struct rsnd_dai_stream *io)
257{
ba9c949f 258 struct rsnd_src *src = rsnd_mod_to_src(mod);
1b7b08ef 259
ba9c949f 260 clk_disable(src->clk);
1b7b08ef
KM
261
262 return 0;
263}
264
ba9c949f 265static int rsnd_src_start(struct rsnd_mod *mod,
1b7b08ef
KM
266 struct rsnd_dai *rdai,
267 struct rsnd_dai_stream *io)
268{
ba9c949f 269 struct rsnd_src *src = rsnd_mod_to_src(mod);
1b7b08ef
KM
270
271 /*
272 * Cancel the initialization and operate the SRC function
ba9c949f 273 * see rsnd_src_set_convert_rate()
1b7b08ef
KM
274 */
275 rsnd_mod_write(mod, SRC_SRCIR, 0);
276
ba9c949f 277 if (rsnd_src_convert_rate(src))
1b7b08ef
KM
278 rsnd_mod_write(mod, SRC_ROUTE_MODE0, 1);
279
280 return 0;
281}
282
283
ba9c949f 284static int rsnd_src_stop(struct rsnd_mod *mod,
1b7b08ef
KM
285 struct rsnd_dai *rdai,
286 struct rsnd_dai_stream *io)
287{
ba9c949f 288 struct rsnd_src *src = rsnd_mod_to_src(mod);
1b7b08ef 289
ba9c949f 290 if (rsnd_src_convert_rate(src))
1b7b08ef
KM
291 rsnd_mod_write(mod, SRC_ROUTE_MODE0, 0);
292
293 return 0;
294}
295
ba9c949f
KM
296static struct rsnd_mod_ops rsnd_src_non_ops = {
297 .name = "src (non)",
1b7b08ef
KM
298};
299
300/*
301 * Gen1 functions
302 */
303static int rsnd_src_set_route_gen1(struct rsnd_mod *mod,
304 struct rsnd_dai *rdai,
305 struct rsnd_dai_stream *io)
374a5281 306{
ba9c949f 307 struct src_route_config {
374a5281
KM
308 u32 mask;
309 int shift;
310 } routes[] = {
311 { 0xF, 0, }, /* 0 */
312 { 0xF, 4, }, /* 1 */
313 { 0xF, 8, }, /* 2 */
314 { 0x7, 12, }, /* 3 */
315 { 0x7, 16, }, /* 4 */
316 { 0x7, 20, }, /* 5 */
317 { 0x7, 24, }, /* 6 */
318 { 0x3, 28, }, /* 7 */
319 { 0x3, 30, }, /* 8 */
320 };
374a5281
KM
321 u32 mask;
322 u32 val;
374a5281
KM
323 int id;
324
374a5281 325 id = rsnd_mod_id(mod);
b5f3d7af 326 if (id < 0 || id >= ARRAY_SIZE(routes))
374a5281
KM
327 return -EIO;
328
329 /*
330 * SRC_ROUTE_SELECT
331 */
332 val = rsnd_dai_is_play(rdai, io) ? 0x1 : 0x2;
333 val = val << routes[id].shift;
334 mask = routes[id].mask << routes[id].shift;
335
336 rsnd_mod_bset(mod, SRC_ROUTE_SEL, mask, val);
337
28dc4b63
KM
338 return 0;
339}
340
ba9c949f 341static int rsnd_src_set_convert_timing_gen1(struct rsnd_mod *mod,
28dc4b63
KM
342 struct rsnd_dai *rdai,
343 struct rsnd_dai_stream *io)
344{
345 struct rsnd_priv *priv = rsnd_mod_to_priv(mod);
ba9c949f 346 struct rsnd_src *src = rsnd_mod_to_src(mod);
28dc4b63 347 struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io);
ba9c949f 348 u32 convert_rate = rsnd_src_convert_rate(src);
28dc4b63
KM
349 u32 mask;
350 u32 val;
351 int shift;
352 int id = rsnd_mod_id(mod);
353 int ret;
354
374a5281
KM
355 /*
356 * SRC_TIMING_SELECT
357 */
358 shift = (id % 4) * 8;
359 mask = 0x1F << shift;
ef749400
KM
360
361 /*
362 * ADG is used as source clock if SRC was used,
363 * then, SSI WS is used as destination clock.
364 * SSI WS is used as source clock if SRC is not used
365 * (when playback, source/destination become reverse when capture)
366 */
28dc4b63
KM
367 ret = 0;
368 if (convert_rate) {
369 /* use ADG */
ef749400 370 val = 0;
28dc4b63
KM
371 ret = rsnd_adg_set_convert_clk_gen1(priv, mod,
372 runtime->rate,
373 convert_rate);
374 } else if (8 == id) {
375 /* use SSI WS, but SRU8 is special */
374a5281 376 val = id << shift;
28dc4b63
KM
377 } else {
378 /* use SSI WS */
374a5281 379 val = (id + 1) << shift;
28dc4b63
KM
380 }
381
382 if (ret < 0)
383 return ret;
374a5281
KM
384
385 switch (id / 4) {
386 case 0:
387 rsnd_mod_bset(mod, SRC_TMG_SEL0, mask, val);
388 break;
389 case 1:
390 rsnd_mod_bset(mod, SRC_TMG_SEL1, mask, val);
391 break;
392 case 2:
393 rsnd_mod_bset(mod, SRC_TMG_SEL2, mask, val);
394 break;
395 }
396
397 return 0;
398}
399
ba9c949f 400static int rsnd_src_set_convert_rate_gen1(struct rsnd_mod *mod,
1b7b08ef
KM
401 struct rsnd_dai *rdai,
402 struct rsnd_dai_stream *io)
374a5281 403{
1b7b08ef 404 int ret;
ef749400 405
ba9c949f 406 ret = rsnd_src_set_convert_rate(mod, rdai, io);
1b7b08ef
KM
407 if (ret < 0)
408 return ret;
ef749400 409
1b7b08ef
KM
410 /* Select SRC mode (fixed value) */
411 rsnd_mod_write(mod, SRC_SRCCR, 0x00010110);
ef749400 412
1b7b08ef
KM
413 /* Set the restriction value of the FS ratio (98%) */
414 rsnd_mod_write(mod, SRC_MNFSR,
415 rsnd_mod_read(mod, SRC_IFSVR) / 100 * 98);
ef749400 416
1b7b08ef 417 /* no SRC_BFSSR settings, since SRC_SRCCR::BUFMD is 0 */
ef749400 418
374a5281
KM
419 return 0;
420}
421
ba9c949f 422static int rsnd_src_init_gen1(struct rsnd_mod *mod,
1b7b08ef
KM
423 struct rsnd_dai *rdai,
424 struct rsnd_dai_stream *io)
07539c1d 425{
374a5281
KM
426 int ret;
427
ba9c949f 428 ret = rsnd_src_init(mod, rdai, io);
7b5ce975
KM
429 if (ret < 0)
430 return ret;
431
1b7b08ef 432 ret = rsnd_src_set_route_gen1(mod, rdai, io);
374a5281
KM
433 if (ret < 0)
434 return ret;
435
ba9c949f 436 ret = rsnd_src_set_convert_rate_gen1(mod, rdai, io);
374a5281
KM
437 if (ret < 0)
438 return ret;
07539c1d 439
ba9c949f 440 ret = rsnd_src_set_convert_timing_gen1(mod, rdai, io);
28dc4b63
KM
441 if (ret < 0)
442 return ret;
443
a204d90c
KM
444 return 0;
445}
446
ba9c949f 447static int rsnd_src_start_gen1(struct rsnd_mod *mod,
1b7b08ef
KM
448 struct rsnd_dai *rdai,
449 struct rsnd_dai_stream *io)
a204d90c 450{
1b7b08ef 451 int id = rsnd_mod_id(mod);
a204d90c 452
1b7b08ef 453 rsnd_mod_bset(mod, SRC_ROUTE_CTRL, (1 << id), (1 << id));
374a5281 454
ba9c949f 455 return rsnd_src_start(mod, rdai, io);
07539c1d
KM
456}
457
ba9c949f 458static int rsnd_src_stop_gen1(struct rsnd_mod *mod,
1b7b08ef
KM
459 struct rsnd_dai *rdai,
460 struct rsnd_dai_stream *io)
a204d90c 461{
e7ce74ea 462 int id = rsnd_mod_id(mod);
a204d90c 463
1b7b08ef 464 rsnd_mod_bset(mod, SRC_ROUTE_CTRL, (1 << id), 0);
e7ce74ea 465
ba9c949f 466 return rsnd_src_stop(mod, rdai, io);
a204d90c
KM
467}
468
ba9c949f 469static struct rsnd_mod_ops rsnd_src_gen1_ops = {
1b7b08ef 470 .name = "sru (gen1)",
ba9c949f
KM
471 .init = rsnd_src_init_gen1,
472 .quit = rsnd_src_quit,
473 .start = rsnd_src_start_gen1,
474 .stop = rsnd_src_stop_gen1,
1b7b08ef 475};
e7ce74ea 476
1b7b08ef
KM
477/*
478 * Gen2 functions
479 */
ba9c949f 480static int rsnd_src_set_convert_rate_gen2(struct rsnd_mod *mod,
629509c5
KM
481 struct rsnd_dai *rdai,
482 struct rsnd_dai_stream *io)
483{
484 int ret;
485
ba9c949f 486 ret = rsnd_src_set_convert_rate(mod, rdai, io);
629509c5
KM
487 if (ret < 0)
488 return ret;
489
490 rsnd_mod_write(mod, SSI_BUSIF_ADINR, rsnd_mod_read(mod, SRC_ADINR));
491 rsnd_mod_write(mod, SSI_BUSIF_MODE, rsnd_mod_read(mod, SRC_BUSIF_MODE));
492
493 rsnd_mod_write(mod, SRC_SRCCR, 0x00011110);
494
495 rsnd_mod_write(mod, SRC_BSDSR, 0x01800000);
496 rsnd_mod_write(mod, SRC_BSISR, 0x00100060);
497
498 return 0;
499}
500
ba9c949f 501static int rsnd_src_set_convert_timing_gen2(struct rsnd_mod *mod,
629509c5
KM
502 struct rsnd_dai *rdai,
503 struct rsnd_dai_stream *io)
504{
505 struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io);
ba9c949f
KM
506 struct rsnd_src *src = rsnd_mod_to_src(mod);
507 u32 convert_rate = rsnd_src_convert_rate(src);
629509c5
KM
508 int ret;
509
510 if (convert_rate)
511 ret = rsnd_adg_set_convert_clk_gen2(mod, rdai, io,
512 runtime->rate,
513 convert_rate);
514 else
515 ret = rsnd_adg_set_convert_timing_gen2(mod, rdai, io);
516
517 return ret;
518}
519
ba9c949f 520static int rsnd_src_probe_gen2(struct rsnd_mod *mod,
76c6fb5c
KM
521 struct rsnd_dai *rdai,
522 struct rsnd_dai_stream *io)
523{
524 struct rsnd_priv *priv = rsnd_mod_to_priv(mod);
ba9c949f 525 struct rsnd_src *src = rsnd_mod_to_src(mod);
76c6fb5c
KM
526 struct device *dev = rsnd_priv_to_dev(priv);
527 int ret;
76c6fb5c
KM
528
529 ret = rsnd_dma_init(priv,
530 rsnd_mod_to_dma(mod),
29e69fd2 531 rsnd_info_is_playback(priv, src),
ba9c949f 532 src->info->dma_id);
76c6fb5c 533 if (ret < 0)
ba9c949f 534 dev_err(dev, "SRC DMA failed\n");
76c6fb5c
KM
535
536 return ret;
537}
538
ba9c949f 539static int rsnd_src_remove_gen2(struct rsnd_mod *mod,
76c6fb5c
KM
540 struct rsnd_dai *rdai,
541 struct rsnd_dai_stream *io)
542{
543 rsnd_dma_quit(rsnd_mod_to_priv(mod), rsnd_mod_to_dma(mod));
544
545 return 0;
546}
547
ba9c949f 548static int rsnd_src_init_gen2(struct rsnd_mod *mod,
629509c5
KM
549 struct rsnd_dai *rdai,
550 struct rsnd_dai_stream *io)
551{
552 int ret;
553
ba9c949f 554 ret = rsnd_src_init(mod, rdai, io);
629509c5
KM
555 if (ret < 0)
556 return ret;
557
ba9c949f 558 ret = rsnd_src_set_convert_rate_gen2(mod, rdai, io);
629509c5
KM
559 if (ret < 0)
560 return ret;
561
ba9c949f 562 ret = rsnd_src_set_convert_timing_gen2(mod, rdai, io);
629509c5
KM
563 if (ret < 0)
564 return ret;
565
566 return 0;
567}
568
ba9c949f 569static int rsnd_src_start_gen2(struct rsnd_mod *mod,
629509c5
KM
570 struct rsnd_dai *rdai,
571 struct rsnd_dai_stream *io)
572{
ba9c949f 573 struct rsnd_src *src = rsnd_mod_to_src(mod);
629509c5 574
ba9c949f 575 rsnd_dma_start(rsnd_mod_to_dma(&src->mod));
629509c5
KM
576
577 rsnd_mod_write(mod, SSI_CTRL, 0x1);
578 rsnd_mod_write(mod, SRC_CTRL, 0x11);
579
ba9c949f 580 return rsnd_src_start(mod, rdai, io);
629509c5
KM
581}
582
ba9c949f 583static int rsnd_src_stop_gen2(struct rsnd_mod *mod,
629509c5
KM
584 struct rsnd_dai *rdai,
585 struct rsnd_dai_stream *io)
586{
ba9c949f 587 struct rsnd_src *src = rsnd_mod_to_src(mod);
629509c5
KM
588
589 rsnd_mod_write(mod, SSI_CTRL, 0);
590 rsnd_mod_write(mod, SRC_CTRL, 0);
591
ba9c949f 592 rsnd_dma_stop(rsnd_mod_to_dma(&src->mod));
629509c5 593
ba9c949f 594 return rsnd_src_stop(mod, rdai, io);
629509c5
KM
595}
596
ba9c949f
KM
597static struct rsnd_mod_ops rsnd_src_gen2_ops = {
598 .name = "src (gen2)",
599 .probe = rsnd_src_probe_gen2,
600 .remove = rsnd_src_remove_gen2,
601 .init = rsnd_src_init_gen2,
602 .quit = rsnd_src_quit,
603 .start = rsnd_src_start_gen2,
604 .stop = rsnd_src_stop_gen2,
629509c5
KM
605};
606
ba9c949f 607struct rsnd_mod *rsnd_src_mod_get(struct rsnd_priv *priv, int id)
07539c1d 608{
ba9c949f 609 if (WARN_ON(id < 0 || id >= rsnd_src_nr(priv)))
8b14719b 610 id = 0;
07539c1d 611
ba9c949f 612 return &((struct rsnd_src *)(priv->src) + id)->mod;
07539c1d
KM
613}
614
90e8e50f
KM
615static void rsnd_of_parse_src(struct platform_device *pdev,
616 const struct rsnd_of_data *of_data,
617 struct rsnd_priv *priv)
618{
619 struct device_node *src_node;
620 struct rcar_snd_info *info = rsnd_priv_to_info(priv);
621 struct rsnd_src_platform_info *src_info;
622 struct device *dev = &pdev->dev;
623 int nr;
624
625 if (!of_data)
626 return;
627
628 src_node = of_get_child_by_name(dev->of_node, "rcar_sound,src");
629 if (!src_node)
630 return;
631
632 nr = of_get_child_count(src_node);
633 if (!nr)
634 return;
635
636 src_info = devm_kzalloc(dev,
637 sizeof(struct rsnd_src_platform_info) * nr,
638 GFP_KERNEL);
639 if (!src_info) {
640 dev_err(dev, "src info allocation error\n");
641 return;
642 }
643
644 info->src_info = src_info;
645 info->src_info_nr = nr;
646}
647
ba9c949f 648int rsnd_src_probe(struct platform_device *pdev,
90e8e50f 649 const struct rsnd_of_data *of_data,
07539c1d
KM
650 struct rsnd_priv *priv)
651{
5da39cf3 652 struct rcar_snd_info *info = rsnd_priv_to_info(priv);
07539c1d 653 struct device *dev = rsnd_priv_to_dev(priv);
ba9c949f 654 struct rsnd_src *src;
013f38fe 655 struct rsnd_mod_ops *ops;
ef749400 656 struct clk *clk;
ba9c949f 657 char name[RSND_SRC_NAME_SIZE];
07539c1d
KM
658 int i, nr;
659
90e8e50f
KM
660 rsnd_of_parse_src(pdev, of_data, priv);
661
07539c1d 662 /*
ba9c949f 663 * init SRC
07539c1d 664 */
ba9c949f 665 nr = info->src_info_nr;
389933d9
KM
666 if (!nr)
667 return 0;
668
ba9c949f
KM
669 src = devm_kzalloc(dev, sizeof(*src) * nr, GFP_KERNEL);
670 if (!src) {
671 dev_err(dev, "SRC allocate failed\n");
07539c1d
KM
672 return -ENOMEM;
673 }
674
ba9c949f
KM
675 priv->src_nr = nr;
676 priv->src = src;
07539c1d 677
ba9c949f
KM
678 for_each_rsnd_src(src, priv, i) {
679 snprintf(name, RSND_SRC_NAME_SIZE, "src.%d", i);
ef749400
KM
680
681 clk = devm_clk_get(dev, name);
682 if (IS_ERR(clk))
683 return PTR_ERR(clk);
684
ba9c949f
KM
685 src->info = &info->src_info[i];
686 src->clk = clk;
07539c1d 687
ba9c949f 688 ops = &rsnd_src_non_ops;
29e69fd2
KM
689 if (rsnd_is_gen1(priv))
690 ops = &rsnd_src_gen1_ops;
691 if (rsnd_is_gen2(priv))
692 ops = &rsnd_src_gen2_ops;
013f38fe 693
ba9c949f 694 rsnd_mod_init(priv, &src->mod, ops, RSND_MOD_SRC, i);
013f38fe 695
ba9c949f 696 dev_dbg(dev, "SRC%d probed\n", i);
374a5281 697 }
07539c1d
KM
698
699 return 0;
700}
This page took 0.278882 seconds and 5 git commands to generate.