ALSA: bebob: drop reuse of incoming packet parameter for outgoing packet parameter

Windows driver for BeBoB-based models mostly wait for transmitted packets,
then transfer packets to the models. This looks for the relationship
between incoming packets and outgoing packets to synchronize the sequence
of presentation timestamp.

However, the sequence between packets of both direction has no
relationship. Even if receiving NO-DATA packets, the drivers transfer
packets with meaningful value in SYT field. Additionally, the order of
starting packets is always the same, independently of the source of clock.
The corresponding driver is expected as a generator of presentation
timestamp and these models can select it as a source of sampling clock.

This commit drops reusing SYT sequence from ALSA bebob driver. The driver
always transfer packets with presentation timestamp generated by ALSA
firewire stack, without re-using the sequence of value in SYT field in
incoming packets to outgoing packets.

Signed-off-by: Takashi Sakamoto <o-takashi@sakamocchi.jp>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
This commit is contained in:
Takashi Sakamoto 2016-05-09 23:15:50 +09:00 committed by Takashi Iwai
parent 2e00fde5c6
commit c71283cb68
2 changed files with 26 additions and 74 deletions

View file

@ -94,7 +94,6 @@ struct snd_bebob {
bool connected;
struct amdtp_stream *master;
struct amdtp_stream tx_stream;
struct amdtp_stream rx_stream;
struct cmp_connection out_conn;

View file

@ -483,30 +483,6 @@ destroy_both_connections(struct snd_bebob *bebob)
cmp_connection_destroy(&bebob->out_conn);
}
static int
get_sync_mode(struct snd_bebob *bebob, enum cip_flags *sync_mode)
{
enum snd_bebob_clock_type src;
int err;
err = snd_bebob_stream_get_clock_src(bebob, &src);
if (err < 0)
return err;
switch (src) {
case SND_BEBOB_CLOCK_TYPE_INTERNAL:
case SND_BEBOB_CLOCK_TYPE_EXTERNAL:
*sync_mode = CIP_SYNC_TO_DEVICE;
break;
default:
case SND_BEBOB_CLOCK_TYPE_SYT:
*sync_mode = 0;
break;
}
return 0;
}
static int
start_stream(struct snd_bebob *bebob, struct amdtp_stream *stream,
unsigned int rate)
@ -584,8 +560,6 @@ end:
int snd_bebob_stream_start_duplex(struct snd_bebob *bebob, unsigned int rate)
{
const struct snd_bebob_rate_spec *rate_spec = bebob->spec->rate;
struct amdtp_stream *master, *slave;
enum cip_flags sync_mode;
unsigned int curr_rate;
int err = 0;
@ -593,22 +567,11 @@ int snd_bebob_stream_start_duplex(struct snd_bebob *bebob, unsigned int rate)
if (bebob->substreams_counter == 0)
goto end;
err = get_sync_mode(bebob, &sync_mode);
if (err < 0)
goto end;
if (sync_mode == CIP_SYNC_TO_DEVICE) {
master = &bebob->tx_stream;
slave = &bebob->rx_stream;
} else {
master = &bebob->rx_stream;
slave = &bebob->tx_stream;
}
/*
* Considering JACK/FFADO streaming:
* TODO: This can be removed hwdep functionality becomes popular.
*/
err = check_connection_used_by_others(bebob, master);
err = check_connection_used_by_others(bebob, &bebob->rx_stream);
if (err < 0)
goto end;
@ -618,11 +581,12 @@ int snd_bebob_stream_start_duplex(struct snd_bebob *bebob, unsigned int rate)
* At bus reset, connections should not be broken here. So streams need
* to be re-started. This is a reason to use SKIP_INIT_DBC_CHECK flag.
*/
if (amdtp_streaming_error(master))
amdtp_stream_stop(master);
if (amdtp_streaming_error(slave))
amdtp_stream_stop(slave);
if (!amdtp_stream_running(master) && !amdtp_stream_running(slave))
if (amdtp_streaming_error(&bebob->rx_stream))
amdtp_stream_stop(&bebob->rx_stream);
if (amdtp_streaming_error(&bebob->tx_stream))
amdtp_stream_stop(&bebob->tx_stream);
if (!amdtp_stream_running(&bebob->rx_stream) &&
!amdtp_stream_running(&bebob->tx_stream))
break_both_connections(bebob);
/* stop streams if rate is different */
@ -635,16 +599,13 @@ int snd_bebob_stream_start_duplex(struct snd_bebob *bebob, unsigned int rate)
if (rate == 0)
rate = curr_rate;
if (rate != curr_rate) {
amdtp_stream_stop(master);
amdtp_stream_stop(slave);
amdtp_stream_stop(&bebob->rx_stream);
amdtp_stream_stop(&bebob->tx_stream);
break_both_connections(bebob);
}
/* master should be always running */
if (!amdtp_stream_running(master)) {
amdtp_stream_set_sync(sync_mode, master, slave);
bebob->master = master;
if (!amdtp_stream_running(&bebob->rx_stream)) {
/*
* NOTE:
* If establishing connections at first, Yamaha GO46
@ -666,7 +627,7 @@ int snd_bebob_stream_start_duplex(struct snd_bebob *bebob, unsigned int rate)
if (err < 0)
goto end;
err = start_stream(bebob, master, rate);
err = start_stream(bebob, &bebob->rx_stream, rate);
if (err < 0) {
dev_err(&bebob->unit->device,
"fail to run AMDTP master stream:%d\n", err);
@ -685,15 +646,16 @@ int snd_bebob_stream_start_duplex(struct snd_bebob *bebob, unsigned int rate)
dev_err(&bebob->unit->device,
"fail to ensure sampling rate: %d\n",
err);
amdtp_stream_stop(master);
amdtp_stream_stop(&bebob->rx_stream);
break_both_connections(bebob);
goto end;
}
}
/* wait first callback */
if (!amdtp_stream_wait_callback(master, CALLBACK_TIMEOUT)) {
amdtp_stream_stop(master);
if (!amdtp_stream_wait_callback(&bebob->rx_stream,
CALLBACK_TIMEOUT)) {
amdtp_stream_stop(&bebob->rx_stream);
break_both_connections(bebob);
err = -ETIMEDOUT;
goto end;
@ -701,20 +663,21 @@ int snd_bebob_stream_start_duplex(struct snd_bebob *bebob, unsigned int rate)
}
/* start slave if needed */
if (!amdtp_stream_running(slave)) {
err = start_stream(bebob, slave, rate);
if (!amdtp_stream_running(&bebob->tx_stream)) {
err = start_stream(bebob, &bebob->tx_stream, rate);
if (err < 0) {
dev_err(&bebob->unit->device,
"fail to run AMDTP slave stream:%d\n", err);
amdtp_stream_stop(master);
amdtp_stream_stop(&bebob->rx_stream);
break_both_connections(bebob);
goto end;
}
/* wait first callback */
if (!amdtp_stream_wait_callback(slave, CALLBACK_TIMEOUT)) {
amdtp_stream_stop(slave);
amdtp_stream_stop(master);
if (!amdtp_stream_wait_callback(&bebob->tx_stream,
CALLBACK_TIMEOUT)) {
amdtp_stream_stop(&bebob->tx_stream);
amdtp_stream_stop(&bebob->rx_stream);
break_both_connections(bebob);
err = -ETIMEDOUT;
}
@ -725,22 +688,12 @@ end:
void snd_bebob_stream_stop_duplex(struct snd_bebob *bebob)
{
struct amdtp_stream *master, *slave;
if (bebob->master == &bebob->rx_stream) {
slave = &bebob->tx_stream;
master = &bebob->rx_stream;
} else {
slave = &bebob->rx_stream;
master = &bebob->tx_stream;
}
if (bebob->substreams_counter == 0) {
amdtp_stream_pcm_abort(master);
amdtp_stream_stop(master);
amdtp_stream_pcm_abort(&bebob->rx_stream);
amdtp_stream_stop(&bebob->rx_stream);
amdtp_stream_pcm_abort(slave);
amdtp_stream_stop(slave);
amdtp_stream_pcm_abort(&bebob->tx_stream);
amdtp_stream_stop(&bebob->tx_stream);
break_both_connections(bebob);
}