usb: add OTG descriptor for android gadget
authorWu, Hao <hao.wu@intel.com>
Thu, 15 Mar 2012 13:09:09 +0000 (21:09 +0800)
committerbuildbot <buildbot@intel.com>
Tue, 20 Mar 2012 23:49:59 +0000 (16:49 -0700)
BZ: 27547

Add USB OTG Descriptor for android gadget, as we need to
support USB OTG function (Both USB Host and Device mode).

Change-Id: I56c6543745777f7e851f77b78eea3e909844f42c
Signed-off-by: Wu, Hao <hao.wu@intel.com>
Reviewed-on: http://android.intel.com:8080/39255
Reviewed-by: Zhuang, Jin Can <jin.can.zhuang@intel.com>
Reviewed-by: Wang, Feng A <feng.a.wang@intel.com>
Reviewed-by: Li, Wenji <wenji.li@intel.com>
Reviewed-by: Tang, Richard <richard.tang@intel.com>
Reviewed-by: Meng, Zhe <zhe.meng@intel.com>
Tested-by: Meng, Zhe <zhe.meng@intel.com>
Reviewed-by: Gross, Mark <mark.gross@intel.com>
Reviewed-by: Saripalli, Ramakrishna <ramakrishna.saripalli@intel.com>
Reviewed-by: buildbot <buildbot@intel.com>
Tested-by: buildbot <buildbot@intel.com>
drivers/usb/gadget/android.c
drivers/usb/gadget/composite.c
include/linux/usb/ch9.h
include/linux/usb/composite.h

index af934c3..d15bbfc 100644 (file)
@@ -150,6 +150,17 @@ static struct usb_device_descriptor device_desc = {
        .bNumConfigurations   = 1,
 };
 
+static struct usb_otg_descriptor otg_descriptor = {
+       .bLength                = sizeof otg_descriptor,
+       .bDescriptorType        = USB_DT_OTG,
+       .bcdOTG                 = 0x0200, /* version 2.0 */
+};
+
+const struct usb_descriptor_header *otg_desc[] = {
+       (struct usb_descriptor_header *) &otg_descriptor,
+       NULL,
+};
+
 static struct usb_configuration android_config_driver = {
        .label          = "android",
        .unbind         = android_unbind_config,
@@ -960,6 +971,9 @@ static int android_bind_config(struct usb_configuration *c)
        struct android_dev *dev = _android_dev;
        int ret = 0;
 
+       if (gadget_is_otg(c->cdev->gadget))
+               c->descriptors = otg_desc;
+
        ret = android_bind_enabled_functions(dev, c);
        if (ret)
                return ret;
@@ -1064,6 +1078,9 @@ static int android_bind(struct usb_composite_dev *cdev)
                device_desc.bcdDevice = __constant_cpu_to_le16(0x9999);
        }
 
+       if (gadget_is_otg(gadget))
+               cdev->otg_desc = &otg_descriptor;
+
        usb_gadget_set_selfpowered(gadget);
        dev->cdev = cdev;
 
index 872ee01..b49246b 100644 (file)
@@ -966,6 +966,12 @@ composite_setup(struct usb_gadget *gadget, const struct usb_ctrlrequest *ctrl)
                        if (value >= 0)
                                value = min(w_length, (u16) value);
                        break;
+               case USB_DT_OTG:
+                       if (cdev->otg_desc) {
+                               memcpy(req->buf, cdev->otg_desc, w_length);
+                               value = w_length;
+                       }
+                       break;
                }
                break;
 
index 4b00afc..44e6903 100644 (file)
@@ -622,17 +622,19 @@ struct usb_qualifier_descriptor {
 
 /*-------------------------------------------------------------------------*/
 
-/* USB_DT_OTG (from OTG 1.0a supplement) */
+/* USB_DT_OTG (from OTG 2.0) */
 struct usb_otg_descriptor {
        __u8  bLength;
        __u8  bDescriptorType;
 
        __u8  bmAttributes;     /* support for HNP, SRP, etc */
+       __le16 bcdOTG;          /* release number, i.e, 2.0 is 0x0200 */
 } __attribute__ ((packed));
 
 /* from usb_otg_descriptor.bmAttributes */
 #define USB_OTG_SRP            (1 << 0)
 #define USB_OTG_HNP            (1 << 1)        /* swap host/device roles */
+#define USB_OTG_ADP            (1 << 2)        /* attachment detection */
 
 /*-------------------------------------------------------------------------*/
 
index 525f194..b9f5a65 100644 (file)
@@ -362,6 +362,9 @@ struct usb_composite_dev {
 
        /* protects deactivations and delayed_status counts*/
        spinlock_t                      lock;
+
+       /* OTG support */
+       struct usb_otg_descriptor       *otg_desc;
 };
 
 extern int usb_string_id(struct usb_composite_dev *c);