Commit aef4ad2f authored by Takashi Sakamoto's avatar Takashi Sakamoto Committed by Takashi Iwai
Browse files

ALSA: fireface: localize a handler for MIDI messages on tx transaction



Content of asynchronous transaction for MIDI messages differs between
Fireface 400 and 800.

This commit adds a model-specific handler for the transaction and adds
arrangement.

Signed-off-by: default avatarTakashi Sakamoto <o-takashi@sakamocchi.jp>
Signed-off-by: default avatarTakashi Iwai <tiwai@suse.de>
parent 3eb8a244
Loading
Loading
Loading
Loading
+38 −0
Original line number Diff line number Diff line
@@ -105,7 +105,45 @@ static int ff400_switch_fetching_mode(struct snd_ff *ff, bool enable)
	return err;
}

static void ff400_handle_midi_msg(struct snd_ff *ff, __le32 *buf, size_t length)
{
	int i;

	for (i = 0; i < length / 4; i++) {
		u32 quad = le32_to_cpu(buf[i]);
		u8 byte;
		unsigned int index;
		struct snd_rawmidi_substream *substream;

		/* Message in first port. */
		/*
		 * This value may represent the index of this unit when the same
		 * units are on the same IEEE 1394 bus. This driver doesn't use
		 * it.
		 */
		index = (quad >> 8) & 0xff;
		if (index > 0) {
			substream = READ_ONCE(ff->tx_midi_substreams[0]);
			if (substream != NULL) {
				byte = quad & 0xff;
				snd_rawmidi_receive(substream, &byte, 1);
			}
		}

		/* Message in second port. */
		index = (quad >> 24) & 0xff;
		if (index > 0) {
			substream = READ_ONCE(ff->tx_midi_substreams[1]);
			if (substream != NULL) {
				byte = (quad >> 16) & 0xff;
				snd_rawmidi_receive(substream, &byte, 1);
			}
		}
	}
}

const struct snd_ff_protocol snd_ff_protocol_ff400 = {
	.handle_midi_msg	= ff400_handle_midi_msg,
	.begin_session		= ff400_begin_session,
	.finish_session		= ff400_finish_session,
	.switch_fetching_mode	= ff400_switch_fetching_mode,
+1 −33
Original line number Diff line number Diff line
@@ -206,42 +206,10 @@ static void handle_midi_msg(struct fw_card *card, struct fw_request *request,
{
	struct snd_ff *ff = callback_data;
	__le32 *buf = data;
	u32 quad;
	u8 byte;
	unsigned int index;
	struct snd_rawmidi_substream *substream;
	int i;

	fw_send_response(card, request, RCODE_COMPLETE);

	for (i = 0; i < length / 4; i++) {
		quad = le32_to_cpu(buf[i]);

		/* Message in first port. */
		/*
		 * This value may represent the index of this unit when the same
		 * units are on the same IEEE 1394 bus. This driver doesn't use
		 * it.
		 */
		index = (quad >> 8) & 0xff;
		if (index > 0) {
			substream = READ_ONCE(ff->tx_midi_substreams[0]);
			if (substream != NULL) {
				byte = quad & 0xff;
				snd_rawmidi_receive(substream, &byte, 1);
			}
		}

		/* Message in second port. */
		index = (quad >> 24) & 0xff;
		if (index > 0) {
			substream = READ_ONCE(ff->tx_midi_substreams[1]);
			if (substream != NULL) {
				byte = (quad >> 16) & 0xff;
				snd_rawmidi_receive(substream, &byte, 1);
			}
		}
	}
	ff->spec->protocol->handle_midi_msg(ff, buf, length);
}

static int allocate_own_address(struct snd_ff *ff, int i)
+1 −0
Original line number Diff line number Diff line
@@ -108,6 +108,7 @@ enum snd_ff_clock_src {
};

struct snd_ff_protocol {
	void (*handle_midi_msg)(struct snd_ff *ff, __le32 *buf, size_t length);
	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);