All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0/4] ALSA: firewire-digi00x: integration to support console models
@ 2017-04-02 14:48 Takashi Sakamoto
  2017-04-02 14:48 ` [PATCH 1/4] ALSA: firewire-digi00x: add support for console models of Digi00x series Takashi Sakamoto
                   ` (4 more replies)
  0 siblings, 5 replies; 6+ messages in thread
From: Takashi Sakamoto @ 2017-04-02 14:48 UTC (permalink / raw)
  To: clemens, tiwai; +Cc: alsa-devel, ffado-devel

Hi,

Disidesign Digi00x series includes two types of unit; rack and console. ALSA
Digi00x driver is originally designed to handle both types.

Recently I got console model and realized that it can't handle console type,
as a result of packet sniffing.

This patchset is to add proper support for unit of the console type, with
new information from the reverse-engineering work.

Takashi Sakamoto (4):
  ALSA: firewire-digi00x: add support for console models of Digi00x
    series
  ALSA: firewire-digi00x: handle all MIDI messages on streaming packets
  ALSA: firewire-digi00x: allow user space applications to read/write
    MIDI messages for all ports
  ALSA: firewire-digi00x: remove transaction handler for unknown purpose

 sound/firewire/digi00x/amdtp-dot.c           |  55 ++++---
 sound/firewire/digi00x/digi00x-midi.c        | 208 ++++++++++-----------------
 sound/firewire/digi00x/digi00x-transaction.c |  88 ++----------
 sound/firewire/digi00x/digi00x.c             |  13 +-
 sound/firewire/digi00x/digi00x.h             |   7 +-
 5 files changed, 145 insertions(+), 226 deletions(-)

-- 
2.9.3

^ permalink raw reply	[flat|nested] 6+ messages in thread

* [PATCH 1/4] ALSA: firewire-digi00x: add support for console models of Digi00x series
  2017-04-02 14:48 [PATCH 0/4] ALSA: firewire-digi00x: integration to support console models Takashi Sakamoto
