Introduce otg_version field in usb_gadget struct.  UDC can
advertise OTG spec version compatibility by setting otg_version
field appropriately.  Gadget drivers fill the bcdOTG field in
OTG descriptor based on UDC's OTG version.

Add sysfs file for host_request and UDC returns the same when
HNP polling request arrives from the host.

Signed-off-by: Pavankumar Kondeti <pkond...@codeaurora.org>
---
This patch changes only gadget Zero. But the final patch will
add OTG2.0 support for all the gadget drivers.

 .../testing/sysfs-devices-platform-_UDC_-gadget    |   14 +++++++++++
 drivers/usb/gadget/composite.c                     |   25 +++++++++++++++++++-
 drivers/usb/gadget/zero.c                          |    3 ++
 include/linux/usb/gadget.h                         |   21 ++++++++++++++++
 4 files changed, 62 insertions(+), 1 deletions(-)

diff --git a/Documentation/ABI/testing/sysfs-devices-platform-_UDC_-gadget 
b/Documentation/ABI/testing/sysfs-devices-platform-_UDC_-gadget
index d548eaa..9c622e4 100644
--- a/Documentation/ABI/testing/sysfs-devices-platform-_UDC_-gadget
+++ b/Documentation/ABI/testing/sysfs-devices-platform-_UDC_-gadget
@@ -19,3 +19,17 @@ Description:
                Possible values are:
                        1 -> ignore the FUA flag
                        0 -> obey the FUA flag
+
+What:          /sys/devices/platform/_UDC_/gadget/host_request
+Date:          December 2010
+Contact:       Pavan Kondeti <pkond...@codeaurora.org>
+Description:
+               OTG 2.0 compliant host keeps polling OTG2.0 peripheral
+               for host role. Set host_request flag, which tells host
+               to give up the host role to peripheral.
+
+               1 -> host role is requested
+               0 -> no effect (automatically cleared upon reset/disconnect)
+
+               (_UDC_ is the name of the USB Device Controller driver)
+
diff --git a/drivers/usb/gadget/composite.c b/drivers/usb/gadget/composite.c
index 21dc0da..f3a2023 100644
--- a/drivers/usb/gadget/composite.c
+++ b/drivers/usb/gadget/composite.c
@@ -978,6 +978,7 @@ static void composite_disconnect(struct usb_gadget *gadget)
        struct usb_composite_dev        *cdev = get_gadget_data(gadget);
        unsigned long                   flags;
 
+       gadget->host_request = 0;
        /* REVISIT:  should we have config and device level
         * disconnect callbacks?
         */
@@ -1003,6 +1004,23 @@ static ssize_t composite_show_suspended(struct device 
*dev,
 
 static DEVICE_ATTR(suspended, 0444, composite_show_suspended, NULL);
 
+static ssize_t composite_set_host_request(struct device *dev,
+                                       struct device_attribute *attr,
+                                       const char *buf, size_t count)
+{
+       struct usb_gadget *gadget = dev_to_usb_gadget(dev);
+       int value;
+
+       if (sscanf(buf, "%d", &value) != 1)
+               return -EINVAL;
+
+       gadget->host_request = !!value;
+       return count;
+
+}
+
+static DEVICE_ATTR(host_request, S_IWUSR, NULL, composite_set_host_request);
+
 static void
 composite_unbind(struct usb_gadget *gadget)
 {
@@ -1047,9 +1065,10 @@ composite_unbind(struct usb_gadget *gadget)
                kfree(cdev->req->buf);
                usb_ep_free_request(gadget->ep0, cdev->req);
        }
+       device_remove_file(&gadget->dev, &dev_attr_host_request);
+       device_remove_file(&gadget->dev, &dev_attr_suspended);
        kfree(cdev);
        set_gadget_data(gadget, NULL);
-       device_remove_file(&gadget->dev, &dev_attr_suspended);
        composite = NULL;
 }
 
@@ -1158,6 +1177,10 @@ static int composite_bind(struct usb_gadget *gadget)
        if (status)
                goto fail;
 
+       status = device_create_file(&gadget->dev, &dev_attr_host_request);
+       if (status)
+               DBG(cdev, "unable to create host_request sysfs file\n");
+
        INFO(cdev, "%s ready\n", composite->name);
        return 0;
 
diff --git a/drivers/usb/gadget/zero.c b/drivers/usb/gadget/zero.c
index 6d16db9..b4fb719 100644
--- a/drivers/usb/gadget/zero.c
+++ b/drivers/usb/gadget/zero.c
@@ -293,6 +293,9 @@ static int __init zero_bind(struct usb_composite_dev *cdev)
 
        setup_timer(&autoresume_timer, zero_autoresume, (unsigned long) cdev);
 
+       if (gadget_is_otg2(cdev->gadget))
+               otg_descriptor.bcdOTG = __constant_cpu_to_le16(0x0200);
+
        /* Register primary, then secondary configuration.  Note that
         * SH3 only allows one config...
         */
diff --git a/include/linux/usb/gadget.h b/include/linux/usb/gadget.h
index 006412c..b891257 100644
--- a/include/linux/usb/gadget.h
+++ b/include/linux/usb/gadget.h
@@ -443,6 +443,8 @@ struct usb_gadget_ops {
  *     operation.  If it does, the gadget driver must also support both.
  * @is_otg: True if the USB device port uses a Mini-AB jack, so that the
  *     gadget driver must provide a USB OTG descriptor.
+ * @otg_version: UDC OTG version based on which gadget driver fills the
+ *     bcdOTG field in a USB OTG descriptor.
  * @is_a_peripheral: False unless is_otg, the "A" end of a USB cable
  *     is in the Mini-AB jack, and HNP has been used to switch roles
  *     so that the "A" device currently acts as A-Peripheral, not A-Host.
@@ -452,6 +454,7 @@ struct usb_gadget_ops {
  *     only supports HNP on a different root port.
  * @b_hnp_enable: OTG device feature flag, indicating that the A-Host
  *     enabled HNP support.
+ * @host_request: A Flag, indicating that user wishes to take the host role.
  * @name: Identifies the controller hardware type.  Used in diagnostics
  *     and sometimes configuration.
  * @dev: Driver model state for this abstract device.
@@ -482,10 +485,14 @@ struct usb_gadget {
        enum usb_device_speed           speed;
        unsigned                        is_dualspeed:1;
        unsigned                        is_otg:1;
+       u16                             otg_version;
+#define        UDC_OTG1        0x0000
+#define        UDC_OTG2        0x0001
        unsigned                        is_a_peripheral:1;
        unsigned                        b_hnp_enable:1;
        unsigned                        a_hnp_support:1;
        unsigned                        a_alt_hnp_support:1;
+       unsigned                        host_request:1;
        const char                      *name;
        struct device                   dev;
 };
@@ -537,6 +544,20 @@ static inline int gadget_is_otg(struct usb_gadget *g)
 }
 
 /**
+ * gadget_is_otg2 - return true if UDC is compliant to OTG 2.0
+ * @g: controller that might have a Mini-AB/Micro-AB connector
+ *
+ */
+static inline int gadget_is_otg2(struct usb_gadget *g)
+{
+#ifdef CONFIG_USB_OTG
+       return g->otg_version && UDC_OTG2;
+#else
+       return 0;
+#endif
+}
+
+/**
  * usb_gadget_frame_number - returns the current frame number
  * @gadget: controller that reports the frame number
  *
-- 
1.7.1

--
Sent by a consultant of the Qualcomm Innovation Center, Inc.
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum.
--
To unsubscribe from this list: send the line "unsubscribe linux-arm-msm" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to