USB: gadget: Add OTG support for ci13xxx_udc
Add support for processing OTG feature requests like b_hnp_enable,
a_hnp_support, test mode features like otg_srp_reqd, otg_hnp_reqd and
HNP polling.
Change-Id: Icb2a8c32c3b566638e48d89bac1aeef453d0e8fa
Signed-off-by: Pavankumar Kondeti <pkondeti@codeaurora.org>
Signed-off-by: Vijayavardhan Vennapusa <vvreddy@codeaurora.org>
diff --git a/drivers/usb/gadget/ci13xxx_msm.c b/drivers/usb/gadget/ci13xxx_msm.c
index 8ea4632..fac777c 100644
--- a/drivers/usb/gadget/ci13xxx_msm.c
+++ b/drivers/usb/gadget/ci13xxx_msm.c
@@ -47,7 +47,8 @@
.flags = CI13XXX_REGS_SHARED |
CI13XXX_REQUIRE_TRANSCEIVER |
CI13XXX_PULLUP_ON_VBUS |
- CI13XXX_ZERO_ITC,
+ CI13XXX_ZERO_ITC |
+ CI13XXX_IS_OTG,
.notify_event = ci13xxx_msm_notify_event,
};
diff --git a/drivers/usb/gadget/ci13xxx_udc.c b/drivers/usb/gadget/ci13xxx_udc.c
index 0fc9a03..b64a38a 100644
--- a/drivers/usb/gadget/ci13xxx_udc.c
+++ b/drivers/usb/gadget/ci13xxx_udc.c
@@ -1918,6 +1918,11 @@
udc->configured = 0;
spin_unlock_irqrestore(udc->lock, flags);
+ gadget->b_hnp_enable = 0;
+ gadget->a_hnp_support = 0;
+ gadget->host_request = 0;
+ gadget->otg_srp_reqd = 0;
+
/* flush all endpoints */
gadget_for_each_ep(ep, gadget) {
usb_ep_fifo_flush(ep);
@@ -2046,8 +2051,15 @@
}
if ((setup->bRequestType & USB_RECIP_MASK) == USB_RECIP_DEVICE) {
- /* Assume that device is bus powered for now. */
- *((u16 *)req->buf) = _udc->remote_wakeup << 1;
+ if (setup->wIndex == OTG_STATUS_SELECTOR) {
+ *((u8 *)req->buf) = _udc->gadget.host_request <<
+ HOST_REQUEST_FLAG;
+ req->length = 1;
+ } else {
+ /* Assume that device is bus powered for now. */
+ *((u16 *)req->buf) = _udc->remote_wakeup << 1;
+ }
+ /* TODO: D1 - Remote Wakeup; D0 - Self Powered */
retval = 0;
} else if ((setup->bRequestType & USB_RECIP_MASK) \
== USB_RECIP_ENDPOINT) {
@@ -2297,8 +2309,7 @@
type != (USB_DIR_IN|USB_RECIP_ENDPOINT) &&
type != (USB_DIR_IN|USB_RECIP_INTERFACE))
goto delegate;
- if (le16_to_cpu(req.wLength) != 2 ||
- le16_to_cpu(req.wValue) != 0)
+ if (le16_to_cpu(req.wValue) != 0)
break;
err = isr_get_status_response(udc, &req);
break;
@@ -2342,6 +2353,16 @@
udc->remote_wakeup = 1;
err = isr_setup_status_phase(udc);
break;
+ case USB_DEVICE_B_HNP_ENABLE:
+ udc->gadget.b_hnp_enable = 1;
+ err = isr_setup_status_phase(udc);
+ break;
+ case USB_DEVICE_A_HNP_SUPPORT:
+ udc->gadget.a_hnp_support = 1;
+ err = isr_setup_status_phase(udc);
+ break;
+ case USB_DEVICE_A_ALT_HNP_SUPPORT:
+ break;
case USB_DEVICE_TEST_MODE:
tmode = le16_to_cpu(req.wIndex) >> 8;
switch (tmode) {
@@ -2354,11 +2375,21 @@
err = isr_setup_status_phase(
udc);
break;
+ case TEST_OTG_SRP_REQD:
+ udc->gadget.otg_srp_reqd = 1;
+ err = isr_setup_status_phase(
+ udc);
+ break;
+ case TEST_OTG_HNP_REQD:
+ udc->gadget.host_request = 1;
+ err = isr_setup_status_phase(
+ udc);
+ break;
default:
break;
}
default:
- goto delegate;
+ break;
}
} else {
goto delegate;
@@ -3206,7 +3237,10 @@
udc->gadget.ops = &usb_gadget_ops;
udc->gadget.speed = USB_SPEED_UNKNOWN;
udc->gadget.is_dualspeed = 1;
- udc->gadget.is_otg = 0;
+ if (udc->udc_driver->flags & CI13XXX_IS_OTG)
+ udc->gadget.is_otg = 1;
+ else
+ udc->gadget.is_otg = 0;
udc->gadget.name = driver->name;
INIT_LIST_HEAD(&udc->gadget.ep_list);
diff --git a/drivers/usb/gadget/ci13xxx_udc.h b/drivers/usb/gadget/ci13xxx_udc.h
index fce611a..13b54c7 100644
--- a/drivers/usb/gadget/ci13xxx_udc.h
+++ b/drivers/usb/gadget/ci13xxx_udc.h
@@ -125,6 +125,7 @@
#define CI13XXX_PULLUP_ON_VBUS BIT(2)
#define CI13XXX_DISABLE_STREAMING BIT(3)
#define CI13XXX_ZERO_ITC BIT(4)
+#define CI13XXX_IS_OTG BIT(5)
#define CI13XXX_CONTROLLER_RESET_EVENT 0
#define CI13XXX_CONTROLLER_CONNECT_EVENT 1