@ 2017-04-02 14:48 ` Takashi Sakamoto
  2017-04-02 14:48 ` [PATCH 2/4] ALSA: firewire-digi00x: handle all MIDI messages on streaming packets Takashi Sakamoto
                   ` (3 subsequent siblings)
  4 siblings, 0 replies; 6+ messages in thread
From: Takashi Sakamoto @ 2017-04-02 14:48 UTC (permalink / raw)
  To: clemens, tiwai; +Cc: alsa-devel, ffado-devel

Digi00x series includes two types of unit; rack and console. As long as
reading information on config rom of Digi 002 console, 'MODEL_ID' field
has a different value from the one on Digi 002 rack.

We've already got a test report from users with Digi 003 rack. We can
assume that console type and rack type has different value in the field.

This commit adds a device entry for console type. For following commits,
this commit also adds a member to 'struct snd_digi00x' to identify console
type.

$ cd linux-firewire-utils/src
$ python2 ./crpp < /sys/bus/firewire/devices/fw1/config_rom
               ROM header and bus information block
               -----------------------------------------------------------------
400  0404f9d0  bus_info_length 4, crc_length 4, crc 63952
404  31333934  bus_name "1394"
408  60647002  irmc 0, cmc 1, isc 1, bmc 0, cyc_clk_acc 100, max_rec 7 (256)
40c  00a07e00  company_id 00a07e     |
410  00a30000  device_id 0000a30000  | EUI-64 00a07e0000a30000

               root directory
               -----------------------------------------------------------------
414  00058a39  directory_length 5, crc 35385
418  0c0043a0  node capabilities
41c  04000001  hardware version
420  0300a07e  vendor
424  81000007  --> descriptor leaf at 440
428  d1000001  --> unit directory at 42c

               unit directory at 42c
               -----------------------------------------------------------------
42c  00046674  directory_length 4, crc 26228
430  120000a3  specifier id
434  13000001  version
438  17000001  model
43c  81000007  --> descriptor leaf at 458

               descriptor leaf at 440
               -----------------------------------------------------------------
440  00055913  leaf_length 5, crc 22803
444  000050f2  descriptor_type 00, specifier_ID 50f2
448  80000000
44c  44696769
450  64657369
454  676e0000

               descriptor leaf at 458
               -----------------------------------------------------------------
458  0004a6fd  leaf_length 4, crc 42749
45c  00000000  textual descriptor
460  00000000  minimal ASCII
464  44696769  "Digi"
468  20303032  " 002"

Signed-off-by: Takashi Sakamoto <o-takashi@sakamocchi.jp>
---
 sound/firewire/digi00x/digi00x.c | 13 +++++++++++--
 sound/firewire/digi00x/digi00x.h |  1 +
 2 files changed, 12 insertions(+), 2 deletions(-)

diff --git a/sound/firewire/digi00x/digi00x.c b/sound/firewire/digi00x/digi00x.c
index cc4776c..1f5e1d2 100644
--- a/sound/firewire/digi00x/digi00x.c
+++ b/sound/firewire/digi00x/digi00x.c
@@ -13,7 +13,8 @@ MODULE_AUTHOR("Takashi Sakamoto <o-takashi@sakamocchi.jp>");
 MODULE_LICENSE("GPL v2");
 
 #define VENDOR_DIGIDESIGN	0x00a07e
-#define MODEL_DIGI00X		0x000002
+#define MODEL_CONSOLE		0x000001
+#define MODEL_RACK		0x000002
 
 static int name_card(struct snd_dg00x *dg00x)
 {
@@ -129,6 +130,8 @@ static int snd_dg00x_probe(struct fw_unit *unit,
 	spin_lock_init(&dg00x->lock);
 	init_waitqueue_head(&dg00x->hwdep_wait);
 
+	dg00x->is_console = entry->model_id == MODEL_CONSOLE;
+
 	/* Allocate and register this sound card later. */
 	INIT_DEFERRABLE_WORK(&dg00x->dwork, do_registration);
 	snd_fw_schedule_registration(unit, &dg00x->dwork);
@@ -183,7 +186,13 @@ static const struct ieee1394_device_id snd_dg00x_id_table[] = {
 		.match_flags = IEEE1394_MATCH_VENDOR_ID |
 			       IEEE1394_MATCH_MODEL_ID,
 		.vendor_id = VENDOR_DIGIDESIGN,
-		.model_id = MODEL_DIGI00X,
+		.model_id = MODEL_CONSOLE,
+	},
+	{
+		.match_flags = IEEE1394_MATCH_VENDOR_ID |
+			       IEEE1394_MATCH_MODEL_ID,
+		.vendor_id = VENDOR_DIGIDESIGN,
+		.model_id = MODEL_RACK,
 	},
 	{}
 };
diff --git a/sound/firewire/digi00x/digi00x.h b/sound/firewire/digi00x/digi00x.h
index 9dc761b..4aefe45d 100644
--- a/sound/firewire/digi00x/digi00x.h
+++ b/sound/firewire/digi00x/digi00x.h
@@ -61,6 +61,7 @@ struct snd_dg00x {
 	/* For asynchronous MIDI controls. */
 	struct snd_rawmidi_substream *in_control;
 	struct snd_fw_async_midi_port out_control;
+	bool is_console;
 };
 
 #define DG00X_ADDR_BASE		0xffffe0000000ull
-- 
2.9.3

^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [PATCH 2/4] ALSA: firewire-digi00x: handle all MIDI messages on streaming packets
  2017-04-02 14:48 [PATCH 0/4] ALSA: firewire-digi00x: integration to support console models Takashi Sakamoto
  2017-04-02 14:48 ` [PATCH 1/4] ALSA: firewire-digi00x: add support for console models of Digi00x series Takashi Sakamoto
