Commit 206cf896 authored by Takashi Sakamoto's avatar Takashi Sakamoto Committed by Takashi Iwai
Browse files

ALSA: fireworks: configure stream parameters in pcm.hw_params callback



This commit is a part of preparation to perform allocation/release
of isochronous resources in pcm.hw_params/hw_free callbacks.

This commit splits out an operation to configure stream parameters into
pcm.hw_params callback. In pcm.prepare callback, establishing
connections and start isochronous contexts.

Signed-off-by: default avatarTakashi Sakamoto <o-takashi@sakamocchi.jp>
Signed-off-by: default avatarTakashi Iwai <tiwai@suse.de>
parent 3d725066
Loading
Loading
Loading
Loading
+49 −33
Original line number Original line Diff line number Diff line
@@ -52,54 +52,38 @@ stop_stream(struct snd_efw *efw, struct amdtp_stream *stream)
		cmp_connection_break(&efw->in_conn);
		cmp_connection_break(&efw->in_conn);
}
}


static int
static int start_stream(struct snd_efw *efw, struct amdtp_stream *stream,
start_stream(struct snd_efw *efw, struct amdtp_stream *stream,
			unsigned int rate)
	     unsigned int sampling_rate)
{
{
	struct cmp_connection *conn;
	struct cmp_connection *conn;
	unsigned int mode, pcm_channels, midi_ports;
	int err;
	int err;


	err = snd_efw_get_multiplier_mode(sampling_rate, &mode);
	if (stream == &efw->tx_stream)
	if (err < 0)
		goto end;
	if (stream == &efw->tx_stream) {
		conn = &efw->out_conn;
		conn = &efw->out_conn;
		pcm_channels = efw->pcm_capture_channels[mode];
	else
		midi_ports = efw->midi_out_ports;
	} else {
		conn = &efw->in_conn;
		conn = &efw->in_conn;
		pcm_channels = efw->pcm_playback_channels[mode];
		midi_ports = efw->midi_in_ports;
	}


	err = amdtp_am824_set_parameters(stream, sampling_rate,
	// Establish connection via CMP.
					 pcm_channels, midi_ports, false);
	if (err < 0)
		goto end;

	/*  establish connection via CMP */
	err = cmp_connection_establish(conn,
	err = cmp_connection_establish(conn,
				       amdtp_stream_get_max_payload(stream));
				       amdtp_stream_get_max_payload(stream));
	if (err < 0)
	if (err < 0)
		goto end;
		return err;


	/* start amdtp stream */
	// Start amdtp stream.
	err = amdtp_stream_start(stream,
	err = amdtp_stream_start(stream, conn->resources.channel, conn->speed);
				 conn->resources.channel,
				 conn->speed);
	if (err < 0) {
	if (err < 0) {
		stop_stream(efw, stream);
		cmp_connection_break(conn);
		goto end;
		return err;
	}
	}


	/* wait first callback */
	// Wait first callback.
	if (!amdtp_stream_wait_callback(stream, CALLBACK_TIMEOUT)) {
	if (!amdtp_stream_wait_callback(stream, CALLBACK_TIMEOUT)) {
		stop_stream(efw, stream);
		amdtp_stream_stop(stream);
		err = -ETIMEDOUT;
		cmp_connection_break(conn);
		return -ETIMEDOUT;
	}
	}
end:

	return err;
	return 0;
}
}


/*
/*
@@ -189,6 +173,24 @@ end:
	return err;
	return err;
}
}


static int keep_resources(struct snd_efw *efw, struct amdtp_stream *stream,
			  unsigned int rate, unsigned int mode)
{
	unsigned int pcm_channels;
	unsigned int midi_ports;

	if (stream == &efw->tx_stream) {
		pcm_channels = efw->pcm_capture_channels[mode];
		midi_ports = efw->midi_out_ports;
	} else {
		pcm_channels = efw->pcm_playback_channels[mode];
		midi_ports = efw->midi_in_ports;
	}

	return amdtp_am824_set_parameters(stream, rate, pcm_channels,
					  midi_ports, false);
}

int snd_efw_stream_reserve_duplex(struct snd_efw *efw, unsigned int rate)
int snd_efw_stream_reserve_duplex(struct snd_efw *efw, unsigned int rate)
{
{
	unsigned int curr_rate;
	unsigned int curr_rate;
@@ -212,9 +214,23 @@ int snd_efw_stream_reserve_duplex(struct snd_efw *efw, unsigned int rate)
	}
	}


	if (efw->substreams_counter == 0 || rate != curr_rate) {
	if (efw->substreams_counter == 0 || rate != curr_rate) {
		unsigned int mode;

		err = snd_efw_command_set_sampling_rate(efw, rate);
		err = snd_efw_command_set_sampling_rate(efw, rate);
		if (err < 0)
		if (err < 0)
			return err;
			return err;

		err = snd_efw_get_multiplier_mode(rate, &mode);
		if (err < 0)
			return err;

		err = keep_resources(efw, &efw->tx_stream, rate, mode);
		if (err < 0)
			return err;

		err = keep_resources(efw, &efw->rx_stream, rate, mode);
		if (err < 0)
			return err;
	}
	}


	return 0;
	return 0;