This gadget is built using a generic approach.
        To use this composite gadget, just load the gadget modules and plug-in
        the USB Cable.

        The g_midi.c file was not modified yet.

        Will come in a separate patch.

Signed-off-by: Felipe Balbi <[EMAIL PROTECTED]>
Signed-off-by: Ragner Magalhaes <[EMAIL PROTECTED]>
---

Index: linux-omap-2.6-ragner/drivers/usb/gadget/composite_functions.c
===================================================================
--- /dev/null
+++ linux-omap-2.6-ragner/drivers/usb/gadget/composite_functions.c
@@ -0,0 +1,304 @@
+/*
+ * composite_functions.c -- USB OMAP Layer for Composite Device Support
+ *
+ * Copyright 2006 (C) Instituto Nokia de Tecnologia - INdT
+ *
+ * This software is distributed under the terms of the GNU General
+ * Public License ("GPL") as published by the Free Software Foundation,
+ * either version 2 of the License of (at you option) any later version.
+ *
+ */
+
+#include <linux/delay.h>
+#include <linux/device.h>
+#include <linux/errno.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/ioport.h>
+#include <linux/kernel.h>
+#include <linux/list.h>
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/sched.h>
+#include <linux/smp_lock.h>
+#include <linux/timer.h>
+#include <linux/utsname.h>
+#include <linux/usb_ch9.h>
+#include <linux/usb_gadget.h>
+#include <linux/usb/composite.h>
+
+#include <asm/byteorder.h>
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/semaphore.h>
+#include <asm/system.h>
+#include <asm/unaligned.h>
+
+#include "gadget_chips.h"
+
+#define COMPOSITE_DESC         "Composite Driver"
+#define COMPOSITE_VERSION      "v1.0-alpha"
+
+
+static const char driver_desc [] = COMPOSITE_DESC;
+
+/* descriptors that are built on-demand */
+static char manufacturer [50];
+static char product_desc [40] = COMPOSITE_DESC;
+static char serial_number [20] = {"0"};
+
+/*-------------------------------------------------------------------------*/
+
+#define NUM_CONFIGS            1
+
+#define VENDOR_ID              0x0525 /* NetChip */
+#define PRODUCT_ID             0Xa4a6 /* Linux-USB Serial */
+#define COMPOSITE_CONFIG_NUMBER                1
+
+/* USB String IDs */
+#define COMPOSITE_MANUFACTURER_ID      1
+#define COMPOSITE_PRODUCT_ID           2
+#define COMPOSITE_SERIALNUMBER_ID      3
+#define COMPOSITE_CONFIG_SRT_ID        4
+
+MODULE_DESCRIPTION(COMPOSITE_DESC);
+MODULE_AUTHOR("Felipe Balbi, Ragner Magalhaes");
+MODULE_LICENSE("GPL");
+
+/* USB Strings, UTF8 */
+
+
+static struct usb_string composite_strings[] = {
+       { COMPOSITE_MANUFACTURER_ID, manufacturer },
+       { COMPOSITE_PRODUCT_ID, product_desc},
+       { COMPOSITE_SERIALNUMBER_ID, serial_number },
+       { COMPOSITE_CONFIG_SRT_ID, "Composite Alpha" },
+       {  } /* end */
+};
+static struct usb_gadget_strings composite_stringtable = {
+       .language               = 0x0409, /* en-US */
+       .strings                = composite_strings,
+};
+static struct usb_device_descriptor composite_device_desc = {
+       .bLength                = USB_DT_DEVICE_SIZE,
+       .bDescriptorType        = USB_DT_DEVICE,
+       .bcdUSB                 = __constant_cpu_to_le16(0x0200),
+       .bDeviceClass           = USB_CLASS_PER_INTERFACE,
+       .bDeviceSubClass        = USB_CLASS_PER_INTERFACE,
+       .bDeviceProtocol        = 0,
+       .idVendor               = __constant_cpu_to_le16(VENDOR_ID),
+       .idProduct              = __constant_cpu_to_le16(PRODUCT_ID),
+       .iManufacturer          = COMPOSITE_MANUFACTURER_ID,
+       .iProduct               = COMPOSITE_PRODUCT_ID,
+       .iSerialNumber          = COMPOSITE_SERIALNUMBER_ID,
+       .bNumConfigurations     = NUM_CONFIGS,
+};
+static struct usb_config_descriptor composite_config_desc = {
+       .bLength                = USB_DT_CONFIG_SIZE,
+       .bDescriptorType        = USB_DT_CONFIG,
+       /* wTotalLenght computed dynamically */
+       .bNumInterfaces         = MAX_COMPOSITE_INTERFACES,
+       .bConfigurationValue    = COMPOSITE_CONFIG_NUMBER,
+       .iConfiguration         = COMPOSITE_CONFIG_SRT_ID,
+       .bmAttributes           = USB_CONFIG_ATT_ONE | USB_CONFIG_ATT_SELFPOWER,
+       .bMaxPower              = 1,
+};
+static struct usb_qualifier_descriptor composite_qualifier_desc = {
+       .bLength =              sizeof composite_qualifier_desc,
+       .bDescriptorType        = USB_DT_DEVICE_QUALIFIER,
+       .bcdUSB                 = __constant_cpu_to_le16(0x0200),
+       .bDeviceClass           = USB_CLASS_PER_INTERFACE,
+       .bNumConfigurations     = NUM_CONFIGS,
+};
+
+struct usb_composite_dev        *cdev;
+
+/* Functions */
+
+/* module */
+static int __init composite_init(void);
+static void __exit composite_exit(void);
+
+/* usb_function register function */
+int usb_function_register(struct usb_function *);
+
+static int composite_func_bind(struct usb_composite_dev *composite_dev)
+{
+       struct usb_gadget *gadget = composite_dev->gadget;
+       cdev = composite_dev;
+
+       /* Code from serial gadget */
+       if (gadget->is_otg) {
+               composite_config_desc.bmAttributes |= USB_CONFIG_ATT_WAKEUP;
+       }
+
+       cdev->config = composite_config_desc;
+       cdev->qual = composite_qualifier_desc;
+
+       /* Last str id in string usb of the composite */
+       cdev->next_string_id = COMPOSITE_CONFIG_SRT_ID;
+
+       snprintf(manufacturer, sizeof(manufacturer), "%s %s with %s",
+               init_utsname()->sysname, init_utsname()->release,
+               driver_desc);
+
+       return 0;
+}
+
+static struct usb_composite_driver composite_drv = {
+       .dev                    = &composite_device_desc,
+       .strings                = &composite_stringtable,
+       .bind                   = composite_func_bind,
+/*     .unbind                 = ..., Do we need to code this? */
+/*     .setup                  = ..., Same as above */
+       .functions              = LIST_HEAD_INIT(composite_drv.functions),
+};
+
+static int reset_interf_functions(void)
+{
+       int status = 0;
+       struct usb_function *f;
+
+       list_for_each_entry (f, &cdev->driver->functions, function) {
+                       cdev->current_func = f;
+               usb_composite_reset_interface(cdev);
+
+               if (status)
+                       goto fail;
+       }
+
+       return 0;
+
+fail:
+       return status;
+}
+
+static int set_interf_functions(void)
+{
+       int status = 0;
+       struct usb_function *f;
+
+       cdev->next_interface_id = 0;
+
+       list_for_each_entry (f, &cdev->driver->functions, function) {
+               cdev->current_func = f;
+               status = usb_composite_interface_id(cdev);
+
+               if (status)
+                       goto fail;
+       }
+       cdev->config.bNumInterfaces = cdev->next_interface_id;
+       return 0;
+fail:
+       return status;
+}
+
+/* usb_function_register
+ *
+ * Get from usb function drivers their struct usb_function
+ * and assembles all of them into one struct usb_composite_driver
+ */
+int  usb_function_register(struct usb_function *g_func)
+{
+       struct usb_composite_driver *d = &composite_drv;
+       int status = 0;
+
+       if (!g_func->name)
+               g_func->name = "Composite Gadget";
+
+       cdev->current_func = g_func;
+       status = g_func->bind(cdev->gadget);
+
+       if (status < 0)
+               goto fail;
+
+       /* Set interface id */
+       status = usb_composite_interface_id(cdev);
+       if (status < 0)
+               goto fail_conf_id;
+
+       /* Set string id */
+       status = usb_composite_string_id(cdev);
+       if (status < 0)
+               goto fail_conf_id;
+
+        cdev->config.bNumInterfaces = cdev->next_interface_id;
+       cdev->current_func = NULL;
+
+       list_add_tail(&g_func->function, &d->functions);
+       printk(KERN_INFO "USB Function registered.\n");
+
+       return 0;
+
+fail_conf_id:
+       g_func->unbind(cdev->gadget);
+       cdev->current_func = NULL;
+
+fail:
+       return status;
+}
+EXPORT_SYMBOL(usb_function_register);
+
+void usb_function_unregister(struct usb_function *g_func)
+{
+       cdev->current_func = g_func;
+       g_func->unbind(cdev->gadget);
+
+       list_del(&g_func->function);
+
+       cdev->current_func = NULL;
+
+       if (reset_interf_functions()) {
+               printk(KERN_INFO "Reset functions error!!!.\n");
+        } else {
+               set_interf_functions();
+        }
+}
+EXPORT_SYMBOL(usb_function_unregister);
+
+/* usb_composite_ep_reset
+ *
+ * This functions reset the state of a single endpoint.
+ */
+int usb_composite_ep_reset (struct usb_ep *ep)
+{
+       if (!ep)
+               return -EINVAL;
+
+       ep->driver_data = NULL;
+
+       return 0;
+}
+EXPORT_SYMBOL(usb_composite_ep_reset);
+
+/* composite_init
+ *
+ * Register as a USB Composite driver
+ *
+ * This function calls composite_function_register() to assemble
+ * composite_drv properly. After that it calls usb_composite_register()
+ * to register this device as a composite device.
+ */
+
+/* This function will register de composite driver */
+static int __init composite_init(void)
+{
+       int retval = 0;
+
+       retval = usb_composite_register(&composite_drv);
+
+       if (retval)
+               return -EINVAL;
+       else
+               return 0;
+}
+
+static void __exit composite_exit(void)
+{
+       usb_composite_unregister(&composite_drv);
+
+       printk(KERN_INFO "composite_exit: %s %s unloaded\n",
+               COMPOSITE_DESC, COMPOSITE_VERSION);
+}
+module_init(composite_init);
+module_exit(composite_exit);

--
Best Regards,

Felipe Balbi
[EMAIL PROTECTED]

Nokia Institute of Technology - INdT
Kernel Developers Team

+55 92 2126 1003


-------------------------------------------------------------------------
Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net's Techsay panel and you'll get the chance to share your
opinions on IT & business topics through brief surveys-and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV
_______________________________________________
linux-usb-devel@lists.sourceforge.net
To unsubscribe, use the last form field at:
https://lists.sourceforge.net/lists/listinfo/linux-usb-devel

Reply via email to