summaryrefslogtreecommitdiff
path: root/sound/firewire/digi00x/digi00x-transaction.c
diff options
context:
space:
mode:
authorTakashi Sakamoto <o-takashi@sakamocchi.jp>2015-10-11 03:30:18 (GMT)
committerTakashi Iwai <tiwai@suse.de>2015-10-11 16:26:14 (GMT)
commitb47f525f760f29c4689a7d9bf768c28fcaac2281 (patch)
tree2735782f109b3ab07398694df8c946b95077086c /sound/firewire/digi00x/digi00x-transaction.c
parent3646a54acda65afdd76737d40c0994b991742e01 (diff)
downloadlinux-b47f525f760f29c4689a7d9bf768c28fcaac2281.tar.xz
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 <o-takashi@sakamocchi.jp> Signed-off-by: Takashi Iwai <tiwai@suse.de>
Diffstat (limited to 'sound/firewire/digi00x/digi00x-transaction.c')
-rw-r--r--sound/firewire/digi00x/digi00x-transaction.c29
1 files changed, 25 insertions, 4 deletions
diff --git a/sound/firewire/digi00x/digi00x-transaction.c b/sound/firewire/digi00x/digi00x-transaction.c
index 8bf5ed5..554324d 100644
--- a/sound/firewire/digi00x/digi00x-transaction.c
+++ b/sound/firewire/digi00x/digi00x-transaction.c
@@ -9,6 +9,18 @@
#include <sound/asound.h>
#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);
}