Commit 3eb8a244 authored by Takashi Sakamoto's avatar Takashi Sakamoto Committed by Takashi Iwai

ALSA: fireface: add driver data for register for MIDI high address

Fireface 400 and 800 have the same mechanism to decide address to which
asynchronous transactions are sent for MIDI messages, however they use
different registers for controllers to notify higher 4 byte of the
address.

This commit adds a model-specific parameter to represent the address.
Additionally, it corrects some comments. I note that these two models have
a difference to enable/disable the transaction.
Signed-off-by: default avatarTakashi Sakamoto <o-takashi@sakamocchi.jp>
Signed-off-by: default avatarTakashi Iwai <tiwai@suse.de>
parent 0085c6ed
......@@ -15,8 +15,6 @@
#define FF400_TX_PACKET_FORMAT 0x00008010050cull
#define FF400_ISOC_COMM_STOP 0x000080100510ull
#define FF400_MIDI_HIGH_ADDR 0x0000801003f4ull
static int ff400_begin_session(struct snd_ff *ff, unsigned int rate)
{
__le32 reg;
......@@ -111,6 +109,4 @@ const struct snd_ff_protocol snd_ff_protocol_ff400 = {
.begin_session = ff400_begin_session,
.finish_session = ff400_finish_session,
.switch_fetching_mode = ff400_switch_fetching_mode,
.midi_high_addr_reg = FF400_MIDI_HIGH_ADDR,
};
......@@ -269,36 +269,33 @@ static int allocate_own_address(struct snd_ff *ff, int i)
}
/*
* The configuration to start asynchronous transactions for MIDI messages is in
* 0x'0000'8010'051c. This register includes the other options, thus this driver
* doesn't touch it and leaves the decision to userspace. The userspace MUST add
* 0x04000000 to write transactions to the register to receive any MIDI
* messages.
*
* Here, I just describe MIDI-related offsets of the register, in little-endian
* order.
*
* Controllers are allowed to register higher 4 bytes of address to receive
* the transactions. The register is 0x'0000'8010'03f4. On the other hand, the
* controllers are not allowed to register lower 4 bytes of the address. They
* are forced to select from 4 options by writing corresponding bits to
* 0x'0000'8010'051c.
* the transactions. Different models have different registers for this purpose;
* e.g. 0x'0000'8010'03f4 for Fireface 400.
* The controllers are not allowed to register lower 4 bytes of the address.
* They are forced to select one of 4 options for the part of address by writing
* corresponding bits to 0x'0000'8010'051f.
*
* The 3rd-6th bits of this register are flags to indicate lower 4 bytes of
* address to which the device transferrs the transactions. In short:
* - 0x20: 0x'....'....'0000'0180
* - 0x10: 0x'....'....'0000'0100
* - 0x08: 0x'....'....'0000'0080
* - 0x04: 0x'....'....'0000'0000
*
* The 3rd-6th bits in MSB of this register are used to indicate lower 4 bytes
* of address to which the device transferrs the transactions.
* - 6th: 0x'....'....'0000'0180
* - 5th: 0x'....'....'0000'0100
* - 4th: 0x'....'....'0000'0080
* - 3rd: 0x'....'....'0000'0000
* This driver configure 0x'....'....'0000'0000 to receive MIDI messages from
* units. The 3rd bit of the register should be configured, however this driver
* deligates this task to userspace applications due to a restriction that this
* register is write-only and the other bits have own effects.
*
* This driver configure 0x'....'....'0000'0000 for units to receive MIDI
* messages. 3rd bit of the register should be configured, however this driver
* deligates this task to user space applications due to a restriction that
* this register is write-only and the other bits have own effects.
* Unlike Fireface 800, Fireface 400 cancels transferring asynchronous
* transactions when the 1st and 2nd of the register stand. These two bits have
* the same effect.
* - 0x02, 0x01: cancel transferring
*
* The 1st and 2nd bits in LSB of this register are used to cancel transferring
* asynchronous transactions. These two bits have the same effect.
* - 1st/2nd: cancel transferring
* On the other hand, the bits have no effect on Fireface 800. This model
* cancels asynchronous transactions when the higher 4 bytes of address is
* overwritten with zero.
*/
int snd_ff_transaction_reregister(struct snd_ff *ff)
{
......@@ -313,7 +310,7 @@ int snd_ff_transaction_reregister(struct snd_ff *ff)
addr = (fw_card->node_id << 16) | (ff->async_handler.offset >> 32);
reg = cpu_to_le32(addr);
return snd_fw_transaction(ff->unit, TCODE_WRITE_QUADLET_REQUEST,
ff->spec->protocol->midi_high_addr_reg,
ff->spec->regs[SND_FF_REG_TYPE_MIDI_HIGH_ADDR],
&reg, sizeof(reg), 0);
}
......@@ -354,7 +351,7 @@ void snd_ff_transaction_unregister(struct snd_ff *ff)
/* Release higher 4 bytes of address. */
reg = cpu_to_le32(0x00000000);
snd_fw_transaction(ff->unit, TCODE_WRITE_QUADLET_REQUEST,
ff->spec->protocol->midi_high_addr_reg,
ff->spec->regs[SND_FF_REG_TYPE_MIDI_HIGH_ADDR],
&reg, sizeof(reg), 0);
fw_core_remove_address_handler(&ff->async_handler);
......
......@@ -152,6 +152,9 @@ static const struct snd_ff_spec spec_ff400 = {
.midi_in_ports = 2,
.midi_out_ports = 2,
.protocol = &snd_ff_protocol_ff400,
.regs = {
[SND_FF_REG_TYPE_MIDI_HIGH_ADDR] = 0x0000801003f4ull,
},
};
static const struct ieee1394_device_id snd_ff_id_table[] = {
......
......@@ -42,6 +42,11 @@
#define SND_FF_REG_FETCH_PCM_FRAMES 0x0000801c0000ull
#define SND_FF_REG_CLOCK_CONFIG 0x0000801c0004ull
enum snd_ff_reg_type {
SND_FF_REG_TYPE_MIDI_HIGH_ADDR = 0,
SND_FF_REG_TYPE_COUNT,
};
struct snd_ff_protocol;
struct snd_ff_spec {
const char *const name;
......@@ -53,6 +58,7 @@ struct snd_ff_spec {
unsigned int midi_out_ports;
const struct snd_ff_protocol *protocol;
u64 regs[SND_FF_REG_TYPE_COUNT];
};
struct snd_ff {
......@@ -105,8 +111,6 @@ struct snd_ff_protocol {
int (*begin_session)(struct snd_ff *ff, unsigned int rate);
void (*finish_session)(struct snd_ff *ff);
int (*switch_fetching_mode)(struct snd_ff *ff, bool enable);
u64 midi_high_addr_reg;
};
extern const struct snd_ff_protocol snd_ff_protocol_ff400;
......
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