@ 2017-04-02 14:48 ` Takashi Sakamoto
  2017-04-02 14:48 ` [PATCH 3/4] ALSA: firewire-digi00x: allow user space applications to read/write MIDI messages for all ports Takashi Sakamoto
                   ` (2 subsequent siblings)
  4 siblings, 0 replies; 6+ messages in thread
From: Takashi Sakamoto @ 2017-04-02 14:48 UTC (permalink / raw)
  To: clemens, tiwai; +Cc: alsa-devel, ffado-devel

At a commit 9dc5d31cdceb ("ALSA: firewire-digi00x: handle MIDI messages in
isochronous packets"), a functionality to handle MIDI messages on
isochronous packet was supported. But this includes some of my
misunderstanding. This commit is to fix them.

For digi00x series, first data channel of data blocks in rx/tx packet
includes MIDI messages. The data channel has 0x80 in 8 bit of its MSB,
however it's against IEC 61883-6. Unique data format is applied:
 - Upper 4 bits of LSB represent port number.
  - 0x0: port 1.
  - 0x2: port 2.
  - 0xe: console port.
 - Lower 4 bits of LSB represent the number of included MIDI message bytes;
   0x0/0x1/0x2.
 - Two bytes of middle of this data channel have MIDI bytes.

Especially, MIDI messages from/to console surface are also transferred by
isochronous packets, as well as physical MIDI ports.

Signed-off-by: Takashi Sakamoto <o-takashi@sakamocchi.jp>
---
 sound/firewire/digi00x/amdtp-dot.c | 55 +++++++++++++++++++++++++-------------
 1 file changed, 37 insertions(+), 18 deletions(-)

diff --git a/sound/firewire/digi00x/amdtp-dot.c b/sound/firewire/digi00x/amdtp-dot.c
index b3cffd0..a468854 100644
--- a/sound/firewire/digi00x/amdtp-dot.c
+++ b/sound/firewire/digi00x/amdtp-dot.c
@@ -28,6 +28,9 @@
  */
 #define MAX_MIDI_RX_BLOCKS	8
 
+/* 3 = MAX(DOT_MIDI_IN_PORTS, DOT_MIDI_OUT_PORTS) + 1. */
+#define MAX_MIDI_PORTS		3
+
 /*
  * The double-oh-three algorithm was discovered by Robin Gareus and Damien
  * Zammit in 2012, with reverse-engineering for Digi 003 Rack.
@@ -42,10 +45,8 @@ struct amdtp_dot {
 	unsigned int pcm_channels;
 	struct dot_state state;
 
-	unsigned int midi_ports;
-	/* 2 = MAX(DOT_MIDI_IN_PORTS, DOT_MIDI_OUT_PORTS) */
-	struct snd_rawmidi_substream *midi[2];
-	int midi_fifo_used[2];
+	struct snd_rawmidi_substream *midi[MAX_MIDI_PORTS];
+	int midi_fifo_used[MAX_MIDI_PORTS];
 	int midi_fifo_limit;
 
 	void (*transfer_samples)(struct amdtp_stream *s,
@@ -124,8 +125,8 @@ int amdtp_dot_set_parameters(struct amdtp_stream *s, unsigned int rate,
 		return -EBUSY;
 
 	/*
-	 * A first data channel is for MIDI conformant data channel, the rest is
-	 * Multi Bit Linear Audio data channel.
+	 * A first data channel is for MIDI messages, the rest is Multi Bit
+	 * Linear Audio data channel.
 	 */
 	err = amdtp_stream_set_parameters(s, rate, pcm_channels + 1);
 	if (err < 0)
@@ -135,11 +136,6 @@ int amdtp_dot_set_parameters(struct amdtp_stream *s, unsigned int rate,
 
 	p->pcm_channels = pcm_channels;
 
-	if (s->direction == AMDTP_IN_STREAM)
-		p->midi_ports = DOT_MIDI_IN_PORTS;
-	else
-		p->midi_ports = DOT_MIDI_OUT_PORTS;
-
 	/*
 	 * We do not know the actual MIDI FIFO size of most devices.  Just
 	 * assume two bytes, i.e., one byte can be received over the bus while
@@ -281,13 +277,25 @@ static void write_midi_messages(struct amdtp_stream *s, __be32 *buffer,
 		b = (u8 *)&buffer[0];
 
 		len = 0;
-		if (port < p->midi_ports &&
+		if (port < MAX_MIDI_PORTS &&
 		    midi_ratelimit_per_packet(s, port) &&
 		    p->midi[port] != NULL)
 			len = snd_rawmidi_transmit(p->midi[port], b + 1, 2);
 
 		if (len > 0) {
-			b[3] = (0x10 << port) | len;
+			/*
+			 * Upper 4 bits of LSB represent port number.
+			 * - 0000b: physical MIDI port 1.
+			 * - 0010b: physical MIDI port 2.
+			 * - 1110b: console MIDI port.
+			 */
+			if (port == 2)
+				b[3] = 0xe0;
+			else if (port == 1)
+				b[3] = 0x20;
+			else
+				b[3] = 0x00;
+			b[3] |= len;
 			midi_use_bytes(s, port, len);
 		} else {
 			b[1] = 0;
@@ -309,11 +317,22 @@ static void read_midi_messages(struct amdtp_stream *s, __be32 *buffer,
 
 	for (f = 0; f < data_blocks; f++) {
 		b = (u8 *)&buffer[0];
-		port = b[3] >> 4;
-		len = b[3] & 0x0f;
 
-		if (port < p->midi_ports && p->midi[port] && len > 0)
-			snd_rawmidi_receive(p->midi[port], b + 1, len);
+		len = b[3] & 0x0f;
+		if (len > 0) {
+			/*
+			 * Upper 4 bits of LSB represent port number.
+			 * - 0000b: physical MIDI port 1. Use port 0.
+			 * - 1110b: console MIDI port. Use port 2.
+			 */
+			if (b[3] >> 4 > 0)
+				port = 2;
+			else
+				port = 0;
+
+			if (port < MAX_MIDI_PORTS && p->midi[port])
+				snd_rawmidi_receive(p->midi[port], b + 1, len);
+		}
 
 		buffer += s->data_block_quadlets;
 	}
@@ -364,7 +383,7 @@ void amdtp_dot_midi_trigger(struct amdtp_stream *s, unsigned int port,
 {
 	struct amdtp_dot *p = s->protocol;
 
-	if (port < p->midi_ports)
+	if (port < MAX_MIDI_PORTS)
 		ACCESS_ONCE(p->midi[port]) = midi;
 }
 
-- 
2.9.3

^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [PATCH 3/4] ALSA: firewire-digi00x: allow user space applications to read/write MIDI messages for all ports
  2017-04-02 14:48 [PATCH 0/4] ALSA: firewire-digi00x: integration to support console models Takashi Sakamoto
  2017-04-02 14:48 ` [PATCH 1/4] ALSA: firewire-digi00x: add support for console models of Digi00x series Takashi Sakamoto
  2017-04-02 14:48 ` [PATCH 2/4] ALSA: firewire-digi00x: handle all MIDI messages on streaming packets Takashi Sakamoto
@ 2017-04-02 14:48 ` Takashi Sakamoto
  2017-04-02 14:48 ` [PATCH 4/4] ALSA: firewire-digi00x: remove transaction handler for unknown purpose Takashi Sakamoto
  2017-04-05 19:34 ` [PATCH 0/4] ALSA: firewire-digi00x: integration to support console models Takashi Iwai
  4 siblings, 0 replies; 6+ messages in thread
