diff options
author | Pavankumar Kondeti <pkondeti@codeaurora.org> | 2011-02-18 07:13:18 -0500 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2011-02-25 14:33:57 -0500 |
commit | 541cace8cd619808424ffaf1c8f7a006e5d55742 (patch) | |
tree | 9ef0990cbe067baad3b0e654ae5fd98db14d0030 /drivers/usb/gadget | |
parent | e2b61c1df650595d0216c6d086024b5a98d949c7 (diff) |
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>
Diffstat (limited to 'drivers/usb/gadget')
-rw-r--r-- | drivers/usb/gadget/ci13xxx_udc.c | 56 | ||||
-rw-r--r-- | drivers/usb/gadget/ci13xxx_udc.h | 1 |
2 files changed, 51 insertions, 6 deletions
diff --git a/drivers/usb/gadget/ci13xxx_udc.c b/drivers/usb/gadget/ci13xxx_udc.c index 17526759c9ce..e09178bc1450 100644 --- a/drivers/usb/gadget/ci13xxx_udc.c +++ b/drivers/usb/gadget/ci13xxx_udc.c | |||
@@ -1784,6 +1784,28 @@ __acquires(mEp->lock) | |||
1784 | } | 1784 | } |
1785 | 1785 | ||
1786 | /** | 1786 | /** |
1787 | * isr_setup_status_complete: setup_status request complete function | ||
1788 | * @ep: endpoint | ||
1789 | * @req: request handled | ||
1790 | * | ||
1791 | * Caller must release lock. Put the port in test mode if test mode | ||
1792 | * feature is selected. | ||
1793 | */ | ||
1794 | static void | ||
1795 | isr_setup_status_complete(struct usb_ep *ep, struct usb_request *req) | ||
1796 | { | ||
1797 | struct ci13xxx *udc = req->context; | ||
1798 | unsigned long flags; | ||
1799 | |||
1800 | trace("%p, %p", ep, req); | ||
1801 | |||
1802 | spin_lock_irqsave(udc->lock, flags); | ||
1803 | if (udc->test_mode) | ||
1804 | hw_port_test_set(udc->test_mode); | ||
1805 | spin_unlock_irqrestore(udc->lock, flags); | ||
1806 | } | ||
1807 | |||
1808 | /** | ||
1787 | * isr_setup_status_phase: queues the status phase of a setup transation | 1809 | * isr_setup_status_phase: queues the status phase of a setup transation |
1788 | * @udc: udc struct | 1810 | * @udc: udc struct |
1789 | * | 1811 | * |
@@ -1799,6 +1821,8 @@ __acquires(mEp->lock) | |||
1799 | trace("%p", udc); | 1821 | trace("%p", udc); |
1800 | 1822 | ||
1801 | mEp = (udc->ep0_dir == TX) ? &udc->ep0out : &udc->ep0in; | 1823 | mEp = (udc->ep0_dir == TX) ? &udc->ep0out : &udc->ep0in; |
1824 | udc->status->context = udc; | ||
1825 | udc->status->complete = isr_setup_status_complete; | ||
1802 | 1826 | ||
1803 | spin_unlock(mEp->lock); | 1827 | spin_unlock(mEp->lock); |
1804 | retval = usb_ep_queue(&mEp->ep, udc->status, GFP_ATOMIC); | 1828 | retval = usb_ep_queue(&mEp->ep, udc->status, GFP_ATOMIC); |
@@ -1859,6 +1883,7 @@ __releases(udc->lock) | |||
1859 | __acquires(udc->lock) | 1883 | __acquires(udc->lock) |
1860 | { | 1884 | { |
1861 | unsigned i; | 1885 | unsigned i; |
1886 | u8 tmode = 0; | ||
1862 | 1887 | ||
1863 | trace("%p", udc); | 1888 | trace("%p", udc); |
1864 | 1889 | ||
@@ -1982,14 +2007,33 @@ __acquires(udc->lock) | |||
1982 | err = usb_ep_set_halt(&udc->ci13xxx_ep[num].ep); | 2007 | err = usb_ep_set_halt(&udc->ci13xxx_ep[num].ep); |
1983 | spin_lock(udc->lock); | 2008 | spin_lock(udc->lock); |
1984 | if (!err) | 2009 | if (!err) |
1985 | err = isr_setup_status_phase(udc); | 2010 | isr_setup_status_phase(udc); |
1986 | } else if (type == (USB_DIR_OUT|USB_RECIP_DEVICE) && | 2011 | } else if (type == (USB_DIR_OUT|USB_RECIP_DEVICE)) { |
1987 | le16_to_cpu(req.wValue) == | ||
1988 | USB_DEVICE_REMOTE_WAKEUP) { | ||
1989 | if (req.wLength != 0) | 2012 | if (req.wLength != 0) |
1990 | break; | 2013 | break; |
1991 | udc->remote_wakeup = 1; | 2014 | switch (le16_to_cpu(req.wValue)) { |
1992 | err = isr_setup_status_phase(udc); | 2015 | case USB_DEVICE_REMOTE_WAKEUP: |
2016 | udc->remote_wakeup = 1; | ||
2017 | err = isr_setup_status_phase(udc); | ||
2018 | break; | ||
2019 | case USB_DEVICE_TEST_MODE: | ||
2020 | tmode = le16_to_cpu(req.wIndex) >> 8; | ||
2021 | switch (tmode) { | ||
2022 | case TEST_J: | ||
2023 | case TEST_K: | ||
2024 | case TEST_SE0_NAK: | ||
2025 | case TEST_PACKET: | ||
2026 | case TEST_FORCE_EN: | ||
2027 | udc->test_mode = tmode; | ||
2028 | err = isr_setup_status_phase( | ||
2029 | udc); | ||
2030 | break; | ||
2031 | default: | ||
2032 | break; | ||
2033 | } | ||
2034 | default: | ||
2035 | goto delegate; | ||
2036 | } | ||
1993 | } else { | 2037 | } else { |
1994 | goto delegate; | 2038 | goto delegate; |
1995 | } | 2039 | } |
diff --git a/drivers/usb/gadget/ci13xxx_udc.h b/drivers/usb/gadget/ci13xxx_udc.h index 6cfab20db6bd..23707775cb43 100644 --- a/drivers/usb/gadget/ci13xxx_udc.h +++ b/drivers/usb/gadget/ci13xxx_udc.h | |||
@@ -131,6 +131,7 @@ struct ci13xxx { | |||
131 | u8 remote_wakeup; /* Is remote wakeup feature | 131 | u8 remote_wakeup; /* Is remote wakeup feature |
132 | enabled by the host? */ | 132 | enabled by the host? */ |
133 | u8 suspended; /* suspended by the host */ | 133 | u8 suspended; /* suspended by the host */ |
134 | u8 test_mode; /* the selected test mode */ | ||
134 | 135 | ||
135 | struct usb_gadget_driver *driver; /* 3rd party gadget driver */ | 136 | struct usb_gadget_driver *driver; /* 3rd party gadget driver */ |
136 | struct ci13xxx_udc_driver *udc_driver; /* device controller driver */ | 137 | struct ci13xxx_udc_driver *udc_driver; /* device controller driver */ |