ALSA: fireface: add driver data for register for MIDI high address
authorTakashi Sakamoto <o-takashi@sakamocchi.jp>
Tue, 11 Dec 2018 10:17:33 +0000 (19:17 +0900)
committerTakashi Iwai <tiwai@suse.de>
Tue, 11 Dec 2018 13:57:16 +0000 (14:57 +0100)
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: Takashi Sakamoto <o-takashi@sakamocchi.jp>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
sound/firewire/fireface/ff-protocol-ff400.c
sound/firewire/fireface/ff-transaction.c
sound/firewire/fireface/ff.c
sound/firewire/fireface/ff.h

index 5cbaff9d6a406eec4ac8235da20c06cffd7ba1f5..b283762e785c224b185568e7f59c1e1ece3f5aaf 100644 (file)
@@ -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,
 };
index fa0bc956696fee9cb0bcc0d541dfc2b4757918af..1ce4cef6ca358897bf57d52a1a0de305ba7bf0b4 100644 (file)
@@ -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);
index 3f61cfeace69e7249658d96f5ec4c108553a5c1d..2ce5e115b0eb895bf67ac8f9af43439017ac1cf3 100644 (file)
@@ -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[] = {
index ea905285beabbe1fc954ca60d2cb9ca05ebc47b2..466304c72d7661d08ad6a143a89e46ef663e2905 100644 (file)
 #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;