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

ALSA: firewire-motu: add message parser to gather meter information in register DSP model



Some of MOTU models allows software to configure their DSP parameters by
accessing to their registers. The models multiplex messages for status of
DSP into isochronous packet as well as PCM frames. The message includes
information of hardware metering, MIDI message, current parameters of DSP.
For my convenience, I call them as 'register DSP' model.

This patch adds message parser for them to gather hardware meter
information.

Signed-off-by: default avatarTakashi Sakamoto <o-takashi@sakamocchi.jp>
Link: https://lore.kernel.org/r/20211015080826.34847-2-o-takashi@sakamocchi.jp


Signed-off-by: default avatarTakashi Iwai <tiwai@suse.de>
parent c18c4966
Loading
Loading
Loading
Loading
+35 −0
Original line number Diff line number Diff line
@@ -108,4 +108,39 @@ struct snd_firewire_tascam_state {
	__be32 data[SNDRV_FIREWIRE_TASCAM_STATE_COUNT];
};

// In below MOTU models, software is allowed to control their DSP by accessing to registers.
//  - 828mk2
//  - 896hd
//  - Traveler
//  - 8 pre
//  - Ultralite
//  - 4 pre
//  - Audio Express
//
// On the other hand, the status of DSP is split into specific messages included in the sequence of
// isochronous packet. ALSA firewire-motu driver gathers the messages and allow userspace applications
// to read it via ioctl. In 828mk2, 896hd, and Traveler, hardware meter for all of physical inputs
// are put into the message, while one pair of physical outputs is selected. The selection is done by
// LSB one byte in asynchronous write quadlet transaction to 0x'ffff'f000'0b2c.
//
// I note that V3HD/V4HD uses asynchronous transaction for the purpose. The destination address is
// registered to 0x'ffff'f000'0b38 and '0b3c by asynchronous write quadlet request. The size of
// message differs between 23 and 51 quadlets. For the case, the number of mixer bus can be extended
// up to 12.

#define SNDRV_FIREWIRE_MOTU_REGISTER_DSP_METER_COUNT	40

/**
 * struct snd_firewire_motu_register_dsp_meter - the container for meter information in DSP
 *						 controlled by register access
 * @data: Signal level meters. The mapping between position and input/output channel is
 *	  model-dependent.
 *
 * The structure expresses the part of DSP status for hardware meter. The u8 storage includes linear
 * value for audio signal level between 0x00 and 0x7f.
 */
struct snd_firewire_motu_register_dsp_meter {
	__u8 data[SNDRV_FIREWIRE_MOTU_REGISTER_DSP_METER_COUNT];
};

#endif /* _UAPI_SOUND_FIREWIRE_H_INCLUDED */
+1 −1
Original line number Diff line number Diff line
@@ -4,5 +4,5 @@ CFLAGS_amdtp-motu.o := -I$(src)
snd-firewire-motu-objs := motu.o amdtp-motu.o motu-transaction.o motu-stream.o \
			  motu-proc.o motu-pcm.o motu-midi.o motu-hwdep.o \
			  motu-protocol-v2.o motu-protocol-v3.o \
			  motu-protocol-v1.o
			  motu-protocol-v1.o motu-register-dsp-message-parser.o
obj-$(CONFIG_SND_FIREWIRE_MOTU) += snd-firewire-motu.o
+6 −0
Original line number Diff line number Diff line
@@ -333,6 +333,7 @@ static unsigned int process_ir_ctx_payloads(struct amdtp_stream *s,
					    unsigned int packets,
					    struct snd_pcm_substream *pcm)
{
	struct snd_motu *motu = container_of(s, struct snd_motu, tx_stream);
	struct amdtp_motu *p = s->protocol;
	unsigned int pcm_frames = 0;
	int i;
@@ -357,6 +358,11 @@ static unsigned int process_ir_ctx_payloads(struct amdtp_stream *s,
			read_midi_messages(s, buf, data_blocks);
	}

	if (motu->spec->flags & SND_MOTU_SPEC_REGISTER_DSP) {
		snd_motu_register_dsp_message_parser_parse(motu, descs, packets,
							   s->data_block_quadlets);
	}

