USB: gadget: android: Integrate f_midi USB MIDI gadget driver
authorMike Lockwood <lockwood@google.com>
Thu, 29 Jan 2015 21:52:51 +0000 (13:52 -0800)
committerMike Lockwood <lockwood@google.com>
Mon, 16 Mar 2015 18:05:34 +0000 (11:05 -0700)
Change-Id: I4c4b99f9d54314fc31445cf42b825527ca483af9
Signed-off-by: Mike Lockwood <lockwood@google.com>
drivers/usb/gadget/android.c
drivers/usb/gadget/f_midi.c

index 83b1240d9b19f8112b7070daeca505eb53c2e7a4..61c5e582bf473d447db995b7b271750cb0248265 100644 (file)
@@ -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)
 {
index b91f519776ce655e05d78974e9f72537bd8995ef..e257a49f29cd036e57b7a90775653088a0f7fae0 100644 (file)
@@ -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: