mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-09 12:17:12 +09:00
USB: gadget: android: Integrate f_midi USB MIDI gadget driver
Change-Id: I4c4b99f9d54314fc31445cf42b825527ca483af9 Signed-off-by: Mike Lockwood <lockwood@google.com>
This commit is contained in:
@@ -32,6 +32,7 @@
|
||||
|
||||
#include "f_fs.c"
|
||||
#include "f_audio_source.c"
|
||||
#include "f_midi.c"
|
||||
#include "f_mass_storage.c"
|
||||
#include "f_mtp.c"
|
||||
#include "f_accessory.c"
|
||||
@@ -51,6 +52,12 @@ static const char longname[] = "Gadget Android";
|
||||
#define VENDOR_ID 0x18D1
|
||||
#define PRODUCT_ID 0x0001
|
||||
|
||||
/* f_midi configuration */
|
||||
#define MIDI_INPUT_PORTS 1
|
||||
#define MIDI_OUTPUT_PORTS 1
|
||||
#define MIDI_BUFFER_SIZE 256
|
||||
#define MIDI_QUEUE_LENGTH 32
|
||||
|
||||
struct android_usb_function {
|
||||
char *name;
|
||||
void *config;
|
||||
@@ -933,6 +940,60 @@ static struct android_usb_function audio_source_function = {
|
||||
.attributes = audio_source_function_attributes,
|
||||
};
|
||||
|
||||
static int midi_function_init(struct android_usb_function *f,
|
||||
struct usb_composite_dev *cdev)
|
||||
{
|
||||
struct midi_alsa_config *config;
|
||||
|
||||
config = kzalloc(sizeof(struct midi_alsa_config), GFP_KERNEL);
|
||||
f->config = config;
|
||||
if (!config)
|
||||
return -ENOMEM;
|
||||
config->card = -1;
|
||||
config->device = -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void midi_function_cleanup(struct android_usb_function *f)
|
||||
{
|
||||
kfree(f->config);
|
||||
}
|
||||
|
||||
static int midi_function_bind_config(struct android_usb_function *f,
|
||||
struct usb_configuration *c)
|
||||
{
|
||||
struct midi_alsa_config *config = f->config;
|
||||
|
||||
return f_midi_bind_config(c, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1,
|
||||
MIDI_INPUT_PORTS, MIDI_OUTPUT_PORTS, MIDI_BUFFER_SIZE,
|
||||
MIDI_QUEUE_LENGTH, config);
|
||||
}
|
||||
|
||||
static ssize_t midi_alsa_show(struct device *dev,
|
||||
struct device_attribute *attr, char *buf)
|
||||
{
|
||||
struct android_usb_function *f = dev_get_drvdata(dev);
|
||||
struct midi_alsa_config *config = f->config;
|
||||
|
||||
/* print ALSA card and device numbers */
|
||||
return sprintf(buf, "%d %d\n", config->card, config->device);
|
||||
}
|
||||
|
||||
static DEVICE_ATTR(alsa, S_IRUGO, midi_alsa_show, NULL);
|
||||
|
||||
static struct device_attribute *midi_function_attributes[] = {
|
||||
&dev_attr_alsa,
|
||||
NULL
|
||||
};
|
||||
|
||||
static struct android_usb_function midi_function = {
|
||||
.name = "midi",
|
||||
.init = midi_function_init,
|
||||
.cleanup = midi_function_cleanup,
|
||||
.bind_config = midi_function_bind_config,
|
||||
.attributes = midi_function_attributes,
|
||||
};
|
||||
|
||||
static struct android_usb_function *supported_functions[] = {
|
||||
&ffs_function,
|
||||
&acm_function,
|
||||
@@ -942,10 +1003,10 @@ static struct android_usb_function *supported_functions[] = {
|
||||
&mass_storage_function,
|
||||
&accessory_function,
|
||||
&audio_source_function,
|
||||
&midi_function,
|
||||
NULL
|
||||
};
|
||||
|
||||
|
||||
static int android_init_functions(struct android_usb_function **functions,
|
||||
struct usb_composite_dev *cdev)
|
||||
{
|
||||
|
||||
@@ -65,6 +65,11 @@ struct gmidi_in_port {
|
||||
uint8_t data[2];
|
||||
};
|
||||
|
||||
struct midi_alsa_config {
|
||||
int card;
|
||||
int device;
|
||||
};
|
||||
|
||||
struct f_midi {
|
||||
struct usb_function func;
|
||||
struct usb_gadget *gadget;
|
||||
@@ -97,7 +102,7 @@ DECLARE_USB_MIDI_OUT_JACK_DESCRIPTOR(1);
|
||||
DECLARE_USB_MS_ENDPOINT_DESCRIPTOR(16);
|
||||
|
||||
/* B.3.1 Standard AC Interface Descriptor */
|
||||
static struct usb_interface_descriptor ac_interface_desc __initdata = {
|
||||
static struct usb_interface_descriptor ac_interface_desc /* __initdata */ = {
|
||||
.bLength = USB_DT_INTERFACE_SIZE,
|
||||
.bDescriptorType = USB_DT_INTERFACE,
|
||||
/* .bInterfaceNumber = DYNAMIC */
|
||||
@@ -108,7 +113,7 @@ static struct usb_interface_descriptor ac_interface_desc __initdata = {
|
||||
};
|
||||
|
||||
/* B.3.2 Class-Specific AC Interface Descriptor */
|
||||
static struct uac1_ac_header_descriptor_1 ac_header_desc __initdata = {
|
||||
static struct uac1_ac_header_descriptor_1 ac_header_desc /* __initdata */ = {
|
||||
.bLength = UAC_DT_AC_HEADER_SIZE(1),
|
||||
.bDescriptorType = USB_DT_CS_INTERFACE,
|
||||
.bDescriptorSubtype = USB_MS_HEADER,
|
||||
@@ -119,7 +124,7 @@ static struct uac1_ac_header_descriptor_1 ac_header_desc __initdata = {
|
||||
};
|
||||
|
||||
/* B.4.1 Standard MS Interface Descriptor */
|
||||
static struct usb_interface_descriptor ms_interface_desc __initdata = {
|
||||
static struct usb_interface_descriptor ms_interface_desc /* __initdata */ = {
|
||||
.bLength = USB_DT_INTERFACE_SIZE,
|
||||
.bDescriptorType = USB_DT_INTERFACE,
|
||||
/* .bInterfaceNumber = DYNAMIC */
|
||||
@@ -130,7 +135,7 @@ static struct usb_interface_descriptor ms_interface_desc __initdata = {
|
||||
};
|
||||
|
||||
/* B.4.2 Class-Specific MS Interface Descriptor */
|
||||
static struct usb_ms_header_descriptor ms_header_desc __initdata = {
|
||||
static struct usb_ms_header_descriptor ms_header_desc /* __initdata */ = {
|
||||
.bLength = USB_DT_MS_HEADER_SIZE,
|
||||
.bDescriptorType = USB_DT_CS_INTERFACE,
|
||||
.bDescriptorSubtype = USB_MS_HEADER,
|
||||
@@ -733,7 +738,7 @@ fail:
|
||||
|
||||
/* MIDI function driver setup/binding */
|
||||
|
||||
static int __init
|
||||
static int /* __init */
|
||||
f_midi_bind(struct usb_configuration *c, struct usb_function *f)
|
||||
{
|
||||
struct usb_descriptor_header **midi_function;
|
||||
@@ -923,16 +928,22 @@ fail:
|
||||
*
|
||||
* Returns zero on success, else negative errno.
|
||||
*/
|
||||
int __init f_midi_bind_config(struct usb_configuration *c,
|
||||
int /* __init */ f_midi_bind_config(struct usb_configuration *c,
|
||||
int index, char *id,
|
||||
unsigned int in_ports,
|
||||
unsigned int out_ports,
|
||||
unsigned int buflen,
|
||||
unsigned int qlen)
|
||||
unsigned int qlen,
|
||||
struct midi_alsa_config* config)
|
||||
{
|
||||
struct f_midi *midi;
|
||||
int status, i;
|
||||
|
||||
if (config) {
|
||||
config->card = -1;
|
||||
config->device = -1;
|
||||
}
|
||||
|
||||
/* sanity check */
|
||||
if (in_ports > MAX_PORTS || out_ports > MAX_PORTS)
|
||||
return -EINVAL;
|
||||
@@ -961,6 +972,10 @@ int __init f_midi_bind_config(struct usb_configuration *c,
|
||||
tasklet_init(&midi->tasklet, f_midi_in_tasklet, (unsigned long) midi);
|
||||
|
||||
/* set up ALSA midi devices */
|
||||
midi->id = kstrdup(id, GFP_KERNEL);
|
||||
midi->index = index;
|
||||
midi->buflen = buflen;
|
||||
midi->qlen = qlen;
|
||||
midi->in_ports = in_ports;
|
||||
midi->out_ports = out_ports;
|
||||
status = f_midi_register_card(midi);
|
||||
@@ -974,15 +989,16 @@ int __init f_midi_bind_config(struct usb_configuration *c,
|
||||
midi->func.set_alt = f_midi_set_alt;
|
||||
midi->func.disable = f_midi_disable;
|
||||
|
||||
midi->id = kstrdup(id, GFP_KERNEL);
|
||||
midi->index = index;
|
||||
midi->buflen = buflen;
|
||||
midi->qlen = qlen;
|
||||
|
||||
status = usb_add_function(c, &midi->func);
|
||||
if (status)
|
||||
goto setup_fail;
|
||||
|
||||
|
||||
if (config) {
|
||||
config->card = midi->rmidi->card->number;
|
||||
config->device = midi->rmidi->device;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
setup_fail:
|
||||
|
||||
Reference in New Issue
Block a user