From b47f525f760f29c4689a7d9bf768c28fcaac2281 Mon Sep 17 00:00:00 2001 From: Takashi Sakamoto Date: Sun, 11 Oct 2015 12:30:18 +0900 Subject: [PATCH 44/50] ALSA: firewire-digi00x: add support of asynchronous transaction for outgoing MIDI messages to physical controls In previous commit, asynchronous transaction for incoming MIDI messages from physical controls is supported. The physical controls may be controlled by receiving MIDI messages at a certain address. This commit supports asynchronous transaction for this purpose. Signed-off-by: Takashi Sakamoto Signed-off-by: Takashi Iwai --- sound/firewire/digi00x/digi00x-transaction.c | 29 ++++++++++++++++++++++++---- sound/firewire/digi00x/digi00x.h | 1 + 2 files changed, 26 insertions(+), 4 deletions(-) diff --git a/sound/firewire/digi00x/digi00x-transaction.c b/sound/firewire/digi00x/digi00x-transaction.c index 8bf5ed5e5f3e..554324d8c602 100644 --- a/sound/firewire/digi00x/digi00x-transaction.c +++ b/sound/firewire/digi00x/digi00x-transaction.c @@ -9,6 +9,18 @@ #include #include "digi00x.h" +static int fill_midi_message(struct snd_rawmidi_substream *substream, u8 *buf) +{ + int bytes; + + buf[0] = 0x80; + bytes = snd_rawmidi_transmit_peek(substream, buf + 1, 2); + if (bytes >= 0) + buf[3] = 0xc0 | bytes; + + return bytes; +} + static void handle_midi_control(struct snd_dg00x *dg00x, __be32 *buf, unsigned int length) { @@ -102,15 +114,24 @@ int snd_dg00x_transaction_register(struct snd_dg00x *dg00x) return err; err = snd_dg00x_transaction_reregister(dg00x); - if (err < 0) { - fw_core_remove_address_handler(&dg00x->async_handler); - dg00x->async_handler.address_callback = NULL; - } + if (err < 0) + goto error; + + err = snd_fw_async_midi_port_init(&dg00x->out_control, dg00x->unit, + DG00X_ADDR_BASE + DG00X_OFFSET_MMC, + 4, fill_midi_message); + if (err < 0) + goto error; return err; +error: + fw_core_remove_address_handler(&dg00x->async_handler); + dg00x->async_handler.address_callback = NULL; + return err; } void snd_dg00x_transaction_unregister(struct snd_dg00x *dg00x) { + snd_fw_async_midi_port_destroy(&dg00x->out_control); fw_core_remove_address_handler(&dg00x->async_handler); } diff --git a/sound/firewire/digi00x/digi00x.h b/sound/firewire/digi00x/digi00x.h index 630f6aabb909..907e73993677 100644 --- a/sound/firewire/digi00x/digi00x.h +++ b/sound/firewire/digi00x/digi00x.h @@ -56,6 +56,7 @@ struct snd_dg00x { /* For asynchronous MIDI controls. */ struct snd_rawmidi_substream *in_control; + struct snd_fw_async_midi_port out_control; }; #define DG00X_ADDR_BASE 0xffffe0000000ull -- 2.4.10