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

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
...@@ -52,54 +52,38 @@ stop_stream(struct snd_efw *efw, struct amdtp_stream *stream) ...@@ -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 @@ int snd_efw_stream_init_duplex(struct snd_efw *efw) ...@@ -189,6 +173,24 @@ int snd_efw_stream_init_duplex(struct snd_efw *efw)
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) ...@@ -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;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment