hc
2024-01-03 2f7c68cb55ecb7331f2381deb497c27155f32faf
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,23 +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"
2241
2342 static unsigned int prealloc_buffer_size_kbytes = 512;
2443 module_param(prealloc_buffer_size_kbytes, uint, 0444);
2544 MODULE_PARM_DESC(prealloc_buffer_size_kbytes, "Preallocate DMA buffer size (KB).");
2645
2746 struct dmaengine_mpcm {
47
+ struct dlp dlp;
2848 struct rk_mdais_dev *mdais;
2949 struct dma_chan *tx_chans[MAX_DAIS];
3050 struct dma_chan *rx_chans[MAX_DAIS];
31
- struct snd_soc_component component;
3251 };
3352
3453 struct dmaengine_mpcm_runtime_data {
54
+ struct dlp_runtime_data drd;
3555 struct dma_chan *chans[MAX_DAIS];
56
+ struct dma_interleaved_template *xt;
3657 dma_cookie_t cookies[MAX_DAIS];
3758 unsigned int *channel_maps;
3859 int num_chans;
....@@ -48,12 +69,17 @@
4869 static inline struct dmaengine_mpcm_runtime_data *substream_to_prtd(
4970 const struct snd_pcm_substream *substream)
5071 {
51
- 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);
5278 }
5379
5480 static struct dmaengine_mpcm *soc_component_to_mpcm(struct snd_soc_component *p)
5581 {
56
- return container_of(p, struct dmaengine_mpcm, component);
82
+ return container_of(soc_component_to_dlp(p), struct dmaengine_mpcm, dlp);
5783 }
5884
5985 static struct dma_chan *to_chan(struct dmaengine_mpcm *pcm,
....@@ -105,7 +131,20 @@
105131 {
106132 struct snd_pcm_substream *substream = arg;
107133 #ifdef CONFIG_SND_SOC_ROCKCHIP_VAD
108
- 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;
109148
110149 if (snd_pcm_vad_attached(substream) &&
111150 substream->stream == SNDRV_PCM_STREAM_CAPTURE) {
....@@ -120,12 +159,21 @@
120159 prtd->pos = 0;
121160
122161 #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
+
123168 snd_pcm_period_elapsed(substream);
124169 }
125170
126171 static void dmaengine_mpcm_get_master_chan(struct dmaengine_mpcm_runtime_data *prtd)
127172 {
128173 int i;
174
+
175
+ if (unlikely(!prtd))
176
+ return;
129177
130178 for (i = prtd->num_chans; i > 0; i--) {
131179 if (prtd->chans[i - 1]) {
....@@ -135,33 +183,76 @@
135183 }
136184 }
137185
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
+
138223 static int dmaengine_mpcm_prepare_and_submit(struct snd_pcm_substream *substream)
139224 {
140225 struct dmaengine_mpcm_runtime_data *prtd = substream_to_prtd(substream);
141226 struct snd_pcm_runtime *runtime = substream->runtime;
142227 struct dma_async_tx_descriptor *desc = NULL;
143
- enum dma_transfer_direction direction;
228
+ struct dma_interleaved_template *xt;
144229 unsigned long flags = DMA_CTRL_ACK;
145
- unsigned int *maps = prtd->channel_maps;
146
- int offset, buffer_bytes, period_bytes;
230
+ unsigned int *maps;
231
+ int offset;
147232 int i;
148233
149
- direction = snd_pcm_substream_to_dma_direction(substream);
234
+ if (unlikely(!prtd || !runtime))
235
+ return -EINVAL;
150236
151237 if (!substream->runtime->no_period_wakeup)
152238 flags |= DMA_PREP_INTERRUPT;
153239
154240 prtd->pos = 0;
155241 offset = 0;
156
- period_bytes = snd_pcm_lib_period_bytes(substream);
157
- buffer_bytes = snd_pcm_lib_buffer_bytes(substream);
242
+
243
+ xt = prtd->xt;
244
+ maps = prtd->channel_maps;
158245 for (i = 0; i < prtd->num_chans; i++) {
159246 if (!prtd->chans[i])
160247 continue;
161
- desc = dmaengine_prep_dma_cyclic(prtd->chans[i],
162
- runtime->dma_addr + offset,
163
- buffer_bytes, period_bytes,
164
- 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);
165256
166257 if (!desc)
167258 return -ENOMEM;
....@@ -185,6 +276,9 @@
185276 {
186277 int i;
187278
279
+ if (unlikely(!prtd))
280
+ return;
281
+
188282 for (i = 0; i < prtd->num_chans; i++) {
189283 if (prtd->chans[i])
190284 dma_async_issue_pending(prtd->chans[i]);
....@@ -194,6 +288,9 @@
194288 static void mpcm_dmaengine_resume(struct dmaengine_mpcm_runtime_data *prtd)
195289 {
196290 int i;
291
+
292
+ if (unlikely(!prtd))
293
+ return;
197294
198295 for (i = 0; i < prtd->num_chans; i++) {
199296 if (prtd->chans[i])
....@@ -205,6 +302,9 @@
205302 {
206303 int i;
207304
305
+ if (unlikely(!prtd))
306
+ return;
307
+
208308 for (i = 0; i < prtd->num_chans; i++) {
209309 if (prtd->chans[i])
210310 dmaengine_pause(prtd->chans[i]);
....@@ -214,6 +314,9 @@
214314 static void mpcm_dmaengine_terminate_all(struct dmaengine_mpcm_runtime_data *prtd)
215315 {
216316 int i;
317
+
318
+ if (unlikely(!prtd))
319
+ return;
217320
218321 for (i = 0; i < prtd->num_chans; i++) {
219322 if (prtd->chans[i])
....@@ -228,6 +331,9 @@
228331 struct dmaengine_mpcm_runtime_data *prtd = substream_to_prtd(substream);
229332 unsigned int pos, size;
230333 void *buf;
334
+
335
+ if (unlikely(!prtd))
336
+ return;
231337
232338 if (snd_pcm_vad_attached(substream) &&
233339 substream->stream == SNDRV_PCM_STREAM_CAPTURE) {
....@@ -249,33 +355,39 @@
249355 }
250356
251357 static int __mpcm_prepare_single_and_submit(struct snd_pcm_substream *substream,
252
- dma_addr_t buf_start, int size)
358
+ int buf_offset, int size)
253359 {
254360 struct dmaengine_mpcm_runtime_data *prtd = substream_to_prtd(substream);
361
+ struct dma_interleaved_template *xt;
255362 struct snd_pcm_runtime *runtime = substream->runtime;
256363 struct dma_async_tx_descriptor *desc;
257
- enum dma_transfer_direction direction;
258364 unsigned long flags = DMA_CTRL_ACK;
259
- unsigned int *maps = prtd->channel_maps;
365
+ unsigned int *maps;
260366 int offset, i;
261367 bool callback = false;
262368
263
- direction = snd_pcm_substream_to_dma_direction(substream);
369
+ if (unlikely(!prtd || !runtime))
370
+ return -EINVAL;
264371
265372 if (!substream->runtime->no_period_wakeup)
266373 flags |= DMA_PREP_INTERRUPT;
267374
268
- offset = 0;
375
+ offset = buf_offset;
376
+ xt = prtd->xt;
377
+ maps = prtd->channel_maps;
269378 for (i = 0; i < prtd->num_chans; i++) {
270379 if (!prtd->chans[i])
271380 continue;
272
- desc = dmaengine_prep_slave_single(prtd->chans[i],
273
- buf_start + offset,
274
- size,
275
- direction, flags);
276381
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);
277388 if (!desc)
278389 return -ENOMEM;
390
+
279391 if (!callback) {
280392 desc->callback = dmaengine_mpcm_single_dma_complete;
281393 desc->callback_param = substream;
....@@ -298,6 +410,9 @@
298410 int offset, i, count, ret;
299411 int buffer_bytes, period_bytes, residue_bytes;
300412
413
+ if (unlikely(!prtd))
414
+ return -EINVAL;
415
+
301416 direction = snd_pcm_substream_to_dma_direction(substream);
302417
303418 if (!substream->runtime->no_period_wakeup)
....@@ -316,15 +431,15 @@
316431 pr_debug("%s: offset: %d, buffer_bytes: %d\n", __func__, offset, buffer_bytes);
317432 pr_debug("%s: count: %d, residue_bytes: %d\n", __func__, count, residue_bytes);
318433 for (i = 0; i < count; i++) {
319
- ret = __mpcm_prepare_single_and_submit(substream, buf_start,
434
+ ret = __mpcm_prepare_single_and_submit(substream, offset,
320435 period_bytes);
321436 if (ret)
322437 return ret;
323
- buf_start += period_bytes;
438
+ offset += period_bytes;
324439 }
325440
326441 if (residue_bytes) {
327
- ret = __mpcm_prepare_single_and_submit(substream, buf_start,
442
+ ret = __mpcm_prepare_single_and_submit(substream, offset,
328443 residue_bytes);
329444 if (ret)
330445 return ret;
....@@ -334,12 +449,50 @@
334449 }
335450 #endif
336451
337
-static int snd_dmaengine_mpcm_trigger(struct snd_soc_component *component,
338
- 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)
339489 {
340490 struct dmaengine_mpcm_runtime_data *prtd = substream_to_prtd(substream);
341491 struct snd_pcm_runtime *runtime = substream->runtime;
342492 int ret;
493
+
494
+ if (unlikely(!prtd || !runtime))
495
+ return -EINVAL;
343496
344497 switch (cmd) {
345498 case SNDRV_PCM_TRIGGER_START:
....@@ -355,16 +508,19 @@
355508 if (ret)
356509 return ret;
357510 mpcm_dma_async_issue_pending(prtd);
511
+ dmaengine_mpcm_dlp_start(component, substream);
358512 break;
359513 case SNDRV_PCM_TRIGGER_RESUME:
360514 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
361515 mpcm_dmaengine_resume(prtd);
362516 break;
363517 case SNDRV_PCM_TRIGGER_SUSPEND:
364
- if (runtime->info & SNDRV_PCM_INFO_PAUSE)
518
+ if (runtime->info & SNDRV_PCM_INFO_PAUSE) {
365519 mpcm_dmaengine_pause(prtd);
366
- else
520
+ } else {
521
+ dmaengine_mpcm_dlp_stop(component, substream);
367522 mpcm_dmaengine_terminate_all(prtd);
523
+ }
368524 prtd->start_flag = false;
369525 break;
370526 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
....@@ -372,6 +528,7 @@
372528 prtd->start_flag = false;
373529 break;
374530 case SNDRV_PCM_TRIGGER_STOP:
531
+ dmaengine_mpcm_dlp_stop(component, substream);
375532 mpcm_dmaengine_terminate_all(prtd);
376533 prtd->start_flag = false;
377534 break;
....@@ -423,22 +580,12 @@
423580 sz = snd_pcm_format_size(format, maps[i]);
424581 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
425582 chan = pcm->tx_chans[i];
426
-#ifdef CONFIG_NO_GKI
427
- if (sz) {
428
- slave_config.src_interlace_size = frame_bytes - sz;
429
- if (slave_config.src_interlace_size)
430
- slave_config.dst_maxburst = sz / slave_config.dst_addr_width;
431
- }
432
-#endif
583
+ if (sz && (frame_bytes - sz) > 0)
584
+ slave_config.dst_maxburst = sz / slave_config.dst_addr_width;
433585 } else {
434586 chan = pcm->rx_chans[i];
435
-#ifdef CONFIG_NO_GKI
436
- if (sz) {
437
- slave_config.dst_interlace_size = frame_bytes - sz;
438
- if (slave_config.dst_interlace_size)
439
- slave_config.src_maxburst = sz / slave_config.src_addr_width;
440
- }
441
-#endif
587
+ if (sz && (frame_bytes - sz) > 0)
588
+ slave_config.src_maxburst = sz / slave_config.src_addr_width;
442589 }
443590 if (!chan)
444591 continue;
....@@ -447,6 +594,11 @@
447594 if (ret)
448595 return ret;
449596 }
597
+
598
+ ret = dlp_hw_params(component, substream, params);
599
+ if (ret)
600
+ return ret;
601
+
450602 return snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(params));
451603 }
452604
....@@ -467,12 +619,12 @@
467619 int ret;
468620
469621 chan = to_chan(pcm, substream);
470
- if (!chan)
622
+ if (!chan || !dma_dev)
471623 return -EINVAL;
472624
473625 memset(&hw, 0, sizeof(hw));
474626 hw.info = SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_MMAP_VALID |
475
- SNDRV_PCM_INFO_INTERLEAVED;
627
+ SNDRV_PCM_INFO_INTERLEAVED;
476628 hw.periods_min = 2;
477629 hw.periods_max = UINT_MAX;
478630 hw.period_bytes_min = 256;
....@@ -542,6 +694,13 @@
542694 if (!prtd)
543695 return -ENOMEM;
544696
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
+
545704 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
546705 prtd->channel_maps = pcm->mdais->playback_channel_maps;
547706 for (i = 0; i < pcm->mdais->num_dais; i++)
....@@ -554,7 +713,8 @@
554713
555714 prtd->num_chans = pcm->mdais->num_dais;
556715 prtd->start_flag = false;
557
- substream->runtime->private_data = prtd;
716
+
717
+ dlp_open(&pcm->dlp, &prtd->drd, substream);
558718
559719 return 0;
560720 }
....@@ -563,6 +723,7 @@
563723 {
564724 struct dmaengine_mpcm *pcm = soc_component_to_mpcm(component);
565725 struct snd_pcm_substream *substream;
726
+ struct device *dma_dev;
566727 size_t prealloc_buffer_size;
567728 size_t max_buffer_size;
568729 unsigned int i;
....@@ -575,9 +736,15 @@
575736 if (!substream)
576737 continue;
577738
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
+
578745 snd_pcm_lib_preallocate_pages(substream,
579746 SNDRV_DMA_TYPE_DEV_IRAM,
580
- dmaengine_dma_dev(pcm, substream),
747
+ dma_dev,
581748 prealloc_buffer_size,
582749 max_buffer_size);
583750 }
....@@ -594,8 +761,12 @@
594761 snd_pcm_uframes_t frames;
595762 unsigned int buf_size;
596763 unsigned int pos = 0;
597
- unsigned int master = prtd->master_chan;
764
+ unsigned int master;
598765
766
+ if (unlikely(!prtd || !runtime))
767
+ return 0;
768
+
769
+ master = prtd->master_chan;
599770 buf_size = snd_pcm_lib_buffer_bytes(substream);
600771 dmaengine_tx_status(prtd->chans[master], prtd->cookies[master], &state);
601772 if (state.residue > 0 && state.residue <= buf_size)
....@@ -640,24 +811,54 @@
640811 static int dmaengine_mpcm_close(struct snd_soc_component *component,
641812 struct snd_pcm_substream *substream)
642813 {
814
+ struct dmaengine_mpcm *pcm = soc_component_to_mpcm(component);
643815 struct dmaengine_mpcm_runtime_data *prtd = substream_to_prtd(substream);
644816
817
+ if (unlikely(!prtd))
818
+ return -EINVAL;
819
+
820
+ dlp_close(&pcm->dlp, &prtd->drd, substream);
821
+
822
+ kfree(prtd->xt);
645823 kfree(prtd);
646824
647825 return 0;
648826 }
649827
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
+
650848 static const struct snd_soc_component_driver dmaengine_mpcm_platform = {
651849 .name = SND_DMAENGINE_MPCM_DRV_NAME,
652850 .probe_order = SND_SOC_COMP_ORDER_LATE,
851
+ .probe = dmaengine_mpcm_probe,
653852 .pcm_construct = dmaengine_mpcm_new,
654853 .open = dmaengine_mpcm_open,
655854 .close = dmaengine_mpcm_close,
656855 .ioctl = dmaengine_mpcm_ioctl,
657856 .hw_params = dmaengine_mpcm_hw_params,
658857 .hw_free = dmaengine_mpcm_hw_free,
659
- .trigger = snd_dmaengine_mpcm_trigger,
858
+ .prepare = dmaengine_mpcm_prepare,
859
+ .trigger = dmaengine_mpcm_trigger,
660860 .pointer = dmaengine_mpcm_pointer,
861
+ .copy_user = dmaengine_mpcm_copy_user,
661862 };
662863
663864 static void dmaengine_mpcm_release_chan(struct dmaengine_mpcm *pcm)
....@@ -671,6 +872,55 @@
671872 dma_release_channel(pcm->rx_chans[i]);
672873 }
673874 }
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
+};
674924
675925 int snd_dmaengine_mpcm_register(struct rk_mdais_dev *mdais)
676926 {
....@@ -689,9 +939,6 @@
689939 if (!pcm)
690940 return -ENOMEM;
691941
692
-#ifdef CONFIG_DEBUG_FS
693
- pcm->component.debugfs_prefix = "dma";
694
-#endif
695942 pcm->mdais = mdais;
696943 for (i = 0; i < num; i++) {
697944 child = mdais->dais[i].dev;
....@@ -710,12 +957,7 @@
710957 }
711958 }
712959
713
- ret = snd_soc_component_initialize(&pcm->component, &dmaengine_mpcm_platform,
714
- dev);
715
- if (ret)
716
- goto err_free_dma;
717
-
718
- ret = snd_soc_add_component(&pcm->component, NULL, 0);
960
+ ret = dlp_register(&pcm->dlp, dev, &dmaengine_mpcm_platform, &dconfig);
719961 if (ret)
720962 goto err_free_dma;
721963