Commit 20b94544 authored by Takashi Sakamoto's avatar Takashi Sakamoto Committed by Takashi Iwai
Browse files

ALSA: dice: add a helper function to restart all of available streams



This commit is a small refactoring for better readability.

Signed-off-by: default avatarTakashi Sakamoto <o-takashi@sakamocchi.jp>
Signed-off-by: default avatarTakashi Iwai <tiwai@suse.de>
parent ec592fd3
Loading
Loading
Loading
Loading
+62 −57
Original line number Diff line number Diff line
@@ -284,6 +284,63 @@ static int start_streams(struct snd_dice *dice, enum amdtp_stream_direction dir,
	return err;
}

static int start_duplex_streams(struct snd_dice *dice, unsigned int rate)
{
	struct reg_params tx_params, rx_params;
	int i;
	int err;

	err = get_register_params(dice, &tx_params, &rx_params);
	if (err < 0)
		return err;

	/* Stop transmission. */
	stop_streams(dice, AMDTP_IN_STREAM, &tx_params);
	stop_streams(dice, AMDTP_OUT_STREAM, &rx_params);
	snd_dice_transaction_clear_enable(dice);
	release_resources(dice);

	err = ensure_phase_lock(dice);
	if (err < 0) {
		dev_err(&dice->unit->device, "fail to ensure phase lock\n");
		return err;
	}

	/* Start both streams. */
	err = start_streams(dice, AMDTP_IN_STREAM, rate, &tx_params);
	if (err < 0)
		goto error;
	err = start_streams(dice, AMDTP_OUT_STREAM, rate, &rx_params);
	if (err < 0)
		goto error;

	err = snd_dice_transaction_set_enable(dice);
	if (err < 0) {
		dev_err(&dice->unit->device, "fail to enable interface\n");
		goto error;
	}

	for (i = 0; i < MAX_STREAMS; i++) {
		if ((i < tx_params.count &&
		    !amdtp_stream_wait_callback(&dice->tx_stream[i],
						CALLBACK_TIMEOUT)) ||
		    (i < rx_params.count &&
		     !amdtp_stream_wait_callback(&dice->rx_stream[i],
						 CALLBACK_TIMEOUT))) {
			err = -ETIMEDOUT;
			goto error;
		}
	}

	return 0;
error:
	stop_streams(dice, AMDTP_IN_STREAM, &tx_params);
	stop_streams(dice, AMDTP_OUT_STREAM, &rx_params);
	snd_dice_transaction_clear_enable(dice);
	release_resources(dice);
	return err;
}

/*
 * MEMO: After this function, there're two states of streams:
 *  - None streams are running.
@@ -293,8 +350,6 @@ 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 = false;
	enum snd_dice_rate_mode mode;
	int err;

@@ -321,7 +376,7 @@ int snd_dice_stream_start_duplex(struct snd_dice *dice, unsigned int rate)
			break;
	}
	if (i < MAX_STREAMS)
		need_to_start = true;
		goto restart;

	/* Check required streams are running or not. */
	err = snd_dice_stream_get_rate_mode(dice, rate, &mode);
@@ -336,61 +391,11 @@ int snd_dice_stream_start_duplex(struct snd_dice *dice, unsigned int rate)
			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);
		stop_streams(dice, AMDTP_OUT_STREAM, &rx_params);
		release_resources(dice);
		goto restart;

		err = ensure_phase_lock(dice);
		if (err < 0) {
			dev_err(&dice->unit->device,
				"fail to ensure phase lock\n");
			goto error;
		}

		/* Start both streams. */
		err = start_streams(dice, AMDTP_IN_STREAM, rate, &tx_params);
		if (err < 0)
			goto error;
		err = start_streams(dice, AMDTP_OUT_STREAM, rate, &rx_params);
		if (err < 0)
			goto error;

		err = snd_dice_transaction_set_enable(dice);
		if (err < 0) {
			dev_err(&dice->unit->device,
				"fail to enable interface\n");
			goto error;
		}

		for (i = 0; i < MAX_STREAMS; i++) {
			if ((i < tx_params.count &&
			    !amdtp_stream_wait_callback(&dice->tx_stream[i],
							CALLBACK_TIMEOUT)) ||
			    (i < rx_params.count &&
			     !amdtp_stream_wait_callback(&dice->rx_stream[i],
							 CALLBACK_TIMEOUT))) {
				err = -ETIMEDOUT;
				goto error;
			}
		}
	}

	return err;
error:
	snd_dice_transaction_clear_enable(dice);
	stop_streams(dice, AMDTP_IN_STREAM, &tx_params);
	stop_streams(dice, AMDTP_OUT_STREAM, &rx_params);
	release_resources(dice);
	return err;
	return 0;
restart:
	return start_duplex_streams(dice, rate);
}

/*