Commit 93cd12d6 authored by Takashi Sakamoto's avatar Takashi Sakamoto Committed by Takashi Iwai

ALSA: bebob: code refactoring for model-dependent quirks

This commit adds enumeration and structure member as code refactoring
regarding to model-dependent quirks.
Signed-off-by: default avatarTakashi Sakamoto <o-takashi@sakamocchi.jp>
Link: https://lore.kernel.org/r/20210611035003.26852-4-o-takashi@sakamocchi.jpSigned-off-by: default avatarTakashi Iwai <tiwai@suse.de>
parent 82fb3bf9
...@@ -159,6 +159,30 @@ check_audiophile_booted(struct fw_unit *unit) ...@@ -159,6 +159,30 @@ check_audiophile_booted(struct fw_unit *unit)
return strncmp(name, "FW Audiophile Bootloader", 24) != 0; return strncmp(name, "FW Audiophile Bootloader", 24) != 0;
} }
static int detect_quirks(struct snd_bebob *bebob, const struct ieee1394_device_id *entry)
{
if (entry->vendor_id == VEN_MAUDIO1) {
switch (entry->model_id) {
case MODEL_MAUDIO_PROFIRELIGHTBRIDGE:
// M-Audio ProFire Lightbridge has a quirk to transfer packets with
// discontinuous cycle or data block counter in early stage of packet
// streaming. The cycle span from the first packet with event is variable.
bebob->quirks |= SND_BEBOB_QUIRK_INITIAL_DISCONTINUOUS_DBC;
break;
case MODEL_MAUDIO_FW1814:
case MODEL_MAUDIO_PROJECTMIX:
// At high sampling rate, M-Audio special firmware transmits empty packet
// with the value of dbc incremented by 8.
bebob->quirks |= SND_BEBOB_QUIRK_WRONG_DBC;
break;
default:
break;
}
}
return 0;
}
static int bebob_probe(struct fw_unit *unit, const struct ieee1394_device_id *entry) static int bebob_probe(struct fw_unit *unit, const struct ieee1394_device_id *entry)
{ {
unsigned int card_index; unsigned int card_index;
...@@ -219,6 +243,10 @@ static int bebob_probe(struct fw_unit *unit, const struct ieee1394_device_id *en ...@@ -219,6 +243,10 @@ static int bebob_probe(struct fw_unit *unit, const struct ieee1394_device_id *en
if (err < 0) if (err < 0)
goto error; goto error;
err = detect_quirks(bebob, entry);
if (err < 0)
goto error;
if (bebob->spec == &maudio_special_spec) { if (bebob->spec == &maudio_special_spec) {
if (entry->model_id == MODEL_MAUDIO_FW1814) if (entry->model_id == MODEL_MAUDIO_FW1814)
err = snd_bebob_maudio_special_discover(bebob, true); err = snd_bebob_maudio_special_discover(bebob, true);
...@@ -230,12 +258,6 @@ static int bebob_probe(struct fw_unit *unit, const struct ieee1394_device_id *en ...@@ -230,12 +258,6 @@ static int bebob_probe(struct fw_unit *unit, const struct ieee1394_device_id *en
if (err < 0) if (err < 0)
goto error; goto error;
// M-Audio ProFire Lightbridge has a quirk to transfer packets with discontinuous cycle or
// data block counter in early stage of packet streaming. The cycle span from the first
// packet with event is variable.
if (entry->vendor_id == VEN_MAUDIO1 && entry->model_id == MODEL_MAUDIO_PROFIRELIGHTBRIDGE)
bebob->discontinuity_quirk = true;
err = snd_bebob_stream_init_duplex(bebob); err = snd_bebob_stream_init_duplex(bebob);
if (err < 0) if (err < 0)
goto error; goto error;
......
...@@ -75,6 +75,11 @@ struct snd_bebob_spec { ...@@ -75,6 +75,11 @@ struct snd_bebob_spec {
const struct snd_bebob_meter_spec *meter; const struct snd_bebob_meter_spec *meter;
}; };
enum snd_bebob_quirk {
SND_BEBOB_QUIRK_INITIAL_DISCONTINUOUS_DBC,
SND_BEBOB_QUIRK_WRONG_DBC,
};
struct snd_bebob { struct snd_bebob {
struct snd_card *card; struct snd_card *card;
struct fw_unit *unit; struct fw_unit *unit;
...@@ -84,6 +89,7 @@ struct snd_bebob { ...@@ -84,6 +89,7 @@ struct snd_bebob {
spinlock_t lock; spinlock_t lock;
const struct snd_bebob_spec *spec; const struct snd_bebob_spec *spec;
unsigned int quirks; // Combination of snd_bebob_quirk enumerations.
unsigned int midi_input_ports; unsigned int midi_input_ports;
unsigned int midi_output_ports; unsigned int midi_output_ports;
...@@ -109,8 +115,6 @@ struct snd_bebob { ...@@ -109,8 +115,6 @@ struct snd_bebob {
/* for M-Audio special devices */ /* for M-Audio special devices */
void *maudio_special_quirk; void *maudio_special_quirk;
bool discontinuity_quirk;
struct amdtp_domain domain; struct amdtp_domain domain;
}; };
......
...@@ -430,6 +430,7 @@ static int start_stream(struct snd_bebob *bebob, struct amdtp_stream *stream) ...@@ -430,6 +430,7 @@ static int start_stream(struct snd_bebob *bebob, struct amdtp_stream *stream)
static int init_stream(struct snd_bebob *bebob, struct amdtp_stream *stream) static int init_stream(struct snd_bebob *bebob, struct amdtp_stream *stream)
{ {
unsigned int flags = CIP_BLOCKING;
enum amdtp_stream_direction dir_stream; enum amdtp_stream_direction dir_stream;
struct cmp_connection *conn; struct cmp_connection *conn;
enum cmp_direction dir_conn; enum cmp_direction dir_conn;
...@@ -445,24 +446,21 @@ static int init_stream(struct snd_bebob *bebob, struct amdtp_stream *stream) ...@@ -445,24 +446,21 @@ static int init_stream(struct snd_bebob *bebob, struct amdtp_stream *stream)
dir_conn = CMP_INPUT; dir_conn = CMP_INPUT;
} }
if (stream == &bebob->tx_stream) {
if (bebob->quirks & SND_BEBOB_QUIRK_WRONG_DBC)
flags |= CIP_EMPTY_HAS_WRONG_DBC;
}
err = cmp_connection_init(conn, bebob->unit, dir_conn, 0); err = cmp_connection_init(conn, bebob->unit, dir_conn, 0);
if (err < 0) if (err < 0)
return err; return err;
err = amdtp_am824_init(stream, bebob->unit, dir_stream, CIP_BLOCKING); err = amdtp_am824_init(stream, bebob->unit, dir_stream, flags);
if (err < 0) { if (err < 0) {
cmp_connection_destroy(conn); cmp_connection_destroy(conn);
return err; return err;
} }
if (stream == &bebob->tx_stream) {
// At high sampling rate, M-Audio special firmware transmits
// empty packet with the value of dbc incremented by 8 but the
// others are valid to IEC 61883-1.
if (bebob->maudio_special_quirk)
bebob->tx_stream.flags |= CIP_EMPTY_HAS_WRONG_DBC;
}
return 0; return 0;
} }
...@@ -630,7 +628,7 @@ int snd_bebob_stream_start_duplex(struct snd_bebob *bebob) ...@@ -630,7 +628,7 @@ int snd_bebob_stream_start_duplex(struct snd_bebob *bebob)
if (err < 0) if (err < 0)
goto error; goto error;
if (!bebob->discontinuity_quirk) if (!(bebob->quirks & SND_BEBOB_QUIRK_INITIAL_DISCONTINUOUS_DBC))
tx_init_skip_cycles = 0; tx_init_skip_cycles = 0;
else else
tx_init_skip_cycles = 16000; tx_init_skip_cycles = 16000;
......
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