mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-09-14 06:35:12 +00:00
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: Pavankumar Kondeti <pkondeti@codeaurora.org> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
This commit is contained in:
parent
e2b61c1df6
commit
541cace8cd
2 changed files with 51 additions and 6 deletions
|
@ -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)
|
||||||
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)
|
||||||
__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)
|
||||||
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 {
|
||||||
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 */
|
||||||
|
|
Loading…
Reference in a new issue