diff --git a/sound/firewire/dice/dice-stream.c b/sound/firewire/dice/dice-stream.c index d3fb460bb86c..b792e7bb6b14 100644 --- a/sound/firewire/dice/dice-stream.c +++ b/sound/firewire/dice/dice-stream.c @@ -294,16 +294,14 @@ int snd_dice_stream_start_duplex(struct snd_dice *dice, unsigned int rate) unsigned int curr_rate; unsigned int i; struct reg_params tx_params, rx_params; - bool need_to_start; + bool need_to_start = false; + enum snd_dice_rate_mode mode; int err; if (dice->substreams_counter == 0) return -EIO; - err = get_register_params(dice, &tx_params, &rx_params); - if (err < 0) - return err; - + /* Check sampling transmission frequency. */ err = snd_dice_transaction_get_rate(dice, &curr_rate); if (err < 0) { dev_err(&dice->unit->device, @@ -315,22 +313,36 @@ int snd_dice_stream_start_duplex(struct snd_dice *dice, unsigned int rate) if (rate != curr_rate) return -EINVAL; - /* Judge to need to restart streams. */ - for (i = 0; i < MAX_STREAMS; i++) { - if (i < tx_params.count) { - if (amdtp_streaming_error(&dice->tx_stream[i]) || - !amdtp_stream_running(&dice->tx_stream[i])) - break; - } - if (i < rx_params.count) { - if (amdtp_streaming_error(&dice->rx_stream[i]) || - !amdtp_stream_running(&dice->rx_stream[i])) - break; - } + /* Check error of packet streaming. */ + for (i = 0; i < MAX_STREAMS; ++i) { + if (amdtp_streaming_error(&dice->tx_stream[i])) + break; + if (amdtp_streaming_error(&dice->rx_stream[i])) + break; } - need_to_start = (i < MAX_STREAMS); + if (i < MAX_STREAMS) + need_to_start = true; + + /* Check required streams are running or not. */ + err = snd_dice_stream_get_rate_mode(dice, rate, &mode); + if (err < 0) + return err; + for (i = 0; i < MAX_STREAMS; ++i) { + if (dice->tx_pcm_chs[i][mode] > 0 && + !amdtp_stream_running(&dice->tx_stream[i])) + break; + if (dice->rx_pcm_chs[i][mode] > 0 && + !amdtp_stream_running(&dice->rx_stream[i])) + break; + } + if (i < MAX_STREAMS) + need_to_start = true; if (need_to_start) { + err = get_register_params(dice, &tx_params, &rx_params); + if (err < 0) + return err; + /* Stop transmission. */ snd_dice_transaction_clear_enable(dice); stop_streams(dice, AMDTP_IN_STREAM, &tx_params); @@ -341,7 +353,7 @@ int snd_dice_stream_start_duplex(struct snd_dice *dice, unsigned int rate) if (err < 0) { dev_err(&dice->unit->device, "fail to ensure phase lock\n"); - return err; + goto error; } /* Start both streams. */