Skip to contentSkip to conversation

MIDI driver for Behringer BCD2000 USB device

PATCH Superseded Mario Kicherer 2 participants 4 messages Feb 20, 2014 – Feb 24, 2014 Sound

v6 of 9 Superseded Latest is v9 →

lore
Share & tools
lore
#0 lore raw

PATCH v6 1/1 MIDI driver for Behringer BCD2000 USB device

This patch adds initial support for the Behringer BCD2000 USB DJ controller. At the moment, only the MIDI part of the device is working, i.e. knobs, buttons and LEDs.

I also plan to add support for the audio part, but I assume that this will require more effort than the rather simple MIDI interface. Progress can be tracked at https://github.com/anyc/snd-usb-bcd2000.

Changes since v5:
- use kernel bitmap functions for devices_used

Changes since v4:
- devices_used as array to support arbitrary number of SNDRV_CARDS
- removed unused array "enable"

Changes since v3:
- applied style and snd_printk changes as suggested by Daniel Mack

Changes since v2:
- applied more changes from Daniel Mack and Clemens Ladisch

Changes since v1:
- fixed the various code style issues, thanks to Daniel Mack and checkpatch.pl.

---
 sound/usb/Kconfig           |  13 ++
 sound/usb/Makefile          |   2 +-
 sound/usb/bcd2000/Makefile  |   3 +
 sound/usb/bcd2000/bcd2000.c | 488 ++++++++++++++++++++++++++++++++++++++++++++
 4 files changed, 505 insertions(+), 1 deletion(-)
 create mode 100644 sound/usb/bcd2000/Makefile
 create mode 100644 sound/usb/bcd2000/bcd2000.c
sound/usb/Kconfig +13 -0
index de9408b..145653a 100644
@@ -146,5 +146,18 @@ config SND_USB_HIFACE
 	  To compile this driver as a module, choose M here: the module
 	  will be called snd-usb-hiface.
 
+config SND_BCD2000
+	tristate "Behringer BCD2000 MIDI driver"
+	select SND_RAWMIDI
+	help
+	  Say Y here to include MIDI support for the Behringer BCD2000 DJ
+	  controller.
+
+	  Audio support is still work-in-progress at
+	  https://github.com/anyc/snd-usb-bcd2000
+
+	  To compile this driver as a module, choose M here: the module
+	  will be called snd-bcd2000.
+
 endif	# SND_USB
 
sound/usb/Makefile +1 -1
index abe668f..2b92f0d 100644
@@ -23,4 +23,4 @@ obj-$(CONFIG_SND_USB_UA101) += snd-usbmidi-lib.o
 obj-$(CONFIG_SND_USB_USX2Y) += snd-usbmidi-lib.o
 obj-$(CONFIG_SND_USB_US122L) += snd-usbmidi-lib.o
 
-obj-$(CONFIG_SND) += misc/ usx2y/ caiaq/ 6fire/ hiface/
+obj-$(CONFIG_SND) += misc/ usx2y/ caiaq/ 6fire/ hiface/ bcd2000/
sound/usb/bcd2000/Makefile new file +3 -0
new file mode 100644
index 0000000..f09ccc0
@@ -0,0 +1,3 @@
+snd-bcd2000-y := bcd2000.o
+
+obj-$(CONFIG_SND_BCD2000) += snd-bcd2000.o
\ No newline at end of file
sound/usb/bcd2000/bcd2000.c new file +488 -0

488 lines not on this page · raw message

Signature · 1 line
1.8.3.2
#1 lore raw

sound/usb/bcd2000/bcd2000.c line 50

Quoted 9 lines · Mario Kicherer
sound/usb/bcd2000/bcd2000.c new file +9 -0
+static unsigned char bcd2000_init_sequence[] = {
+	0x07, 0x00, 0x00, 0x00, 0x78, 0x48, 0x1c, 0x81,
+	0xc4, 0x00, 0x00, 0x00, 0x5e, 0x53, 0x4a, 0xf7,
+	0x18, 0xfa, 0x11, 0xff, 0x6c, 0xf3, 0x90, 0xff,
+	0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
+	0x18, 0xfa, 0x11, 0xff, 0x14, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0xf2, 0x34, 0x4a, 0xf7,
+	0x18, 0xfa, 0x11, 0xff
+};

I wonder how much of this is the actual init sequence, and how much is random garbage. :-)

sound/usb/bcd2000/bcd2000.c line 128

Quoted 6 lines
sound/usb/bcd2000/bcd2000.c new file +6 -0
+	/*
+	 * Packet structure: mm nn oo (pp)
+	 *	mm: payload length
+	 *	nn: MIDI command or note
+	 *	oo: note or velocity
+	 *	pp: velocity

The device often sends data as single-byte packets, so the structure actually is "length data...".

sound/usb/bcd2000/bcd2000.c line 155

Quoted 3 lines
sound/usb/bcd2000/bcd2000.c new file +3 -0
+	/* copy the "set LED" command bytes */
+	memcpy(bcd2k->midi_out_buf, device_cmd_prefix,
+		sizeof(device_cmd_prefix));

