[PATCH 4/5] USB: msm72k_udc: Add Test Mode support

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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


[Index of Archives]     [Linux Media]     [Linux Input]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [Old Linux USB Devel Archive]

  Powered by Linux