[alsa-devel] How to add a new MIDI device to the usbaudio driver
I have just received a new MIDI instrument (Starr Labs Z7S) which is not recognized by the kernel, and I'd like to add support for it. I'm hoping that it uses a standard MIDI interface and it's just a matter of adding the correct entry in the table of devices.
I have tried to add an entry to sound/usb/usbquirks.h (sound/usb/quirks-table.h in later kernels), but so far I haven't succeeded. Is there any documentation for how to do this, and which options to use? Google hasn't really turned up anything...
On Mon, Aug 22, 2011 at 12:52 PM, Kristian Amlie kristian@amlie.name wrote:
I have just received a new MIDI instrument (Starr Labs Z7S) which is not recognized by the kernel, and I'd like to add support for it. I'm hoping that it uses a standard MIDI interface and it's just a matter of adding the correct entry in the table of devices.
I have tried to add an entry to sound/usb/usbquirks.h (sound/usb/quirks-table.h in later kernels), but so far I haven't succeeded. Is there any documentation for how to do this, and which options to use? Google hasn't really turned up anything...
The USB descriptors should give us a hint. Can you send your "lsusb -v" output, please?
Daniel
On 08/22/11 12:54, Daniel Mack wrote:
On Mon, Aug 22, 2011 at 12:52 PM, Kristian Amlie kristian@amlie.name wrote:
I have just received a new MIDI instrument (Starr Labs Z7S) which is not recognized by the kernel, and I'd like to add support for it. I'm hoping that it uses a standard MIDI interface and it's just a matter of adding the correct entry in the table of devices.
I have tried to add an entry to sound/usb/usbquirks.h (sound/usb/quirks-table.h in later kernels), but so far I haven't succeeded. Is there any documentation for how to do this, and which options to use? Google hasn't really turned up anything...
The USB descriptors should give us a hint. Can you send your "lsusb -v" output, please?
Sure! Here is the lsusb -v output for the device:
------- Bus 003 Device 010: ID 0403:b8d8 Future Technology Devices International, Ltd Device Descriptor: bLength 18 bDescriptorType 1 bcdUSB 2.00 bDeviceClass 0 (Defined at Interface level) bDeviceSubClass 0 bDeviceProtocol 0 bMaxPacketSize0 8 idVendor 0x0403 Future Technology Devices International, Ltd idProduct 0xb8d8 bcdDevice 6.00 iManufacturer 1 STARR LABS iProduct 2 Starr Labs MIDI USB device iSerial 3 FTPW490R bNumConfigurations 1 Configuration Descriptor: bLength 9 bDescriptorType 2 wTotalLength 32 bNumInterfaces 1 bConfigurationValue 1 iConfiguration 0 bmAttributes 0x80 (Bus Powered) MaxPower 500mA Interface Descriptor: bLength 9 bDescriptorType 4 bInterfaceNumber 0 bAlternateSetting 0 bNumEndpoints 2 bInterfaceClass 255 Vendor Specific Class bInterfaceSubClass 255 Vendor Specific Subclass bInterfaceProtocol 255 Vendor Specific Protocol iInterface 2 Starr Labs MIDI USB device Endpoint Descriptor: bLength 7 bDescriptorType 5 bEndpointAddress 0x81 EP 1 IN bmAttributes 2 Transfer Type Bulk Synch Type None Usage Type Data wMaxPacketSize 0x0040 1x 64 bytes bInterval 0 Endpoint Descriptor: bLength 7 bDescriptorType 5 bEndpointAddress 0x02 EP 2 OUT bmAttributes 2 Transfer Type Bulk Synch Type None Usage Type Data wMaxPacketSize 0x0040 1x 64 bytes bInterval 0 Device Status: 0x0000 (Bus Powered) -------
On Mon, Aug 22, 2011 at 1:40 PM, Kristian Amlie kristian@amlie.name wrote:
On 08/22/11 12:54, Daniel Mack wrote:
On Mon, Aug 22, 2011 at 12:52 PM, Kristian Amlie kristian@amlie.name wrote:
I have just received a new MIDI instrument (Starr Labs Z7S) which is not recognized by the kernel, and I'd like to add support for it. I'm hoping that it uses a standard MIDI interface and it's just a matter of adding the correct entry in the table of devices.
I have tried to add an entry to sound/usb/usbquirks.h (sound/usb/quirks-table.h in later kernels), but so far I haven't succeeded. Is there any documentation for how to do this, and which options to use? Google hasn't really turned up anything...
The USB descriptors should give us a hint. Can you send your "lsusb -v" output, please?
Sure! Here is the lsusb -v output for the device:
It doesn't seem to be using a standard MIDI interface, but there's a chance that it accepts raw MIDI byte streams. Can you check the patch below?
Daniel
diff --git a/sound/usb/quirks-table.h b/sound/usb/quirks-table.h index a42e3ef..0f8aa11 100644 --- a/sound/usb/quirks-table.h +++ b/sound/usb/quirks-table.h @@ -39,6 +39,16 @@ .idProduct = prod, \ .bInterfaceClass = USB_CLASS_VENDOR_SPEC
+/* Starr Labs MIDI USB device */ +{ + USB_DEVICE(0x0403, 0xb8d8), + .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) { + /* .vendor_name = "STARR LABS", */ + /* .product_name = "Starr Labs MIDI USB device", */ + .ifnum = 0, + .type = QUIRK_MIDI_RAW_BYTES + } +}, /* Creative/Toshiba Multimedia Center SB-0500 */ { USB_DEVICE(0x041e, 0x3048),
On 08/22/11 13:49, Daniel Mack wrote:
It doesn't seem to be using a standard MIDI interface, but there's a chance that it accepts raw MIDI byte streams. Can you check the patch below?
With that patch, the device shows up, but aseqdump does not report any MIDI events after connecting to it.
The Windows drivers are called "USB Serial Converter" and "USB Serial Port", so maybe it's all wrapped in a different protocol. Does that name ring a bell?
On Tue, Aug 23, 2011 at 9:35 AM, Kristian Amlie kristian@amlie.name wrote:
On 08/22/11 13:49, Daniel Mack wrote:
It doesn't seem to be using a standard MIDI interface, but there's a chance that it accepts raw MIDI byte streams. Can you check the patch below?
With that patch, the device shows up, but aseqdump does not report any MIDI events after connecting to it.
The Windows drivers are called "USB Serial Converter" and "USB Serial Port", so maybe it's all wrapped in a different protocol. Does that name ring a bell?
That's possible, and it should be easy to support these type of devices in ALSA. However, some logic is neccessary to configure the hardware to its correct baud rate and hardware protocol. The easiest way to determine the setup sequence is certainly to sniff the Windows driver communication with some tool like usbsnoop. Can you give that a try?
Daniel
Am Dienstag, den 23.08.2011, 10:43 +0200 schrieb Daniel Mack:
On Tue, Aug 23, 2011 at 9:35 AM, Kristian Amlie kristian@amlie.name wrote:
On 08/22/11 13:49, Daniel Mack wrote:
It doesn't seem to be using a standard MIDI interface, but there's a chance that it accepts raw MIDI byte streams. Can you check the patch below?
With that patch, the device shows up, but aseqdump does not report any MIDI events after connecting to it.
The Windows drivers are called "USB Serial Converter" and "USB Serial Port", so maybe it's all wrapped in a different protocol. Does that name ring a bell?
That's possible, and it should be easy to support these type of devices in ALSA. However, some logic is neccessary to configure the hardware to its correct baud rate and hardware protocol. The easiest way to determine the setup sequence is certainly to sniff the Windows driver communication with some tool like usbsnoop. Can you give that a try?
… and ask the manufacturer about GNU/Linux support.
Something like, you bought the hardware and expect it to work everywhere. Additionally they make money by selling the hardware and not developing a driver, so they should publish the documentation and even pay someone – like Daniel or Clemens ? – to write the support for their hardware. (Only when they say they do not have any money or something like that, you can also tell them to donate/provide free hardware for the developer and a contact address to their M$ Windows developer for questions.)
I am putting Greg into CC for possible sample texts or insights/best practices on how to approach manufacturers.
Thanks,
Paul
On Tue, Aug 23, 2011 at 11:03 AM, Paul Menzel paulepanter@users.sourceforge.net wrote:
Am Dienstag, den 23.08.2011, 10:43 +0200 schrieb Daniel Mack:
On Tue, Aug 23, 2011 at 9:35 AM, Kristian Amlie kristian@amlie.name wrote:
On 08/22/11 13:49, Daniel Mack wrote:
It doesn't seem to be using a standard MIDI interface, but there's a chance that it accepts raw MIDI byte streams. Can you check the patch below?
With that patch, the device shows up, but aseqdump does not report any MIDI events after connecting to it.
The Windows drivers are called "USB Serial Converter" and "USB Serial Port", so maybe it's all wrapped in a different protocol. Does that name ring a bell?
That's possible, and it should be easy to support these type of devices in ALSA. However, some logic is neccessary to configure the hardware to its correct baud rate and hardware protocol. The easiest way to determine the setup sequence is certainly to sniff the Windows driver communication with some tool like usbsnoop. Can you give that a try?
… and ask the manufacturer about GNU/Linux support.
Something like, you bought the hardware and expect it to work everywhere. Additionally they make money by selling the hardware and not developing a driver, so they should publish the documentation and even pay someone – like Daniel or Clemens ? – to write the support for their hardware. (Only when they say they do not have any money or something like that, you can also tell them to donate/provide free hardware for the developer and a contact address to their M$ Windows developer for questions.)
While I agree in general to your points, I think its not worth the effort in this particular case. It's probably very easy to add support for this by just sending one magic usb_control_msg up-front, and it's not complicated to sniff that value. From a customer standpoint, again, I'm sure the manufacturer will just state that they didn't promise any Linux support, and so you can't claim it.
Daniel
On 08/23/11 11:22, Daniel Mack wrote:
On Tue, Aug 23, 2011 at 11:03 AM, Paul Menzel paulepanter@users.sourceforge.net wrote:
Am Dienstag, den 23.08.2011, 10:43 +0200 schrieb Daniel Mack:
On Tue, Aug 23, 2011 at 9:35 AM, Kristian Amlie kristian@amlie.name wrote:
The Windows drivers are called "USB Serial Converter" and "USB Serial Port", so maybe it's all wrapped in a different protocol. Does that name ring a bell?
That's possible, and it should be easy to support these type of devices in ALSA. However, some logic is neccessary to configure the hardware to its correct baud rate and hardware protocol. The easiest way to determine the setup sequence is certainly to sniff the Windows driver communication with some tool like usbsnoop. Can you give that a try?
I will, but it will take a bit of time, since well, I have to install Windows first... :-)
The driver names I just read from the manual.
… and ask the manufacturer about GNU/Linux support.
Something like, you bought the hardware and expect it to work everywhere. Additionally they make money by selling the hardware and not developing a driver, so they should publish the documentation and even pay someone – like Daniel or Clemens ? – to write the support for their hardware. (Only when they say they do not have any money or something like that, you can also tell them to donate/provide free hardware for the developer and a contact address to their M$ Windows developer for questions.)
While I agree in general to your points, I think its not worth the effort in this particular case. It's probably very easy to add support for this by just sending one magic usb_control_msg up-front, and it's not complicated to sniff that value. From a customer standpoint, again, I'm sure the manufacturer will just state that they didn't promise any Linux support, and so you can't claim it.
Their homepage states "We are currently in the final phase of development in making all of our instruments class compliant.", which I take to mean that they want their future products to use a standard MIDI interface. Right now, Windows 7 and Vista 64 users are also left in the dark, so I think they are as eager to fix this as we are, they just decided to do it on the hardware side instead of the software side.
Am Dienstag, den 23.08.2011, 11:42 +0200 schrieb Kristian Amlie:
On 08/23/11 11:22, Daniel Mack wrote:
On Tue, Aug 23, 2011 at 11:03 AM, Paul Menzel wrote:
[…]
… and ask the manufacturer about GNU/Linux support.
Something like, you bought the hardware and expect it to work everywhere. Additionally they make money by selling the hardware and not developing a driver, so they should publish the documentation and even pay someone – like Daniel or Clemens ? – to write the support for their hardware. (Only when they say they do not have any money or something like that, you can also tell them to donate/provide free hardware for the developer and a contact address to their M$ Windows developer for questions.)
While I agree in general to your points, I think its not worth the effort in this particular case. It's probably very easy to add support for this by just sending one magic usb_control_msg up-front, and it's not complicated to sniff that value. From a customer standpoint, again, I'm sure the manufacturer will just state that they didn't promise any Linux support, and so you can't claim it.
Their homepage states "We are currently in the final phase of development in making all of our instruments class compliant.", which I take to mean that they want their future products to use a standard MIDI interface. Right now, Windows 7 and Vista 64 users are also left in the dark, so I think they are as eager to fix this as we are, they just decided to do it on the hardware side instead of the software side.
Still sending a message to them, would be good in my opinion.
1. It shows them, that people are using their devices on GNU/Linux and that their decision to make it class compliant is a good move. 2. If they want to change that, maybe they are even releasing the necessary documentation so you can save your time installing Windows.
Thanks,
Paul
On 08/23/11 12:02, Paul Menzel wrote:
Am Dienstag, den 23.08.2011, 11:42 +0200 schrieb Kristian Amlie:
On 08/23/11 11:22, Daniel Mack wrote:
On Tue, Aug 23, 2011 at 11:03 AM, Paul Menzel wrote:
… and ask the manufacturer about GNU/Linux support.
Something like, you bought the hardware and expect it to work everywhere. Additionally they make money by selling the hardware and not developing a driver, so they should publish the documentation and even pay someone – like Daniel or Clemens ? – to write the support for their hardware. (Only when they say they do not have any money or something like that, you can also tell them to donate/provide free hardware for the developer and a contact address to their M$ Windows developer for questions.)
While I agree in general to your points, I think its not worth the effort in this particular case. It's probably very easy to add support for this by just sending one magic usb_control_msg up-front, and it's not complicated to sniff that value. From a customer standpoint, again, I'm sure the manufacturer will just state that they didn't promise any Linux support, and so you can't claim it.
Their homepage states "We are currently in the final phase of development in making all of our instruments class compliant.", which I take to mean that they want their future products to use a standard MIDI interface. Right now, Windows 7 and Vista 64 users are also left in the dark, so I think they are as eager to fix this as we are, they just decided to do it on the hardware side instead of the software side.
Still sending a message to them, would be good in my opinion.
- It shows them, that people are using their devices on GNU/Linux and
that their decision to make it class compliant is a good move. 2. If they want to change that, maybe they are even releasing the necessary documentation so you can save your time installing Windows.
FYI, I sent them a message saying that Linux support has been added. I thought it was better to put it in a positive light if we could: Now they know that their devices are used in Linux, *and* they got a driver for free!
Kristian Amlie wrote:
idVendor 0x0403 Future Technology Devices International, Ltd idProduct 0xb8d8
There is a kernel driver for this chipset; try "modprobe ftdi_sio product=0xb8d8". This will give you a serial port which you can try to configure for the correct baud rate and see whether MIDI bytes come out. (There is currently no mechanism to make a MIDI device from such a serial port; this would require extending or creating a driver.)
Regards, Clemens
On Tue, Aug 23, 2011 at 11:38 AM, Clemens Ladisch clemens@ladisch.de wrote:
Kristian Amlie wrote:
idVendor 0x0403 Future Technology Devices International, Ltd idProduct 0xb8d8
There is a kernel driver for this chipset; try "modprobe ftdi_sio product=0xb8d8". This will give you a serial port which you can try to configure for the correct baud rate and see whether MIDI bytes come out. (There is currently no mechanism to make a MIDI device from such a serial port; this would require extending or creating a driver.)
Yes, an easy one, which just hard-codes the device to 31250,8N1. I'm not sure whether the USB serial driver can handle this baud rate, btw. I had quick look earlier and it seems that it would require a divider setup that is not currently supported. Hence I though just sniffing the setup is probably the easiest way to go.
Daniel
On 08/23/11 11:38, Clemens Ladisch wrote:
Kristian Amlie wrote:
idVendor 0x0403 Future Technology Devices International, Ltd idProduct 0xb8d8
There is a kernel driver for this chipset; try "modprobe ftdi_sio product=0xb8d8". This will give you a serial port which you can try to configure for the correct baud rate and see whether MIDI bytes come out. (There is currently no mechanism to make a MIDI device from such a serial port; this would require extending or creating a driver.)
Forgive me, I'm not very well acquainted with how serial drivers work in Linux. The driver did give me a new device, so here is what I tried:
$ setserial /dev/ttyUSB0 spd_normal uart 16550A $ cat /dev/ttyUSB0 > dump
I was not able to get any output from the serial device, however, while cat was running and I was pressing buttons on the instrument, it spontaneously changed program on me (MIDI program change), so *something* goes across the wire.
On Tue, Aug 23, 2011 at 12:07 PM, Kristian Amlie kristian@amlie.name wrote:
On 08/23/11 11:38, Clemens Ladisch wrote:
Kristian Amlie wrote:
idVendor 0x0403 Future Technology Devices International, Ltd idProduct 0xb8d8
There is a kernel driver for this chipset; try "modprobe ftdi_sio product=0xb8d8". This will give you a serial port which you can try to configure for the correct baud rate and see whether MIDI bytes come out. (There is currently no mechanism to make a MIDI device from such a serial port; this would require extending or creating a driver.)
Forgive me, I'm not very well acquainted with how serial drivers work in Linux. The driver did give me a new device, so here is what I tried:
$ setserial /dev/ttyUSB0 spd_normal uart 16550A $ cat /dev/ttyUSB0 > dump
I was not able to get any output from the serial device, however, while cat was running and I was pressing buttons on the instrument, it spontaneously changed program on me (MIDI program change), so *something* goes across the wire.
Try "cu" (provided in the package "uucp" on some distributions), and see if you can make the hardware operate on 31250 Baud, which is the nominal rate for MIDI. If you can, you should be able to receive a raw MIDI byte stream. But as I say, I think that requires a special divider setup that is not supported by the ftdi_sio driver.
Daniel
On 08/23/11 12:16, Daniel Mack wrote:
On Tue, Aug 23, 2011 at 12:07 PM, Kristian Amlie kristian@amlie.name wrote:
On 08/23/11 11:38, Clemens Ladisch wrote:
Kristian Amlie wrote:
idVendor 0x0403 Future Technology Devices International, Ltd idProduct 0xb8d8
There is a kernel driver for this chipset; try "modprobe ftdi_sio product=0xb8d8". This will give you a serial port which you can try to configure for the correct baud rate and see whether MIDI bytes come out. (There is currently no mechanism to make a MIDI device from such a serial port; this would require extending or creating a driver.)
Forgive me, I'm not very well acquainted with how serial drivers work in Linux. The driver did give me a new device, so here is what I tried:
$ setserial /dev/ttyUSB0 spd_normal uart 16550A $ cat /dev/ttyUSB0 > dump
I was not able to get any output from the serial device, however, while cat was running and I was pressing buttons on the instrument, it spontaneously changed program on me (MIDI program change), so *something* goes across the wire.
Try "cu" (provided in the package "uucp" on some distributions), and see if you can make the hardware operate on 31250 Baud, which is the nominal rate for MIDI. If you can, you should be able to receive a raw MIDI byte stream. But as I say, I think that requires a special divider setup that is not supported by the ftdi_sio driver.
I was not able to to use 31250 baud as you suggested. However, I tried 38400 baud, and that seemed to work. I got a small number of bytes everytime I pressed a key on the instrument.
Using the following command line:
$ cu -s 38400 -l /dev/ttyUSB0 | hexdump -C
and pressing the same key repeatedly with the same force, I got the following output:
00000000 18 f9 ff 18 03 f8 18 f9 ff 18 01 f8 18 f9 ff 18 |................| 00000010 01 f8 18 fb ff 18 01 f8 18 fb ff 18 01 f8 18 fb |................| 00000020 ff 18 03 f8 18 f9 ff 18 01 f8 18 fb ff 18 01 f8 |................| 00000030 18 fb ff 18 01 f8 18 fb ff 18 01 f8 07 43 6f 6e |.............Con| 00000040 6e 65 63 74 65 64 2e 0a 07 43 6f 6e 6e 65 63 74 |nected...Connect| 00000050 65 64 2e 0a 0a 07 44 69 73 63 6f 6e 6e 65 63 74 |ed....Disconnect| 00000060 65 64 2e 0a |ed..| 00000064
On Tue, Aug 23, 2011 at 1:57 PM, Kristian Amlie kristian@amlie.name wrote:
I was not able to to use 31250 baud as you suggested. However, I tried 38400 baud, and that seemed to work. I got a small number of bytes everytime I pressed a key on the instrument.
Using the following command line:
$ cu -s 38400 -l /dev/ttyUSB0 | hexdump -C
and pressing the same key repeatedly with the same force, I got the following output:
00000000 18 f9 ff 18 03 f8 18 f9 ff 18 01 f8 18 f9 ff 18 |................| 00000010 01 f8 18 fb ff 18 01 f8 18 fb ff 18 01 f8 18 fb |................| 00000020 ff 18 03 f8 18 f9 ff 18 01 f8 18 fb ff 18 01 f8 |................| 00000030 18 fb ff 18 01 f8 18 fb ff 18 01 f8 07 43 6f 6e |.............Con| 00000040 6e 65 63 74 65 64 2e 0a 07 43 6f 6e 6e 65 63 74 |nected...Connect| 00000050 65 64 2e 0a 0a 07 44 69 73 63 6f 6e 6e 65 63 74 |ed....Disconnect| 00000060 65 64 2e 0a |ed..| 00000064
That hexdump reads as "Connected....Disconnected". Are you sure you get useful data from cu?
If you are certain about this, I would recommend you add some debug printk() into drivers/usb/serial/ftdi_sio.c and trace what values the functions change_speed() and update_mctrl() pass to usb_control_msg() when the device is connected and cu is started. Once we have this information, I can prepare a patch to add the control messages to the MIDI driver.
Daniel
On 08/23/11 14:20, Daniel Mack wrote:
On Tue, Aug 23, 2011 at 1:57 PM, Kristian Amlie kristian@amlie.name wrote:
I was not able to to use 31250 baud as you suggested. However, I tried 38400 baud, and that seemed to work. I got a small number of bytes everytime I pressed a key on the instrument.
Using the following command line:
$ cu -s 38400 -l /dev/ttyUSB0 | hexdump -C
and pressing the same key repeatedly with the same force, I got the following output:
00000000 18 f9 ff 18 03 f8 18 f9 ff 18 01 f8 18 f9 ff 18 |................| 00000010 01 f8 18 fb ff 18 01 f8 18 fb ff 18 01 f8 18 fb |................| 00000020 ff 18 03 f8 18 f9 ff 18 01 f8 18 fb ff 18 01 f8 |................| 00000030 18 fb ff 18 01 f8 18 fb ff 18 01 f8 07 43 6f 6e |.............Con| 00000040 6e 65 63 74 65 64 2e 0a 07 43 6f 6e 6e 65 63 74 |nected...Connect| 00000050 65 64 2e 0a 0a 07 44 69 73 63 6f 6e 6e 65 63 74 |ed....Disconnect| 00000060 65 64 2e 0a |ed..| 00000064
That hexdump reads as "Connected....Disconnected". Are you sure you get useful data from cu?
Quite sure. Those messages are just from cu (I assume), telling me that I connected and disconnected (by killing it). If I run it without piping, they appear before and after the bytestream as they should. I don't really know why they appear at the end in that output; maybe a buffering issue.
In either case, the important data is in the three first lines. That is what appears while I'm pressing the keys.
If you are certain about this, I would recommend you add some debug printk() into drivers/usb/serial/ftdi_sio.c and trace what values the functions change_speed() and update_mctrl() pass to usb_control_msg() when the device is connected and cu is started. Once we have this information, I can prepare a patch to add the control messages to the MIDI driver.
Alright, I guess it is the urb_value and urb_index values you are interested in?
Here is the output from one complete run of cu, including connecting, pressing a key once on the instrument and killing cu afterwards:
[20380.847492] change_speed(): urb_value: 16696, urb_index: 0 [20380.849364] update_mctrl(): urb_value: 771, priv->interface: 0 [20380.851360] change_speed(): urb_value: 49230, urb_index: 0 [20380.854412] change_speed(): urb_value: 49230, urb_index: 0 [20380.857361] change_speed(): urb_value: 49230, urb_index: 0 [20387.615704] change_speed(): urb_value: 16696, urb_index: 0 [20387.619557] update_mctrl(): urb_value: 768, priv->interface: 0
On Tue, Aug 23, 2011 at 3:12 PM, Kristian Amlie kristian@amlie.name wrote:
Here is the output from one complete run of cu, including connecting, pressing a key once on the instrument and killing cu afterwards:
[20380.847492] change_speed(): urb_value: 16696, urb_index: 0 [20380.849364] update_mctrl(): urb_value: 771, priv->interface: 0 [20380.851360] change_speed(): urb_value: 49230, urb_index: 0 [20380.854412] change_speed(): urb_value: 49230, urb_index: 0 [20380.857361] change_speed(): urb_value: 49230, urb_index: 0 [20387.615704] change_speed(): urb_value: 16696, urb_index: 0 [20387.619557] update_mctrl(): urb_value: 768, priv->interface: 0
And now once again without killing cu, please. I'm interested in the last commands that occur before the device starts working.
Daniel
On 08/23/11 15:16, Daniel Mack wrote:
On Tue, Aug 23, 2011 at 3:12 PM, Kristian Amlie kristian@amlie.name wrote:
Here is the output from one complete run of cu, including connecting, pressing a key once on the instrument and killing cu afterwards:
... And now once again without killing cu, please. I'm interested in the last commands that occur before the device starts working.
Here you go:
[21535.096008] change_speed(): urb_value: 16696, urb_index: 0 [21535.097918] update_mctrl(): urb_value: 771, priv->interface: 0 [21535.099917] change_speed(): urb_value: 49230, urb_index: 0 [21535.103055] change_speed(): urb_value: 49230, urb_index: 0 [21535.106037] change_speed(): urb_value: 49230, urb_index: 0
On Tue, Aug 23, 2011 at 3:28 PM, Kristian Amlie kristian@amlie.name wrote:
On 08/23/11 15:16, Daniel Mack wrote:
On Tue, Aug 23, 2011 at 3:12 PM, Kristian Amlie kristian@amlie.name wrote:
Here is the output from one complete run of cu, including connecting, pressing a key once on the instrument and killing cu afterwards:
... And now once again without killing cu, please. I'm interested in the last commands that occur before the device starts working.
Here you go:
[21535.096008] change_speed(): urb_value: 16696, urb_index: 0 [21535.097918] update_mctrl(): urb_value: 771, priv->interface: 0 [21535.099917] change_speed(): urb_value: 49230, urb_index: 0 [21535.103055] change_speed(): urb_value: 49230, urb_index: 0 [21535.106037] change_speed(): urb_value: 49230, urb_index: 0
Ok, then let's try the attached patch. In case it doesn't work, you might need to check whether there are any more ctrl requests sent by the fdti_sio driver that need to be added to the MIDI driver as well.
Daniel
On 08/23/11 15:44, Daniel Mack wrote:
On Tue, Aug 23, 2011 at 3:28 PM, Kristian Amlie kristian@amlie.name wrote:
On 08/23/11 15:16, Daniel Mack wrote:
On Tue, Aug 23, 2011 at 3:12 PM, Kristian Amlie kristian@amlie.name wrote:
Here is the output from one complete run of cu, including connecting, pressing a key once on the instrument and killing cu afterwards:
... And now once again without killing cu, please. I'm interested in the last commands that occur before the device starts working.
Here you go:
[21535.096008] change_speed(): urb_value: 16696, urb_index: 0 [21535.097918] update_mctrl(): urb_value: 771, priv->interface: 0 [21535.099917] change_speed(): urb_value: 49230, urb_index: 0 [21535.103055] change_speed(): urb_value: 49230, urb_index: 0 [21535.106037] change_speed(): urb_value: 49230, urb_index: 0
Ok, then let's try the attached patch. In case it doesn't work, you might need to check whether there are any more ctrl requests sent by the fdti_sio driver that need to be added to the MIDI driver as well.
That resulted in the following oops:
------- BUG: unable to handle kernel NULL pointer dereference at (null) IP: [< (null)>] (null) PGD 0 Oops: 0010 [#1] SMP CPU 0 Modules linked in: snd_usb_audio snd_usbmidi_lib snd_rawmidi freq_table mperf ipv6 snd_seq_oss snd_seq_midi_event snd_seq snd_seq_device snd_pcm_oss snd_mixer_oss usbhid dm_mod snd_hda_codec_idt arc4 iwl4965 snd_hda_intel iwl_legacy snd_hda_codec ehci_hcd mac80211 snd_hwdep snd_pcm firmware_class i2c_i801 cfg80211 video processor snd_timer backlight i2c_core uhci_hcd thermal snd rfkill usbcore sky2 thermal_sys dcdbas snd_page_alloc ac joydev button pcspkr battery sg rtc
Pid: 1042, comm: khubd Not tainted 3.0.0 #3 Dell Inc. XPS M1530 / RIP: 0010:[<0000000000000000>] [< (null)>] (null) RSP: 0018:ffff8801188df918 EFLAGS: 00010283 RAX: 000000000000000c RBX: ffff8801188df960 RCX: ffffffffa021edc0 RDX: ffffffffa0224a80 RSI: ffff88011982c600 RDI: ffff880118058900 RBP: ffff8801188df920 R08: 000000000000000c R09: ffff88011b3ff47f R10: 000000000000000c R11: ffff8801188df870 R12: ffff880118058900 R13: 0000000000000000 R14: ffff880118a0f800 R15: ffffffffa021edc0 FS: 0000000000000000(0000) GS:ffff88011fc00000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 000000008005003b CR2: 0000000000000000 CR3: 0000000001645000 CR4: 00000000000006f0 DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 DR3: 0000000000000000 DR6: 00000000ffff0ff0 DR7: 0000000000000400 Process khubd (pid: 1042, threadinfo ffff8801188de000, task ffff88011f7633a0) Stack: ffffffffa021a823 ffff8801188df9b0 ffffffffa0216983 ffff88011f7055a0 ffff880118058a80 ffff880118a0f888 ffff88011982c600 00000000ffffffff ffff880119b22d88 3a33303430425355 ffffff0038643862 ffff88011982c600 Call Trace: [<ffffffffa021a823>] ? snd_usb_create_quirk+0x20/0x22 [snd_usb_audio] [<ffffffffa0216983>] usb_audio_probe+0x56f/0x6e8 [snd_usb_audio] [<ffffffffa0079da0>] usb_probe_interface+0xcb/0x115 [usbcore] [<ffffffff8133e2ea>] driver_probe_device+0xa3/0x151 [<ffffffff8133e413>] ? __driver_attach+0x7b/0x7b [<ffffffff8133e446>] __device_attach+0x33/0x3c [<ffffffff8133d866>] bus_for_each_drv+0x51/0x88 [<ffffffff8133e4d7>] device_attach+0x64/0x7c [<ffffffff8133d6a4>] bus_probe_device+0x22/0x39 [<ffffffff8133c661>] device_add+0x41c/0x58f [<ffffffff81343002>] ? device_pm_init+0x3c/0x6e [<ffffffffa0079239>] usb_set_configuration+0x4a5/0x4f7 [usbcore] [<ffffffffa007fcc2>] generic_probe+0x4a/0x78 [usbcore] [<ffffffffa0079459>] usb_probe_device+0x15/0x17 [usbcore] [<ffffffff8133e2ea>] driver_probe_device+0xa3/0x151 [<ffffffff8133e413>] ? __driver_attach+0x7b/0x7b [<ffffffff8133e446>] __device_attach+0x33/0x3c [<ffffffff8133d866>] bus_for_each_drv+0x51/0x88 [<ffffffff8133e4d7>] device_attach+0x64/0x7c [<ffffffff8133d6a4>] bus_probe_device+0x22/0x39 [<ffffffff8133c661>] device_add+0x41c/0x58f [<ffffffffa0072bbf>] usb_new_device+0x74/0xb7 [usbcore] [<ffffffffa007437f>] hub_thread+0xcf8/0x11e5 [usbcore] [<ffffffff8147341d>] ? schedule+0x7c8/0x861 [<ffffffff810491f2>] ? wake_up_bit+0x23/0x23 [<ffffffffa0073687>] ? hub_probe+0x72e/0x72e [usbcore] [<ffffffff81048de7>] kthread+0x81/0x89 [<ffffffff81476954>] kernel_thread_helper+0x4/0x10 [<ffffffff81048d66>] ? kthread_worker_fn+0x145/0x145 [<ffffffff81476950>] ? gs_change+0xb/0xb Code: Bad RIP value. RIP [< (null)>] (null) RSP <ffff8801188df918> CR2: 0000000000000000 ---[ end trace 69eca745138acea4 ]--- -------
On Wed, Aug 24, 2011 at 10:09 AM, Kristian Amlie kristian@amlie.name wrote:
That resulted in the following oops:
BUG: unable to handle kernel NULL pointer dereference at (null)
Hmm? Can you trace where this happens and which dereferenced pointer is NULL? I don't see it, sorry.
Daniel
On 08/24/11 10:32, Daniel Mack wrote:
Hmm? Can you trace where this happens and which dereferenced pointer is NULL? I don't see it, sorry.
The attached patch solves the NULL pointer dereference. With this patch, the device shows up as a MIDI device, but still produces no events according to aseqdump.
I did a more thorough examination of the calls to usb_control_msg() from the ftdi_sio driver, and this is what I came up with:
Plugging it in:
Calling usb_control_msg() from read_latency_timer(): value=0, index=0 Calling usb_control_msg() from write_latency_timer(): value=1, index=0 usb 3-2: FTDI USB Serial Device converter now attached to ttyUSB0
Starting cu:
Calling usb_control_msg() from ftdi_open(): value=0, index=0 Calling usb_control_msg() from ftdi_set_termios(): value=8, index=0 Calling usb_control_msg() from change_speed(): value=16696, index=0 Calling usb_control_msg() from ftdi_set_termios(): value=0, index=0 Calling usb_control_msg() from update_mctrl(): value=771, index=0 Calling usb_control_msg() from ftdi_set_termios(): value=8, index=0 Calling usb_control_msg() from change_speed(): value=49230, index=0 Calling usb_control_msg() from ftdi_set_termios(): value=0, index=0 Calling usb_control_msg() from ftdi_set_termios(): value=8, index=0 Calling usb_control_msg() from change_speed(): value=49230, index=0 Calling usb_control_msg() from ftdi_set_termios(): value=0, index=0 Calling usb_control_msg() from ftdi_set_termios(): value=8, index=0 Calling usb_control_msg() from change_speed(): value=49230, index=0 Calling usb_control_msg() from ftdi_set_termios(): value=4881, index=1024
Killing cu:
Calling usb_control_msg() from ftdi_set_termios(): value=8, index=0 Calling usb_control_msg() from change_speed(): value=16696, index=0 Calling usb_control_msg() from ftdi_set_termios(): value=0, index=0 Calling usb_control_msg() from ftdi_dtr_rts(): value=0, index=0 Calling usb_control_msg() from update_mctrl(): value=768, index=0
On Wed, Aug 24, 2011 at 12:14 PM, Kristian Amlie kristian@amlie.name wrote:
On 08/24/11 10:32, Daniel Mack wrote:
Hmm? Can you trace where this happens and which dereferenced pointer is NULL? I don't see it, sorry.
The attached patch solves the NULL pointer dereference. With this patch, the device shows up as a MIDI device, but still produces no events according to aseqdump.
Eh, quite obvious. Thanks for spotting.
I did a more thorough examination of the calls to usb_control_msg() from the ftdi_sio driver, and this is what I came up with:
Plugging it in:
Calling usb_control_msg() from read_latency_timer(): value=0, index=0 Calling usb_control_msg() from write_latency_timer(): value=1, index=0 usb 3-2: FTDI USB Serial Device converter now attached to ttyUSB0
Starting cu:
Calling usb_control_msg() from ftdi_open(): value=0, index=0 Calling usb_control_msg() from ftdi_set_termios(): value=8, index=0 Calling usb_control_msg() from change_speed(): value=16696, index=0 Calling usb_control_msg() from ftdi_set_termios(): value=0, index=0 Calling usb_control_msg() from update_mctrl(): value=771, index=0 Calling usb_control_msg() from ftdi_set_termios(): value=8, index=0 Calling usb_control_msg() from change_speed(): value=49230, index=0 Calling usb_control_msg() from ftdi_set_termios(): value=0, index=0 Calling usb_control_msg() from ftdi_set_termios(): value=8, index=0 Calling usb_control_msg() from change_speed(): value=49230, index=0 Calling usb_control_msg() from ftdi_set_termios(): value=0, index=0 Calling usb_control_msg() from ftdi_set_termios(): value=8, index=0 Calling usb_control_msg() from change_speed(): value=49230, index=0 Calling usb_control_msg() from ftdi_set_termios(): value=4881, index=1024
Ok - can you play around with these commands and add them to the MIDI driver? The stubs are all there now, and I think all that's missing is the termios call and maybe write_latency_timer(). I could prepare another patch, but I think it's faster if you just try around which command sequence helps :)
Daniel
On 08/24/11 12:29, Daniel Mack wrote:
Ok - can you play around with these commands and add them to the MIDI driver? The stubs are all there now, and I think all that's missing is the termios call and maybe write_latency_timer(). I could prepare another patch, but I think it's faster if you just try around which command sequence helps :)
I have tried to replicate the control messages to the best of my ability, but I'm still getting no MIDI events. The actual values in the stream may still be wrong (as per Clemens' email), so is there anywhere I can hook into to see if I get any USB activity *at all*?
On Wed, Aug 24, 2011 at 3:14 PM, Kristian Amlie kristian@amlie.name wrote:
On 08/24/11 12:29, Daniel Mack wrote:
Ok - can you play around with these commands and add them to the MIDI driver? The stubs are all there now, and I think all that's missing is the termios call and maybe write_latency_timer(). I could prepare another patch, but I think it's faster if you just try around which command sequence helps :)
I have tried to replicate the control messages to the best of my ability, but I'm still getting no MIDI events. The actual values in the stream may still be wrong (as per Clemens' email), so is there anywhere I can hook into to see if I get any USB activity *at all*?
Yes, you can check for received usb packets in snd_usbmidi_in_urb_complete().
Daniel Mack wrote:
Ok, then let's try the attached patch.
/* reset the port */
err = snd_usbmidi_ftdi_command(umidi, 0, 0);
if (err < 0)
break;
/* set mctrl */
err = snd_usbmidi_ftdi_command(umidi, 1, 0x303);
if (err < 0)
break;
The chip reads its initial configuration from the EEPROM, so these commands might not be necessary.
/* set baud rate */
err = snd_usbmidi_ftdi_command(umidi, 3, 0xc04e);
Replace 0xc04e with 0x60 to get exactly 31250 baud.
Furthermore, the FT232RL chip sends two modem status bytes in its packets, so we need something like this to prevent them from being interpreted as MIDI:
--- a/sound/usb/midi.c +++ b/sound/usb/midi.c @@ -791,7 +791,8 @@ static struct usb_protocol_ops snd_usbmidi_novation_ops = { static void snd_usbmidi_raw_input(struct snd_usb_midi_in_endpoint* ep, uint8_t* buffer, int buffer_length) { - snd_usbmidi_input_data(ep, 0, buffer, buffer_length); + if (buffer_length > 2) + snd_usbmidi_input_data(ep, 0, buffer + 2, buffer_length - 2); }
static void snd_usbmidi_raw_output(struct snd_usb_midi_out_endpoint* ep,
Regards, Clemens
Gentlemen, I believe we've got ourselves a new driver!
It turns out the problem I was having earlier where MIDI events didn't arrive, was a pilot error (reloading the wrong module). With my latest patch, both MIDI input and output works. I'll send it in a separate email for review.
Thanks a lot to Daniel and Clemens! Your help was a invaluable!
One caveat I have discovered with the patch: If you keep the instrument plugged in, but reload the driver, then the driver gets out of sync with the MIDI messages and won't report any. This seems to be because, in the stream, the message type is cached and subsequent messages do not report what type of message they are unless they are switching to a new type (going from control message to note message, for example). You can reset the stream by manually generating MIDI messages of different types (turn the volume knob while pressing a few notes), or eventually the instrument will reset itself and send the type anyway. So it's not critical, but would be nice to fix. I'm not sure how to solve it though...
On 08/24/11 21:51, Clemens Ladisch wrote:
/* reset the port */
err = snd_usbmidi_ftdi_command(umidi, 0, 0);
if (err < 0)
break;
/* set mctrl */
err = snd_usbmidi_ftdi_command(umidi, 1, 0x303);
if (err < 0)
break;
The chip reads its initial configuration from the EEPROM, so these commands might not be necessary.
You're right, they're not.
/* set baud rate */
err = snd_usbmidi_ftdi_command(umidi, 3, 0xc04e);
Replace 0xc04e with 0x60 to get exactly 31250 baud.
That did the trick! Thanks!
Furthermore, the FT232RL chip sends two modem status bytes in its packets, so we need something like this to prevent them from being interpreted as MIDI:
Done!
Based on a patch by Daniel Mack. --- sound/usb/midi.c | 29 +++++++++++++++++++++++++++++ sound/usb/quirks-table.h | 11 +++++++++++ sound/usb/quirks.c | 1 + sound/usb/usbaudio.h | 1 + 4 files changed, 42 insertions(+), 0 deletions(-)
diff --git a/sound/usb/midi.c b/sound/usb/midi.c index f928910..ec7a799 100644 --- a/sound/usb/midi.c +++ b/sound/usb/midi.c @@ -816,6 +816,18 @@ static struct usb_protocol_ops snd_usbmidi_raw_ops = { .output = snd_usbmidi_raw_output, };
+static void snd_usbmidi_ftdi_input(struct snd_usb_midi_in_endpoint* ep, + uint8_t* buffer, int buffer_length) +{ + if (buffer_length > 2) + snd_usbmidi_input_data(ep, 0, buffer + 2, buffer_length - 2); +} + +static struct usb_protocol_ops snd_usbmidi_ftdi_ops = { + .input = snd_usbmidi_ftdi_input, + .output = snd_usbmidi_raw_output, +}; + static void snd_usbmidi_us122l_input(struct snd_usb_midi_in_endpoint *ep, uint8_t *buffer, int buffer_length) { @@ -2073,6 +2085,13 @@ void snd_usbmidi_input_start(struct list_head* p) snd_usbmidi_input_start_ep(umidi->endpoints[i].in); }
+static int snd_usbmidi_ftdi_command(struct snd_usb_midi *umidi, + u8 command, u16 value, u16 index) +{ + return usb_control_msg(umidi->dev, usb_sndctrlpipe(umidi->dev, 0), + command, 0x40, value, index, NULL, 0, 1000); +} + /* * Creates and registers everything needed for a MIDI streaming interface. */ @@ -2163,6 +2182,16 @@ int snd_usbmidi_create(struct snd_card *card, /* endpoint 1 is input-only */ endpoints[1].out_cables = 0; break; + case QUIRK_MIDI_FTDI: + umidi->usb_protocol_ops = &snd_usbmidi_ftdi_ops; + + /* set baud rate */ + err = snd_usbmidi_ftdi_command(umidi, 3, 0x60, 0); + if (err < 0) + break; + + err = snd_usbmidi_detect_per_port_endpoints(umidi, endpoints); + break; default: snd_printd(KERN_ERR "invalid quirk type %d\n", quirk->type); err = -ENXIO; diff --git a/sound/usb/quirks-table.h b/sound/usb/quirks-table.h index 0b2ae8e..68ca427 100644 --- a/sound/usb/quirks-table.h +++ b/sound/usb/quirks-table.h @@ -39,6 +39,17 @@ .idProduct = prod, \ .bInterfaceClass = USB_CLASS_VENDOR_SPEC
+/* Starr Labs MIDI USB device */ +{ + USB_DEVICE(0x0403, 0xb8d8), + .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) { + /* .vendor_name = "STARR LABS", */ + /* .product_name = "Starr Labs MIDI USB device", */ + .ifnum = 0, + .type = QUIRK_MIDI_FTDI + } +}, + /* Creative/Toshiba Multimedia Center SB-0500 */ { USB_DEVICE(0x041e, 0x3048), diff --git a/sound/usb/quirks.c b/sound/usb/quirks.c index 090e193..65591df 100644 --- a/sound/usb/quirks.c +++ b/sound/usb/quirks.c @@ -306,6 +306,7 @@ int snd_usb_create_quirk(struct snd_usb_audio *chip, [QUIRK_MIDI_EMAGIC] = create_any_midi_quirk, [QUIRK_MIDI_CME] = create_any_midi_quirk, [QUIRK_MIDI_AKAI] = create_any_midi_quirk, + [QUIRK_MIDI_FTDI] = create_any_midi_quirk, [QUIRK_AUDIO_STANDARD_INTERFACE] = create_standard_audio_quirk, [QUIRK_AUDIO_FIXED_ENDPOINT] = create_fixed_stream_quirk, [QUIRK_AUDIO_EDIROL_UAXX] = create_uaxx_quirk, diff --git a/sound/usb/usbaudio.h b/sound/usb/usbaudio.h index 1e79986..3e2b035 100644 --- a/sound/usb/usbaudio.h +++ b/sound/usb/usbaudio.h @@ -80,6 +80,7 @@ enum quirk_type { QUIRK_MIDI_CME, QUIRK_MIDI_AKAI, QUIRK_MIDI_US122L, + QUIRK_MIDI_FTDI, QUIRK_AUDIO_STANDARD_INTERFACE, QUIRK_AUDIO_FIXED_ENDPOINT, QUIRK_AUDIO_EDIROL_UAXX,
Very good :) Just one minor thing below, and you can add my acked-by.
Remember to re-send the patch with your Signed-off-by: line, and see Documentation/SubmittingPatches for the details.
Daniel
On Thu, Aug 25, 2011 at 1:35 PM, Kristian Amlie kristian@amlie.name wrote:
Based on a patch by Daniel Mack.
sound/usb/midi.c | 29 +++++++++++++++++++++++++++++ sound/usb/quirks-table.h | 11 +++++++++++ sound/usb/quirks.c | 1 + sound/usb/usbaudio.h | 1 + 4 files changed, 42 insertions(+), 0 deletions(-)
diff --git a/sound/usb/midi.c b/sound/usb/midi.c index f928910..ec7a799 100644 --- a/sound/usb/midi.c +++ b/sound/usb/midi.c @@ -816,6 +816,18 @@ static struct usb_protocol_ops snd_usbmidi_raw_ops = { .output = snd_usbmidi_raw_output, };
+static void snd_usbmidi_ftdi_input(struct snd_usb_midi_in_endpoint* ep,
- uint8_t* buffer, int buffer_length)
+{
- if (buffer_length > 2)
- snd_usbmidi_input_data(ep, 0, buffer + 2, buffer_length - 2);
+}
+static struct usb_protocol_ops snd_usbmidi_ftdi_ops = {
- .input = snd_usbmidi_ftdi_input,
- .output = snd_usbmidi_raw_output,
+};
static void snd_usbmidi_us122l_input(struct snd_usb_midi_in_endpoint *ep, uint8_t *buffer, int buffer_length) { @@ -2073,6 +2085,13 @@ void snd_usbmidi_input_start(struct list_head* p) snd_usbmidi_input_start_ep(umidi->endpoints[i].in); }
+static int snd_usbmidi_ftdi_command(struct snd_usb_midi *umidi,
- u8 command, u16 value, u16 index)
+{
- return usb_control_msg(umidi->dev, usb_sndctrlpipe(umidi->dev, 0),
- command, 0x40, value, index, NULL, 0, 1000);
+}
With only one use of this function, I'd say you can inline the code.
/* * Creates and registers everything needed for a MIDI streaming interface. */ @@ -2163,6 +2182,16 @@ int snd_usbmidi_create(struct snd_card *card, /* endpoint 1 is input-only */ endpoints[1].out_cables = 0; break;
- case QUIRK_MIDI_FTDI:
- umidi->usb_protocol_ops = &snd_usbmidi_ftdi_ops;
- /* set baud rate */
- err = snd_usbmidi_ftdi_command(umidi, 3, 0x60, 0);
- if (err < 0)
- break;
- err = snd_usbmidi_detect_per_port_endpoints(umidi, endpoints);
- break;
default: snd_printd(KERN_ERR "invalid quirk type %d\n", quirk->type); err = -ENXIO; diff --git a/sound/usb/quirks-table.h b/sound/usb/quirks-table.h index 0b2ae8e..68ca427 100644 --- a/sound/usb/quirks-table.h +++ b/sound/usb/quirks-table.h @@ -39,6 +39,17 @@ .idProduct = prod, \ .bInterfaceClass = USB_CLASS_VENDOR_SPEC
+/* Starr Labs MIDI USB device */ +{
- USB_DEVICE(0x0403, 0xb8d8),
- .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
- /* .vendor_name = "STARR LABS", */
- /* .product_name = "Starr Labs MIDI USB device", */
- .ifnum = 0,
- .type = QUIRK_MIDI_FTDI
- }
+},
/* Creative/Toshiba Multimedia Center SB-0500 */ { USB_DEVICE(0x041e, 0x3048), diff --git a/sound/usb/quirks.c b/sound/usb/quirks.c index 090e193..65591df 100644 --- a/sound/usb/quirks.c +++ b/sound/usb/quirks.c @@ -306,6 +306,7 @@ int snd_usb_create_quirk(struct snd_usb_audio *chip, [QUIRK_MIDI_EMAGIC] = create_any_midi_quirk, [QUIRK_MIDI_CME] = create_any_midi_quirk, [QUIRK_MIDI_AKAI] = create_any_midi_quirk,
- [QUIRK_MIDI_FTDI] = create_any_midi_quirk,
[QUIRK_AUDIO_STANDARD_INTERFACE] = create_standard_audio_quirk, [QUIRK_AUDIO_FIXED_ENDPOINT] = create_fixed_stream_quirk, [QUIRK_AUDIO_EDIROL_UAXX] = create_uaxx_quirk, diff --git a/sound/usb/usbaudio.h b/sound/usb/usbaudio.h index 1e79986..3e2b035 100644 --- a/sound/usb/usbaudio.h +++ b/sound/usb/usbaudio.h @@ -80,6 +80,7 @@ enum quirk_type { QUIRK_MIDI_CME, QUIRK_MIDI_AKAI, QUIRK_MIDI_US122L,
- QUIRK_MIDI_FTDI,
QUIRK_AUDIO_STANDARD_INTERFACE, QUIRK_AUDIO_FIXED_ENDPOINT, QUIRK_AUDIO_EDIROL_UAXX, -- 1.7.3.4
Based on a patch by Daniel Mack.
Signed-off-by: Kristian Amlie kristian@amlie.name Acked-by: Daniel Mack zonque@gmail.com --- sound/usb/midi.c | 23 +++++++++++++++++++++++ sound/usb/quirks-table.h | 11 +++++++++++ sound/usb/quirks.c | 1 + sound/usb/usbaudio.h | 1 + 4 files changed, 36 insertions(+), 0 deletions(-)
diff --git a/sound/usb/midi.c b/sound/usb/midi.c index f928910..5110e78 100644 --- a/sound/usb/midi.c +++ b/sound/usb/midi.c @@ -816,6 +816,18 @@ static struct usb_protocol_ops snd_usbmidi_raw_ops = { .output = snd_usbmidi_raw_output, };
+static void snd_usbmidi_ftdi_input(struct snd_usb_midi_in_endpoint* ep, + uint8_t* buffer, int buffer_length) +{ + if (buffer_length > 2) + snd_usbmidi_input_data(ep, 0, buffer + 2, buffer_length - 2); +} + +static struct usb_protocol_ops snd_usbmidi_ftdi_ops = { + .input = snd_usbmidi_ftdi_input, + .output = snd_usbmidi_raw_output, +}; + static void snd_usbmidi_us122l_input(struct snd_usb_midi_in_endpoint *ep, uint8_t *buffer, int buffer_length) { @@ -2163,6 +2175,17 @@ int snd_usbmidi_create(struct snd_card *card, /* endpoint 1 is input-only */ endpoints[1].out_cables = 0; break; + case QUIRK_MIDI_FTDI: + umidi->usb_protocol_ops = &snd_usbmidi_ftdi_ops; + + /* set baud rate */ + err = usb_control_msg(umidi->dev, usb_sndctrlpipe(umidi->dev, 0), + 3, 0x40, 0x60, 0, NULL, 0, 1000); + if (err < 0) + break; + + err = snd_usbmidi_detect_per_port_endpoints(umidi, endpoints); + break; default: snd_printd(KERN_ERR "invalid quirk type %d\n", quirk->type); err = -ENXIO; diff --git a/sound/usb/quirks-table.h b/sound/usb/quirks-table.h index 0b2ae8e..68ca427 100644 --- a/sound/usb/quirks-table.h +++ b/sound/usb/quirks-table.h @@ -39,6 +39,17 @@ .idProduct = prod, \ .bInterfaceClass = USB_CLASS_VENDOR_SPEC
+/* Starr Labs MIDI USB device */ +{ + USB_DEVICE(0x0403, 0xb8d8), + .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) { + /* .vendor_name = "STARR LABS", */ + /* .product_name = "Starr Labs MIDI USB device", */ + .ifnum = 0, + .type = QUIRK_MIDI_FTDI + } +}, + /* Creative/Toshiba Multimedia Center SB-0500 */ { USB_DEVICE(0x041e, 0x3048), diff --git a/sound/usb/quirks.c b/sound/usb/quirks.c index 090e193..65591df 100644 --- a/sound/usb/quirks.c +++ b/sound/usb/quirks.c @@ -306,6 +306,7 @@ int snd_usb_create_quirk(struct snd_usb_audio *chip, [QUIRK_MIDI_EMAGIC] = create_any_midi_quirk, [QUIRK_MIDI_CME] = create_any_midi_quirk, [QUIRK_MIDI_AKAI] = create_any_midi_quirk, + [QUIRK_MIDI_FTDI] = create_any_midi_quirk, [QUIRK_AUDIO_STANDARD_INTERFACE] = create_standard_audio_quirk, [QUIRK_AUDIO_FIXED_ENDPOINT] = create_fixed_stream_quirk, [QUIRK_AUDIO_EDIROL_UAXX] = create_uaxx_quirk, diff --git a/sound/usb/usbaudio.h b/sound/usb/usbaudio.h index 1e79986..3e2b035 100644 --- a/sound/usb/usbaudio.h +++ b/sound/usb/usbaudio.h @@ -80,6 +80,7 @@ enum quirk_type { QUIRK_MIDI_CME, QUIRK_MIDI_AKAI, QUIRK_MIDI_US122L, + QUIRK_MIDI_FTDI, QUIRK_AUDIO_STANDARD_INTERFACE, QUIRK_AUDIO_FIXED_ENDPOINT, QUIRK_AUDIO_EDIROL_UAXX,
Kristian Amlie wrote:
Based on a patch by Daniel Mack.
Signed-off-by: Kristian Amlie kristian@amlie.name Acked-by: Daniel Mack zonque@gmail.com
Thanks, applied.
Clemens
On Thu, Aug 25, 2011 at 1:28 PM, Kristian Amlie kristian@amlie.name wrote:
One caveat I have discovered with the patch: If you keep the instrument plugged in, but reload the driver, then the driver gets out of sync with the MIDI messages and won't report any. This seems to be because, in the stream, the message type is cached and subsequent messages do not report what type of message they are unless they are switching to a new type (going from control message to note message, for example). You can reset the stream by manually generating MIDI messages of different types (turn the volume knob while pressing a few notes), or eventually the instrument will reset itself and send the type anyway. So it's not critical, but would be nice to fix. I'm not sure how to solve it though...
What you're seeing here is a general problem of the MIDI protocol that cannot be fixed. If a receiver misses the running state update, it can't do anything but wait for the next one.
Daniel
Kristian Amlie wrote:
I tried 38400 baud, and that seemed to work. I got a small number of bytes everytime I pressed a key on the instrument.
18 f9 ff 18 03 f8 18 f9 ff 18 01 f8 18 f9 ff 18 01 f8 18 fb ff 18 01 f8 18 fb ff 18 01 f8 18 fb ff 18 03 f8 18 f9 ff 18 01 f8 18 fb ff 18 01 f8 18 fb ff 18 01 f8 18 fb ff 18 01 f8
This is not MIDI. However, these value might by explained by a 31250-baud signal sampled at 38400 baud.
Daniel Mack wrote:
I think that requires a special divider setup that is not supported by the ftdi_sio driver.
Indeed.
Kristian, what do the .inf files that come with the Windows driver say?
Regards, Clemens
On Wed, Aug 24, 2011 at 1:44 PM, Clemens Ladisch clemens@ladisch.de wrote:
This is not MIDI. However, these value might by explained by a 31250-baud signal sampled at 38400 baud.
Daniel Mack wrote:
I think that requires a special divider setup that is not supported by the ftdi_sio driver.
Indeed.
OTOH - the devices only produces MIDI events internally, so there's actually no evidence that it operates at 31250 baud. It could be anything else. Kristian, I think you need to investigate a little more :)
Daniel
On 08/24/11 13:44, Clemens Ladisch wrote:
Kristian Amlie wrote:
I tried 38400 baud, and that seemed to work. I got a small number of bytes everytime I pressed a key on the instrument.
18 f9 ff 18 03 f8 18 f9 ff 18 01 f8 18 f9 ff 18 01 f8 18 fb ff 18 01 f8 18 fb ff 18 01 f8 18 fb ff 18 03 f8 18 f9 ff 18 01 f8 18 fb ff 18 01 f8 18 fb ff 18 01 f8 18 fb ff 18 01 f8
This is not MIDI. However, these value might by explained by a 31250-baud signal sampled at 38400 baud.
Indeed. I have tried different baud rates and that produces different values. I'm starting to suspect that the "cu" tool itself does not support certain baud rates, even if the ftdi_sio driver does.
Daniel Mack wrote:
I think that requires a special divider setup that is not supported by the ftdi_sio driver.
Indeed.
Kristian, what do the .inf files that come with the Windows driver say?
I have attached the three files that come with the installation. I'm not sure what to look for myself, I'm afraid.
At least FTDI is mentioned all over the place so we must be on the right track.
Kristian Amlie wrote:
On 08/24/11 13:44, Clemens Ladisch wrote:
Kristian, what do the .inf files that come with the Windows driver say?
I have attached the three files that come with the installation. I'm not sure what to look for myself, I'm afraid.
ftdiport.inf says: | HKR,,"ConfigData",1,11,04,00,00,10,27,00,00,88,13,00,00,C4,09,00,00,E2,04,00,00,71,02,00,00,38,41,00,00,9C,80,00,00,4E,C0,00,00,34,00,00,00,1A,00,00,00,0D,00,00,00,06,40,00,00,03,80,00,00,00,00,00,00,D0,80,00,00
These are just the standard baud rates. But the driver doesn't expose a COM port with selectable baud rates anyway.
The dmusftdi.sys driver was written by Starr Labs. I guess it manually sets a custom baud rate.
I'll look into how to set a custom baud rate.
Regards, Clemens
participants (4)
-
Clemens Ladisch
-
Daniel Mack
-
Kristian Amlie
-
Paul Menzel