This is also used for data request and input selection, so it's not "set LED" but just "MIDI output".

sound/usb/bcd2000/bcd2000.c line 249

Quoted 6 lines
sound/usb/bcd2000/bcd2000.c new file +6 -0
+static void bcd2000_input_complete(struct urb *urb)
+{
+	if (urb->status) {
+		dev_warn(dev, PREFIX "input urb->status: %i\n", urb->status);
+		return;
+	}

This will stop the input even on transient errors.

sound/usb/bcd2000/bcd2000.c line 261

Quoted 4 lines
sound/usb/bcd2000/bcd2000.c new file +4 -0
+	/* acknowledge received packet */
+	ret = usb_submit_urb(bcd2k->midi_in_urb, GFP_ATOMIC);
+	if (ret < 0)
+		dev_err(dev, "unable to submit urb. OOM!?\n");

Don't guess, just show ret. :)

sound/usb/bcd2000/bcd2000.c line 413

Quoted 6 lines
sound/usb/bcd2000/bcd2000.c new file +6 -0
+	strcpy(card->driver, DEVICE_NAME);
+	strcpy(card->shortname, DEVICE_SHORTNAME);
+	usb_make_path(bcd2k->dev, usb_path, sizeof(usb_path));
+	snprintf(bcd2k->card->longname, sizeof(bcd2k->card->longname),
+			DEVICE_NAME ", at %s",
+			usb_path);
$ cat /proc/asound/cards
...
18 [bcd2000        ]: Behringer BCD200bcd2000 - bcd2000
                      Behringer BCD2000, at usb-0000:00:13.1-3

The driver name just identifies the driver, it does not need the vendor name. (And it should not overflow its buffer.)

The short name is shown to the user in many places, so it should be properly capitalized.

The long name does not need the comma.

sound/usb/bcd2000/bcd2000.c line 415

Quoted 1 line
sound/usb/bcd2000/bcd2000.c new file +1 -0
+	dev_info(&bcd2k->dev->dev, PREFIX "%s", bcd2k->card->longname);

What use does this message have in the log?

Regards,
Clemens

#2 lore raw
Quoted 2 lines · Clemens Ladisch

I wonder how much of this is the actual init sequence, and how much is random garbage. :-)

Me too, but I want to make sure the module works before I start experimenting and risk modifying/damaging my device. Some bytes in between stay the same, some seem to change randomly everytime I plug in
the device.

Quoted 2 lines

The device often sends data as single-byte packets, so the structure actually is "length data...".

Yeah, it's a bit misleading here. I'll change this part.

Quoted 8 lines

sound/usb/bcd2000/bcd2000.c line 249

Quoted 6 lines
sound/usb/bcd2000/bcd2000.c new file +6 -0
+static void bcd2000_input_complete(struct urb *urb)
+{
+	if (urb->status) {
+		dev_warn(dev, PREFIX "input urb->status: %i\n", urb->status);
+		return;
+	}

This will stop the input even on transient errors.

Hm, so, it is important to send the "acknowledge" urb afterwards nonetheless?

Quoted 5 lines
$ cat /proc/asound/cards
...
18 [bcd2000        ]: Behringer BCD200bcd2000 - bcd2000
                       Behringer BCD2000, at usb-0000:00:13.1-3
Quoted 7 lines

The driver name just identifies the driver, it does not need the vendor name. (And it should not overflow its buffer.)

The short name is shown to the user in many places, so it should be properly capitalized.

The long name does not need the comma.

I removed the macros and just placed the names in there directly as that's the only place they're used anyway.

Do you actually own a BCD2000?

Quoted 3 lines

sound/usb/bcd2000/bcd2000.c line 415

Quoted 1 line
sound/usb/bcd2000/bcd2000.c new file +1 -0
+	dev_info(&bcd2k->dev->dev, PREFIX "%s", bcd2k->card->longname);

What use does this message have in the log?

I saw this in another driver and thought this is common practice. I'll remove it then.

Thank you for your comments!
Mario

#3 lore raw
Quoted 10 lines · Mario Kicherer
Quoted 8 lines · Clemens Ladisch

sound/usb/bcd2000/bcd2000.c line 249

Quoted 6 lines
sound/usb/bcd2000/bcd2000.c new file +6 -0
+static void bcd2000_input_complete(struct urb *urb)
+{
+    if (urb->status) {
+        dev_warn(dev, PREFIX "input urb->status: %i\n", urb->status);
+        return;
+    }

This will stop the input even on transient errors.

Quoted 2 lines

Hm, so, it is important to send the "acknowledge" urb afterwards nonetheless?

This has nothing to do with acknowledging. Once the completion callback was called, the URB is again owned by your driver, and nothing happens unless you submit it again.

The only reason not to re-submit the URB is a permanent error (i.e., if the device has been unplugged).

Quoted 1 line

Do you actually own a BCD2000?

Yes.

Regards,
Clemens