Merge tag 'mailbox-v6.12' of git://git.kernel.org/pub/scm/linux/kernel/git/jassibrar...
[linux-2.6-block.git] / sound / soc / sh / rcar / src.c
CommitLineData
1e0edd4d
KM
1// SPDX-License-Identifier: GPL-2.0
2//
3// Renesas R-Car SRC support
4//
5// Copyright (C) 2013 Renesas Solutions Corp.
6// Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
2b627869 7
63346d3d
KM
8/*
9 * You can use Synchronous Sampling Rate Convert (if no DVC)
10 *
11 * amixer set "SRC Out Rate" on
12 * aplay xxx.wav &
13 * amixer set "SRC Out Rate" 96000 // convert rate to 96000Hz
14 * amixer set "SRC Out Rate" 22050 // convert rate to 22050Hz
15 */
16
2b627869
KM
17/*
18 * you can enable below define if you don't need
19 * SSI interrupt status debug message when debugging
1788a152 20 * see rsnd_print_irq_status()
2b627869
KM
21 *
22 * #define RSND_DEBUG_NO_IRQ_STATUS 1
23 */
24
340d79a1 25#include <linux/of_irq.h>
07539c1d
KM
26#include "rsnd.h"
27
8aefda50
KM
28#define SRC_NAME "src"
29
cfcefe01
KM
30/* SCU_SYSTEM_STATUS0/1 */
31#define OUF_SRC(id) ((1 << (id + 16)) | (1 << id))
32
ba9c949f 33struct rsnd_src {
07539c1d 34 struct rsnd_mod mod;
940e9479 35 struct rsnd_mod *dma;
43cb6954
KM
36 struct rsnd_kctrl_cfg_s sen; /* sync convert enable */
37 struct rsnd_kctrl_cfg_s sync; /* sync convert */
adf6a681 38 int irq;
07539c1d
KM
39};
40
ba9c949f 41#define RSND_SRC_NAME_SIZE 16
374a5281 42
adf6a681 43#define rsnd_src_get(priv, id) ((struct rsnd_src *)(priv->src) + id)
da599fd3 44#define rsnd_src_nr(priv) ((priv)->src_nr)
ab2049f9 45#define rsnd_src_sync_is_enabled(mod) (rsnd_mod_to_src(mod)->sen.val)
82e76ed3 46
ba9c949f
KM
47#define rsnd_mod_to_src(_mod) \
48 container_of((_mod), struct rsnd_src, mod)
39cf3c40 49
ba9c949f 50#define for_each_rsnd_src(pos, priv, i) \
39cf3c40 51 for ((i) = 0; \
ba9c949f
KM
52 ((i) < rsnd_src_nr(priv)) && \
53 ((pos) = (struct rsnd_src *)(priv)->src + i); \
39cf3c40
KM
54 i++)
55
56
ef749400
KM
57/*
58 * image of SRC (Sampling Rate Converter)
59 *
60 * 96kHz <-> +-----+ 48kHz +-----+ 48kHz +-------+
61 * 48kHz <-> | SRC | <------> | SSI | <-----> | codec |
62 * 44.1kHz <-> +-----+ +-----+ +-------+
63 * ...
64 *
65 */
374a5281 66
98efeeae 67static void rsnd_src_activation(struct rsnd_mod *mod)
379febfd
KM
68{
69 rsnd_mod_write(mod, SRC_SWRSR, 0);
70 rsnd_mod_write(mod, SRC_SWRSR, 1);
71}
72
475a361a
KM
73static void rsnd_src_halt(struct rsnd_mod *mod)
74{
75 rsnd_mod_write(mod, SRC_SRCIR, 1);
76 rsnd_mod_write(mod, SRC_SWRSR, 0);
77}
78
9b99e9a7
KM
79static struct dma_chan *rsnd_src_dma_req(struct rsnd_dai_stream *io,
80 struct rsnd_mod *mod)
72adc61f
KM
81{
82 struct rsnd_priv *priv = rsnd_mod_to_priv(mod);
72adc61f
KM
83 int is_play = rsnd_io_is_play(io);
84
85 return rsnd_dma_request_channel(rsnd_src_of_node(priv),
039f2ccc 86 SRC_NAME, mod,
72adc61f
KM
87 is_play ? "rx" : "tx");
88}
89
88c61cff 90static u32 rsnd_src_convert_rate(struct rsnd_dai_stream *io,
1a9be9ee 91 struct rsnd_mod *mod)
43cb6954 92{
43cb6954 93 struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io);
1a9be9ee 94 struct rsnd_src *src = rsnd_mod_to_src(mod);
43cb6954
KM
95 u32 convert_rate;
96
97 if (!runtime)
98 return 0;
99
ab2049f9 100 if (!rsnd_src_sync_is_enabled(mod))
c2aaaa57 101 return rsnd_io_converted_rate(io);
43cb6954
KM
102
103 convert_rate = src->sync.val;
104
105 if (!convert_rate)
c2aaaa57 106 convert_rate = rsnd_io_converted_rate(io);
43cb6954
KM
107
108 if (!convert_rate)
109 convert_rate = runtime->rate;
110
111 return convert_rate;
112}
113
cbf1494f
KM
114unsigned int rsnd_src_get_rate(struct rsnd_priv *priv,
115 struct rsnd_dai_stream *io,
116 int is_in)
1b7b08ef 117{
b1eac430 118 struct rsnd_mod *src_mod = rsnd_io_to_mod_src(io);
cbf1494f 119 struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io);
b1eac430 120 unsigned int rate = 0;
cbf1494f
KM
121 int is_play = rsnd_io_is_play(io);
122
123 /*
cbf1494f
KM
124 * Playback
125 * runtime_rate -> [SRC] -> convert_rate
126 *
127 * Capture
128 * convert_rate -> [SRC] -> runtime_rate
129 */
130
131 if (is_play == is_in)
132 return runtime->rate;
1b7b08ef 133
1a9be9ee
KM
134 /*
135 * return convert rate if SRC is used,
136 * otherwise, return runtime->rate as usual
137 */
138 if (src_mod)
139 rate = rsnd_src_convert_rate(io, src_mod);
1b7b08ef 140
1b7b08ef
KM
141 if (!rate)
142 rate = runtime->rate;
143
144 return rate;
145}
146
399706df 147static const u32 bsdsr_table_pattern1[] = {
7674bec4
KM
148 0x01800000, /* 6 - 1/6 */
149 0x01000000, /* 6 - 1/4 */
150 0x00c00000, /* 6 - 1/3 */
151 0x00800000, /* 6 - 1/2 */
152 0x00600000, /* 6 - 2/3 */
153 0x00400000, /* 6 - 1 */
154};
155
399706df 156static const u32 bsdsr_table_pattern2[] = {
7674bec4
KM
157 0x02400000, /* 6 - 1/6 */
158 0x01800000, /* 6 - 1/4 */
159 0x01200000, /* 6 - 1/3 */
160 0x00c00000, /* 6 - 1/2 */
161 0x00900000, /* 6 - 2/3 */
162 0x00600000, /* 6 - 1 */
163};
164
399706df 165static const u32 bsisr_table[] = {
7674bec4
KM
166 0x00100060, /* 6 - 1/6 */
167 0x00100040, /* 6 - 1/4 */
168 0x00100030, /* 6 - 1/3 */
169 0x00100020, /* 6 - 1/2 */
170 0x00100020, /* 6 - 2/3 */
171 0x00100020, /* 6 - 1 */
172};
173
399706df 174static const u32 chan288888[] = {
7674bec4
KM
175 0x00000006, /* 1 to 2 */
176 0x000001fe, /* 1 to 8 */
177 0x000001fe, /* 1 to 8 */
178 0x000001fe, /* 1 to 8 */
179 0x000001fe, /* 1 to 8 */
180 0x000001fe, /* 1 to 8 */
181};
182
399706df 183static const u32 chan244888[] = {
7674bec4
KM
184 0x00000006, /* 1 to 2 */
185 0x0000001e, /* 1 to 4 */
186 0x0000001e, /* 1 to 4 */
187 0x000001fe, /* 1 to 8 */
188 0x000001fe, /* 1 to 8 */
189 0x000001fe, /* 1 to 8 */
190};
191
399706df 192static const u32 chan222222[] = {
7674bec4
KM
193 0x00000006, /* 1 to 2 */
194 0x00000006, /* 1 to 2 */
195 0x00000006, /* 1 to 2 */
196 0x00000006, /* 1 to 2 */
197 0x00000006, /* 1 to 2 */
198 0x00000006, /* 1 to 2 */
199};
200
75916f65
KM
201static void rsnd_src_set_convert_rate(struct rsnd_dai_stream *io,
202 struct rsnd_mod *mod)
1b7b08ef 203{
75916f65
KM
204 struct rsnd_priv *priv = rsnd_mod_to_priv(mod);
205 struct device *dev = rsnd_priv_to_dev(priv);
206 struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io);
90431eb4 207 int is_play = rsnd_io_is_play(io);
67923f77 208 int use_src = 0;
0102eed5 209 u32 fin, fout;
75916f65
KM
210 u32 ifscr, fsrate, adinr;
211 u32 cr, route;
90431eb4 212 u32 i_busif, o_busif, tmp;
7674bec4
KM
213 const u32 *bsdsr_table;
214 const u32 *chptn;
75916f65 215 uint ratio;
7674bec4
KM
216 int chan;
217 int idx;
1b7b08ef 218
75916f65
KM
219 if (!runtime)
220 return;
43cb6954 221
0102eed5
KM
222 fin = rsnd_src_get_in_rate(priv, io);
223 fout = rsnd_src_get_out_rate(priv, io);
224
7674bec4
KM
225 chan = rsnd_runtime_channel_original(io);
226
75916f65 227 /* 6 - 1/6 are very enough ratio for SRC_BSDSR */
0102eed5 228 if (fin == fout)
75916f65 229 ratio = 0;
0102eed5
KM
230 else if (fin > fout)
231 ratio = 100 * fin / fout;
75916f65 232 else
0102eed5 233 ratio = 100 * fout / fin;
1b7b08ef 234
75916f65
KM
235 if (ratio > 600) {
236 dev_err(dev, "FSO/FSI ratio error\n");
237 return;
238 }
1b7b08ef 239
67923f77
KM
240 use_src = (fin != fout) | rsnd_src_sync_is_enabled(mod);
241
75916f65 242 /*
b65cb7a5 243 * SRC_ADINR
75916f65 244 */
7674bec4 245 adinr = rsnd_get_adinr_bit(mod, io) | chan;
1b7b08ef 246
75916f65 247 /*
b65cb7a5 248 * SRC_IFSCR / SRC_IFSVR
75916f65
KM
249 */
250 ifscr = 0;
251 fsrate = 0;
67923f77 252 if (use_src) {
93ca33c9
HY
253 u64 n;
254
75916f65 255 ifscr = 1;
93ca33c9
HY
256 n = (u64)0x0400000 * fin;
257 do_div(n, fout);
258 fsrate = n;
75916f65 259 }
cfcefe01 260
75916f65 261 /*
b65cb7a5 262 * SRC_SRCCR / SRC_ROUTE_MODE0
75916f65
KM
263 */
264 cr = 0x00011110;
265 route = 0x0;
67923f77 266 if (use_src) {
75916f65 267 route = 0x1;
3b7843ff 268
ab2049f9 269 if (rsnd_src_sync_is_enabled(mod)) {
75916f65
KM
270 cr |= 0x1;
271 route |= rsnd_io_is_play(io) ?
272 (0x1 << 24) : (0x1 << 25);
273 }
274 }
43cb6954 275
75916f65
KM
276 /*
277 * SRC_BSDSR / SRC_BSISR
7674bec4
KM
278 *
279 * see
280 * Combination of Register Setting Related to
281 * FSO/FSI Ratio and Channel, Latency
75916f65
KM
282 */
283 switch (rsnd_mod_id(mod)) {
7674bec4
KM
284 case 0:
285 chptn = chan288888;
286 bsdsr_table = bsdsr_table_pattern1;
287 break;
288 case 1:
289 case 3:
290 case 4:
291 chptn = chan244888;
292 bsdsr_table = bsdsr_table_pattern1;
293 break;
294 case 2:
295 case 9:
296 chptn = chan222222;
297 bsdsr_table = bsdsr_table_pattern1;
298 break;
75916f65
KM
299 case 5:
300 case 6:
301 case 7:
302 case 8:
7674bec4
KM
303 chptn = chan222222;
304 bsdsr_table = bsdsr_table_pattern2;
75916f65
KM
305 break;
306 default:
7674bec4 307 goto convert_rate_err;
75916f65 308 }
1b7b08ef 309
7674bec4
KM
310 /*
311 * E3 need to overwrite
312 */
0b8ef53e 313 if (rsnd_is_gen3_e3(priv))
7674bec4
KM
314 switch (rsnd_mod_id(mod)) {
315 case 0:
316 case 4:
317 chptn = chan222222;
318 }
319
320 for (idx = 0; idx < ARRAY_SIZE(chan222222); idx++)
321 if (chptn[idx] & (1 << chan))
322 break;
323
324 if (chan > 8 ||
325 idx >= ARRAY_SIZE(chan222222))
326 goto convert_rate_err;
327
90431eb4
KM
328 /* BUSIF_MODE */
329 tmp = rsnd_get_busif_shift(io, mod);
330 i_busif = ( is_play ? tmp : 0) | 1;
331 o_busif = (!is_play ? tmp : 0) | 1;
332
0fbab951
KM
333 rsnd_mod_write(mod, SRC_ROUTE_MODE0, route);
334
75916f65
KM
335 rsnd_mod_write(mod, SRC_SRCIR, 1); /* initialize */
336 rsnd_mod_write(mod, SRC_ADINR, adinr);
337 rsnd_mod_write(mod, SRC_IFSCR, ifscr);
338 rsnd_mod_write(mod, SRC_IFSVR, fsrate);
339 rsnd_mod_write(mod, SRC_SRCCR, cr);
7674bec4
KM
340 rsnd_mod_write(mod, SRC_BSDSR, bsdsr_table[idx]);
341 rsnd_mod_write(mod, SRC_BSISR, bsisr_table[idx]);
75916f65 342 rsnd_mod_write(mod, SRC_SRCIR, 0); /* cancel initialize */
1b7b08ef 343
90431eb4
KM
344 rsnd_mod_write(mod, SRC_I_BUSIF_MODE, i_busif);
345 rsnd_mod_write(mod, SRC_O_BUSIF_MODE, o_busif);
346
75916f65 347 rsnd_mod_write(mod, SRC_BUSIF_DALIGN, rsnd_get_dalign(mod, io));
1b7b08ef 348
0102eed5 349 rsnd_adg_set_src_timesel_gen2(mod, io, fin, fout);
7674bec4
KM
350
351 return;
352
353convert_rate_err:
354 dev_err(dev, "unknown BSDSR/BSDIR settings\n");
1b7b08ef
KM
355}
356
b5b442ab
KM
357static int rsnd_src_irq(struct rsnd_mod *mod,
358 struct rsnd_dai_stream *io,
359 struct rsnd_priv *priv,
360 int enable)
cfcefe01
KM
361{
362 struct rsnd_src *src = rsnd_mod_to_src(mod);
363 u32 sys_int_val, int_val, sys_int_mask;
adf6a681 364 int irq = src->irq;
cfcefe01
KM
365 int id = rsnd_mod_id(mod);
366
367 sys_int_val =
368 sys_int_mask = OUF_SRC(id);
369 int_val = 0x3300;
370
371 /*
372 * IRQ is not supported on non-DT
373 * see
75916f65 374 * rsnd_src_probe_()
cfcefe01
KM
375 */
376 if ((irq <= 0) || !enable) {
377 sys_int_val = 0;
378 int_val = 0;
379 }
380
1a1bf58a
KM
381 /*
382 * WORKAROUND
383 *
ab2049f9 384 * ignore over flow error when rsnd_src_sync_is_enabled()
1a1bf58a 385 */
ab2049f9 386 if (rsnd_src_sync_is_enabled(mod))
1a1bf58a
KM
387 sys_int_val = sys_int_val & 0xffff;
388
cfcefe01
KM
389 rsnd_mod_write(mod, SRC_INT_ENABLE0, int_val);
390 rsnd_mod_bset(mod, SCU_SYS_INT_EN0, sys_int_mask, sys_int_val);
391 rsnd_mod_bset(mod, SCU_SYS_INT_EN1, sys_int_mask, sys_int_val);
b5b442ab
KM
392
393 return 0;
cfcefe01
KM
394}
395
8cc225f7 396static void rsnd_src_status_clear(struct rsnd_mod *mod)
cfcefe01
KM
397{
398 u32 val = OUF_SRC(rsnd_mod_id(mod));
399
42b197e7
KM
400 rsnd_mod_write(mod, SCU_SYS_STATUS0, val);
401 rsnd_mod_write(mod, SCU_SYS_STATUS1, val);
cfcefe01
KM
402}
403
6a25c8da 404static bool rsnd_src_error_occurred(struct rsnd_mod *mod)
cfcefe01 405{
2b627869
KM
406 struct rsnd_priv *priv = rsnd_mod_to_priv(mod);
407 struct device *dev = rsnd_priv_to_dev(priv);
1a1bf58a 408 u32 val0, val1;
2b627869 409 u32 status0, status1;
cfcefe01
KM
410 bool ret = false;
411
1a1bf58a
KM
412 val0 = val1 = OUF_SRC(rsnd_mod_id(mod));
413
414 /*
415 * WORKAROUND
416 *
ab2049f9 417 * ignore over flow error when rsnd_src_sync_is_enabled()
1a1bf58a 418 */
ab2049f9 419 if (rsnd_src_sync_is_enabled(mod))
1a1bf58a
KM
420 val0 = val0 & 0xffff;
421
2b627869
KM
422 status0 = rsnd_mod_read(mod, SCU_SYS_STATUS0);
423 status1 = rsnd_mod_read(mod, SCU_SYS_STATUS1);
424 if ((status0 & val0) || (status1 & val1)) {
1788a152
KM
425 rsnd_print_irq_status(dev, "%s err status : 0x%08x, 0x%08x\n",
426 rsnd_mod_name(mod), status0, status1);
2b627869 427
cfcefe01 428 ret = true;
2b627869 429 }
cfcefe01 430
cfcefe01
KM
431 return ret;
432}
433
75916f65
KM
434static int rsnd_src_start(struct rsnd_mod *mod,
435 struct rsnd_dai_stream *io,
436 struct rsnd_priv *priv)
cfcefe01 437{
1a1bf58a
KM
438 u32 val;
439
440 /*
441 * WORKAROUND
442 *
443 * Enable SRC output if you want to use sync convert together with DVC
444 */
ab2049f9 445 val = (rsnd_io_to_mod_dvc(io) && !rsnd_src_sync_is_enabled(mod)) ?
1a1bf58a 446 0x01 : 0x11;
cfcefe01
KM
447
448 rsnd_mod_write(mod, SRC_CTRL, val);
449
cfcefe01
KM
450 return 0;
451}
452
75916f65
KM
453static int rsnd_src_stop(struct rsnd_mod *mod,
454 struct rsnd_dai_stream *io,
455 struct rsnd_priv *priv)
cfcefe01 456{
31739a68 457 rsnd_mod_write(mod, SRC_CTRL, 0);
cfcefe01 458
75916f65
KM
459 return 0;
460}
461
462static int rsnd_src_init(struct rsnd_mod *mod,
463 struct rsnd_dai_stream *io,
464 struct rsnd_priv *priv)
465{
466 struct rsnd_src *src = rsnd_mod_to_src(mod);
376be51c 467 int ret;
cfcefe01 468
ef30da1c
KM
469 /* reset sync convert_rate */
470 src->sync.val = 0;
471
376be51c
JJ
472 ret = rsnd_mod_power_on(mod);
473 if (ret < 0)
474 return ret;
75916f65 475
98efeeae 476 rsnd_src_activation(mod);
75916f65
KM
477
478 rsnd_src_set_convert_rate(io, mod);
479
8cc225f7 480 rsnd_src_status_clear(mod);
75916f65 481
75916f65 482 return 0;
cfcefe01
KM
483}
484
75916f65
KM
485static int rsnd_src_quit(struct rsnd_mod *mod,
486 struct rsnd_dai_stream *io,
487 struct rsnd_priv *priv)
b761bf27 488{
75916f65 489 struct rsnd_src *src = rsnd_mod_to_src(mod);
75916f65 490
475a361a
KM
491 rsnd_src_halt(mod);
492
75916f65
KM
493 rsnd_mod_power_off(mod);
494
75916f65
KM
495 /* reset sync convert_rate */
496 src->sync.val = 0;
497
498 return 0;
b761bf27
KM
499}
500
75916f65
KM
501static void __rsnd_src_interrupt(struct rsnd_mod *mod,
502 struct rsnd_dai_stream *io)
cfcefe01 503{
02299d98 504 struct rsnd_priv *priv = rsnd_mod_to_priv(mod);
6a25c8da 505 bool stop = false;
02299d98
KM
506
507 spin_lock(&priv->lock);
cfcefe01 508
02299d98 509 /* ignore all cases if not working */
d5bbe7de 510 if (!rsnd_io_is_working(io))
75916f65 511 goto rsnd_src_interrupt_out;
cfcefe01 512
6a25c8da
KM
513 if (rsnd_src_error_occurred(mod))
514 stop = true;
88c61cff 515
8cc225f7 516 rsnd_src_status_clear(mod);
75916f65 517rsnd_src_interrupt_out:
8cc225f7 518
02299d98 519 spin_unlock(&priv->lock);
6a25c8da
KM
520
521 if (stop)
522 snd_pcm_stop_xrun(io->substream);
88c61cff
KM
523}
524
75916f65 525static irqreturn_t rsnd_src_interrupt(int irq, void *data)
88c61cff
KM
526{
527 struct rsnd_mod *mod = data;
528
75916f65 529 rsnd_mod_interrupt(mod, __rsnd_src_interrupt);
cfcefe01
KM
530
531 return IRQ_HANDLED;
532}
533
75916f65
KM
534static int rsnd_src_probe_(struct rsnd_mod *mod,
535 struct rsnd_dai_stream *io,
536 struct rsnd_priv *priv)
76c6fb5c 537{
ba9c949f 538 struct rsnd_src *src = rsnd_mod_to_src(mod);
76c6fb5c 539 struct device *dev = rsnd_priv_to_dev(priv);
adf6a681 540 int irq = src->irq;
76c6fb5c 541 int ret;
76c6fb5c 542
cfcefe01
KM
543 if (irq > 0) {
544 /*
545 * IRQ is not supported on non-DT
546 * see
b5b442ab 547 * rsnd_src_irq()
cfcefe01
KM
548 */
549 ret = devm_request_irq(dev, irq,
75916f65 550 rsnd_src_interrupt,
cfcefe01
KM
551 IRQF_SHARED,
552 dev_name(dev), mod);
553 if (ret)
b543b52a 554 return ret;
cfcefe01
KM
555 }
556
b99305d2 557 ret = rsnd_dma_attach(io, mod, &src->dma);
8aefda50 558
76c6fb5c
KM
559 return ret;
560}
561
75916f65 562static int rsnd_src_pcm_new(struct rsnd_mod *mod,
2c0fac19 563 struct rsnd_dai_stream *io,
43cb6954
KM
564 struct snd_soc_pcm_runtime *rtd)
565{
43cb6954
KM
566 struct rsnd_src *src = rsnd_mod_to_src(mod);
567 int ret;
568
569 /*
570 * enable SRC sync convert if possible
571 */
572
7115cb91 573 /*
61a219fe
KM
574 * It can't use SRC Synchronous convert
575 * when Capture if it uses CMD
7115cb91 576 */
61a219fe 577 if (rsnd_io_to_mod_cmd(io) && !rsnd_io_is_play(io))
7115cb91
KM
578 return 0;
579
43cb6954
KM
580 /*
581 * enable sync convert
582 */
b65a7ccc 583 ret = rsnd_kctrl_new_s(mod, io, rtd,
43cb6954
KM
584 rsnd_io_is_play(io) ?
585 "SRC Out Rate Switch" :
586 "SRC In Rate Switch",
f0b04d8b 587 rsnd_kctrl_accept_anytime,
75916f65 588 rsnd_src_set_convert_rate,
43cb6954
KM
589 &src->sen, 1);
590 if (ret < 0)
591 return ret;
592
b65a7ccc 593 ret = rsnd_kctrl_new_s(mod, io, rtd,
43cb6954
KM
594 rsnd_io_is_play(io) ?
595 "SRC Out Rate" :
596 "SRC In Rate",
f0b04d8b 597 rsnd_kctrl_accept_runtime,
75916f65 598 rsnd_src_set_convert_rate,
43cb6954
KM
599 &src->sync, 192000);
600
601 return ret;
602}
603
1f9c82b5
KM
604#ifdef CONFIG_DEBUG_FS
605static void rsnd_src_debug_info(struct seq_file *m,
606 struct rsnd_dai_stream *io,
607 struct rsnd_mod *mod)
608{
6e4e5432 609 rsnd_debugfs_mod_reg_show(m, mod, RSND_BASE_SCU,
1f9c82b5
KM
610 rsnd_mod_id(mod) * 0x20, 0x20);
611 seq_puts(m, "\n");
6e4e5432 612 rsnd_debugfs_mod_reg_show(m, mod, RSND_BASE_SCU,
1f9c82b5
KM
613 0x1c0, 0x20);
614 seq_puts(m, "\n");
6e4e5432 615 rsnd_debugfs_mod_reg_show(m, mod, RSND_BASE_SCU,
1f9c82b5
KM
616 0x200 + rsnd_mod_id(mod) * 0x40, 0x40);
617}
618#define DEBUG_INFO .debug_info = rsnd_src_debug_info
619#else
620#define DEBUG_INFO
621#endif
622
75916f65 623static struct rsnd_mod_ops rsnd_src_ops = {
7e7fe06d
KM
624 .name = SRC_NAME,
625 .dma_req = rsnd_src_dma_req,
626 .probe = rsnd_src_probe_,
627 .init = rsnd_src_init,
628 .quit = rsnd_src_quit,
629 .start = rsnd_src_start,
630 .stop = rsnd_src_stop,
631 .irq = rsnd_src_irq,
7e7fe06d
KM
632 .pcm_new = rsnd_src_pcm_new,
633 .get_status = rsnd_mod_get_status,
1f9c82b5 634 DEBUG_INFO
629509c5
KM
635};
636
ba9c949f 637struct rsnd_mod *rsnd_src_mod_get(struct rsnd_priv *priv, int id)
07539c1d 638{
ba9c949f 639 if (WARN_ON(id < 0 || id >= rsnd_src_nr(priv)))
8b14719b 640 id = 0;
07539c1d 641
adf6a681 642 return rsnd_mod_get(rsnd_src_get(priv, id));
90e8e50f
KM
643}
644
2ea6b074 645int rsnd_src_probe(struct rsnd_priv *priv)
07539c1d 646{
adf6a681
KM
647 struct device_node *node;
648 struct device_node *np;
07539c1d 649 struct device *dev = rsnd_priv_to_dev(priv);
ba9c949f 650 struct rsnd_src *src;
ef749400 651 struct clk *clk;
ba9c949f 652 char name[RSND_SRC_NAME_SIZE];
2f78dd7f 653 int i, nr, ret;
07539c1d 654
adf6a681
KM
655 node = rsnd_src_of_node(priv);
656 if (!node)
657 return 0; /* not used is not error */
90e8e50f 658
c413983e 659 nr = rsnd_node_count(priv, node, SRC_NAME);
adf6a681
KM
660 if (!nr) {
661 ret = -EINVAL;
662 goto rsnd_src_probe_done;
663 }
389933d9 664
a86854d0 665 src = devm_kcalloc(dev, nr, sizeof(*src), GFP_KERNEL);
adf6a681
KM
666 if (!src) {
667 ret = -ENOMEM;
668 goto rsnd_src_probe_done;
669 }
07539c1d 670
ba9c949f
KM
671 priv->src_nr = nr;
672 priv->src = src;
07539c1d 673
adf6a681
KM
674 i = 0;
675 for_each_child_of_node(node, np) {
de196515
SS
676 if (!of_device_is_available(np))
677 goto skip;
678
d09a7db4
KM
679 i = rsnd_node_fixed_index(dev, np, SRC_NAME, i);
680 if (i < 0) {
681 ret = -EINVAL;
682 of_node_put(np);
683 goto rsnd_src_probe_done;
684 }
c413983e 685
adf6a681
KM
686 src = rsnd_src_get(priv, i);
687
8aefda50
KM
688 snprintf(name, RSND_SRC_NAME_SIZE, "%s.%d",
689 SRC_NAME, i);
ef749400 690
adf6a681
KM
691 src->irq = irq_of_parse_and_map(np, 0);
692 if (!src->irq) {
693 ret = -EINVAL;
53ba2aa3 694 of_node_put(np);
adf6a681
KM
695 goto rsnd_src_probe_done;
696 }
ef749400 697
adf6a681
KM
698 clk = devm_clk_get(dev, name);
699 if (IS_ERR(clk)) {
700 ret = PTR_ERR(clk);
53ba2aa3 701 of_node_put(np);
adf6a681
KM
702 goto rsnd_src_probe_done;
703 }
07539c1d 704
e8e7b7bd 705 ret = rsnd_mod_init(priv, rsnd_mod_get(src),
7e7fe06d 706 &rsnd_src_ops, clk, RSND_MOD_SRC, i);
53ba2aa3
JL
707 if (ret) {
708 of_node_put(np);
adf6a681 709 goto rsnd_src_probe_done;
53ba2aa3 710 }
adf6a681 711
de196515 712skip:
adf6a681 713 i++;
374a5281 714 }
07539c1d 715
adf6a681
KM
716 ret = 0;
717
718rsnd_src_probe_done:
719 of_node_put(node);
720
721 return ret;
07539c1d 722}
2f78dd7f 723
2ea6b074 724void rsnd_src_remove(struct rsnd_priv *priv)
2f78dd7f
KM
725{
726 struct rsnd_src *src;
727 int i;
728
729 for_each_rsnd_src(src, priv, i) {
b76e218a 730 rsnd_mod_quit(rsnd_mod_get(src));
2f78dd7f
KM
731 }
732}