forked from ~ljy/RK356X_SDK_RELEASE

hc
2024-01-31 f70575805708cabdedea7498aaa3f710fde4d920
kernel/sound/soc/rockchip/rockchip_multi_dais_pcm.c
....@@ -1,4 +1,4 @@
1
-// SPDX-License-Identifier: GPL-2.0
1
+// SPDX-License-Identifier: GPL-2.0-or-later
22 /*
33 * ALSA SoC Audio Layer - Rockchip Multi-DAIS-PCM driver
44 *
....@@ -16,19 +16,44 @@
1616 #include <sound/soc.h>
1717
1818 #include "rockchip_multi_dais.h"
19
+#include "rockchip_dlp.h"
1920
20
-#define MAX_FIFO_SIZE 32 /* max fifo size in frames */
21
-#define SND_DMAENGINE_MPCM_DRV_NAME "snd_dmaengine_mpcm"
21
+#define I2S_TXFIFOLR 0xc
22
+#define I2S_RXFIFOLR 0x2c
23
+#define SAI_TXFIFOLR 0x1c
24
+#define SAI_RXFIFOLR 0x20
25
+
26
+/* XFL4 is compatible for old version */
27
+#define I2S_FIFOLR_XFL4(v) (((v) & GENMASK(29, 24)) >> 24)
28
+#define I2S_FIFOLR_XFL3(v) (((v) & GENMASK(23, 18)) >> 18)
29
+#define I2S_FIFOLR_XFL2(v) (((v) & GENMASK(17, 12)) >> 12)
30
+#define I2S_FIFOLR_XFL1(v) (((v) & GENMASK(11, 6)) >> 6)
31
+#define I2S_FIFOLR_XFL0(v) (((v) & GENMASK(5, 0)) >> 0)
32
+
33
+/* XFIFOLR: Transfer / Receive FIFO Level Register */
34
+#define SAI_FIFOLR_XFL3(v) (((v) & GENMASK(23, 18)) >> 18)
35
+#define SAI_FIFOLR_XFL2(v) (((v) & GENMASK(17, 12)) >> 12)
36
+#define SAI_FIFOLR_XFL1(v) (((v) & GENMASK(11, 6)) >> 6)
37
+#define SAI_FIFOLR_XFL0(v) (((v) & GENMASK(5, 0)) >> 0)
38
+
39
+#define MAX_FIFO_SIZE 32 /* max fifo size in frames */
40
+#define SND_DMAENGINE_MPCM_DRV_NAME "snd_dmaengine_mpcm"
41
+
42
+static unsigned int prealloc_buffer_size_kbytes = 512;
43
+module_param(prealloc_buffer_size_kbytes, uint, 0444);
44
+MODULE_PARM_DESC(prealloc_buffer_size_kbytes, "Preallocate DMA buffer size (KB).");
2245
2346 struct dmaengine_mpcm {
47
+ struct dlp dlp;
2448 struct rk_mdais_dev *mdais;
2549 struct dma_chan *tx_chans[MAX_DAIS];
2650 struct dma_chan *rx_chans[MAX_DAIS];
27
- struct snd_soc_component component;
2851 };
2952
3053 struct dmaengine_mpcm_runtime_data {
54
+ struct dlp_runtime_data drd;
3155 struct dma_chan *chans[MAX_DAIS];
56
+ struct dma_interleaved_template *xt;
3257 dma_cookie_t cookies[MAX_DAIS];
3358 unsigned int *channel_maps;
3459 int num_chans;
....@@ -44,12 +69,17 @@
4469 static inline struct dmaengine_mpcm_runtime_data *substream_to_prtd(
4570 const struct snd_pcm_substream *substream)
4671 {
47
- return substream->runtime->private_data;
72
+ struct dlp_runtime_data *drd = substream_to_drd(substream);
73
+
74
+ if (!drd)
75
+ return NULL;
76
+
77
+ return container_of(drd, struct dmaengine_mpcm_runtime_data, drd);
4878 }
4979
5080 static struct dmaengine_mpcm *soc_component_to_mpcm(struct snd_soc_component *p)
5181 {
52
- return container_of(p, struct dmaengine_mpcm, component);
82
+ return container_of(soc_component_to_dlp(p), struct dmaengine_mpcm, dlp);
5383 }
5484
5585 static struct dma_chan *to_chan(struct dmaengine_mpcm *pcm,
....@@ -101,7 +131,20 @@
101131 {
102132 struct snd_pcm_substream *substream = arg;
103133 #ifdef CONFIG_SND_SOC_ROCKCHIP_VAD
104
- struct dmaengine_mpcm_runtime_data *prtd = substream_to_prtd(substream);
134
+ struct dmaengine_mpcm_runtime_data *prtd;
135
+#endif
136
+ struct dlp_runtime_data *drd;
137
+ struct dlp *dlp;
138
+
139
+ snd_pcm_stream_lock_irq(substream);
140
+ if (!substream->runtime) {
141
+ snd_pcm_stream_unlock_irq(substream);
142
+ return;
143
+ }
144
+#ifdef CONFIG_SND_SOC_ROCKCHIP_VAD
145
+ prtd = substream_to_prtd(substream);
146
+ if (unlikely(!prtd))
147
+ return;
105148
106149 if (snd_pcm_vad_attached(substream) &&
107150 substream->stream == SNDRV_PCM_STREAM_CAPTURE) {
....@@ -116,12 +159,21 @@
116159 prtd->pos = 0;
117160
118161 #endif
162
+ drd = substream_to_drd(substream);
163
+ dlp = drd->parent;
164
+
165
+ dlp_dma_complete(dlp, drd);
166
+ snd_pcm_stream_unlock_irq(substream);
167
+
119168 snd_pcm_period_elapsed(substream);
120169 }
121170
122171 static void dmaengine_mpcm_get_master_chan(struct dmaengine_mpcm_runtime_data *prtd)
123172 {
124173 int i;
174
+
175
+ if (unlikely(!prtd))
176
+ return;
125177
126178 for (i = prtd->num_chans; i > 0; i--) {
127179 if (prtd->chans[i - 1]) {
....@@ -131,33 +183,76 @@
131183 }
132184 }
133185
186
+static int dmaengine_config_interleaved(struct snd_pcm_substream *substream,
187
+ struct dma_interleaved_template *xt,
188
+ int offset, int sample_bytes, int nump, int numf)
189
+{
190
+ struct snd_pcm_runtime *runtime = substream->runtime;
191
+ int frame_bytes;
192
+
193
+ frame_bytes = frames_to_bytes(runtime, 1);
194
+
195
+ xt->frame_size = 1;
196
+ xt->sgl[0].size = sample_bytes;
197
+ xt->sgl[0].icg = frame_bytes - sample_bytes;
198
+
199
+#ifdef CONFIG_NO_GKI
200
+ xt->nump = nump;
201
+#endif
202
+ xt->numf = numf;
203
+
204
+ xt->dir = snd_pcm_substream_to_dma_direction(substream);
205
+
206
+ if (xt->dir == DMA_MEM_TO_DEV) {
207
+ xt->src_start = runtime->dma_addr + offset;
208
+ xt->src_inc = true;
209
+ xt->src_sgl = true;
210
+ xt->dst_inc = false;
211
+ xt->dst_sgl = false;
212
+ } else {
213
+ xt->dst_start = runtime->dma_addr + offset;
214
+ xt->src_inc = false;
215
+ xt->src_sgl = false;
216
+ xt->dst_inc = true;
217
+ xt->dst_sgl = true;
218
+ }
219
+
220
+ return 0;
221
+}
222
+
134223 static int dmaengine_mpcm_prepare_and_submit(struct snd_pcm_substream *substream)
135224 {
136225 struct dmaengine_mpcm_runtime_data *prtd = substream_to_prtd(substream);
137226 struct snd_pcm_runtime *runtime = substream->runtime;
138227 struct dma_async_tx_descriptor *desc = NULL;
139
- enum dma_transfer_direction direction;
228
+ struct dma_interleaved_template *xt;
140229 unsigned long flags = DMA_CTRL_ACK;
141
- unsigned int *maps = prtd->channel_maps;
142
- int offset, buffer_bytes, period_bytes;
230
+ unsigned int *maps;
231
+ int offset;
143232 int i;
144233
145
- direction = snd_pcm_substream_to_dma_direction(substream);
234
+ if (unlikely(!prtd || !runtime))
235
+ return -EINVAL;
146236
147237 if (!substream->runtime->no_period_wakeup)
148238 flags |= DMA_PREP_INTERRUPT;
149239
150240 prtd->pos = 0;
151241 offset = 0;
152
- period_bytes = snd_pcm_lib_period_bytes(substream);
153
- buffer_bytes = snd_pcm_lib_buffer_bytes(substream);
242
+
243
+ xt = prtd->xt;
244
+ maps = prtd->channel_maps;
154245 for (i = 0; i < prtd->num_chans; i++) {
155246 if (!prtd->chans[i])
156247 continue;
157
- desc = dmaengine_prep_dma_cyclic(prtd->chans[i],
158
- runtime->dma_addr + offset,
159
- buffer_bytes, period_bytes,
160
- direction, flags);
248
+
249
+ dmaengine_config_interleaved(substream, xt, offset,
250
+ samples_to_bytes(runtime, maps[i]),
251
+ runtime->period_size,
252
+ runtime->buffer_size);
253
+
254
+ desc = dmaengine_prep_interleaved_dma(prtd->chans[i], xt,
255
+ flags | DMA_PREP_REPEAT);
161256
162257 if (!desc)
163258 return -ENOMEM;
....@@ -181,6 +276,9 @@
181276 {
182277 int i;
183278
279
+ if (unlikely(!prtd))
280
+ return;
281
+
184282 for (i = 0; i < prtd->num_chans; i++) {
185283 if (prtd->chans[i])
186284 dma_async_issue_pending(prtd->chans[i]);
....@@ -190,6 +288,9 @@
190288 static void mpcm_dmaengine_resume(struct dmaengine_mpcm_runtime_data *prtd)
191289 {
192290 int i;
291
+
292
+ if (unlikely(!prtd))
293
+ return;
193294
194295 for (i = 0; i < prtd->num_chans; i++) {
195296 if (prtd->chans[i])
....@@ -201,6 +302,9 @@
201302 {
202303 int i;
203304
305
+ if (unlikely(!prtd))
306
+ return;
307
+
204308 for (i = 0; i < prtd->num_chans; i++) {
205309 if (prtd->chans[i])
206310 dmaengine_pause(prtd->chans[i]);
....@@ -210,6 +314,9 @@
210314 static void mpcm_dmaengine_terminate_all(struct dmaengine_mpcm_runtime_data *prtd)
211315 {
212316 int i;
317
+
318
+ if (unlikely(!prtd))
319
+ return;
213320
214321 for (i = 0; i < prtd->num_chans; i++) {
215322 if (prtd->chans[i])
....@@ -224,6 +331,9 @@
224331 struct dmaengine_mpcm_runtime_data *prtd = substream_to_prtd(substream);
225332 unsigned int pos, size;
226333 void *buf;
334
+
335
+ if (unlikely(!prtd))
336
+ return;
227337
228338 if (snd_pcm_vad_attached(substream) &&
229339 substream->stream == SNDRV_PCM_STREAM_CAPTURE) {
....@@ -245,33 +355,39 @@
245355 }
246356
247357 static int __mpcm_prepare_single_and_submit(struct snd_pcm_substream *substream,
248
- dma_addr_t buf_start, int size)
358
+ int buf_offset, int size)
249359 {
250360 struct dmaengine_mpcm_runtime_data *prtd = substream_to_prtd(substream);
361
+ struct dma_interleaved_template *xt;
251362 struct snd_pcm_runtime *runtime = substream->runtime;
252363 struct dma_async_tx_descriptor *desc;
253
- enum dma_transfer_direction direction;
254364 unsigned long flags = DMA_CTRL_ACK;
255
- unsigned int *maps = prtd->channel_maps;
365
+ unsigned int *maps;
256366 int offset, i;
257367 bool callback = false;
258368
259
- direction = snd_pcm_substream_to_dma_direction(substream);
369
+ if (unlikely(!prtd || !runtime))
370
+ return -EINVAL;
260371
261372 if (!substream->runtime->no_period_wakeup)
262373 flags |= DMA_PREP_INTERRUPT;
263374
264
- offset = 0;
375
+ offset = buf_offset;
376
+ xt = prtd->xt;
377
+ maps = prtd->channel_maps;
265378 for (i = 0; i < prtd->num_chans; i++) {
266379 if (!prtd->chans[i])
267380 continue;
268
- desc = dmaengine_prep_slave_single(prtd->chans[i],
269
- buf_start + offset,
270
- size,
271
- direction, flags);
272381
382
+ dmaengine_config_interleaved(substream, xt, offset,
383
+ samples_to_bytes(runtime, maps[i]),
384
+ 0,
385
+ bytes_to_frames(runtime, size));
386
+
387
+ desc = dmaengine_prep_interleaved_dma(prtd->chans[i], xt, flags);
273388 if (!desc)
274389 return -ENOMEM;
390
+
275391 if (!callback) {
276392 desc->callback = dmaengine_mpcm_single_dma_complete;
277393 desc->callback_param = substream;
....@@ -294,6 +410,9 @@
294410 int offset, i, count, ret;
295411 int buffer_bytes, period_bytes, residue_bytes;
296412
413
+ if (unlikely(!prtd))
414
+ return -EINVAL;
415
+
297416 direction = snd_pcm_substream_to_dma_direction(substream);
298417
299418 if (!substream->runtime->no_period_wakeup)
....@@ -312,15 +431,15 @@
312431 pr_debug("%s: offset: %d, buffer_bytes: %d\n", __func__, offset, buffer_bytes);
313432 pr_debug("%s: count: %d, residue_bytes: %d\n", __func__, count, residue_bytes);
314433 for (i = 0; i < count; i++) {
315
- ret = __mpcm_prepare_single_and_submit(substream, buf_start,
434
+ ret = __mpcm_prepare_single_and_submit(substream, offset,
316435 period_bytes);
317436 if (ret)
318437 return ret;
319
- buf_start += period_bytes;
438
+ offset += period_bytes;
320439 }
321440
322441 if (residue_bytes) {
323
- ret = __mpcm_prepare_single_and_submit(substream, buf_start,
442
+ ret = __mpcm_prepare_single_and_submit(substream, offset,
324443 residue_bytes);
325444 if (ret)
326445 return ret;
....@@ -330,12 +449,50 @@
330449 }
331450 #endif
332451
333
-static int snd_dmaengine_mpcm_trigger(struct snd_soc_component *component,
334
- struct snd_pcm_substream *substream, int cmd)
452
+static snd_pcm_uframes_t dmaengine_mpcm_raw_pointer(struct snd_soc_component *component,
453
+ struct snd_pcm_substream *substream)
454
+{
455
+ struct dmaengine_mpcm_runtime_data *prtd = substream_to_prtd(substream);
456
+ struct dma_tx_state state;
457
+ unsigned int buf_size;
458
+ unsigned int pos = 0;
459
+ unsigned int master;
460
+
461
+ if (unlikely(!prtd))
462
+ return 0;
463
+
464
+ master = prtd->master_chan;
465
+ buf_size = snd_pcm_lib_buffer_bytes(substream);
466
+ dmaengine_tx_status(prtd->chans[master], prtd->cookies[master], &state);
467
+ if (state.residue > 0 && state.residue <= buf_size)
468
+ pos = buf_size - state.residue;
469
+
470
+ return bytes_to_frames(substream->runtime, pos);
471
+}
472
+
473
+static int dmaengine_mpcm_dlp_start(struct snd_soc_component *component,
474
+ struct snd_pcm_substream *substream)
475
+{
476
+ struct dmaengine_mpcm *pcm = soc_component_to_mpcm(component);
477
+
478
+ return dlp_start(component, substream, pcm->mdais->dev, dmaengine_mpcm_raw_pointer);
479
+}
480
+
481
+static void dmaengine_mpcm_dlp_stop(struct snd_soc_component *component,
482
+ struct snd_pcm_substream *substream)
483
+{
484
+ dlp_stop(component, substream, dmaengine_mpcm_raw_pointer);
485
+}
486
+
487
+static int dmaengine_mpcm_trigger(struct snd_soc_component *component,
488
+ struct snd_pcm_substream *substream, int cmd)
335489 {
336490 struct dmaengine_mpcm_runtime_data *prtd = substream_to_prtd(substream);
337491 struct snd_pcm_runtime *runtime = substream->runtime;
338492 int ret;
493
+
494
+ if (unlikely(!prtd || !runtime))
495
+ return -EINVAL;
339496
340497 switch (cmd) {
341498 case SNDRV_PCM_TRIGGER_START:
....@@ -351,16 +508,19 @@
351508 if (ret)
352509 return ret;
353510 mpcm_dma_async_issue_pending(prtd);
511
+ dmaengine_mpcm_dlp_start(component, substream);
354512 break;
355513 case SNDRV_PCM_TRIGGER_RESUME:
356514 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
357515 mpcm_dmaengine_resume(prtd);
358516 break;
359517 case SNDRV_PCM_TRIGGER_SUSPEND:
360
- if (runtime->info & SNDRV_PCM_INFO_PAUSE)
518
+ if (runtime->info & SNDRV_PCM_INFO_PAUSE) {
361519 mpcm_dmaengine_pause(prtd);
362
- else
520
+ } else {
521
+ dmaengine_mpcm_dlp_stop(component, substream);
363522 mpcm_dmaengine_terminate_all(prtd);
523
+ }
364524 prtd->start_flag = false;
365525 break;
366526 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
....@@ -368,6 +528,7 @@
368528 prtd->start_flag = false;
369529 break;
370530 case SNDRV_PCM_TRIGGER_STOP:
531
+ dmaengine_mpcm_dlp_stop(component, substream);
371532 mpcm_dmaengine_terminate_all(prtd);
372533 prtd->start_flag = false;
373534 break;
....@@ -419,22 +580,12 @@
419580 sz = snd_pcm_format_size(format, maps[i]);
420581 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
421582 chan = pcm->tx_chans[i];
422
-#ifdef CONFIG_NO_GKI
423
- if (sz) {
424
- slave_config.src_interlace_size = frame_bytes - sz;
425
- if (slave_config.src_interlace_size)
426
- slave_config.dst_maxburst = sz / slave_config.dst_addr_width;
427
- }
428
-#endif
583
+ if (sz && (frame_bytes - sz) > 0)
584
+ slave_config.dst_maxburst = sz / slave_config.dst_addr_width;
429585 } else {
430586 chan = pcm->rx_chans[i];
431
-#ifdef CONFIG_NO_GKI
432
- if (sz) {
433
- slave_config.dst_interlace_size = frame_bytes - sz;
434
- if (slave_config.dst_interlace_size)
435
- slave_config.src_maxburst = sz / slave_config.src_addr_width;
436
- }
437
-#endif
587
+ if (sz && (frame_bytes - sz) > 0)
588
+ slave_config.src_maxburst = sz / slave_config.src_addr_width;
438589 }
439590 if (!chan)
440591 continue;
....@@ -443,6 +594,11 @@
443594 if (ret)
444595 return ret;
445596 }
597
+
598
+ ret = dlp_hw_params(component, substream, params);
599
+ if (ret)
600
+ return ret;
601
+
446602 return snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(params));
447603 }
448604
....@@ -463,12 +619,12 @@
463619 int ret;
464620
465621 chan = to_chan(pcm, substream);
466
- if (!chan)
622
+ if (!chan || !dma_dev)
467623 return -EINVAL;
468624
469625 memset(&hw, 0, sizeof(hw));
470626 hw.info = SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_MMAP_VALID |
471
- SNDRV_PCM_INFO_INTERLEAVED;
627
+ SNDRV_PCM_INFO_INTERLEAVED;
472628 hw.periods_min = 2;
473629 hw.periods_max = UINT_MAX;
474630 hw.period_bytes_min = 256;
....@@ -538,6 +694,13 @@
538694 if (!prtd)
539695 return -ENOMEM;
540696
697
+ prtd->xt = kzalloc(sizeof(struct dma_interleaved_template) +
698
+ sizeof(struct data_chunk), GFP_KERNEL);
699
+ if (!prtd->xt) {
700
+ kfree(prtd);
701
+ return -ENOMEM;
702
+ }
703
+
541704 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
542705 prtd->channel_maps = pcm->mdais->playback_channel_maps;
543706 for (i = 0; i < pcm->mdais->num_dais; i++)
....@@ -550,7 +713,8 @@
550713
551714 prtd->num_chans = pcm->mdais->num_dais;
552715 prtd->start_flag = false;
553
- substream->runtime->private_data = prtd;
716
+
717
+ dlp_open(&pcm->dlp, &prtd->drd, substream);
554718
555719 return 0;
556720 }
....@@ -559,11 +723,12 @@
559723 {
560724 struct dmaengine_mpcm *pcm = soc_component_to_mpcm(component);
561725 struct snd_pcm_substream *substream;
726
+ struct device *dma_dev;
562727 size_t prealloc_buffer_size;
563728 size_t max_buffer_size;
564729 unsigned int i;
565730
566
- prealloc_buffer_size = 512 * 1024;
731
+ prealloc_buffer_size = prealloc_buffer_size_kbytes * 1024;
567732 max_buffer_size = SIZE_MAX;
568733
569734 for (i = SNDRV_PCM_STREAM_PLAYBACK; i <= SNDRV_PCM_STREAM_CAPTURE; i++) {
....@@ -571,9 +736,15 @@
571736 if (!substream)
572737 continue;
573738
739
+ dma_dev = dmaengine_dma_dev(pcm, substream);
740
+ if (!dma_dev) {
741
+ dev_err(component->dev, "No chan found, should assign 'rockchip,no-dmaengine' in DT\n");
742
+ return -EINVAL;
743
+ }
744
+
574745 snd_pcm_lib_preallocate_pages(substream,
575746 SNDRV_DMA_TYPE_DEV_IRAM,
576
- dmaengine_dma_dev(pcm, substream),
747
+ dma_dev,
577748 prealloc_buffer_size,
578749 max_buffer_size);
579750 }
....@@ -590,8 +761,12 @@
590761 snd_pcm_uframes_t frames;
591762 unsigned int buf_size;
592763 unsigned int pos = 0;
593
- unsigned int master = prtd->master_chan;
764
+ unsigned int master;
594765
766
+ if (unlikely(!prtd || !runtime))
767
+ return 0;
768
+
769
+ master = prtd->master_chan;
595770 buf_size = snd_pcm_lib_buffer_bytes(substream);
596771 dmaengine_tx_status(prtd->chans[master], prtd->cookies[master], &state);
597772 if (state.residue > 0 && state.residue <= buf_size)
....@@ -636,24 +811,54 @@
636811 static int dmaengine_mpcm_close(struct snd_soc_component *component,
637812 struct snd_pcm_substream *substream)
638813 {
814
+ struct dmaengine_mpcm *pcm = soc_component_to_mpcm(component);
639815 struct dmaengine_mpcm_runtime_data *prtd = substream_to_prtd(substream);
640816
817
+ if (unlikely(!prtd))
818
+ return -EINVAL;
819
+
820
+ dlp_close(&pcm->dlp, &prtd->drd, substream);
821
+
822
+ kfree(prtd->xt);
641823 kfree(prtd);
642824
643825 return 0;
644826 }
645827
828
+static int dmaengine_mpcm_copy_user(struct snd_soc_component *component,
829
+ struct snd_pcm_substream *substream,
830
+ int channel, unsigned long hwoff,
831
+ void __user *buf, unsigned long bytes)
832
+{
833
+ return dlp_copy_user(component, substream, channel, hwoff, buf, bytes);
834
+}
835
+
836
+
837
+static int dmaengine_mpcm_prepare(struct snd_soc_component *component,
838
+ struct snd_pcm_substream *substream)
839
+{
840
+ return dlp_prepare(component, substream);
841
+}
842
+
843
+static int dmaengine_mpcm_probe(struct snd_soc_component *component)
844
+{
845
+ return dlp_probe(component);
846
+}
847
+
646848 static const struct snd_soc_component_driver dmaengine_mpcm_platform = {
647849 .name = SND_DMAENGINE_MPCM_DRV_NAME,
648850 .probe_order = SND_SOC_COMP_ORDER_LATE,
851
+ .probe = dmaengine_mpcm_probe,
649852 .pcm_construct = dmaengine_mpcm_new,
650853 .open = dmaengine_mpcm_open,
651854 .close = dmaengine_mpcm_close,
652855 .ioctl = dmaengine_mpcm_ioctl,
653856 .hw_params = dmaengine_mpcm_hw_params,
654857 .hw_free = dmaengine_mpcm_hw_free,
655
- .trigger = snd_dmaengine_mpcm_trigger,
858
+ .prepare = dmaengine_mpcm_prepare,
859
+ .trigger = dmaengine_mpcm_trigger,
656860 .pointer = dmaengine_mpcm_pointer,
861
+ .copy_user = dmaengine_mpcm_copy_user,
657862 };
658863
659864 static void dmaengine_mpcm_release_chan(struct dmaengine_mpcm *pcm)
....@@ -667,6 +872,55 @@
667872 dma_release_channel(pcm->rx_chans[i]);
668873 }
669874 }
875
+
876
+static int dmaengine_mpcm_get_fifo_count(struct device *dev,
877
+ struct snd_pcm_substream *substream)
878
+{
879
+ struct rk_mdais_dev *mdais = dev_get_drvdata(dev);
880
+ struct dmaengine_mpcm_runtime_data *prtd = substream_to_prtd(substream);
881
+ struct snd_soc_component *component;
882
+ unsigned int tx, rx, reg;
883
+ int val = 0;
884
+
885
+ if (unlikely(!prtd))
886
+ return -EINVAL;
887
+
888
+ component = mdais->dais[prtd->master_chan].dai->component;
889
+ if (unlikely(!component))
890
+ return -EINVAL;
891
+
892
+ if (strstr(dev_driver_string(component->dev), "i2s")) {
893
+ /* compatible for both I2S and I2STDM controller */
894
+ tx = snd_soc_component_read(component, I2S_TXFIFOLR);
895
+ rx = snd_soc_component_read(component, I2S_RXFIFOLR);
896
+
897
+ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
898
+ val = I2S_FIFOLR_XFL3(tx) +
899
+ I2S_FIFOLR_XFL2(tx) +
900
+ I2S_FIFOLR_XFL1(tx) +
901
+ I2S_FIFOLR_XFL0(tx);
902
+ else
903
+ /* XFL4 is compatible for old version */
904
+ val = I2S_FIFOLR_XFL4(tx) +
905
+ I2S_FIFOLR_XFL3(rx) +
906
+ I2S_FIFOLR_XFL2(rx) +
907
+ I2S_FIFOLR_XFL1(rx) +
908
+ I2S_FIFOLR_XFL0(rx);
909
+ } else if (strstr(dev_driver_string(component->dev), "sai")) {
910
+ reg = substream->stream ? SAI_RXFIFOLR : SAI_TXFIFOLR;
911
+
912
+ val = SAI_FIFOLR_XFL3(reg) +
913
+ SAI_FIFOLR_XFL2(reg) +
914
+ SAI_FIFOLR_XFL1(reg) +
915
+ SAI_FIFOLR_XFL0(reg);
916
+ }
917
+
918
+ return val;
919
+}
920
+
921
+static const struct snd_dlp_config dconfig = {
922
+ .get_fifo_count = dmaengine_mpcm_get_fifo_count,
923
+};
670924
671925 int snd_dmaengine_mpcm_register(struct rk_mdais_dev *mdais)
672926 {
....@@ -703,12 +957,7 @@
703957 }
704958 }
705959
706
- ret = snd_soc_component_initialize(&pcm->component, &dmaengine_mpcm_platform,
707
- dev);
708
- if (ret)
709
- goto err_free_dma;
710
-
711
- ret = snd_soc_add_component(&pcm->component, NULL, 0);
960
+ ret = dlp_register(&pcm->dlp, dev, &dmaengine_mpcm_platform, &dconfig);
712961 if (ret)
713962 goto err_free_dma;
714963