Commit db40eeb2 authored by Takashi Sakamoto's avatar Takashi Sakamoto Committed by Takashi Iwai

ALSA: fireworks: support AMDTP domain

This commit adds AMDTP domain support for ALSA fireworks driver.
Signed-off-by: default avatarTakashi Sakamoto <o-takashi@sakamocchi.jp>
Signed-off-by: default avatarTakashi Iwai <tiwai@suse.de>
parent b0db4d51
...@@ -107,6 +107,8 @@ struct snd_efw { ...@@ -107,6 +107,8 @@ struct snd_efw {
u8 *resp_buf; u8 *resp_buf;
u8 *pull_ptr; u8 *pull_ptr;
u8 *push_ptr; u8 *push_ptr;
struct amdtp_domain domain;
}; };
int snd_efw_transaction_cmd(struct fw_unit *unit, int snd_efw_transaction_cmd(struct fw_unit *unit,
......
...@@ -61,17 +61,6 @@ static int init_stream(struct snd_efw *efw, struct amdtp_stream *stream) ...@@ -61,17 +61,6 @@ static int init_stream(struct snd_efw *efw, struct amdtp_stream *stream)
return err; return err;
} }
static void
stop_stream(struct snd_efw *efw, struct amdtp_stream *stream)
{
amdtp_stream_stop(stream);
if (stream == &efw->tx_stream)
cmp_connection_break(&efw->out_conn);
else
cmp_connection_break(&efw->in_conn);
}
static int start_stream(struct snd_efw *efw, struct amdtp_stream *stream, static int start_stream(struct snd_efw *efw, struct amdtp_stream *stream,
unsigned int rate) unsigned int rate)
{ {
...@@ -89,19 +78,13 @@ static int start_stream(struct snd_efw *efw, struct amdtp_stream *stream, ...@@ -89,19 +78,13 @@ static int start_stream(struct snd_efw *efw, struct amdtp_stream *stream,
return err; return err;
// Start amdtp stream. // Start amdtp stream.
err = amdtp_stream_start(stream, conn->resources.channel, conn->speed); err = amdtp_domain_add_stream(&efw->domain, stream,
conn->resources.channel, conn->speed);
if (err < 0) { if (err < 0) {
cmp_connection_break(conn); cmp_connection_break(conn);
return err; return err;
} }
// Wait first callback.
if (!amdtp_stream_wait_callback(stream, CALLBACK_TIMEOUT)) {
amdtp_stream_stop(stream);
cmp_connection_break(conn);
return -ETIMEDOUT;
}
return 0; return 0;
} }
...@@ -155,6 +138,13 @@ int snd_efw_stream_init_duplex(struct snd_efw *efw) ...@@ -155,6 +138,13 @@ int snd_efw_stream_init_duplex(struct snd_efw *efw)
return err; return err;
} }
err = amdtp_domain_init(&efw->domain);
if (err < 0) {
destroy_stream(efw, &efw->tx_stream);
destroy_stream(efw, &efw->rx_stream);
return err;
}
// set IEC61883 compliant mode (actually not fully compliant...). // set IEC61883 compliant mode (actually not fully compliant...).
err = snd_efw_command_set_tx_mode(efw, SND_EFW_TRANSPORT_MODE_IEC61883); err = snd_efw_command_set_tx_mode(efw, SND_EFW_TRANSPORT_MODE_IEC61883);
if (err < 0) { if (err < 0) {
...@@ -209,8 +199,10 @@ int snd_efw_stream_reserve_duplex(struct snd_efw *efw, unsigned int rate) ...@@ -209,8 +199,10 @@ int snd_efw_stream_reserve_duplex(struct snd_efw *efw, unsigned int rate)
if (rate == 0) if (rate == 0)
rate = curr_rate; rate = curr_rate;
if (rate != curr_rate) { if (rate != curr_rate) {
stop_stream(efw, &efw->tx_stream); amdtp_domain_stop(&efw->domain);
stop_stream(efw, &efw->rx_stream);
cmp_connection_break(&efw->out_conn);
cmp_connection_break(&efw->in_conn);
cmp_connection_release(&efw->out_conn); cmp_connection_release(&efw->out_conn);
cmp_connection_release(&efw->in_conn); cmp_connection_release(&efw->in_conn);
...@@ -250,47 +242,57 @@ int snd_efw_stream_start_duplex(struct snd_efw *efw) ...@@ -250,47 +242,57 @@ int snd_efw_stream_start_duplex(struct snd_efw *efw)
if (efw->substreams_counter == 0) if (efw->substreams_counter == 0)
return -EIO; return -EIO;
err = snd_efw_command_get_sampling_rate(efw, &rate);
if (err < 0)
return err;
if (amdtp_streaming_error(&efw->rx_stream) || if (amdtp_streaming_error(&efw->rx_stream) ||
amdtp_streaming_error(&efw->tx_stream)) { amdtp_streaming_error(&efw->tx_stream)) {
stop_stream(efw, &efw->rx_stream); amdtp_domain_stop(&efw->domain);
stop_stream(efw, &efw->tx_stream); cmp_connection_break(&efw->out_conn);
cmp_connection_break(&efw->in_conn);
} }
/* master should be always running */ err = snd_efw_command_get_sampling_rate(efw, &rate);
if (err < 0)
return err;
if (!amdtp_stream_running(&efw->rx_stream)) { if (!amdtp_stream_running(&efw->rx_stream)) {
err = start_stream(efw, &efw->rx_stream, rate); err = start_stream(efw, &efw->rx_stream, rate);
if (err < 0) { if (err < 0)
dev_err(&efw->unit->device,
"fail to start AMDTP master stream:%d\n", err);
goto error; goto error;
}
}
if (!amdtp_stream_running(&efw->tx_stream)) {
err = start_stream(efw, &efw->tx_stream, rate); err = start_stream(efw, &efw->tx_stream, rate);
if (err < 0) { if (err < 0)
dev_err(&efw->unit->device, goto error;
"fail to start AMDTP slave stream:%d\n", err);
err = amdtp_domain_start(&efw->domain);
if (err < 0)
goto error;
// Wait first callback.
if (!amdtp_stream_wait_callback(&efw->rx_stream,
CALLBACK_TIMEOUT) ||
!amdtp_stream_wait_callback(&efw->tx_stream,
CALLBACK_TIMEOUT)) {
err = -ETIMEDOUT;
goto error; goto error;
} }
} }
return 0; return 0;
error: error:
stop_stream(efw, &efw->rx_stream); amdtp_domain_stop(&efw->domain);
stop_stream(efw, &efw->tx_stream);
cmp_connection_break(&efw->out_conn);
cmp_connection_break(&efw->in_conn);
return err; return err;
} }
void snd_efw_stream_stop_duplex(struct snd_efw *efw) void snd_efw_stream_stop_duplex(struct snd_efw *efw)
{ {
if (efw->substreams_counter == 0) { if (efw->substreams_counter == 0) {
stop_stream(efw, &efw->tx_stream); amdtp_domain_stop(&efw->domain);
stop_stream(efw, &efw->rx_stream);
cmp_connection_break(&efw->out_conn);
cmp_connection_break(&efw->in_conn);
cmp_connection_release(&efw->out_conn); cmp_connection_release(&efw->out_conn);
cmp_connection_release(&efw->in_conn); cmp_connection_release(&efw->in_conn);
...@@ -299,8 +301,10 @@ void snd_efw_stream_stop_duplex(struct snd_efw *efw) ...@@ -299,8 +301,10 @@ void snd_efw_stream_stop_duplex(struct snd_efw *efw)
void snd_efw_stream_update_duplex(struct snd_efw *efw) void snd_efw_stream_update_duplex(struct snd_efw *efw)
{ {
stop_stream(efw, &efw->rx_stream); amdtp_domain_stop(&efw->domain);
stop_stream(efw, &efw->tx_stream);
cmp_connection_break(&efw->out_conn);
cmp_connection_break(&efw->in_conn);
amdtp_stream_pcm_abort(&efw->rx_stream); amdtp_stream_pcm_abort(&efw->rx_stream);
amdtp_stream_pcm_abort(&efw->tx_stream); amdtp_stream_pcm_abort(&efw->tx_stream);
...@@ -308,6 +312,8 @@ void snd_efw_stream_update_duplex(struct snd_efw *efw) ...@@ -308,6 +312,8 @@ void snd_efw_stream_update_duplex(struct snd_efw *efw)
void snd_efw_stream_destroy_duplex(struct snd_efw *efw) void snd_efw_stream_destroy_duplex(struct snd_efw *efw)
{ {
amdtp_domain_destroy(&efw->domain);
destroy_stream(efw, &efw->rx_stream); destroy_stream(efw, &efw->rx_stream);
destroy_stream(efw, &efw->tx_stream); destroy_stream(efw, &efw->tx_stream);
} }
......
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