Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

ASoC: fsl: fsl_qmc_audio: Split channel buffer and PCM pointer handling

The driver mixes some internal values for channel DMA buffer handling
and PCM pointer handling. In the currently supported interleaved mode,
this mix does not lead to any issues but in order to prepare the
support for the non-interleaved mode, having them clearly separated will
ease the support and avoid additional computation to convert values used
in channel DMA buffer management in values usable for PCM pointer.

Use a specific set of variable for PCM pointer handling and an other set
for channel DMA buffer.

Signed-off-by: Herve Codina <herve.codina@bootlin.com>
Link: https://patch.msgid.link/20240701113038.55144-4-herve.codina@bootlin.com
Signed-off-by: Mark Brown <broonie@kernel.org>

authored by

Herve Codina and committed by
Mark Brown
42212b2c 86dd725b

+46 -38
+46 -38
sound/soc/fsl/fsl_qmc_audio.c
··· 35 35 36 36 struct qmc_dai_prtd { 37 37 struct qmc_dai *qmc_dai; 38 - dma_addr_t dma_buffer_start; 39 - dma_addr_t period_ptr_submitted; 40 - dma_addr_t period_ptr_ended; 41 - dma_addr_t dma_buffer_end; 42 - size_t period_size; 38 + 39 + snd_pcm_uframes_t buffer_ended; 40 + snd_pcm_uframes_t buffer_size; 41 + snd_pcm_uframes_t period_size; 42 + 43 + dma_addr_t ch_dma_addr_start; 44 + dma_addr_t ch_dma_addr_current; 45 + dma_addr_t ch_dma_addr_end; 46 + size_t ch_dma_size; 47 + 43 48 struct snd_pcm_substream *substream; 44 49 }; 45 50 ··· 70 65 struct snd_pcm_runtime *runtime = substream->runtime; 71 66 struct qmc_dai_prtd *prtd = substream->runtime->private_data; 72 67 73 - prtd->dma_buffer_start = runtime->dma_addr; 74 - prtd->dma_buffer_end = runtime->dma_addr + params_buffer_bytes(params); 75 - prtd->period_size = params_period_bytes(params); 76 - prtd->period_ptr_submitted = prtd->dma_buffer_start; 77 - prtd->period_ptr_ended = prtd->dma_buffer_start; 78 68 prtd->substream = substream; 69 + 70 + prtd->buffer_ended = 0; 71 + prtd->buffer_size = params_buffer_size(params); 72 + prtd->period_size = params_period_size(params); 73 + 74 + prtd->ch_dma_addr_start = runtime->dma_addr; 75 + prtd->ch_dma_addr_end = runtime->dma_addr + params_buffer_bytes(params); 76 + prtd->ch_dma_addr_current = prtd->ch_dma_addr_start; 77 + prtd->ch_dma_size = params_period_bytes(params); 79 78 80 79 return 0; 81 80 } ··· 89 80 struct qmc_dai_prtd *prtd = context; 90 81 int ret; 91 82 92 - prtd->period_ptr_ended += prtd->period_size; 93 - if (prtd->period_ptr_ended >= prtd->dma_buffer_end) 94 - prtd->period_ptr_ended = prtd->dma_buffer_start; 83 + prtd->buffer_ended += prtd->period_size; 84 + if (prtd->buffer_ended >= prtd->buffer_size) 85 + prtd->buffer_ended = 0; 95 86 96 - prtd->period_ptr_submitted += prtd->period_size; 97 - if (prtd->period_ptr_submitted >= prtd->dma_buffer_end) 98 - prtd->period_ptr_submitted = prtd->dma_buffer_start; 87 + prtd->ch_dma_addr_current += prtd->ch_dma_size; 88 + if (prtd->ch_dma_addr_current >= prtd->ch_dma_addr_end) 89 + prtd->ch_dma_addr_current = prtd->ch_dma_addr_start; 99 90 100 91 ret = qmc_chan_write_submit(prtd->qmc_dai->qmc_chan, 101 - prtd->period_ptr_submitted, prtd->period_size, 92 + prtd->ch_dma_addr_current, prtd->ch_dma_size, 102 93 qmc_audio_pcm_write_complete, prtd); 103 94 if (ret) { 104 95 dev_err(prtd->qmc_dai->dev, "write_submit failed %d\n", ··· 113 104 struct qmc_dai_prtd *prtd = context; 114 105 int ret; 115 106 116 - if (length != prtd->period_size) { 107 + if (length != prtd->ch_dma_size) { 117 108 dev_err(prtd->qmc_dai->dev, "read complete length = %zu, exp %zu\n", 118 - length, prtd->period_size); 109 + length, prtd->ch_dma_size); 119 110 } 120 111 121 - prtd->period_ptr_ended += prtd->period_size; 122 - if (prtd->period_ptr_ended >= prtd->dma_buffer_end) 123 - prtd->period_ptr_ended = prtd->dma_buffer_start; 112 + prtd->buffer_ended += prtd->period_size; 113 + if (prtd->buffer_ended >= prtd->buffer_size) 114 + prtd->buffer_ended = 0; 124 115 125 - prtd->period_ptr_submitted += prtd->period_size; 126 - if (prtd->period_ptr_submitted >= prtd->dma_buffer_end) 127 - prtd->period_ptr_submitted = prtd->dma_buffer_start; 116 + prtd->ch_dma_addr_current += prtd->ch_dma_size; 117 + if (prtd->ch_dma_addr_current >= prtd->ch_dma_addr_end) 118 + prtd->ch_dma_addr_current = prtd->ch_dma_addr_start; 128 119 129 120 ret = qmc_chan_read_submit(prtd->qmc_dai->qmc_chan, 130 - prtd->period_ptr_submitted, prtd->period_size, 121 + prtd->ch_dma_addr_current, prtd->ch_dma_size, 131 122 qmc_audio_pcm_read_complete, prtd); 132 123 if (ret) { 133 124 dev_err(prtd->qmc_dai->dev, "read_submit failed %d\n", ··· 153 144 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { 154 145 /* Submit first chunk ... */ 155 146 ret = qmc_chan_write_submit(prtd->qmc_dai->qmc_chan, 156 - prtd->period_ptr_submitted, prtd->period_size, 147 + prtd->ch_dma_addr_current, prtd->ch_dma_size, 157 148 qmc_audio_pcm_write_complete, prtd); 158 149 if (ret) { 159 150 dev_err(component->dev, "write_submit failed %d\n", ··· 162 153 } 163 154 164 155 /* ... prepare next one ... */ 165 - prtd->period_ptr_submitted += prtd->period_size; 166 - if (prtd->period_ptr_submitted >= prtd->dma_buffer_end) 167 - prtd->period_ptr_submitted = prtd->dma_buffer_start; 156 + prtd->ch_dma_addr_current += prtd->ch_dma_size; 157 + if (prtd->ch_dma_addr_current >= prtd->ch_dma_addr_end) 158 + prtd->ch_dma_addr_current = prtd->ch_dma_addr_start; 168 159 169 160 /* ... and send it */ 170 161 ret = qmc_chan_write_submit(prtd->qmc_dai->qmc_chan, 171 - prtd->period_ptr_submitted, prtd->period_size, 162 + prtd->ch_dma_addr_current, prtd->ch_dma_size, 172 163 qmc_audio_pcm_write_complete, prtd); 173 164 if (ret) { 174 165 dev_err(component->dev, "write_submit failed %d\n", ··· 178 169 } else { 179 170 /* Submit first chunk ... */ 180 171 ret = qmc_chan_read_submit(prtd->qmc_dai->qmc_chan, 181 - prtd->period_ptr_submitted, prtd->period_size, 172 + prtd->ch_dma_addr_current, prtd->ch_dma_size, 182 173 qmc_audio_pcm_read_complete, prtd); 183 174 if (ret) { 184 175 dev_err(component->dev, "read_submit failed %d\n", ··· 187 178 } 188 179 189 180 /* ... prepare next one ... */ 190 - prtd->period_ptr_submitted += prtd->period_size; 191 - if (prtd->period_ptr_submitted >= prtd->dma_buffer_end) 192 - prtd->period_ptr_submitted = prtd->dma_buffer_start; 181 + prtd->ch_dma_addr_current += prtd->ch_dma_size; 182 + if (prtd->ch_dma_addr_current >= prtd->ch_dma_addr_end) 183 + prtd->ch_dma_addr_current = prtd->ch_dma_addr_start; 193 184 194 185 /* ... and send it */ 195 186 ret = qmc_chan_read_submit(prtd->qmc_dai->qmc_chan, 196 - prtd->period_ptr_submitted, prtd->period_size, 187 + prtd->ch_dma_addr_current, prtd->ch_dma_size, 197 188 qmc_audio_pcm_read_complete, prtd); 198 189 if (ret) { 199 190 dev_err(component->dev, "write_submit failed %d\n", ··· 224 215 { 225 216 struct qmc_dai_prtd *prtd = substream->runtime->private_data; 226 217 227 - return bytes_to_frames(substream->runtime, 228 - prtd->period_ptr_ended - prtd->dma_buffer_start); 218 + return prtd->buffer_ended; 229 219 } 230 220 231 221 static int qmc_audio_of_xlate_dai_name(struct snd_soc_component *component,