diff --git a/sound/firewire/dice/dice-pcm.c b/sound/firewire/dice/dice-pcm.c
index e252949..3762bd3 100644
--- a/sound/firewire/dice/dice-pcm.c
+++ b/sound/firewire/dice/dice-pcm.c
@@ -11,28 +11,34 @@
 
 static int limit_channels_and_rates(struct snd_dice *dice,
 				    struct snd_pcm_runtime *runtime,
-				    struct amdtp_stream *stream)
+				    enum amdtp_stream_direction dir,
+				    unsigned int index, unsigned int size)
 {
 	struct snd_pcm_hardware *hw = &runtime->hw;
+	struct amdtp_stream *stream;
 	unsigned int rate;
-	__be32 reg[2];
+	__be32 reg;
 	int err;
 
 	/*
 	 * Retrieve current Multi Bit Linear Audio data channel and limit to
 	 * it.
 	 */
-	if (stream == &dice->tx_stream[0]) {
-		err = snd_dice_transaction_read_tx(dice, TX_NUMBER_AUDIO,
-						   reg, sizeof(reg));
+	if (dir == AMDTP_IN_STREAM) {
+		stream = &dice->tx_stream[index];
+		err = snd_dice_transaction_read_tx(dice,
+				size * index + TX_NUMBER_AUDIO,
+				&reg, sizeof(reg));
 	} else {
-		err = snd_dice_transaction_read_rx(dice, RX_NUMBER_AUDIO,
-						   reg, sizeof(reg));
+		stream = &dice->rx_stream[index];
+		err = snd_dice_transaction_read_rx(dice,
+				size * index + RX_NUMBER_AUDIO,
+				&reg, sizeof(reg));
 	}
 	if (err < 0)
 		return err;
 
-	hw->channels_min = hw->channels_max = be32_to_cpu(reg[0]);
+	hw->channels_min = hw->channels_max = be32_to_cpu(reg);
 
 	/* Retrieve current sampling transfer frequency and limit to it. */
 	err = snd_dice_transaction_get_rate(dice, &rate);
@@ -62,7 +68,10 @@ static int init_hw_info(struct snd_dice *dice,
 {
 	struct snd_pcm_runtime *runtime = substream->runtime;
 	struct snd_pcm_hardware *hw = &runtime->hw;
+	enum amdtp_stream_direction dir;
 	struct amdtp_stream *stream;
+	__be32 reg[2];
+	unsigned int count, size;
 	int err;
 
 	hw->info = SNDRV_PCM_INFO_MMAP |
@@ -74,13 +83,28 @@ static int init_hw_info(struct snd_dice *dice,
 
 	if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) {
 		hw->formats = AM824_IN_PCM_FORMAT_BITS;
-		stream = &dice->tx_stream[0];
+		dir = AMDTP_IN_STREAM;
+		stream = &dice->tx_stream[substream->number];
+		err = snd_dice_transaction_read_tx(dice, TX_NUMBER, reg,
+						   sizeof(reg));
 	} else {
 		hw->formats = AM824_OUT_PCM_FORMAT_BITS;
-		stream = &dice->rx_stream[0];
+		dir = AMDTP_OUT_STREAM;
+		stream = &dice->rx_stream[substream->number];
+		err = snd_dice_transaction_read_rx(dice, RX_NUMBER, reg,
+						   sizeof(reg));
 	}
 
-	err = limit_channels_and_rates(dice, runtime, stream);
+	if (err < 0)
+		return err;
+
+	count = min_t(unsigned int, be32_to_cpu(reg[0]), MAX_STREAMS);
+	if (substream->number >= count)
+		return -ENXIO;
+
+	size = be32_to_cpu(reg[1]) * 4;
+	err = limit_channels_and_rates(dice, substream->runtime, dir,
+				       substream->number, size);
 	if (err < 0)
 		return err;
 	limit_period_and_buffer(hw);
@@ -122,7 +146,7 @@ static int capture_hw_params(struct snd_pcm_substream *substream,
 			     struct snd_pcm_hw_params *hw_params)
 {
 	struct snd_dice *dice = substream->private_data;
-	struct amdtp_stream *stream = &dice->tx_stream[0];
+	struct amdtp_stream *stream = &dice->tx_stream[substream->number];
 	int err;
 
 	err = snd_pcm_lib_alloc_vmalloc_buffer(substream,
@@ -144,7 +168,7 @@ static int playback_hw_params(struct snd_pcm_substream *substream,
 			      struct snd_pcm_hw_params *hw_params)
 {
 	struct snd_dice *dice = substream->private_data;
-	struct amdtp_stream *stream = &dice->rx_stream[0];
+	struct amdtp_stream *stream = &dice->rx_stream[substream->number];
 	int err;
 
 	err = snd_pcm_lib_alloc_vmalloc_buffer(substream,
@@ -198,7 +222,7 @@ static int playback_hw_free(struct snd_pcm_substream *substream)
 static int capture_prepare(struct snd_pcm_substream *substream)
 {
 	struct snd_dice *dice = substream->private_data;
-	struct amdtp_stream *stream = &dice->tx_stream[0];
+	struct amdtp_stream *stream = &dice->tx_stream[substream->number];
 	int err;
 
 	mutex_lock(&dice->mutex);
@@ -212,7 +236,7 @@ static int capture_prepare(struct snd_pcm_substream *substream)
 static int playback_prepare(struct snd_pcm_substream *substream)
 {
 	struct snd_dice *dice = substream->private_data;
-	struct amdtp_stream *stream = &dice->rx_stream[0];
+	struct amdtp_stream *stream = &dice->rx_stream[substream->number];
 	int err;
 
 	mutex_lock(&dice->mutex);
@@ -227,7 +251,7 @@ static int playback_prepare(struct snd_pcm_substream *substream)
 static int capture_trigger(struct snd_pcm_substream *substream, int cmd)
 {
 	struct snd_dice *dice = substream->private_data;
-	struct amdtp_stream *stream = &dice->tx_stream[0];
+	struct amdtp_stream *stream = &dice->tx_stream[substream->number];
 
 	switch (cmd) {
 	case SNDRV_PCM_TRIGGER_START:
@@ -245,7 +269,7 @@ static int capture_trigger(struct snd_pcm_substream *substream, int cmd)
 static int playback_trigger(struct snd_pcm_substream *substream, int cmd)
 {
 	struct snd_dice *dice = substream->private_data;
-	struct amdtp_stream *stream = &dice->rx_stream[0];
+	struct amdtp_stream *stream = &dice->rx_stream[substream->number];
 
 	switch (cmd) {
 	case SNDRV_PCM_TRIGGER_START:
@@ -264,14 +288,14 @@ static int playback_trigger(struct snd_pcm_substream *substream, int cmd)
 static snd_pcm_uframes_t capture_pointer(struct snd_pcm_substream *substream)
 {
 	struct snd_dice *dice = substream->private_data;
-	struct amdtp_stream *stream = &dice->tx_stream[0];
+	struct amdtp_stream *stream = &dice->tx_stream[substream->number];
 
 	return amdtp_stream_pcm_pointer(stream);
 }
 static snd_pcm_uframes_t playback_pointer(struct snd_pcm_substream *substream)
 {
 	struct snd_dice *dice = substream->private_data;
-	struct amdtp_stream *stream = &dice->rx_stream[0];
+	struct amdtp_stream *stream = &dice->rx_stream[substream->number];
 
 	return amdtp_stream_pcm_pointer(stream);
 }
@@ -307,25 +331,17 @@ int snd_dice_create_pcm(struct snd_dice *dice)
 	unsigned int capture, playback;
 	int err;
 
-	/*
-	 * Check whether PCM substreams are required.
-	 *
-	 * TODO: in the case that any PCM substreams are not avail at a certain
-	 * sampling transfer frequency?
-	 */
-	err = snd_dice_transaction_read_tx(dice, TX_NUMBER_AUDIO,
-					   &reg, sizeof(reg));
+	/* Check whether PCM substreams are required. */
+	capture = playback = 0;
+	err = snd_dice_transaction_read_tx(dice, TX_NUMBER, &reg, sizeof(reg));
 	if (err < 0)
 		return err;
-	if (be32_to_cpu(reg) > 0)
-		capture = 1;
+	capture = min_t(unsigned int, be32_to_cpu(reg), MAX_STREAMS);
 
-	err = snd_dice_transaction_read_rx(dice, RX_NUMBER_AUDIO,
-					   &reg, sizeof(reg));
+	err = snd_dice_transaction_read_rx(dice, RX_NUMBER, &reg, sizeof(reg));
 	if (err < 0)
 		return err;
-	if (be32_to_cpu(reg) > 0)
-		playback = 1;
+	playback = min_t(unsigned int, be32_to_cpu(reg), MAX_STREAMS);
 
 	err = snd_pcm_new(dice->card, "DICE", 0, playback, capture, &pcm);
 	if (err < 0)
