Implement the test modes mentioned in 7.1.20 section of USB 2.0
specification.  High-speed capable devices must support these test
modes to facilitate compliance testing.

Signed-off-by: Pavankumar Kondeti <[email protected]>
Signed-off-by: Vamsi Krishna <[email protected]>
---
 drivers/usb/gadget/msm72k_udc.c  |   49 +++++++++++++++++++++++++++++++++++++-
 include/linux/usb/msm_hsusb_hw.h |   11 ++++++++
 2 files changed, 59 insertions(+), 1 deletions(-)

diff --git a/drivers/usb/gadget/msm72k_udc.c b/drivers/usb/gadget/msm72k_udc.c
index 9922d3d..dadb7c2 100644
--- a/drivers/usb/gadget/msm72k_udc.c
+++ b/drivers/usb/gadget/msm72k_udc.c
@@ -168,6 +168,7 @@ struct usb_info {
 
        unsigned int ep0_dir;
        u8 remote_wakeup;
+       u16 test_mode;
 };
 
 static const struct usb_ep_ops msm72k_ep_ops;
@@ -509,11 +510,47 @@ static void ep0_queue_ack_complete(struct usb_ep *ep, 
struct usb_request *req)
                ep0_complete(ep, req);
 }
 
+static void ep0_setup_ack_complete(struct usb_ep *ep, struct usb_request *req)
+{
+       struct msm_endpoint *ept = to_msm_endpoint(ep);
+       struct usb_info *ui = ept->ui;
+       unsigned int temp;
+
+       if (!ui->test_mode)
+               return;
+
+       switch (ui->test_mode) {
+       case J_TEST:
+               INFO("usb electrical test mode: (J)\n");
+               temp = readl(USB_PORTSC) & (~PORTSC_PTC);
+               writel(temp | PORTSC_PTC_J_STATE, USB_PORTSC);
+               break;
+
+       case K_TEST:
+               INFO("usb electrical test mode: (K)\n");
+               temp = readl(USB_PORTSC) & (~PORTSC_PTC);
+               writel(temp | PORTSC_PTC_K_STATE, USB_PORTSC);
+               break;
+
+       case SE0_NAK_TEST:
+               INFO("usb electrical test mode: (SE0-NAK)\n");
+               temp = readl(USB_PORTSC) & (~PORTSC_PTC);
+               writel(temp | PORTSC_PTC_SE0_NAK, USB_PORTSC);
+               break;
+
+       case TST_PKT_TEST:
+               INFO("usb electrical test mode: (TEST_PKT)\n");
+               temp = readl(USB_PORTSC) & (~PORTSC_PTC);
+               writel(temp | PORTSC_PTC_TST_PKT, USB_PORTSC);
+               break;
+       }
+}
+
 static void ep0_setup_ack(struct usb_info *ui)
 {
        struct usb_request *req = ui->setup_req;
        req->length = 0;
-       req->complete = 0;
+       req->complete = ep0_setup_ack_complete;
        usb_ept_queue_xfer(&ui->ep0in, req);
 }
 
@@ -635,6 +672,16 @@ static void handle_setup(struct usb_info *ui)
                        goto ack;
                } else if (ctl.bRequest == USB_REQ_SET_FEATURE) {
                        switch (ctl.wValue) {
+                       case USB_DEVICE_TEST_MODE:
+                               switch (ctl.wIndex) {
+                               case J_TEST:
+                               case K_TEST:
+                               case SE0_NAK_TEST:
+                               case TST_PKT_TEST:
+                                       ui->test_mode = ctl.wIndex;
+                                       goto ack;
+                               }
+                               goto stall;
                        case USB_DEVICE_REMOTE_WAKEUP:
                                ui->remote_wakeup = 1;
                                goto ack;
diff --git a/include/linux/usb/msm_hsusb_hw.h b/include/linux/usb/msm_hsusb_hw.h
index ae13342..22360c2 100644
--- a/include/linux/usb/msm_hsusb_hw.h
+++ b/include/linux/usb/msm_hsusb_hw.h
@@ -204,6 +204,17 @@ struct ept_queue_item {
 #define PORTSC_FPR             (1 << 6)
 #define PORTSC_SUSP            (1 << 7)
 
+/* test mode support */
+#define J_TEST                 (0x0100)
+#define K_TEST                 (0x0200)
+#define SE0_NAK_TEST           (0x0300)
+#define TST_PKT_TEST           (0x0400)
+#define PORTSC_PTC             (0xf << 16)
+#define PORTSC_PTC_J_STATE     (0x01 << 16)
+#define PORTSC_PTC_K_STATE     (0x02 << 16)
+#define PORTSC_PTC_SE0_NAK     (0x03 << 16)
+#define PORTSC_PTC_TST_PKT     (0x04 << 16)
+
 #define PORTSC_PTS_MASK       (3 << 30)
 #define PORTSC_PTS_ULPI       (2 << 30)
 #define PORTSC_PTS_SERIAL     (3 << 30)
-- 
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 [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to