diff --git a/3rdparty/patches/ravenna-alsa-fix-playback-rw-mode.patch b/3rdparty/patches/ravenna-alsa-fix-playback-rw-mode.patch index 9061fd4..33af6c8 100644 --- a/3rdparty/patches/ravenna-alsa-fix-playback-rw-mode.patch +++ b/3rdparty/patches/ravenna-alsa-fix-playback-rw-mode.patch @@ -1,27 +1,525 @@ diff --git a/driver/audio_driver.c b/driver/audio_driver.c -index 3d9debd..cc6240e 100644 --- a/driver/audio_driver.c +++ b/driver/audio_driver.c -@@ -936,6 +936,8 @@ - chip->dma_playback_offset = 0; - chip->dma_playback_buffer = runtime->dma_area; - chip->pcm_playback_buffer_size = snd_pcm_lib_buffer_bytes(chip->playback_substream); -+ // early startup to fix problem with read-write interleaved mode pre-buffering -+ chip->mr_alsa_audio_ops->start_interrupts(chip->ravenna_peer, 1); +@@ -99,24 +99,14 @@ + static struct alsa_ops *g_mr_alsa_audio_ops; + + +-static int mr_alsa_audio_pcm_capture_copy( struct snd_pcm_substream *substream, +- int channel, snd_pcm_uframes_t pos, +- void __user *src, +- snd_pcm_uframes_t count); + static int mr_alsa_audio_pcm_capture_copy_internal( struct snd_pcm_substream *substream, + int channel, uint32_t pos, + void __user *src, +- snd_pcm_uframes_t count, +- bool to_user_space); +-static int mr_alsa_audio_pcm_playback_copy( struct snd_pcm_substream *substream, +- int channel, snd_pcm_uframes_t pos, +- void __user *src, + snd_pcm_uframes_t count); + static int mr_alsa_audio_pcm_playback_copy_internal( struct snd_pcm_substream *substream, + int channel, uint32_t pos, + void __user *src, +- snd_pcm_uframes_t count, +- bool from_user_space); ++ snd_pcm_uframes_t count); + + /// "chip" : the main private structure + struct mr_alsa_audio_chip +@@ -611,6 +601,7 @@ + chip->mr_alsa_audio_ops->get_interrupts_frame_size(chip->ravenna_peer, &ptp_frame_size); + if(direction == 1 && chip->capture_substream != NULL) + { ++ unsigned long bytes_to_frame_factor; + struct snd_pcm_runtime *runtime = chip->capture_substream->runtime; + ring_buffer_size = chip->current_dsd ? MR_ALSA_RINGBUFFER_NB_FRAMES : runtime->period_size * runtime->periods; + if (ring_buffer_size > MR_ALSA_RINGBUFFER_NB_FRAMES) +@@ -620,22 +611,15 @@ + } + + /// DMA case +- if (runtime->access == SNDRV_PCM_ACCESS_MMAP_INTERLEAVED || +- runtime->access == SNDRV_PCM_ACCESS_MMAP_NONINTERLEAVED || +- runtime->access == SNDRV_PCM_ACCESS_MMAP_COMPLEX) +- { +- unsigned long bytes_to_frame_factor = runtime->channels * chip->current_alsa_capture_stride; +- +- //printk(KERN_DEBUG "capture copy pos=%u, dma_pos=%u, count=%u, channels=%d pcm_size=%u\n", chip->capture_buffer_pos, pos, ptp_frame_size, runtime->channels, pcm_buffer_size); +- mr_alsa_audio_pcm_capture_copy_internal(chip->capture_substream, runtime->channels/*channel*/, +- chip->capture_buffer_pos, chip->dma_capture_buffer + chip->dma_capture_offset/**src*/, ptp_frame_size, false); ++ bytes_to_frame_factor = runtime->channels * chip->current_alsa_capture_stride; + +- chip->dma_capture_offset += ptp_frame_size * bytes_to_frame_factor; +- if (chip->dma_capture_offset >= chip->pcm_capture_buffer_size) +- { +- chip->dma_capture_offset -= chip->pcm_capture_buffer_size; +- } +- } ++ //printk(KERN_DEBUG "capture copy pos=%u, dma_pos=%u, count=%u, channels=%d pcm_size=%u\n", chip->capture_buffer_pos, pos, ptp_frame_size, runtime->channels, pcm_buffer_size); ++ mr_alsa_audio_pcm_capture_copy_internal(chip->capture_substream, runtime->channels/*channel*/, ++ chip->capture_buffer_pos, chip->dma_capture_buffer + chip->dma_capture_offset/**src*/, ptp_frame_size); ++ ++ chip->dma_capture_offset += ptp_frame_size * bytes_to_frame_factor; ++ if (chip->dma_capture_offset >= chip->pcm_capture_buffer_size) ++ chip->dma_capture_offset -= chip->pcm_capture_buffer_size; + + chip->capture_buffer_pos += ptp_frame_size; + if(chip->capture_buffer_pos >= ring_buffer_size) +@@ -654,6 +638,7 @@ + } + else if(direction == 0 && chip->playback_substream != NULL) + { ++ unsigned long bytes_to_frame_factor; + struct snd_pcm_runtime *runtime = chip->playback_substream->runtime; + ring_buffer_size = chip->current_dsd ? MR_ALSA_RINGBUFFER_NB_FRAMES : runtime->period_size * runtime->periods; + if (ring_buffer_size > MR_ALSA_RINGBUFFER_NB_FRAMES) +@@ -662,23 +647,14 @@ + return -2; + } + +- /// DMA case +- if (runtime->access == SNDRV_PCM_ACCESS_MMAP_INTERLEAVED || +- runtime->access == SNDRV_PCM_ACCESS_MMAP_NONINTERLEAVED || +- runtime->access == SNDRV_PCM_ACCESS_MMAP_COMPLEX) +- { +- unsigned long bytes_to_frame_factor = runtime->channels * chip->current_alsa_playback_stride; +- +- //printk(KERN_DEBUG "playback copy pos=%u, dma_pos=%u, count=%u, channels=%d pcm_size=%u\n", chip->playback_buffer_pos, pos, ptp_frame_size, runtime->channels, pcm_buffer_size); +- mr_alsa_audio_pcm_playback_copy_internal(chip->playback_substream, runtime->channels/*channel*/, +- chip->playback_buffer_pos/*pos*/, chip->dma_playback_buffer + chip->dma_playback_offset/*src*/, ptp_frame_size/*count*/, false); +- +- chip->dma_playback_offset += ptp_frame_size * bytes_to_frame_factor; +- if (chip->dma_playback_offset >= chip->pcm_playback_buffer_size) +- { +- chip->dma_playback_offset -= chip->pcm_playback_buffer_size; +- } +- } ++ bytes_to_frame_factor = runtime->channels * chip->current_alsa_playback_stride; ++ //printk(KERN_DEBUG "playback copy pos=%u, dma_pos=%u, count=%u, channels=%d pcm_size=%u\n", chip->playback_buffer_pos, pos, ptp_frame_size, runtime->channels, pcm_buffer_size); ++ mr_alsa_audio_pcm_playback_copy_internal(chip->playback_substream, runtime->channels/*channel*/, ++ chip->playback_buffer_pos/*pos*/, chip->dma_playback_buffer + chip->dma_playback_offset/*src*/, ptp_frame_size/*count*/); ++ ++ chip->dma_playback_offset += ptp_frame_size * bytes_to_frame_factor; ++ if (chip->dma_playback_offset >= chip->pcm_playback_buffer_size) ++ chip->dma_playback_offset -= chip->pcm_playback_buffer_size; + + chip->playback_buffer_pos += ptp_frame_size; + if (chip->playback_buffer_pos >= ring_buffer_size) +@@ -988,18 +964,9 @@ + if(alsa_sub->stream == SNDRV_PCM_STREAM_PLAYBACK) + { + /// DMA case +- if (alsa_sub->runtime->access == SNDRV_PCM_ACCESS_MMAP_INTERLEAVED || +- alsa_sub->runtime->access == SNDRV_PCM_ACCESS_MMAP_NONINTERLEAVED || +- alsa_sub->runtime->access == SNDRV_PCM_ACCESS_MMAP_COMPLEX) +- { +- struct snd_pcm_runtime *runtime = alsa_sub->runtime; +- unsigned long bytes_to_frame_factor = runtime->channels * chip->current_alsa_playback_stride; +- offset = chip->dma_playback_offset / bytes_to_frame_factor; +- } +- else +- { +- offset = chip->playback_buffer_pos; +- } ++ struct snd_pcm_runtime *runtime = alsa_sub->runtime; ++ unsigned long bytes_to_frame_factor = runtime->channels * chip->current_alsa_playback_stride; ++ offset = chip->dma_playback_offset / bytes_to_frame_factor; + + /// Ravenna DSD always uses a rate of 352k with eventual zero padding to maintain a 32 bit alignment + /// while DSD in ALSA uses a continuous 8, 16 or 32 bit aligned stream with at 352k, 176k or 88k +@@ -1022,19 +989,9 @@ + } + else if(alsa_sub->stream == SNDRV_PCM_STREAM_CAPTURE) + { +- /// DMA case +- if (alsa_sub->runtime->access == SNDRV_PCM_ACCESS_MMAP_INTERLEAVED || +- alsa_sub->runtime->access == SNDRV_PCM_ACCESS_MMAP_NONINTERLEAVED || +- alsa_sub->runtime->access == SNDRV_PCM_ACCESS_MMAP_COMPLEX) +- { +- struct snd_pcm_runtime *runtime = alsa_sub->runtime; +- unsigned long bytes_to_frame_factor = runtime->channels * chip->current_alsa_capture_stride; +- offset = chip->dma_capture_offset / bytes_to_frame_factor; +- } +- else +- { +- chip->mr_alsa_audio_ops->get_input_jitter_buffer_offset(chip->ravenna_peer, &offset); +- } ++ struct snd_pcm_runtime *runtime = alsa_sub->runtime; ++ unsigned long bytes_to_frame_factor = runtime->channels * chip->current_alsa_capture_stride; ++ offset = chip->dma_capture_offset / bytes_to_frame_factor; + + /// Ravenna DSD always uses a rate of 352k with eventual zero padding to maintain a 32 bit alignment + /// while DSD in ALSA uses a continuous 8, 16 or 32 bit aligned stream with at 352k, 176k or 88k +@@ -1166,36 +1123,10 @@ + }; + + +-#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,13,0) +-static int mr_alsa_audio_pcm_capture_copy_user( struct snd_pcm_substream *substream, +- int channel, unsigned long pos, +- void __user *src, +- unsigned long count) +- { +- struct mr_alsa_audio_chip* chip = snd_pcm_substream_chip(substream); +- struct snd_pcm_runtime *runtime = substream->runtime; +- bool interleaved = runtime->access == SNDRV_PCM_ACCESS_RW_INTERLEAVED ? 1 : 0; +- unsigned long bytes_to_frame_factor = runtime->channels * chip->current_alsa_capture_stride; +- return mr_alsa_audio_pcm_capture_copy(substream, interleaved ? -1 : channel, pos / bytes_to_frame_factor, src, count / bytes_to_frame_factor); +-} +-#endif +- +-static int mr_alsa_audio_pcm_capture_copy( struct snd_pcm_substream *substream, +- int channel, snd_pcm_uframes_t pos, +- void __user *src, +- snd_pcm_uframes_t count) +-{ +- struct mr_alsa_audio_chip *chip = snd_pcm_substream_chip(substream); +- uint32_t ravenna_buffer_pos = pos * chip->nb_capture_interrupts_per_period; +- +- return mr_alsa_audio_pcm_capture_copy_internal(substream, channel, ravenna_buffer_pos, src, count, true); +-} +- + static int mr_alsa_audio_pcm_capture_copy_internal( struct snd_pcm_substream *substream, + int channel, uint32_t pos, + void __user *src, +- snd_pcm_uframes_t count, +- bool to_user_space) ++ snd_pcm_uframes_t count) + { + struct mr_alsa_audio_chip *chip = snd_pcm_substream_chip(substream); + struct snd_pcm_runtime *runtime = substream->runtime; +@@ -1204,43 +1135,22 @@ + unsigned int strideIn = chip->current_alsa_capture_stride; + uint32_t ravenna_buffer_pos = pos; + +- // todo DSD capture +- //uint32_t dsdrate = mr_alsa_audio_get_dsd_sample_rate(runtime->format, runtime->rate); +- //uint32_t dsdmode = (dsdrate > 0? mr_alsa_audio_get_dsd_mode(dsdrate) : 0); +- +- +- /// Ravenna DSD always uses a rate of 352k with eventual zero padding to maintain a 32 bit alignment +- /// while DSD in ALSA uses a continuous 8, 16 or 32 bit aligned stream with at 352k, 176k or 88k +- /// so respective ring buffers might have different scale and size +- //uint32_t alsa_ring_buffer_nb_frames = MR_ALSA_RINGBUFFER_NB_FRAMES / chip->nb_capture_interrupts_per_period; +- +- //printk("entering mr_alsa_audio_pcm_capture_copy (channel=%d, count=%lu) (substream name=%s #%d) ...\n", channel, count, substream->name, substream->number); +- //printk("Bitwidth = %u, strideIn = %u\n", nb_logical_bits, strideIn); +- +- //if(snd_BUG_ON(ravenna_buffer_pos >= MR_ALSA_RINGBUFFER_NB_FRAMES)) +- // ravenna_buffer_pos -= MR_ALSA_RINGBUFFER_NB_FRAMES; +- +- +- //printk("capture_copy: rate = %u, dsdmode = %u, #IRQ per period = %u, count = %lu, pos = %lu, ravenna_buffer_pos = %u\n", (dsdrate > 0? dsdrate : runtime->rate), dsdmode, chip->nb_capture_interrupts_per_period, count, pos, ravenna_buffer_pos); +- //printk("capture_copy: rate = %u, #IRQ per period = %u, count = %zu, pos = %u, ravenna_buffer_pos = %u, channels = %u\n", runtime->rate, chip->nb_capture_interrupts_per_period, count, pos, ravenna_buffer_pos, runtime->channels); +- +- + if(interleaved) + { + switch(nb_logical_bits) + { + case 16: +- MTConvertMappedInt32ToInt16LEInterleave(chip->capture_buffer_channels_map, ravenna_buffer_pos, src, runtime->channels, count, to_user_space); ++ MTConvertMappedInt32ToInt16LEInterleave(chip->capture_buffer_channels_map, ravenna_buffer_pos, src, runtime->channels, count, false); + break; + case 24: + { + switch(strideIn) + { + case 3: +- MTConvertMappedInt32ToInt24LEInterleave(chip->capture_buffer_channels_map, ravenna_buffer_pos, src, runtime->channels, count, to_user_space); ++ MTConvertMappedInt32ToInt24LEInterleave(chip->capture_buffer_channels_map, ravenna_buffer_pos, src, runtime->channels, count, false); + break; + case 4: +- MTConvertMappedInt32ToInt24LE4ByteInterleave(chip->capture_buffer_channels_map, ravenna_buffer_pos, src, runtime->channels, count, to_user_space); ++ MTConvertMappedInt32ToInt24LE4ByteInterleave(chip->capture_buffer_channels_map, ravenna_buffer_pos, src, runtime->channels, count, false); + break; + default: + { +@@ -1251,7 +1161,7 @@ + break; + } + case 32: +- MTConvertMappedInt32ToInt32LEInterleave(chip->capture_buffer_channels_map, ravenna_buffer_pos, src, runtime->channels, count, to_user_space); ++ MTConvertMappedInt32ToInt32LEInterleave(chip->capture_buffer_channels_map, ravenna_buffer_pos, src, runtime->channels, count, false); + break; } - else if(substream->stream == SNDRV_PCM_STREAM_CAPTURE) + } +@@ -1263,47 +1173,11 @@ + return count; + } + +-/// This callback is called whenever the alsa application wants to write data +-/// We use it here to do all the de-interleaving, format conversion and DSD re-packing +-/// The intermediate buffer is actually the alsa (dma) buffer, allocated in hw_params() +-/// The incoming data (src) is user land memory pointer, so copy_from_user() must be used for memory copy +-#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,13,0) +-static int mr_alsa_audio_pcm_playback_copy_user( struct snd_pcm_substream *substream, +- int channel, unsigned long pos, +- void __user *src, +- unsigned long count) +-{ +- struct mr_alsa_audio_chip* chip = snd_pcm_substream_chip(substream); +- struct snd_pcm_runtime *runtime = substream->runtime; +- unsigned long bytes_to_frame_factor = runtime->channels * chip->current_alsa_playback_stride; +- return mr_alsa_audio_pcm_playback_copy(substream, channel, pos / bytes_to_frame_factor, src, count / bytes_to_frame_factor); +-} +-#endif +- +-/// This callback is called whenever the alsa application wants to write data +-/// We use it here to do all the de-interleaving, format conversion and DSD re-packing +-/// The intermediate buffer is actually the alsa (dma) buffer, allocated in hw_params() +-/// The incoming data (src) is user land memory pointer, so copy_from_user() must be used for memory copy +-static int mr_alsa_audio_pcm_playback_copy( struct snd_pcm_substream *substream, +- int channel, snd_pcm_uframes_t pos, +- void __user *src, +- snd_pcm_uframes_t count) +-{ +- struct mr_alsa_audio_chip *chip = snd_pcm_substream_chip(substream); +- /// Ravenna DSD always uses a rate of 352k with eventual zero padding to maintain a 32 bit alignment +- /// while DSD in ALSA uses a continuous 8, 16 or 32 bit aligned stream with at 352k, 176k or 88k +- /// so respective ring buffers might have different scale and size +- uint32_t ravenna_buffer_pos = pos * chip->nb_playback_interrupts_per_period; +- +- return mr_alsa_audio_pcm_playback_copy_internal(substream, channel, ravenna_buffer_pos, src, count, true); +-} +- + + static int mr_alsa_audio_pcm_playback_copy_internal( struct snd_pcm_substream *substream, + int channel, uint32_t pos, + void __user *src, +- snd_pcm_uframes_t count, +- bool from_user_space) ++ snd_pcm_uframes_t count) + { + struct mr_alsa_audio_chip *chip = snd_pcm_substream_chip(substream); + struct snd_pcm_runtime *runtime = substream->runtime; +@@ -1316,8 +1190,6 @@ + uint32_t dsdmode = (dsdrate > 0? mr_alsa_audio_get_dsd_mode(dsdrate) : 0); + uint32_t ravenna_buffer_pos = pos; + +- //printk("playback_copy: rate = %u, dsdmode = %u, #IRQ per period = %u, count = %u, pos = %lu, ravenna_buffer_pos = %u, alsa_pb_sac = %llu, ravenna_pb_sac = %llu\n", (dsdrate > 0? dsdrate : runtime->rate), dsdmode, chip->nb_playback_interrupts_per_period, count, pos, ravenna_buffer_pos, chip->playback_buffer_alsa_sac, chip->playback_buffer_rav_sac); +- + if(interleaved) + { + /// de-interleaving +@@ -1325,145 +1197,70 @@ + unsigned int stepIn = runtime->channels * strideIn; + unsigned int stepOut = strideOut * chip->nb_playback_interrupts_per_period; + uint32_t ring_buffer_size = MR_ALSA_RINGBUFFER_NB_FRAMES * strideOut; +- //printk("playback_copy: de-interleaving %u frames, pos = %llu, ravenna_buffer_pos = %u, with strideIn = %u, strideOut = %u, stepIn = %u, stepOut = %u, ravBuffer_csize = %u \n", count, pos, ravenna_buffer_pos, strideIn, strideOut, stepIn, stepOut, (unsigned int)ravBuffer_csize); + +- if (from_user_space) ++ for (chn = 0; chn < runtime->channels; ++chn) { -index 5a90eca..8023708 100644 ---- a/driver/manager.c -+++ b/driver/manager.c -@@ -271,6 +271,10 @@ - return false; - - MTAL_DP("MergingRAVENNAAudioDriver::startIO\n"); -+ if (is_playback && self->m_bIsPlaybackIO) -+ return true; -+ if (!is_playback && self->m_bIsRecordingIO) -+ return true; - - if (!is_playback) { - printk(KERN_DEBUG "starting capture I/O\n"); +- for (chn = 0; chn < runtime->channels; ++chn) ++ uint32_t currentOutPos = ravenna_buffer_pos * strideOut; ++ snd_pcm_uframes_t frmCnt = 0; ++ in = (unsigned char*)src + chn * strideIn; ++ out = chip->playback_buffer + chn * ring_buffer_size + currentOutPos; ++ // ++ ///Conversion to Signed integer 32 bit LE ++ for (frmCnt = 0; frmCnt < count; ++frmCnt) + { +- uint32_t currentOutPos = ravenna_buffer_pos * strideOut; +- snd_pcm_uframes_t frmCnt = 0; +- in = (unsigned char*)src + chn * strideIn; +- out = chip->playback_buffer + chn * ring_buffer_size + currentOutPos; +- // +- ///Conversion to Signed integer 32 bit LE +- for (frmCnt = 0; frmCnt < count; ++frmCnt) ++ /// assumes Little Endian ++ if (dsdmode == 0) + { +- /// assumes Little Endian +- int32_t val = 0; +- if (dsdmode == 0) +- { +- switch (nb_logical_bits) +- { +- case 16: +- __get_user(((unsigned char*)&val)[3], &in[1]); +- __get_user(((unsigned char*)&val)[2], &in[0]); +- break; +- case 24: +- __get_user(((unsigned char*)&val)[3], &in[2]); +- __get_user(((unsigned char*)&val)[2], &in[1]); +- __get_user(((unsigned char*)&val)[1], &in[0]); +- break; +- case 32: +- __get_user(val, (int32_t*)in); +- break; +- } +- *((int32_t*)out) = val; +- } +- else +- { +- /// interleaved DSD stream to non interleaved 32 bit aligned blocks with 1/2/4 DSD bytes per 32 bit +- uint32_t out_cnt; +- for (out_cnt = 0; out_cnt < chip->nb_playback_interrupts_per_period; ++out_cnt) +- { +- switch (dsdmode) +- { +- case 1: ///DSD64 +- __get_user(((unsigned char*)&val)[0], &in[out_cnt]); +- break; +- case 2: ///DSD128 +- __get_user(((unsigned char*)&val)[1], &in[2 * out_cnt + 1]); +- __get_user(((unsigned char*)&val)[0], &in[2 * out_cnt]); +- break; +- case 4: ///DSD256 +- __get_user(val, (int32_t*)in); +- break; +- } +- ((int32_t*)out)[out_cnt] = val; +- } +- } +- +- in += stepIn; +- if (currentOutPos + stepOut >= ring_buffer_size) ++ switch (nb_logical_bits) + { +- currentOutPos = 0; +- out = chip->playback_buffer + chn * ring_buffer_size; +- } +- else +- { +- currentOutPos += stepOut; +- out += stepOut; ++ case 16: ++ out[3] = in[1]; ++ out[2] = in[0]; ++ out[1] = 0; ++ out[0] = 0; ++ break; ++ case 24: ++ out[3] = in[2]; ++ out[2] = in[1]; ++ out[1] = in[0]; ++ out[0] = 0; ++ break; ++ case 32: ++ *(int32_t*)out = *(int32_t*)in; ++ break; + } + } +- } +- } +- else +- { +- for (chn = 0; chn < runtime->channels; ++chn) +- { +- uint32_t currentOutPos = ravenna_buffer_pos * strideOut; +- snd_pcm_uframes_t frmCnt = 0; +- in = (unsigned char*)src + chn * strideIn; +- out = chip->playback_buffer + chn * ring_buffer_size + currentOutPos; +- // +- ///Conversion to Signed integer 32 bit LE +- for (frmCnt = 0; frmCnt < count; ++frmCnt) ++ else + { +- /// assumes Little Endian +- int32_t val = 0; +- if (dsdmode == 0) ++ /// interleaved DSD stream to non interleaved 32 bit aligned blocks with 1/2/4 DSD bytes per 32 bit ++ uint32_t out_cnt; ++ for (out_cnt = 0; out_cnt < chip->nb_playback_interrupts_per_period; ++out_cnt) + { +- switch (nb_logical_bits) ++ switch (dsdmode) + { +- case 16: +- +- ((unsigned char*)&val)[3] = in[1]; +- ((unsigned char*)&val)[2] = in[0]; ++ case 1: ///DSD64 ++ ((int32_t*)out)[out_cnt] = *(int32_t*)(in + out_cnt) & 0xFF; + break; +- case 24: +- ((unsigned char*)&val)[3] = in[2]; +- ((unsigned char*)&val)[2] = in[1]; +- ((unsigned char*)&val)[1] = in[0]; ++ case 2: ///DSD128 ++ ((int32_t*)out)[out_cnt] = (((int32_t)(in[2 * out_cnt + 1]) << 8) | ((int32_t)(in[2 * out_cnt]))) & 0xFFFF; + break; +- case 32: +- val = *(int32_t*)(in); ++ case 4: ///DSD256 ++ ((int32_t*)out)[out_cnt] = *(int32_t*)(in); + break; + } +- *((int32_t*)out) = val; +- } +- else +- { +- /// interleaved DSD stream to non interleaved 32 bit aligned blocks with 1/2/4 DSD bytes per 32 bit +- uint32_t out_cnt; +- for (out_cnt = 0; out_cnt < chip->nb_playback_interrupts_per_period; ++out_cnt) +- { +- switch (dsdmode) +- { +- case 1: ///DSD64 +- val = *(int32_t*)(in + out_cnt) & 0xFF; +- break; +- case 2: ///DSD128 +- val = (((int32_t)(in[2 * out_cnt + 1]) << 8) | ((int32_t)(in[2 * out_cnt]))) & 0xFFFF; +- break; +- case 4: ///DSD256 +- val = *(int32_t*)(in); +- break; +- } +- ((int32_t*)out)[out_cnt] = val; +- } + } ++ } + +- in += stepIn; +- if (currentOutPos + stepOut >= ring_buffer_size) +- { +- currentOutPos = 0; +- out = chip->playback_buffer + chn * ring_buffer_size; +- } +- else +- { +- currentOutPos += stepOut; +- out += stepOut; +- } ++ in += stepIn; ++ if (currentOutPos + stepOut >= ring_buffer_size) ++ { ++ currentOutPos = 0; ++ out = chip->playback_buffer + chn * ring_buffer_size; ++ } ++ else ++ { ++ currentOutPos += stepOut; ++ out += stepOut; + } + } + } +@@ -2042,11 +1839,6 @@ + .prepare = mr_alsa_audio_pcm_prepare, + .trigger = mr_alsa_audio_pcm_trigger, + .pointer = mr_alsa_audio_pcm_pointer, +-#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,13,0) +- .copy_user = mr_alsa_audio_pcm_playback_copy_user, +-#else +- .copy = mr_alsa_audio_pcm_playback_copy, +-#endif + .page = snd_pcm_lib_get_vmalloc_page, + }; + +@@ -2060,13 +1852,6 @@ + .prepare = mr_alsa_audio_pcm_prepare, + .trigger = mr_alsa_audio_pcm_trigger, + .pointer = mr_alsa_audio_pcm_pointer, +-#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,13,0) +- .copy_user = mr_alsa_audio_pcm_capture_copy_user, +- .fill_silence = NULL, +-#else +- .copy = mr_alsa_audio_pcm_capture_copy, +- .silence = NULL, //mr_alsa_audio_pcm_silence, +-#endif + .page = snd_pcm_lib_get_vmalloc_page, + }; +