From: Takashi Sakamoto @ 2017-04-02 14:48 UTC (permalink / raw)
  To: clemens, tiwai; +Cc: alsa-devel, ffado-devel

At a commit c5fcee0373b3 ("ALSA: firewire-digi00x: add MIDI operations for
MIDI control port"), I described that MIDI messages for control surface is
transferred by a different way from the messages for physical ports.
However, this is wrong. MIDI messages to/from all of MIDI ports are
transferred by isochronous packets.

This commit removes codes to transfer MIDI messages via asynchronous
transaction, from MIDI handling layer.

Signed-off-by: Takashi Sakamoto <o-takashi@sakamocchi.jp>
---
 sound/firewire/digi00x/digi00x-midi.c | 208 +++++++++++++---------------------
 1 file changed, 79 insertions(+), 129 deletions(-)

diff --git a/sound/firewire/digi00x/digi00x-midi.c b/sound/firewire/digi00x/digi00x-midi.c
index 915d2a2..7ab3d08 100644
--- a/sound/firewire/digi00x/digi00x-midi.c
+++ b/sound/firewire/digi00x/digi00x-midi.c
@@ -8,7 +8,7 @@
 
 #include "digi00x.h"
 
-static int midi_phys_open(struct snd_rawmidi_substream *substream)
+static int midi_open(struct snd_rawmidi_substream *substream)
 {
 	struct snd_dg00x *dg00x = substream->rmidi->private_data;
 	int err;
@@ -27,7 +27,7 @@ static int midi_phys_open(struct snd_rawmidi_substream *substream)
 	return err;
 }
 
-static int midi_phys_close(struct snd_rawmidi_substream *substream)
+static int midi_close(struct snd_rawmidi_substream *substream)
 {
 	struct snd_dg00x *dg00x = substream->rmidi->private_data;
 
@@ -40,180 +40,130 @@ static int midi_phys_close(struct snd_rawmidi_substream *substream)
 	return 0;
 }
 
-static void midi_phys_capture_trigger(struct snd_rawmidi_substream *substream,
-				      int up)
+static void midi_capture_trigger(struct snd_rawmidi_substream *substream,
+				 int up)
 {
 	struct snd_dg00x *dg00x = substream->rmidi->private_data;
+	unsigned int port;
 	unsigned long flags;
 
-	spin_lock_irqsave(&dg00x->lock, flags);
-
-	if (up)
-		amdtp_dot_midi_trigger(&dg00x->tx_stream, substream->number,
-				       substream);
+	if (substream->rmidi->device == 0)
+		port = substream->number;
 	else
-		amdtp_dot_midi_trigger(&dg00x->tx_stream, substream->number,
-				       NULL);
-
-	spin_unlock_irqrestore(&dg00x->lock, flags);
-}
-
-static void midi_phys_playback_trigger(struct snd_rawmidi_substream *substream,
-				       int up)
-{
-	struct snd_dg00x *dg00x = substream->rmidi->private_data;
-	unsigned long flags;
+		port = 2;
 
 	spin_lock_irqsave(&dg00x->lock, flags);
 
 	if (up)
-		amdtp_dot_midi_trigger(&dg00x->rx_stream, substream->number,
-				       substream);
+		amdtp_dot_midi_trigger(&dg00x->tx_stream, port, substream);
 	else
-		amdtp_dot_midi_trigger(&dg00x->rx_stream, substream->number,
-				       NULL);
+		amdtp_dot_midi_trigger(&dg00x->tx_stream, port, NULL);
 
 	spin_unlock_irqrestore(&dg00x->lock, flags);
 }
 
-static int midi_ctl_open(struct snd_rawmidi_substream *substream)
-{
-	/* Do nothing. */
-	return 0;
-}
-
-static int midi_ctl_capture_close(struct snd_rawmidi_substream *substream)
-{
-	/* Do nothing. */
-	return 0;
-}
-
-static int midi_ctl_playback_close(struct snd_rawmidi_substream *substream)
-{
-	struct snd_dg00x *dg00x = substream->rmidi->private_data;
-
-	snd_fw_async_midi_port_finish(&dg00x->out_control);
-
-	return 0;
-}
-
-static void midi_ctl_capture_trigger(struct snd_rawmidi_substream *substream,
-				     int up)
+static void midi_playback_trigger(struct snd_rawmidi_substream *substream,
+				  int up)
 {
 	struct snd_dg00x *dg00x = substream->rmidi->private_data;
+	unsigned int port;
 	unsigned long flags;
 
-	spin_lock_irqsave(&dg00x->lock, flags);
-
-	if (up)
-		dg00x->in_control = substream;
+	if (substream->rmidi->device == 0)
+		port = substream->number;
 	else
-		dg00x->in_control = NULL;
-
-	spin_unlock_irqrestore(&dg00x->lock, flags);
-}
-
-static void midi_ctl_playback_trigger(struct snd_rawmidi_substream *substream,
-				      int up)
-{
-	struct snd_dg00x *dg00x = substream->rmidi->private_data;
-	unsigned long flags;
+		port = 2;
 
 	spin_lock_irqsave(&dg00x->lock, flags);
 
 	if (up)
-		snd_fw_async_midi_port_run(&dg00x->out_control, substream);
+		amdtp_dot_midi_trigger(&dg00x->rx_stream, port, substream);
+	else
+		amdtp_dot_midi_trigger(&dg00x->rx_stream, port, NULL);
 
 	spin_unlock_irqrestore(&dg00x->lock, flags);
 }
 
-static void set_midi_substream_names(struct snd_dg00x *dg00x,
-				     struct snd_rawmidi_str *str,
-				     bool is_ctl)
+static void set_substream_names(struct snd_dg00x *dg00x,
+				struct snd_rawmidi *rmidi, bool is_console)
 {
 	struct snd_rawmidi_substream *subs;
-
-	list_for_each_entry(subs, &str->substreams, list) {
-		if (!is_ctl)
-			snprintf(subs->name, sizeof(subs->name),
-				 "%s MIDI %d",
-				 dg00x->card->shortname, subs->number + 1);
-		else
-			/* This port is for asynchronous transaction. */
-			snprintf(subs->name, sizeof(subs->name),
-				 "%s control",
-				 dg00x->card->shortname);
+	struct snd_rawmidi_str *str;
+	int i;
+
+	for (i = 0; i < 2; ++i) {
+		str = &rmidi->streams[i];
+
+		list_for_each_entry(subs, &str->substreams, list) {
+			if (!is_console) {
+				snprintf(subs->name, sizeof(subs->name),
+					 "%s MIDI %d",
+					 dg00x->card->shortname,
+					 subs->number + 1);
+			} else {
+				snprintf(subs->name, sizeof(subs->name),
+					 "%s control",
+					 dg00x->card->shortname);
+			}
+		}
 	}
 }
 
-int snd_dg00x_create_midi_devices(struct snd_dg00x *dg00x)
+static int add_substream_pair(struct snd_dg00x *dg00x, unsigned int out_ports,
+			      unsigned int in_ports, bool is_console)
 {
-	static const struct snd_rawmidi_ops phys_capture_ops = {
-		.open		= midi_phys_open,
-		.close		= midi_phys_close,
-		.trigger	= midi_phys_capture_trigger,
-	};
-	static const struct snd_rawmidi_ops phys_playback_ops = {
-		.open		= midi_phys_open,
-		.close		= midi_phys_close,
-		.trigger	= midi_phys_playback_trigger,
+	static const struct snd_rawmidi_ops capture_ops = {
+		.open = midi_open,
+		.close = midi_close,
+		.trigger = midi_capture_trigger,
 	};
-	static const struct snd_rawmidi_ops ctl_capture_ops = {
-		.open		= midi_ctl_open,
-		.close		= midi_ctl_capture_close,
-		.trigger	= midi_ctl_capture_trigger,
+	static const struct snd_rawmidi_ops playback_ops = {
+		.open = midi_open,
+		.close = midi_close,
+		.trigger = midi_playback_trigger,
 	};
-	static const struct snd_rawmidi_ops ctl_playback_ops = {
-		.open		= midi_ctl_open,
-		.close		= midi_ctl_playback_close,
-		.trigger	= midi_ctl_playback_trigger,
-	};
-	struct snd_rawmidi *rmidi[2];
-	struct snd_rawmidi_str *str;
-	unsigned int i;
+	const char *label;
+	struct snd_rawmidi *rmidi;
 	int err;
 
 	/* Add physical midi ports. */
-	err = snd_rawmidi_new(dg00x->card, dg00x->card->driver, 0,
-			DOT_MIDI_OUT_PORTS, DOT_MIDI_IN_PORTS, &rmidi[0]);
+	err = snd_rawmidi_new(dg00x->card, dg00x->card->driver, is_console,
+			      out_ports, in_ports, &rmidi);
 	if (err < 0)
 		return err;
+	rmidi->private_data = dg00x;
 
-	snprintf(rmidi[0]->name, sizeof(rmidi[0]->name),
-		 "%s MIDI", dg00x->card->shortname);
-
-	snd_rawmidi_set_ops(rmidi[0], SNDRV_RAWMIDI_STREAM_INPUT,
-			    &phys_capture_ops);
-	snd_rawmidi_set_ops(rmidi[0], SNDRV_RAWMIDI_STREAM_OUTPUT,
-			    &phys_playback_ops);
+	if (!is_console)
+		label = "%s control";
+	else
+		label = "%s MIDI";
+	snprintf(rmidi->name, sizeof(rmidi->name), label,
+		 dg00x->card->shortname);
 
-	/* Add a pair of control midi ports. */
-	err = snd_rawmidi_new(dg00x->card, dg00x->card->driver, 1,
-			      1, 1, &rmidi[1]);
-	if (err < 0)
-		return err;
+	snd_rawmidi_set_ops(rmidi, SNDRV_RAWMIDI_STREAM_OUTPUT, &playback_ops);
+	snd_rawmidi_set_ops(rmidi, SNDRV_RAWMIDI_STREAM_INPUT, &capture_ops);
 
-	snprintf(rmidi[1]->name, sizeof(rmidi[1]->name),
-		 "%s control", dg00x->card->shortname);
+	rmidi->info_flags |= SNDRV_RAWMIDI_INFO_INPUT |
+			     SNDRV_RAWMIDI_INFO_OUTPUT |
+			     SNDRV_RAWMIDI_INFO_DUPLEX;
 
-	snd_rawmidi_set_ops(rmidi[1], SNDRV_RAWMIDI_STREAM_INPUT,
-			    &ctl_capture_ops);
-	snd_rawmidi_set_ops(rmidi[1], SNDRV_RAWMIDI_STREAM_OUTPUT,
-			    &ctl_playback_ops);
+	set_substream_names(dg00x, rmidi, is_console);
 
-	for (i = 0; i < ARRAY_SIZE(rmidi); i++) {
-		rmidi[i]->private_data = dg00x;
+	return 0;
+}
 
-		rmidi[i]->info_flags |= SNDRV_RAWMIDI_INFO_INPUT;
-		str = &rmidi[i]->streams[SNDRV_RAWMIDI_STREAM_INPUT];
-		set_midi_substream_names(dg00x, str, i);
+int snd_dg00x_create_midi_devices(struct snd_dg00x *dg00x)
+{
+	int err;
 
-		rmidi[i]->info_flags |= SNDRV_RAWMIDI_INFO_OUTPUT;
-		str = &rmidi[i]->streams[SNDRV_RAWMIDI_STREAM_OUTPUT];
-		set_midi_substream_names(dg00x, str, i);
+	/* Add physical midi ports. */
+	err = add_substream_pair(dg00x, DOT_MIDI_OUT_PORTS, DOT_MIDI_IN_PORTS,
+				 false);
+	if (err < 0)
+		return err;
 
-		rmidi[i]->info_flags |= SNDRV_RAWMIDI_INFO_DUPLEX;
-	}
+	if (dg00x->is_console)
+		err = add_substream_pair(dg00x, 1, 1, true);
 
-	return 0;
+	return err;
 }
-- 
2.9.3

^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [PATCH 4/4] ALSA: firewire-digi00x: remove transaction handler for unknown purpose
  2017-04-02 14:48 [PATCH 0/4] ALSA: firewire-digi00x: integration to support console models Takashi Sakamoto
                   ` (2 preceding siblings ...)
  2017-04-02 14:48 ` [PATCH 3/4] ALSA: firewire-digi00x: allow user space applications to read/write MIDI messages for all ports Takashi Sakamoto
@ 2017-04-02 14:48 ` Takashi Sakamoto
  2017-04-05 19:34 ` [PATCH 0/4] ALSA: firewire-digi00x: integration to support console models Takashi Iwai
  4 siblings, 0 replies; 6+ messages in thread
From: Takashi Sakamoto @ 2017-04-02 14:48 UTC (permalink / raw)
  To: clemens, tiwai; +Cc: alsa-devel, ffado-devel

For digi00x series, asynchronous transaction is not used to transfer MIDI
messages to/from control surface. One of transction handlers in my previous
work loses its practical meaning.

This commit removes the handler. I note that unit of console type
transfers 0x00001000 to registered address of host space when switching
to 'standalone' mode. Then the unit generates bus reset.

Signed-off-by: Takashi Sakamoto <o-takashi@sakamocchi.jp>
---
 sound/firewire/digi00x/digi00x-transaction.c | 88 +++++-----------------------
 sound/firewire/digi00x/digi00x.h             |  6 +-
 2 files changed, 17 insertions(+), 77 deletions(-)

diff --git a/sound/firewire/digi00x/digi00x-transaction.c b/sound/firewire/digi00x/digi00x-transaction.c
index 735d356..af9bc85 100644
--- a/sound/firewire/digi00x/digi00x-transaction.c
+++ b/sound/firewire/digi00x/digi00x-transaction.c
@@ -9,40 +9,6 @@
 #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)
-{
-	struct snd_rawmidi_substream *substream;
-	unsigned int i;
-	unsigned int len;
-	u8 *b;
-
-	substream = ACCESS_ONCE(dg00x->in_control);
-	if (substream == NULL)
-		return;
-
-	length /= 4;
-
-	for (i = 0; i < length; i++) {
-		b = (u8 *)&buf[i];
-		len = b[3] & 0xf;
-		if (len > 0)
-			snd_rawmidi_receive(dg00x->in_control, b + 1, len);
-	}
-}
-
 static void handle_unknown_message(struct snd_dg00x *dg00x,
 				   unsigned long long offset, __be32 *buf)
 {
@@ -63,39 +29,36 @@ static void handle_message(struct fw_card *card, struct fw_request *request,
 	struct snd_dg00x *dg00x = callback_data;
 	__be32 *buf = (__be32 *)data;
 
+	fw_send_response(card, request, RCODE_COMPLETE);
+
 	if (offset == dg00x->async_handler.offset)
 		handle_unknown_message(dg00x, offset, buf);
-	else if (offset == dg00x->async_handler.offset + 4)
-		handle_midi_control(dg00x, buf, length);
-
-	fw_send_response(card, request, RCODE_COMPLETE);
 }
 
 int snd_dg00x_transaction_reregister(struct snd_dg00x *dg00x)
 {
 	struct fw_device *device = fw_parent_device(dg00x->unit);
 	__be32 data[2];
-	int err;
 
 	/* Unknown. 4bytes. */
 	data[0] = cpu_to_be32((device->card->node_id << 16) |
 			      (dg00x->async_handler.offset >> 32));
 	data[1] = cpu_to_be32(dg00x->async_handler.offset);
-	err = snd_fw_transaction(dg00x->unit, TCODE_WRITE_BLOCK_REQUEST,
-				 DG00X_ADDR_BASE + DG00X_OFFSET_MESSAGE_ADDR,
-				 &data, sizeof(data), 0);
-	if (err < 0)
-		return err;
-
-	/* Asynchronous transactions for MIDI control message. */
-	data[0] = cpu_to_be32((device->card->node_id << 16) |
-			      (dg00x->async_handler.offset >> 32));
-	data[1] = cpu_to_be32(dg00x->async_handler.offset + 4);
 	return snd_fw_transaction(dg00x->unit, TCODE_WRITE_BLOCK_REQUEST,
-				  DG00X_ADDR_BASE + DG00X_OFFSET_MIDI_CTL_ADDR,
+				  DG00X_ADDR_BASE + DG00X_OFFSET_MESSAGE_ADDR,
 				  &data, sizeof(data), 0);
 }
 
+void snd_dg00x_transaction_unregister(struct snd_dg00x *dg00x)
+{
+	if (dg00x->async_handler.callback_data == NULL)
+		return;
+
+	fw_core_remove_address_handler(&dg00x->async_handler);
+
+	dg00x->async_handler.callback_data = NULL;
+}
+
 int snd_dg00x_transaction_register(struct snd_dg00x *dg00x)
 {
 	static const struct fw_address_region resp_register_region = {
@@ -104,7 +67,7 @@ int snd_dg00x_transaction_register(struct snd_dg00x *dg00x)
 	};
 	int err;
 
-	dg00x->async_handler.length = 12;
+	dg00x->async_handler.length = 4;
 	dg00x->async_handler.address_callback = handle_message;
 	dg00x->async_handler.callback_data = dg00x;
 
@@ -115,28 +78,7 @@ int snd_dg00x_transaction_register(struct snd_dg00x *dg00x)
 
 	err = snd_dg00x_transaction_reregister(dg00x);
 	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;
+		snd_dg00x_transaction_unregister(dg00x);
 
 	return err;
-error:
-	fw_core_remove_address_handler(&dg00x->async_handler);
-	dg00x->async_handler.callback_data = NULL;
-	return err;
-}
-
-void snd_dg00x_transaction_unregister(struct snd_dg00x *dg00x)
-{
-	if (dg00x->async_handler.callback_data == NULL)
-		return;
-
-	snd_fw_async_midi_port_destroy(&dg00x->out_control);
-	fw_core_remove_address_handler(&dg00x->async_handler);
-
-	dg00x->async_handler.callback_data = NULL;
 }
diff --git a/sound/firewire/digi00x/digi00x.h b/sound/firewire/digi00x/digi00x.h
index 4aefe45d..1275a50 100644
--- a/sound/firewire/digi00x/digi00x.h
+++ b/sound/firewire/digi00x/digi00x.h
@@ -58,9 +58,7 @@ struct snd_dg00x {
 	struct fw_address_handler async_handler;
 	u32 msg;
 
-	/* For asynchronous MIDI controls. */
-	struct snd_rawmidi_substream *in_control;
-	struct snd_fw_async_midi_port out_control;
+	/* Console models have additional MIDI ports for control surface. */
 	bool is_console;
 };
 
@@ -68,7 +66,7 @@ struct snd_dg00x {
 
 #define DG00X_OFFSET_STREAMING_STATE	0x0000
 #define DG00X_OFFSET_STREAMING_SET	0x0004
-#define DG00X_OFFSET_MIDI_CTL_ADDR	0x0008
+/* unknown but address in host space	0x0008 */
 /* For LSB of the address		0x000c */
 /* unknown				0x0010 */
 #define DG00X_OFFSET_MESSAGE_ADDR	0x0014
-- 
2.9.3

^ permalink raw reply related	[flat|nested] 6+ messages in thread

* Re: [PATCH 0/4] ALSA: firewire-digi00x: integration to support console models
  2017-04-02 14:48 [PATCH 0/4] ALSA: firewire-digi00x: integration to support console models Takashi Sakamoto
                   ` (3 preceding siblings ...)
  2017-04-02 14:48 ` [PATCH 4/4] ALSA: firewire-digi00x: remove transaction handler for unknown purpose Takashi Sakamoto
@ 2017-04-05 19:34 ` Takashi Iwai
  4 siblings, 0 replies; 6+ messages in thread
From: Takashi Iwai @ 2017-04-05 19:34 UTC (permalink / raw)
  To: Takashi Sakamoto; +Cc: alsa-devel, clemens, ffado-devel

On Sun, 02 Apr 2017 16:48:23 +0200,
Takashi Sakamoto wrote:
> 
> Hi,
> 
> Disidesign Digi00x series includes two types of unit; rack and console. ALSA
> Digi00x driver is originally designed to handle both types.
> 
> Recently I got console model and realized that it can't handle console type,
> as a result of packet sniffing.
> 
> This patchset is to add proper support for unit of the console type, with
> new information from the reverse-engineering work.

Applied all four patches now.  Thanks.


Takashi

> 
> Takashi Sakamoto (4):
>   ALSA: firewire-digi00x: add support for console models of Digi00x
>     series
>   ALSA: firewire-digi00x: handle all MIDI messages on streaming packets
>   ALSA: firewire-digi00x: allow user space applications to read/write
>     MIDI messages for all ports
>   ALSA: firewire-digi00x: remove transaction handler for unknown purpose
> 
>  sound/firewire/digi00x/amdtp-dot.c           |  55 ++++---
>  sound/firewire/digi00x/digi00x-midi.c        | 208 ++++++++++-----------------
>  sound/firewire/digi00x/digi00x-transaction.c |  88 ++----------
>  sound/firewire/digi00x/digi00x.c             |  13 +-
>  sound/firewire/digi00x/digi00x.h             |   7 +-
>  5 files changed, 145 insertions(+), 226 deletions(-)
> 
> -- 
> 2.9.3
> 

^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2017-04-05 19:34 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-04-02 14:48 [PATCH 0/4] ALSA: firewire-digi00x: integration to support console models Takashi Sakamoto
2017-04-02 14:48 ` [PATCH 1/4] ALSA: firewire-digi00x: add support for console models of Digi00x series Takashi Sakamoto
2017-04-02 14:48 ` [PATCH 2/4] ALSA: firewire-digi00x: handle all MIDI messages on streaming packets Takashi Sakamoto
2017-04-02 14:48 ` [PATCH 3/4] ALSA: firewire-digi00x: allow user space applications to read/write MIDI messages for all ports Takashi Sakamoto
2017-04-02 14:48 ` [PATCH 4/4] ALSA: firewire-digi00x: remove transaction handler for unknown purpose Takashi Sakamoto
2017-04-05 19:34 ` [PATCH 0/4] ALSA: firewire-digi00x: integration to support console models Takashi Iwai

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.