return;
 
 sfc_found:
-       s->dual_wire = (s->flags & CIP_HI_DUALWIRE) && sfc > CIP_SFC_96000;
-       if (s->dual_wire) {
-               sfc -= 2;
-               rate /= 2;
-               s->pcm_channels = pcm_channels * 2;
-       } else {
-               s->pcm_channels = pcm_channels;
-       }
+       s->pcm_channels = pcm_channels;
        s->sfc = sfc;
        s->data_block_quadlets = s->pcm_channels + midi_channels;
        s->midi_ports = midi_ports;
 static void amdtp_write_s32(struct amdtp_stream *s,
                            struct snd_pcm_substream *pcm,
                            __be32 *buffer, unsigned int frames);
-static void amdtp_write_s16_dualwire(struct amdtp_stream *s,
-                                    struct snd_pcm_substream *pcm,
-                                    __be32 *buffer, unsigned int frames);
-static void amdtp_write_s32_dualwire(struct amdtp_stream *s,
-                                    struct snd_pcm_substream *pcm,
-                                    __be32 *buffer, unsigned int frames);
 static void amdtp_read_s32(struct amdtp_stream *s,
                           struct snd_pcm_substream *pcm,
                           __be32 *buffer, unsigned int frames);
-static void amdtp_read_s32_dualwire(struct amdtp_stream *s,
-                                   struct snd_pcm_substream *pcm,
-                                   __be32 *buffer, unsigned int frames);
 
 /**
  * amdtp_stream_set_pcm_format - set the PCM format
                /* fall through */
        case SNDRV_PCM_FORMAT_S16:
                if (s->direction == AMDTP_OUT_STREAM) {
-                       if (s->dual_wire)
-                               s->transfer_samples = amdtp_write_s16_dualwire;
-                       else
-                               s->transfer_samples = amdtp_write_s16;
+                       s->transfer_samples = amdtp_write_s16;
                        break;
                }
                WARN_ON(1);
                /* fall through */
        case SNDRV_PCM_FORMAT_S32:
-               if (s->direction == AMDTP_OUT_STREAM) {
-                       if (s->dual_wire)
-                               s->transfer_samples = amdtp_write_s32_dualwire;
-                       else
-                               s->transfer_samples = amdtp_write_s32;
-               } else {
-                       if (s->dual_wire)
-                               s->transfer_samples = amdtp_read_s32_dualwire;
-                       else
-                               s->transfer_samples = amdtp_read_s32;
-               }
+               if (s->direction == AMDTP_OUT_STREAM)
+                       s->transfer_samples = amdtp_write_s32;
+               else
+                       s->transfer_samples = amdtp_read_s32;
                break;
        }
 }
        }
 }
 
-static void amdtp_write_s32_dualwire(struct amdtp_stream *s,
-                                    struct snd_pcm_substream *pcm,
-                                    __be32 *buffer, unsigned int frames)
-{
-       struct snd_pcm_runtime *runtime = pcm->runtime;
-       unsigned int channels, remaining_frames, i, c;
-       const u32 *src;
-
-       src = (void *)runtime->dma_area +
-                       frames_to_bytes(runtime, s->pcm_buffer_pointer);
-       remaining_frames = runtime->buffer_size - s->pcm_buffer_pointer;
-       channels = s->pcm_channels / 2;
-
-       for (i = 0; i < frames; ++i) {
-               for (c = 0; c < channels; ++c) {
-                       buffer[s->pcm_positions[c] * 2] =
-                                       cpu_to_be32((*src >> 8) | 0x40000000);
-                       src++;
-               }
-               buffer += 1;
-               for (c = 0; c < channels; ++c) {
-                       buffer[s->pcm_positions[c] * 2] =
-                                       cpu_to_be32((*src >> 8) | 0x40000000);
-                       src++;
-               }
-               buffer += s->data_block_quadlets - 1;
-               if (--remaining_frames == 0)
-                       src = (void *)runtime->dma_area;
-       }
-}
-
-static void amdtp_write_s16_dualwire(struct amdtp_stream *s,
-                                    struct snd_pcm_substream *pcm,
-                                    __be32 *buffer, unsigned int frames)
-{
-       struct snd_pcm_runtime *runtime = pcm->runtime;
-       unsigned int channels, remaining_frames, i, c;
-       const u16 *src;
-
-       src = (void *)runtime->dma_area +
-                       frames_to_bytes(runtime, s->pcm_buffer_pointer);
-       remaining_frames = runtime->buffer_size - s->pcm_buffer_pointer;
-       channels = s->pcm_channels / 2;
-
-       for (i = 0; i < frames; ++i) {
-               for (c = 0; c < channels; ++c) {
-                       buffer[s->pcm_positions[c] * 2] =
-                                       cpu_to_be32((*src << 8) | 0x40000000);
-                       src++;
-               }
-               buffer += 1;
-               for (c = 0; c < channels; ++c) {
-                       buffer[s->pcm_positions[c] * 2] =
-                                       cpu_to_be32((*src << 8) | 0x40000000);
-                       src++;
-               }
-               buffer += s->data_block_quadlets - 1;
-               if (--remaining_frames == 0)
-                       src = (void *)runtime->dma_area;
-       }
-}
-
 static void amdtp_read_s32(struct amdtp_stream *s,
                           struct snd_pcm_substream *pcm,
                           __be32 *buffer, unsigned int frames)
        }
 }
 
