mirror of
https://github.com/edk2-porting/linux-next.git
synced 2024-12-23 20:53:53 +08:00
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:
parent
2e00fde5c6
commit
c71283cb68
@ -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;
|
||||
|
@ -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);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user