Commit 541cace8 authored by Pavankumar Kondeti's avatar Pavankumar Kondeti Committed by Greg Kroah-Hartman

USB: gadget: Add test mode support for ci13xxx_udc

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: default avatarPavankumar Kondeti <pkondeti@codeaurora.org>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@suse.de>
parent e2b61c1d
...@@ -1783,6 +1783,28 @@ __acquires(mEp->lock) ...@@ -1783,6 +1783,28 @@ __acquires(mEp->lock)
return retval; return retval;
} }
/**
* isr_setup_status_complete: setup_status request complete function
* @ep: endpoint
* @req: request handled
*
* Caller must release lock. Put the port in test mode if test mode
* feature is selected.
*/
static void
isr_setup_status_complete(struct usb_ep *ep, struct usb_request *req)
{
struct ci13xxx *udc = req->context;
unsigned long flags;
trace("%p, %p", ep, req);
spin_lock_irqsave(udc->lock, flags);
if (udc->test_mode)
hw_port_test_set(udc->test_mode);
spin_unlock_irqrestore(udc->lock, flags);
}
/** /**
* isr_setup_status_phase: queues the status phase of a setup transation * isr_setup_status_phase: queues the status phase of a setup transation
* @udc: udc struct * @udc: udc struct
...@@ -1799,6 +1821,8 @@ __acquires(mEp->lock) ...@@ -1799,6 +1821,8 @@ __acquires(mEp->lock)
trace("%p", udc); trace("%p", udc);
mEp = (udc->ep0_dir == TX) ? &udc->ep0out : &udc->ep0in; mEp = (udc->ep0_dir == TX) ? &udc->ep0out : &udc->ep0in;
udc->status->context = udc;
udc->status->complete = isr_setup_status_complete;
spin_unlock(mEp->lock); spin_unlock(mEp->lock);
retval = usb_ep_queue(&mEp->ep, udc->status, GFP_ATOMIC); retval = usb_ep_queue(&mEp->ep, udc->status, GFP_ATOMIC);
...@@ -1859,6 +1883,7 @@ __releases(udc->lock) ...@@ -1859,6 +1883,7 @@ __releases(udc->lock)
__acquires(udc->lock) __acquires(udc->lock)
{ {
unsigned i; unsigned i;
u8 tmode = 0;
trace("%p", udc); trace("%p", udc);
...@@ -1982,14 +2007,33 @@ __acquires(udc->lock) ...@@ -1982,14 +2007,33 @@ __acquires(udc->lock)
err = usb_ep_set_halt(&udc->ci13xxx_ep[num].ep); err = usb_ep_set_halt(&udc->ci13xxx_ep[num].ep);
spin_lock(udc->lock); spin_lock(udc->lock);
if (!err) if (!err)
err = isr_setup_status_phase(udc); isr_setup_status_phase(udc);
} else if (type == (USB_DIR_OUT|USB_RECIP_DEVICE) && } else if (type == (USB_DIR_OUT|USB_RECIP_DEVICE)) {
le16_to_cpu(req.wValue) ==
USB_DEVICE_REMOTE_WAKEUP) {
if (req.wLength != 0) if (req.wLength != 0)
break; break;
udc->remote_wakeup = 1; switch (le16_to_cpu(req.wValue)) {
err = isr_setup_status_phase(udc); case USB_DEVICE_REMOTE_WAKEUP:
udc->remote_wakeup = 1;
err = isr_setup_status_phase(udc);
break;
case USB_DEVICE_TEST_MODE:
tmode = le16_to_cpu(req.wIndex) >> 8;
switch (tmode) {
case TEST_J:
case TEST_K:
case TEST_SE0_NAK:
case TEST_PACKET:
case TEST_FORCE_EN:
udc->test_mode = tmode;
err = isr_setup_status_phase(
udc);
break;
default:
break;
}
default:
goto delegate;
}
} else { } else {
goto delegate; goto delegate;
} }
......
...@@ -131,6 +131,7 @@ struct ci13xxx { ...@@ -131,6 +131,7 @@ struct ci13xxx {
u8 remote_wakeup; /* Is remote wakeup feature u8 remote_wakeup; /* Is remote wakeup feature
enabled by the host? */ enabled by the host? */
u8 suspended; /* suspended by the host */ u8 suspended; /* suspended by the host */
u8 test_mode; /* the selected test mode */
struct usb_gadget_driver *driver; /* 3rd party gadget driver */ struct usb_gadget_driver *driver; /* 3rd party gadget driver */
struct ci13xxx_udc_driver *udc_driver; /* device controller driver */ struct ci13xxx_udc_driver *udc_driver; /* device controller driver */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment