ALSA: firewire-tascam: support AMDTP domain
This commit adds AMDTP domain support for ALSA firewire-tascam driver. Signed-off-by: Takashi Sakamoto <o-takashi@sakamocchi.jp> Signed-off-by: Takashi Iwai <tiwai@suse.de>alistair/sunxi64-5.4-dsi
parent
9a08067ec3
commit
c281d46a51
|
@ -180,9 +180,6 @@ static void finish_session(struct snd_tscm *tscm)
|
||||||
{
|
{
|
||||||
__be32 reg;
|
__be32 reg;
|
||||||
|
|
||||||
amdtp_stream_stop(&tscm->rx_stream);
|
|
||||||
amdtp_stream_stop(&tscm->tx_stream);
|
|
||||||
|
|
||||||
reg = 0;
|
reg = 0;
|
||||||
snd_fw_transaction(tscm->unit, TCODE_WRITE_QUADLET_REQUEST,
|
snd_fw_transaction(tscm->unit, TCODE_WRITE_QUADLET_REQUEST,
|
||||||
TSCM_ADDR_BASE + TSCM_OFFSET_START_STREAMING,
|
TSCM_ADDR_BASE + TSCM_OFFSET_START_STREAMING,
|
||||||
|
@ -339,8 +336,16 @@ int snd_tscm_stream_init_duplex(struct snd_tscm *tscm)
|
||||||
return err;
|
return err;
|
||||||
|
|
||||||
err = init_stream(tscm, &tscm->rx_stream);
|
err = init_stream(tscm, &tscm->rx_stream);
|
||||||
if (err < 0)
|
if (err < 0) {
|
||||||
destroy_stream(tscm, &tscm->tx_stream);
|
destroy_stream(tscm, &tscm->tx_stream);
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
err = amdtp_domain_init(&tscm->domain);
|
||||||
|
if (err < 0) {
|
||||||
|
destroy_stream(tscm, &tscm->tx_stream);
|
||||||
|
destroy_stream(tscm, &tscm->rx_stream);
|
||||||
|
}
|
||||||
|
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
@ -348,17 +353,18 @@ int snd_tscm_stream_init_duplex(struct snd_tscm *tscm)
|
||||||
// At bus reset, streaming is stopped and some registers are clear.
|
// At bus reset, streaming is stopped and some registers are clear.
|
||||||
void snd_tscm_stream_update_duplex(struct snd_tscm *tscm)
|
void snd_tscm_stream_update_duplex(struct snd_tscm *tscm)
|
||||||
{
|
{
|
||||||
amdtp_stream_pcm_abort(&tscm->tx_stream);
|
amdtp_domain_stop(&tscm->domain);
|
||||||
amdtp_stream_stop(&tscm->tx_stream);
|
|
||||||
|
|
||||||
|
amdtp_stream_pcm_abort(&tscm->tx_stream);
|
||||||
amdtp_stream_pcm_abort(&tscm->rx_stream);
|
amdtp_stream_pcm_abort(&tscm->rx_stream);
|
||||||
amdtp_stream_stop(&tscm->rx_stream);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// This function should be called before starting streams or after stopping
|
// This function should be called before starting streams or after stopping
|
||||||
// streams.
|
// streams.
|
||||||
void snd_tscm_stream_destroy_duplex(struct snd_tscm *tscm)
|
void snd_tscm_stream_destroy_duplex(struct snd_tscm *tscm)
|
||||||
{
|
{
|
||||||
|
amdtp_domain_destroy(&tscm->domain);
|
||||||
|
|
||||||
destroy_stream(tscm, &tscm->rx_stream);
|
destroy_stream(tscm, &tscm->rx_stream);
|
||||||
destroy_stream(tscm, &tscm->tx_stream);
|
destroy_stream(tscm, &tscm->tx_stream);
|
||||||
}
|
}
|
||||||
|
@ -373,6 +379,8 @@ int snd_tscm_stream_reserve_duplex(struct snd_tscm *tscm, unsigned int rate)
|
||||||
return err;
|
return err;
|
||||||
|
|
||||||
if (tscm->substreams_counter == 0 || rate != curr_rate) {
|
if (tscm->substreams_counter == 0 || rate != curr_rate) {
|
||||||
|
amdtp_domain_stop(&tscm->domain);
|
||||||
|
|
||||||
finish_session(tscm);
|
finish_session(tscm);
|
||||||
|
|
||||||
fw_iso_resources_free(&tscm->tx_resources);
|
fw_iso_resources_free(&tscm->tx_resources);
|
||||||
|
@ -405,8 +413,10 @@ int snd_tscm_stream_start_duplex(struct snd_tscm *tscm, unsigned int rate)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if (amdtp_streaming_error(&tscm->rx_stream) ||
|
if (amdtp_streaming_error(&tscm->rx_stream) ||
|
||||||
amdtp_streaming_error(&tscm->tx_stream))
|
amdtp_streaming_error(&tscm->tx_stream)) {
|
||||||
|
amdtp_domain_stop(&tscm->domain);
|
||||||
finish_session(tscm);
|
finish_session(tscm);
|
||||||
|
}
|
||||||
|
|
||||||
if (generation != fw_parent_device(tscm->unit)->card->generation) {
|
if (generation != fw_parent_device(tscm->unit)->card->generation) {
|
||||||
err = fw_iso_resources_update(&tscm->tx_resources);
|
err = fw_iso_resources_update(&tscm->tx_resources);
|
||||||
|
@ -419,6 +429,8 @@ int snd_tscm_stream_start_duplex(struct snd_tscm *tscm, unsigned int rate)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!amdtp_stream_running(&tscm->rx_stream)) {
|
if (!amdtp_stream_running(&tscm->rx_stream)) {
|
||||||
|
int spd = fw_parent_device(tscm->unit)->max_speed;
|
||||||
|
|
||||||
err = set_stream_formats(tscm, rate);
|
err = set_stream_formats(tscm, rate);
|
||||||
if (err < 0)
|
if (err < 0)
|
||||||
goto error;
|
goto error;
|
||||||
|
@ -427,27 +439,23 @@ int snd_tscm_stream_start_duplex(struct snd_tscm *tscm, unsigned int rate)
|
||||||
if (err < 0)
|
if (err < 0)
|
||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
err = amdtp_stream_start(&tscm->rx_stream,
|
err = amdtp_domain_add_stream(&tscm->domain, &tscm->rx_stream,
|
||||||
tscm->rx_resources.channel,
|
tscm->rx_resources.channel, spd);
|
||||||
fw_parent_device(tscm->unit)->max_speed);
|
|
||||||
if (err < 0)
|
if (err < 0)
|
||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
|
err = amdtp_domain_add_stream(&tscm->domain, &tscm->tx_stream,
|
||||||
|
tscm->tx_resources.channel, spd);
|
||||||
|
if (err < 0)
|
||||||
|
goto error;
|
||||||
|
|
||||||
|
err = amdtp_domain_start(&tscm->domain);
|
||||||
|
if (err < 0)
|
||||||
|
return err;
|
||||||
|
|
||||||
if (!amdtp_stream_wait_callback(&tscm->rx_stream,
|
if (!amdtp_stream_wait_callback(&tscm->rx_stream,
|
||||||
CALLBACK_TIMEOUT)) {
|
CALLBACK_TIMEOUT) ||
|
||||||
err = -ETIMEDOUT;
|
!amdtp_stream_wait_callback(&tscm->tx_stream,
|
||||||
goto error;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!amdtp_stream_running(&tscm->tx_stream)) {
|
|
||||||
err = amdtp_stream_start(&tscm->tx_stream,
|
|
||||||
tscm->tx_resources.channel,
|
|
||||||
fw_parent_device(tscm->unit)->max_speed);
|
|
||||||
if (err < 0)
|
|
||||||
goto error;
|
|
||||||
|
|
||||||
if (!amdtp_stream_wait_callback(&tscm->tx_stream,
|
|
||||||
CALLBACK_TIMEOUT)) {
|
CALLBACK_TIMEOUT)) {
|
||||||
err = -ETIMEDOUT;
|
err = -ETIMEDOUT;
|
||||||
goto error;
|
goto error;
|
||||||
|
@ -456,6 +464,7 @@ int snd_tscm_stream_start_duplex(struct snd_tscm *tscm, unsigned int rate)
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
error:
|
error:
|
||||||
|
amdtp_domain_stop(&tscm->domain);
|
||||||
finish_session(tscm);
|
finish_session(tscm);
|
||||||
|
|
||||||
return err;
|
return err;
|
||||||
|
@ -464,6 +473,7 @@ error:
|
||||||
void snd_tscm_stream_stop_duplex(struct snd_tscm *tscm)
|
void snd_tscm_stream_stop_duplex(struct snd_tscm *tscm)
|
||||||
{
|
{
|
||||||
if (tscm->substreams_counter == 0) {
|
if (tscm->substreams_counter == 0) {
|
||||||
|
amdtp_domain_stop(&tscm->domain);
|
||||||
finish_session(tscm);
|
finish_session(tscm);
|
||||||
|
|
||||||
fw_iso_resources_free(&tscm->tx_resources);
|
fw_iso_resources_free(&tscm->tx_resources);
|
||||||
|
|
|
@ -97,6 +97,8 @@ struct snd_tscm {
|
||||||
struct snd_firewire_tascam_change queue[SND_TSCM_QUEUE_COUNT];
|
struct snd_firewire_tascam_change queue[SND_TSCM_QUEUE_COUNT];
|
||||||
unsigned int pull_pos;
|
unsigned int pull_pos;
|
||||||
unsigned int push_pos;
|
unsigned int push_pos;
|
||||||
|
|
||||||
|
struct amdtp_domain domain;
|
||||||
};
|
};
|
||||||
|
|
||||||
#define TSCM_ADDR_BASE 0xffff00000000ull
|
#define TSCM_ADDR_BASE 0xffff00000000ull
|
||||||
|
|
Loading…
Reference in New Issue