ALSA: dice/firewire-lib: Keep dualwire mode but obsolete CIP_HI_DUALWIRE

In previous commit, AMDTP functionality in firewire-lib supports mapping
for PCM data channels. With this mapping, firewire-lib can obsolete
a flag, CIP_HI_DUALWIRE, but Dice driver still keeps dual wire mode.

Signed-off-by: Takashi Sakamoto <o-takashi@sakamocchi.jp>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
diff --git a/sound/firewire/dice.c b/sound/firewire/dice.c
index 26b2158..cd4c6b6 100644
--- a/sound/firewire/dice.c
+++ b/sound/firewire/dice.c
@@ -563,7 +563,7 @@
 			  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);
@@ -575,15 +575,36 @@
 	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));
@@ -1361,7 +1382,7 @@
 	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;