	// For tracepoints.
	if (trace_data_block_sph_enabled() ||
	    trace_data_block_message_enabled())
+9 −5
Original line number Diff line number Diff line
@@ -275,7 +275,8 @@ const struct snd_motu_spec snd_motu_spec_828mk2 = {
	.name = "828mk2",
	.protocol_version = SND_MOTU_PROTOCOL_V2,
	.flags = SND_MOTU_SPEC_RX_MIDI_2ND_Q |
		 SND_MOTU_SPEC_TX_MIDI_2ND_Q,
		 SND_MOTU_SPEC_TX_MIDI_2ND_Q |
		 SND_MOTU_SPEC_REGISTER_DSP,
	.tx_fixed_pcm_chunks = {14, 14, 0},
	.rx_fixed_pcm_chunks = {14, 14, 0},
};
@@ -283,7 +284,7 @@ const struct snd_motu_spec snd_motu_spec_828mk2 = {
const struct snd_motu_spec snd_motu_spec_896hd = {
	.name = "896HD",
	.protocol_version = SND_MOTU_PROTOCOL_V2,
	// No support for MIDI.
	.flags = SND_MOTU_SPEC_REGISTER_DSP,
	.tx_fixed_pcm_chunks = {14, 14, 8},
	.rx_fixed_pcm_chunks = {14, 14, 8},
};
@@ -292,7 +293,8 @@ const struct snd_motu_spec snd_motu_spec_traveler = {
	.name = "Traveler",
	.protocol_version = SND_MOTU_PROTOCOL_V2,
	.flags = SND_MOTU_SPEC_RX_MIDI_2ND_Q |
		 SND_MOTU_SPEC_TX_MIDI_2ND_Q,
		 SND_MOTU_SPEC_TX_MIDI_2ND_Q |
		 SND_MOTU_SPEC_REGISTER_DSP,
	.tx_fixed_pcm_chunks = {14, 14, 8},
	.rx_fixed_pcm_chunks = {14, 14, 8},
};
@@ -301,7 +303,8 @@ const struct snd_motu_spec snd_motu_spec_ultralite = {
	.name = "UltraLite",
	.protocol_version = SND_MOTU_PROTOCOL_V2,
	.flags = SND_MOTU_SPEC_RX_MIDI_2ND_Q |
		 SND_MOTU_SPEC_TX_MIDI_2ND_Q,
		 SND_MOTU_SPEC_TX_MIDI_2ND_Q |
		 SND_MOTU_SPEC_REGISTER_DSP,
	.tx_fixed_pcm_chunks = {14, 14, 0},
	.rx_fixed_pcm_chunks = {14, 14, 0},
};
@@ -310,7 +313,8 @@ const struct snd_motu_spec snd_motu_spec_8pre = {
	.name = "8pre",
	.protocol_version = SND_MOTU_PROTOCOL_V2,
	.flags = SND_MOTU_SPEC_RX_MIDI_2ND_Q |
		 SND_MOTU_SPEC_TX_MIDI_2ND_Q,
		 SND_MOTU_SPEC_TX_MIDI_2ND_Q |
		 SND_MOTU_SPEC_REGISTER_DSP,
	// Two dummy chunks always in the end of data block.
	.tx_fixed_pcm_chunks = {10, 10, 0},
	.rx_fixed_pcm_chunks = {6, 6, 0},
+3 −1
Original line number Diff line number Diff line
@@ -293,7 +293,8 @@ const struct snd_motu_spec snd_motu_spec_audio_express = {
	.name = "AudioExpress",
	.protocol_version = SND_MOTU_PROTOCOL_V3,
	.flags = SND_MOTU_SPEC_RX_MIDI_2ND_Q |
		 SND_MOTU_SPEC_TX_MIDI_3RD_Q,
		 SND_MOTU_SPEC_TX_MIDI_3RD_Q |
		 SND_MOTU_SPEC_REGISTER_DSP,
	.tx_fixed_pcm_chunks = {10, 10, 0},
	.rx_fixed_pcm_chunks = {10, 10, 0},
};
@@ -301,6 +302,7 @@ const struct snd_motu_spec snd_motu_spec_audio_express = {
const struct snd_motu_spec snd_motu_spec_4pre = {
	.name = "4pre",
	.protocol_version = SND_MOTU_PROTOCOL_V3,
	.flags = SND_MOTU_SPEC_REGISTER_DSP,
	.tx_fixed_pcm_chunks = {10, 10, 0},
	.rx_fixed_pcm_chunks = {10, 10, 0},
};
Loading