Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit f2ebf92c authored by Ben Williamson's avatar Ben Williamson Committed by Greg Kroah-Hartman
Browse files

USB: gmidi: New USB MIDI Gadget class driver.



This driver is glue between the USB gadget interface
and the ALSA MIDI interface. It allows us to appear
as a MIDI Streaming device to a host system on the
other end of a USB cable.

This includes linux/usb/audio.h and linux/usb/midi.h
containing definitions from the relevant USB specifications
for USB audio and USB MIDI devices.

The following changes have been made since the first RFC
posting:

* Bug fixes to endpoint handling.
* Workaround for USB_REQ_SET_CONFIGURATION handling,
  not understood yet.
* Added SND and SND_RAWMIDI dependencies in Kconfig.
* Moved usb_audio.h and usb_midi.h to usb/*.h
* Added module parameters for ALSA card index and id.
* Added module parameters for USB descriptor IDs and strings.
* Removed some unneeded stuff inherited from zero.c, more to go.
* Provide DECLARE_* macros for the variable-length structs.
* Use kmalloc instead of usb_ep_alloc_buffer.
* Limit source to 80 columns.
* Return actual error code instead of -ENOMEM in a few places.

Signed-off-by: default avatarBen Williamson <ben.williamson@greyinnovation.com>
Cc: David Brownell <david-b@pacbell.net>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@suse.de>
parent ba307f58
Loading
Loading
Loading
Loading
+14 −0
Original line number Diff line number Diff line
@@ -404,6 +404,20 @@ config USB_G_SERIAL
	  which includes instructions and a "driver info file" needed to
	  make MS-Windows work with this driver.

config USB_MIDI_GADGET
	tristate "MIDI Gadget (EXPERIMENTAL)"
	depends on SND && EXPERIMENTAL
	select SND_RAWMIDI
	help
	  The MIDI Gadget acts as a USB Audio device, with one MIDI
	  input and one MIDI output. These MIDI jacks appear as
	  a sound "card" in the ALSA sound system. Other MIDI
	  connections can then be made on the gadget system, using
	  ALSA's aconnect utility etc.

	  Say "y" to link the driver statically, or "m" to build a
	  dynamically linked module called "g_midi".


# put drivers that need isochronous transfer support (for audio
# or video class gadget drivers), or specific hardware, here.
+2 −0
Original line number Diff line number Diff line
@@ -15,6 +15,7 @@ obj-$(CONFIG_USB_AT91) += at91_udc.o
g_zero-objs			:= zero.o usbstring.o config.o epautoconf.o
g_ether-objs			:= ether.o usbstring.o config.o epautoconf.o
g_serial-objs			:= serial.o usbstring.o config.o epautoconf.o
g_midi-objs			:= gmidi.o usbstring.o config.o epautoconf.o
gadgetfs-objs			:= inode.o
g_file_storage-objs		:= file_storage.o usbstring.o config.o \
					epautoconf.o
@@ -28,4 +29,5 @@ obj-$(CONFIG_USB_ETH) += g_ether.o
obj-$(CONFIG_USB_GADGETFS)	+= gadgetfs.o
obj-$(CONFIG_USB_FILE_STORAGE)	+= g_file_storage.o
obj-$(CONFIG_USB_G_SERIAL)	+= g_serial.o
obj-$(CONFIG_USB_MIDI_GADGET)	+= g_midi.o
+1337 −0

File added.

Preview size limit exceeded, changes collapsed.

+53 −0
Original line number Diff line number Diff line
/*
 * <linux/usb/audio.h> -- USB Audio definitions.
 *
 * Copyright (C) 2006 Thumtronics Pty Ltd.
 * Developed for Thumtronics by Grey Innovation
 * Ben Williamson <ben.williamson@greyinnovation.com>
 *
 * This software is distributed under the terms of the GNU General Public
 * License ("GPL") version 2, as published by the Free Software Foundation.
 *
 * This file holds USB constants and structures defined
 * by the USB Device Class Definition for Audio Devices.
 * Comments below reference relevant sections of that document:
 *
 * http://www.usb.org/developers/devclass_docs/audio10.pdf
 */

#ifndef __LINUX_USB_AUDIO_H
#define __LINUX_USB_AUDIO_H

#include <linux/types.h>

/* A.2 Audio Interface Subclass Codes */
#define USB_SUBCLASS_AUDIOCONTROL	0x01
#define USB_SUBCLASS_AUDIOSTREAMING	0x02
#define USB_SUBCLASS_MIDISTREAMING	0x03

/* 4.3.2  Class-Specific AC Interface Descriptor */
struct usb_ac_header_descriptor {
	__u8  bLength;			// 8+n
	__u8  bDescriptorType;		// USB_DT_CS_INTERFACE
	__u8  bDescriptorSubtype;	// USB_MS_HEADER
	__le16 bcdADC;			// 0x0100
	__le16 wTotalLength;		// includes Unit and Terminal desc.
	__u8  bInCollection;		// n
	__u8  baInterfaceNr[];		// [n]
} __attribute__ ((packed));

#define USB_DT_AC_HEADER_SIZE(n)	(8+(n))

