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: Takashi Sakamoto <o-takashi@sakamocchi.jp> Signed-off-by: Takashi Iwai <tiwai@suse.de>
This commit is contained in:
parent
3d7250667e
commit
206cf896d6
|
@ -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;
|
||||||
|
|
Loading…
Reference in New Issue