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 <pkondeti@xxxxxxxxxxxxxx> Signed-off-by: Vamsi Krishna <vskrishn@xxxxxxxxxxxxxx> --- 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-usb" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html