ALSA: firewire-motu: code refactoring to handle model specific switch for protocol v2
In MOTU FireWire series, devices which support protocol version 2 have several types of hardware design to process audio data frames for isoc packet. Roughly devices are categorized into three groups: - 828mkII - Traveler/896HD - UltraLite/8pre FireWire Some bit flags in register addressed by 0x'ffff'f000'0b14 includes device-specific effects. This commit cleanups implementation of protocol v2 in this point. Signed-off-by: Takashi Sakamoto <o-takashi@sakamocchi.jp> Link: https://lore.kernel.org/r/20191030080644.1704-6-o-takashi@sakamocchi.jp Signed-off-by: Takashi Iwai <tiwai@suse.de>
This commit is contained in:
parent
4b2079f80a
commit
bd10737282
@ -12,10 +12,8 @@
|
||||
#define V2_CLOCK_RATE_SHIFT 3
|
||||
#define V2_CLOCK_SRC_MASK 0x00000007
|
||||
#define V2_CLOCK_SRC_SHIFT 0
|
||||
#define V2_CLOCK_TRAVELER_FETCH_DISABLE 0x04000000
|
||||
#define V2_CLOCK_TRAVELER_FETCH_ENABLE 0x03000000
|
||||
#define V2_CLOCK_8PRE_FETCH_DISABLE 0x02000000
|
||||
#define V2_CLOCK_8PRE_FETCH_ENABLE 0x00000000
|
||||
#define V2_CLOCK_FETCH_ENABLE 0x02000000
|
||||
#define V2_CLOCK_MODEL_SPECIFIC 0x04000000
|
||||
|
||||
#define V2_IN_OUT_CONF_OFFSET 0x0c04
|
||||
#define V2_OPT_OUT_IFACE_MASK 0x00000c00
|
||||
@ -73,11 +71,6 @@ static int v2_set_clock_rate(struct snd_motu *motu, unsigned int rate)
|
||||
data &= ~V2_CLOCK_RATE_MASK;
|
||||
data |= i << V2_CLOCK_RATE_SHIFT;
|
||||
|
||||
if (motu->spec == &snd_motu_spec_traveler) {
|
||||
data &= ~V2_CLOCK_TRAVELER_FETCH_ENABLE;
|
||||
data |= V2_CLOCK_TRAVELER_FETCH_DISABLE;
|
||||
}
|
||||
|
||||
reg = cpu_to_be32(data);
|
||||
return snd_motu_transaction_write(motu, V2_CLOCK_STATUS_OFFSET, ®,
|
||||
sizeof(reg));
|
||||
@ -145,42 +138,49 @@ static int v2_get_clock_source(struct snd_motu *motu,
|
||||
|
||||
static int v2_switch_fetching_mode(struct snd_motu *motu, bool enable)
|
||||
{
|
||||
enum snd_motu_clock_source src;
|
||||
__be32 reg;
|
||||
u32 data;
|
||||
int err = 0;
|
||||
|
||||
if (motu->spec == &snd_motu_spec_traveler ||
|
||||
motu->spec == &snd_motu_spec_8pre) {
|
||||
err = snd_motu_transaction_read(motu, V2_CLOCK_STATUS_OFFSET,
|
||||
®, sizeof(reg));
|
||||
// 828mkII implements Altera ACEX 1K EP1K30. Nothing to do.
|
||||
if (motu->spec == &snd_motu_spec_828mk2)
|
||||
return 0;
|
||||
|
||||
err = snd_motu_transaction_read(motu, V2_CLOCK_STATUS_OFFSET, ®,
|
||||
sizeof(reg));
|
||||
if (err < 0)
|
||||
return err;
|
||||
data = be32_to_cpu(reg);
|
||||
|
||||
err = get_clock_source(motu, data, &src);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
data &= ~(V2_CLOCK_FETCH_ENABLE | V2_CLOCK_MODEL_SPECIFIC);
|
||||
if (enable)
|
||||
data |= V2_CLOCK_FETCH_ENABLE;
|
||||
|
||||
if (motu->spec->flags & SND_MOTU_SPEC_SUPPORT_CLOCK_X4) {
|
||||
// Expected for Traveler and 896HD, which implements Altera
|
||||
// Cyclone EP1C3.
|
||||
data |= V2_CLOCK_MODEL_SPECIFIC;
|
||||
} else {
|
||||
// For UltraLite and 8pre, which implements Xilinx Spartan
|
||||
// XC3S200.
|
||||
unsigned int rate;
|
||||
|
||||
err = get_clock_rate(data, &rate);
|
||||
if (err < 0)
|
||||
return err;
|
||||
data = be32_to_cpu(reg);
|
||||
|
||||
if (motu->spec == &snd_motu_spec_traveler) {
|
||||
data &= ~(V2_CLOCK_TRAVELER_FETCH_DISABLE |
|
||||
V2_CLOCK_TRAVELER_FETCH_ENABLE);
|
||||
|
||||
if (enable)
|
||||
data |= V2_CLOCK_TRAVELER_FETCH_ENABLE;
|
||||
else
|
||||
data |= V2_CLOCK_TRAVELER_FETCH_DISABLE;
|
||||
} else if (motu->spec == &snd_motu_spec_8pre) {
|
||||
data &= ~(V2_CLOCK_8PRE_FETCH_DISABLE |
|
||||
V2_CLOCK_8PRE_FETCH_ENABLE);
|
||||
|
||||
if (enable)
|
||||
data |= V2_CLOCK_8PRE_FETCH_DISABLE;
|
||||
else
|
||||
data |= V2_CLOCK_8PRE_FETCH_ENABLE;
|
||||
}
|
||||
|
||||
reg = cpu_to_be32(data);
|
||||
err = snd_motu_transaction_write(motu, V2_CLOCK_STATUS_OFFSET,
|
||||
®, sizeof(reg));
|
||||
if (src == SND_MOTU_CLOCK_SOURCE_SPH && rate > 48000)
|
||||
data |= V2_CLOCK_MODEL_SPECIFIC;
|
||||
}
|
||||
|
||||
return err;
|
||||
reg = cpu_to_be32(data);
|
||||
return snd_motu_transaction_write(motu, V2_CLOCK_STATUS_OFFSET, ®,
|
||||
sizeof(reg));
|
||||
}
|
||||
|
||||
static void calculate_fixed_part(struct snd_motu_packet_format *formats,
|
||||
|
@ -172,7 +172,7 @@ static void motu_bus_update(struct fw_unit *unit)
|
||||
snd_motu_transaction_reregister(motu);
|
||||
}
|
||||
|
||||
static const struct snd_motu_spec motu_828mk2 = {
|
||||
const struct snd_motu_spec snd_motu_spec_828mk2 = {
|
||||
.name = "828mk2",
|
||||
.protocol = &snd_motu_protocol_v2,
|
||||
.flags = SND_MOTU_SPEC_SUPPORT_CLOCK_X2 |
|
||||
@ -187,7 +187,7 @@ static const struct snd_motu_spec motu_828mk2 = {
|
||||
.analog_out_ports = 8,
|
||||
};
|
||||
|
||||
const struct snd_motu_spec snd_motu_spec_traveler = {
|
||||
static const struct snd_motu_spec motu_traveler = {
|
||||
.name = "Traveler",
|
||||
.protocol = &snd_motu_protocol_v2,
|
||||
.flags = SND_MOTU_SPEC_SUPPORT_CLOCK_X2 |
|
||||
@ -202,7 +202,7 @@ const struct snd_motu_spec snd_motu_spec_traveler = {
|
||||
.analog_out_ports = 8,
|
||||
};
|
||||
|
||||
const struct snd_motu_spec snd_motu_spec_8pre = {
|
||||
static const struct snd_motu_spec motu_8pre = {
|
||||
.name = "8pre",
|
||||
.protocol = &snd_motu_protocol_v2,
|
||||
// In tx, use coax chunks for mix-return 1/2. In rx, use coax chunks for
|
||||
@ -270,9 +270,9 @@ static const struct snd_motu_spec motu_4pre = {
|
||||
}
|
||||
|
||||
static const struct ieee1394_device_id motu_id_table[] = {
|
||||
SND_MOTU_DEV_ENTRY(0x000003, &motu_828mk2),
|
||||
SND_MOTU_DEV_ENTRY(0x000009, &snd_motu_spec_traveler),
|
||||
SND_MOTU_DEV_ENTRY(0x00000f, &snd_motu_spec_8pre),
|
||||
SND_MOTU_DEV_ENTRY(0x000003, &snd_motu_spec_828mk2),
|
||||
SND_MOTU_DEV_ENTRY(0x000009, &motu_traveler),
|
||||
SND_MOTU_DEV_ENTRY(0x00000f, &motu_8pre),
|
||||
SND_MOTU_DEV_ENTRY(0x000015, &motu_828mk3), /* FireWire only. */
|
||||
SND_MOTU_DEV_ENTRY(0x000035, &motu_828mk3), /* Hybrid. */
|
||||
SND_MOTU_DEV_ENTRY(0x000033, &motu_audio_express),
|
||||
|
@ -130,8 +130,7 @@ struct snd_motu_spec {
|
||||
extern const struct snd_motu_protocol snd_motu_protocol_v2;
|
||||
extern const struct snd_motu_protocol snd_motu_protocol_v3;
|
||||
|
||||
extern const struct snd_motu_spec snd_motu_spec_traveler;
|
||||
extern const struct snd_motu_spec snd_motu_spec_8pre;
|
||||
extern const struct snd_motu_spec snd_motu_spec_828mk2;
|
||||
|
||||
int amdtp_motu_init(struct amdtp_stream *s, struct fw_unit *unit,
|
||||
enum amdtp_stream_direction dir,
|
||||
|
Loading…
Reference in New Issue
Block a user