-static void amdtp_read_s32_dualwire(struct amdtp_stream *s,
-                                   struct snd_pcm_substream *pcm,
-                                   __be32 *buffer, unsigned int frames)
-{
-       struct snd_pcm_runtime *runtime = pcm->runtime;
-       unsigned int channels, remaining_frames, i, c;
-       u32 *dst;
-
-       dst = (void *)runtime->dma_area +
-                       frames_to_bytes(runtime, s->pcm_buffer_pointer);
-       remaining_frames = runtime->buffer_size - s->pcm_buffer_pointer;
-       channels = s->pcm_channels / 2;
-
-       for (i = 0; i < frames; ++i) {
-               for (c = 0; c < channels; ++c) {
-                       *dst =
-                            be32_to_cpu(buffer[s->pcm_positions[c] * 2]) << 8;
-                       dst++;
-               }
-               buffer += 1;
-               for (c = 0; c < channels; ++c) {
-                       *dst =
-                            be32_to_cpu(buffer[s->pcm_positions[c] * 2]) << 8;
-                       dst++;
-               }
-               buffer += s->data_block_quadlets - 1;
-               if (--remaining_frames == 0)
-                       dst = (void *)runtime->dma_area;
-       }
-}
-
 static void amdtp_fill_pcm_silence(struct amdtp_stream *s,
                                   __be32 *buffer, unsigned int frames)
 {
        }
 }
 
-static void amdtp_fill_pcm_silence_dualwire(struct amdtp_stream *s,
-                                          __be32 *buffer, unsigned int frames)
-{
-       unsigned int i, c, channels;
-
-       channels = s->pcm_channels / 2;
-       for (i = 0; i < frames; ++i) {
-               for (c = 0; c < channels; ++c) {
-                       buffer[s->pcm_positions[c] * 2] =
-                       buffer[s->pcm_positions[c] * 2 + 1] =
-                                               cpu_to_be32(0x40000000);
-               }
-               buffer += s->data_block_quadlets;
-       }
-}
 static void amdtp_fill_midi(struct amdtp_stream *s,
                            __be32 *buffer, unsigned int frames)
 {
                                unsigned int frames)
 {      unsigned int ptr;
 
-       if (s->dual_wire)
-               frames *= 2;
-
        ptr = s->pcm_buffer_pointer + frames;
        if (ptr >= pcm->runtime->buffer_size)
                ptr -= pcm->runtime->buffer_size;
        pcm = ACCESS_ONCE(s->pcm);
        if (pcm)
                s->transfer_samples(s, pcm, buffer, data_blocks);
-       else if (s->dual_wire)
-               amdtp_fill_pcm_silence_dualwire(s, buffer, data_blocks);
        else
                amdtp_fill_pcm_silence(s, buffer, data_blocks);
        if (s->midi_ports)
 
                          struct snd_pcm_hw_params *hw_params)
 {
        struct dice *dice = substream->private_data;
-       unsigned int rate_index, mode;
+       unsigned int rate_index, mode, rate, channels, i;
        int err;
 
        mutex_lock(&dice->mutex);
        if (err < 0)
                return err;
 
-       rate_index = rate_to_index(params_rate(hw_params));
+       rate = params_rate(hw_params);
+       rate_index = rate_to_index(rate);
        err = dice_change_rate(dice, rate_index << CLOCK_RATE_SHIFT);
        if (err < 0)
                return err;
 
+       /*
+        * At rates above 96 kHz, pretend that the stream runs at half the
+        * actual sample rate with twice the number of channels; two samples
+        * of a channel are stored consecutively in the packet. Requires
+        * blocking mode and PCM buffer size should be aligned to SYT_INTERVAL.
+        */
+       channels = params_channels(hw_params);
+       if (rate_index > 4) {
+               if (channels > AMDTP_MAX_CHANNELS_FOR_PCM / 2) {
+                       err = -ENOSYS;
+                       return err;
+               }
+
+               for (i = 0; i < channels; i++) {
+                       dice->stream.pcm_positions[i * 2] = i;
+                       dice->stream.pcm_positions[i * 2 + 1] = i + channels;
+               }
+
+               rate /= 2;
+               channels *= 2;
+       }
+
        mode = rate_index_to_mode(rate_index);
-       amdtp_stream_set_parameters(&dice->stream,
-                                   params_rate(hw_params),
-                                   params_channels(hw_params),
+       amdtp_stream_set_parameters(&dice->stream, rate, channels,
                                    dice->rx_midi_ports[mode]);
        amdtp_stream_set_pcm_format(&dice->stream,
                                    params_format(hw_params));
        dice->resources.channels_mask = 0x00000000ffffffffuLL;
 
        err = amdtp_stream_init(&dice->stream, unit, AMDTP_OUT_STREAM,
-                               CIP_BLOCKING | CIP_HI_DUALWIRE);
+                               CIP_BLOCKING);
        if (err < 0)
                goto err_resources;