/* As above, but more useful for defining your own descriptors: */
#define DECLARE_USB_AC_HEADER_DESCRIPTOR(n) 			\
struct usb_ac_header_descriptor_##n {				\
	__u8  bLength;						\
	__u8  bDescriptorType;					\
	__u8  bDescriptorSubtype;				\
	__le16 bcdADC;						\
	__le16 wTotalLength;					\
	__u8  bInCollection;					\
	__u8  baInterfaceNr[n];					\
} __attribute__ ((packed))

#endif
+112 −0
Original line number Diff line number Diff line
/*
 * <linux/usb/midi.h> -- USB MIDI definitions.
 *
 * Copyright (C) 2006 Thumtronics Pty Ltd.
 * Developed for Thumtronics by Grey Innovation
 * Ben Williamson <ben.williamson@greyinnovation.com>
 *
 * This software is distributed under the terms of the GNU General Public
 * License ("GPL") version 2, as published by the Free Software Foundation.
 *
 * This file holds USB constants and structures defined
 * by the USB Device Class Definition for MIDI Devices.
 * Comments below reference relevant sections of that document:
 *
 * http://www.usb.org/developers/devclass_docs/midi10.pdf
 */

#ifndef __LINUX_USB_MIDI_H
#define __LINUX_USB_MIDI_H

#include <linux/types.h>

/* A.1  MS Class-Specific Interface Descriptor Subtypes */
#define USB_MS_HEADER		0x01
#define USB_MS_MIDI_IN_JACK	0x02
#define USB_MS_MIDI_OUT_JACK	0x03
#define USB_MS_ELEMENT		0x04

/* A.2  MS Class-Specific Endpoint Descriptor Subtypes */
#define USB_MS_GENERAL		0x01

/* A.3  MS MIDI IN and OUT Jack Types */
#define USB_MS_EMBEDDED		0x01
#define USB_MS_EXTERNAL		0x02

/* 6.1.2.1  Class-Specific MS Interface Header Descriptor */
struct usb_ms_header_descriptor {
	__u8  bLength;
	__u8  bDescriptorType;
	__u8  bDescriptorSubtype;
	__le16 bcdMSC;
	__le16 wTotalLength;
} __attribute__ ((packed));

#define USB_DT_MS_HEADER_SIZE	7

/* 6.1.2.2  MIDI IN Jack Descriptor */
struct usb_midi_in_jack_descriptor {
	__u8  bLength;
	__u8  bDescriptorType;		// USB_DT_CS_INTERFACE
	__u8  bDescriptorSubtype;	// USB_MS_MIDI_IN_JACK
	__u8  bJackType;		// USB_MS_EMBEDDED/EXTERNAL
	__u8  bJackID;
	__u8  iJack;
} __attribute__ ((packed));

#define USB_DT_MIDI_IN_SIZE	6

struct usb_midi_source_pin {
	__u8  baSourceID;
	__u8  baSourcePin;
} __attribute__ ((packed));

/* 6.1.2.3  MIDI OUT Jack Descriptor */
struct usb_midi_out_jack_descriptor {
	__u8  bLength;
	__u8  bDescriptorType;		// USB_DT_CS_INTERFACE
	__u8  bDescriptorSubtype;	// USB_MS_MIDI_OUT_JACK
	__u8  bJackType;		// USB_MS_EMBEDDED/EXTERNAL
	__u8  bJackID;
	__u8  bNrInputPins;		// p
	struct usb_midi_source_pin pins[]; // [p]
	/*__u8  iJack;  -- ommitted due to variable-sized pins[] */
} __attribute__ ((packed));

#define USB_DT_MIDI_OUT_SIZE(p)	(7 + 2 * (p))

/* As above, but more useful for defining your own descriptors: */
#define DECLARE_USB_MIDI_OUT_JACK_DESCRIPTOR(p)			\
struct usb_midi_out_jack_descriptor_##p {			\
	__u8  bLength;						\
	__u8  bDescriptorType;					\
	__u8  bDescriptorSubtype;				\
	__u8  bJackType;					\
	__u8  bJackID;						\
	__u8  bNrInputPins;					\
	struct usb_midi_source_pin pins[p];			\
	__u8  iJack;						\
} __attribute__ ((packed))

/* 6.2.2  Class-Specific MS Bulk Data Endpoint Descriptor */
struct usb_ms_endpoint_descriptor {
	__u8  bLength;			// 4+n
	__u8  bDescriptorType;		// USB_DT_CS_ENDPOINT
	__u8  bDescriptorSubtype;	// USB_MS_GENERAL
	__u8  bNumEmbMIDIJack;		// n
	__u8  baAssocJackID[];		// [n]
} __attribute__ ((packed));

#define USB_DT_MS_ENDPOINT_SIZE(n)	(4 + (n))

/* As above, but more useful for defining your own descriptors: */
#define DECLARE_USB_MS_ENDPOINT_DESCRIPTOR(n)			\
struct usb_ms_endpoint_descriptor_##n {				\
	__u8  bLength;						\
	__u8  bDescriptorType;					\
	__u8  bDescriptorSubtype;				\
	__u8  bNumEmbMIDIJack;					\
	__u8  baAssocJackID[n];					\
} __attribute__ ((packed))

#endif