summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFrank Gevaerts <frank@gevaerts.be>2008-02-26 18:02:26 +0000
committerFrank Gevaerts <frank@gevaerts.be>2008-02-26 18:02:26 +0000
commit97d7f39680ff973468c600d91ace1c7adf2773fd (patch)
treee4d5210ec4432103b4796491bd2c0dfcca24ea73
parenta36dbaa2c4c755c28269396f22b4b50dbfbb6e39 (diff)
downloadrockbox-97d7f39680ff973468c600d91ace1c7adf2773fd.zip
rockbox-97d7f39680ff973468c600d91ace1c7adf2773fd.tar.gz
rockbox-97d7f39680ff973468c600d91ace1c7adf2773fd.tar.bz2
rockbox-97d7f39680ff973468c600d91ace1c7adf2773fd.tar.xz
added support for USB port test modes, which are (a) required by the spec, and (b) needed for electrical (i.e. signal quality) testing
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@16427 a1c6a512-1295-4272-9138-f99709370657
-rw-r--r--firmware/export/usb_drv.h1
-rw-r--r--firmware/target/arm/usb-drv-pp502x.c25
-rw-r--r--firmware/usbstack/usb_core.c23
3 files changed, 43 insertions, 6 deletions
diff --git a/firmware/export/usb_drv.h b/firmware/export/usb_drv.h
index 430f03b..89eca01 100644
--- a/firmware/export/usb_drv.h
+++ b/firmware/export/usb_drv.h
@@ -36,5 +36,6 @@ void usb_drv_wait(int endpoint, bool send);
bool usb_drv_powered(void);
int usb_drv_port_speed(void);
void usb_drv_cancel_all_transfers(void);
+void usb_drv_set_test_mode(int mode);
#endif
diff --git a/firmware/target/arm/usb-drv-pp502x.c b/firmware/target/arm/usb-drv-pp502x.c
index 4b9199a..9241208 100644
--- a/firmware/target/arm/usb-drv-pp502x.c
+++ b/firmware/target/arm/usb-drv-pp502x.c
@@ -175,7 +175,7 @@
#define PORTSCX_PTC_DISABLE (0x00000000)
#define PORTSCX_PTC_JSTATE (0x00010000)
#define PORTSCX_PTC_KSTATE (0x00020000)
-#define PORTSCX_PTC_SEQNAK (0x00030000)
+#define PORTSCX_PTC_SE0NAK (0x00030000)
#define PORTSCX_PTC_PACKET (0x00040000)
#define PORTSCX_PTC_FORCE_EN (0x00050000)
#define PORTSCX_PTC_BIT_POS (16)
@@ -530,6 +530,29 @@ void usb_drv_reset_endpoint(int endpoint, bool send)
while (REG_ENDPTFLUSH & mask);
}
+void usb_drv_set_test_mode(int mode)
+{
+ switch(mode){
+ case 0:
+ REG_PORTSC1 &= ~PORTSCX_PORT_TEST_CTRL;
+ break;
+ case 1:
+ REG_PORTSC1 |= PORTSCX_PTC_JSTATE;
+ break;
+ case 2:
+ REG_PORTSC1 |= PORTSCX_PTC_KSTATE;
+ break;
+ case 3:
+ REG_PORTSC1 |= PORTSCX_PTC_SE0NAK;
+ break;
+ case 4:
+ REG_PORTSC1 |= PORTSCX_PTC_PACKET;
+ break;
+ case 5:
+ REG_PORTSC1 |= PORTSCX_PTC_FORCE_EN;
+ break;
+ }
+}
/*-------------------------------------------------------------------------*/
diff --git a/firmware/usbstack/usb_core.c b/firmware/usbstack/usb_core.c
index d7473e4..38797bc 100644
--- a/firmware/usbstack/usb_core.c
+++ b/firmware/usbstack/usb_core.c
@@ -571,11 +571,24 @@ static void usb_core_control_request_handler(struct usb_ctrlrequest* req)
case USB_REQ_SET_FEATURE:
logf("usb_core: SET_FEATURE");
- if (req->wValue)
- usb_drv_stall(req->wIndex & 0xf, true,(req->wIndex & 0x80) !=0);
- else
- usb_drv_stall(req->wIndex & 0xf, false,(req->wIndex & 0x80) !=0);
- ack_control(req);
+ switch(req->bRequestType & 0x0f){
+ case 0: /* Device */
+ if(req->wValue == 2) { /* TEST_MODE */
+ int mode=req->wIndex>>8;
+ ack_control(req);
+ usb_drv_set_test_mode(mode);
+ }
+ break;
+ case 2: /* Endpoint */
+ if (req->wValue)
+ usb_drv_stall(req->wIndex & 0xf, true,(req->wIndex & 0x80) !=0);
+ else
+ usb_drv_stall(req->wIndex & 0xf, false,(req->wIndex & 0x80) !=0);
+ ack_control(req);
+ break;
+ default:
+ break;
+ }
break;
case USB_REQ_SET_ADDRESS: {