diff options
Diffstat (limited to 'drivers/usb')
-rw-r--r-- | drivers/usb/gadget/Kconfig | 4 | ||||
-rw-r--r-- | drivers/usb/gadget/atmel_usba_udc.c | 41 | ||||
-rw-r--r-- | drivers/usb/gadget/atmel_usba_udc.h | 9 |
3 files changed, 46 insertions, 8 deletions
diff --git a/drivers/usb/gadget/Kconfig b/drivers/usb/gadget/Kconfig index 6f45dd669b33..d681bb27fa58 100644 --- a/drivers/usb/gadget/Kconfig +++ b/drivers/usb/gadget/Kconfig | |||
@@ -118,10 +118,10 @@ config USB_AMD5536UDC | |||
118 | config USB_GADGET_ATMEL_USBA | 118 | config USB_GADGET_ATMEL_USBA |
119 | boolean "Atmel USBA" | 119 | boolean "Atmel USBA" |
120 | select USB_GADGET_DUALSPEED | 120 | select USB_GADGET_DUALSPEED |
121 | depends on AVR32 | 121 | depends on AVR32 || ARCH_AT91CAP9 |
122 | help | 122 | help |
123 | USBA is the integrated high-speed USB Device controller on | 123 | USBA is the integrated high-speed USB Device controller on |
124 | the AT32AP700x processors from Atmel. | 124 | the AT32AP700x and AT91CAP9 processors from Atmel. |
125 | 125 | ||
126 | config USB_ATMEL_USBA | 126 | config USB_ATMEL_USBA |
127 | tristate | 127 | tristate |
diff --git a/drivers/usb/gadget/atmel_usba_udc.c b/drivers/usb/gadget/atmel_usba_udc.c index ddb7301a0138..c9a3c2a462c4 100644 --- a/drivers/usb/gadget/atmel_usba_udc.c +++ b/drivers/usb/gadget/atmel_usba_udc.c | |||
@@ -326,6 +326,28 @@ static int vbus_is_present(struct usba_udc *udc) | |||
326 | return 1; | 326 | return 1; |
327 | } | 327 | } |
328 | 328 | ||
329 | #if defined(CONFIG_AVR32) | ||
330 | |||
331 | static void toggle_bias(int is_on) | ||
332 | { | ||
333 | } | ||
334 | |||
335 | #elif defined(CONFIG_ARCH_AT91) | ||
336 | |||
337 | #include <asm/arch/at91_pmc.h> | ||
338 | |||
339 | static void toggle_bias(int is_on) | ||
340 | { | ||
341 | unsigned int uckr = at91_sys_read(AT91_CKGR_UCKR); | ||
342 | |||
343 | if (is_on) | ||
344 | at91_sys_write(AT91_CKGR_UCKR, uckr | AT91_PMC_BIASEN); | ||
345 | else | ||
346 | at91_sys_write(AT91_CKGR_UCKR, uckr & ~(AT91_PMC_BIASEN)); | ||
347 | } | ||
348 | |||
349 | #endif /* CONFIG_ARCH_AT91 */ | ||
350 | |||
329 | static void next_fifo_transaction(struct usba_ep *ep, struct usba_request *req) | 351 | static void next_fifo_transaction(struct usba_ep *ep, struct usba_request *req) |
330 | { | 352 | { |
331 | unsigned int transaction_len; | 353 | unsigned int transaction_len; |
@@ -1457,7 +1479,7 @@ restart: | |||
1457 | DBG(DBG_HW, "Packet length: %u\n", pkt_len); | 1479 | DBG(DBG_HW, "Packet length: %u\n", pkt_len); |
1458 | if (pkt_len != sizeof(crq)) { | 1480 | if (pkt_len != sizeof(crq)) { |
1459 | pr_warning("udc: Invalid packet length %u " | 1481 | pr_warning("udc: Invalid packet length %u " |
1460 | "(expected %lu)\n", pkt_len, sizeof(crq)); | 1482 | "(expected %zu)\n", pkt_len, sizeof(crq)); |
1461 | set_protocol_stall(udc, ep); | 1483 | set_protocol_stall(udc, ep); |
1462 | return; | 1484 | return; |
1463 | } | 1485 | } |
@@ -1615,6 +1637,7 @@ static irqreturn_t usba_udc_irq(int irq, void *devid) | |||
1615 | DBG(DBG_INT, "irq, status=%#08x\n", status); | 1637 | DBG(DBG_INT, "irq, status=%#08x\n", status); |
1616 | 1638 | ||
1617 | if (status & USBA_DET_SUSPEND) { | 1639 | if (status & USBA_DET_SUSPEND) { |
1640 | toggle_bias(0); | ||
1618 | usba_writel(udc, INT_CLR, USBA_DET_SUSPEND); | 1641 | usba_writel(udc, INT_CLR, USBA_DET_SUSPEND); |
1619 | DBG(DBG_BUS, "Suspend detected\n"); | 1642 | DBG(DBG_BUS, "Suspend detected\n"); |
1620 | if (udc->gadget.speed != USB_SPEED_UNKNOWN | 1643 | if (udc->gadget.speed != USB_SPEED_UNKNOWN |
@@ -1626,6 +1649,7 @@ static irqreturn_t usba_udc_irq(int irq, void *devid) | |||
1626 | } | 1649 | } |
1627 | 1650 | ||
1628 | if (status & USBA_WAKE_UP) { | 1651 | if (status & USBA_WAKE_UP) { |
1652 | toggle_bias(1); | ||
1629 | usba_writel(udc, INT_CLR, USBA_WAKE_UP); | 1653 | usba_writel(udc, INT_CLR, USBA_WAKE_UP); |
1630 | DBG(DBG_BUS, "Wake Up CPU detected\n"); | 1654 | DBG(DBG_BUS, "Wake Up CPU detected\n"); |
1631 | } | 1655 | } |
@@ -1719,12 +1743,14 @@ static irqreturn_t usba_vbus_irq(int irq, void *devid) | |||
1719 | vbus = gpio_get_value(udc->vbus_pin); | 1743 | vbus = gpio_get_value(udc->vbus_pin); |
1720 | if (vbus != udc->vbus_prev) { | 1744 | if (vbus != udc->vbus_prev) { |
1721 | if (vbus) { | 1745 | if (vbus) { |
1722 | usba_writel(udc, CTRL, USBA_EN_USBA); | 1746 | toggle_bias(1); |
1747 | usba_writel(udc, CTRL, USBA_ENABLE_MASK); | ||
1723 | usba_writel(udc, INT_ENB, USBA_END_OF_RESET); | 1748 | usba_writel(udc, INT_ENB, USBA_END_OF_RESET); |
1724 | } else { | 1749 | } else { |
1725 | udc->gadget.speed = USB_SPEED_UNKNOWN; | 1750 | udc->gadget.speed = USB_SPEED_UNKNOWN; |
1726 | reset_all_endpoints(udc); | 1751 | reset_all_endpoints(udc); |
1727 | usba_writel(udc, CTRL, 0); | 1752 | toggle_bias(0); |
1753 | usba_writel(udc, CTRL, USBA_DISABLE_MASK); | ||
1728 | spin_unlock(&udc->lock); | 1754 | spin_unlock(&udc->lock); |
1729 | udc->driver->disconnect(&udc->gadget); | 1755 | udc->driver->disconnect(&udc->gadget); |
1730 | spin_lock(&udc->lock); | 1756 | spin_lock(&udc->lock); |
@@ -1777,7 +1803,8 @@ int usb_gadget_register_driver(struct usb_gadget_driver *driver) | |||
1777 | /* If Vbus is present, enable the controller and wait for reset */ | 1803 | /* If Vbus is present, enable the controller and wait for reset */ |
1778 | spin_lock_irqsave(&udc->lock, flags); | 1804 | spin_lock_irqsave(&udc->lock, flags); |
1779 | if (vbus_is_present(udc) && udc->vbus_prev == 0) { | 1805 | if (vbus_is_present(udc) && udc->vbus_prev == 0) { |
1780 | usba_writel(udc, CTRL, USBA_EN_USBA); | 1806 | toggle_bias(1); |
1807 | usba_writel(udc, CTRL, USBA_ENABLE_MASK); | ||
1781 | usba_writel(udc, INT_ENB, USBA_END_OF_RESET); | 1808 | usba_writel(udc, INT_ENB, USBA_END_OF_RESET); |
1782 | } | 1809 | } |
1783 | spin_unlock_irqrestore(&udc->lock, flags); | 1810 | spin_unlock_irqrestore(&udc->lock, flags); |
@@ -1810,7 +1837,8 @@ int usb_gadget_unregister_driver(struct usb_gadget_driver *driver) | |||
1810 | spin_unlock_irqrestore(&udc->lock, flags); | 1837 | spin_unlock_irqrestore(&udc->lock, flags); |
1811 | 1838 | ||
1812 | /* This will also disable the DP pullup */ | 1839 | /* This will also disable the DP pullup */ |
1813 | usba_writel(udc, CTRL, 0); | 1840 | toggle_bias(0); |
1841 | usba_writel(udc, CTRL, USBA_DISABLE_MASK); | ||
1814 | 1842 | ||
1815 | driver->unbind(&udc->gadget); | 1843 | driver->unbind(&udc->gadget); |
1816 | udc->gadget.dev.driver = NULL; | 1844 | udc->gadget.dev.driver = NULL; |
@@ -1880,7 +1908,8 @@ static int __init usba_udc_probe(struct platform_device *pdev) | |||
1880 | 1908 | ||
1881 | /* Make sure we start from a clean slate */ | 1909 | /* Make sure we start from a clean slate */ |
1882 | clk_enable(pclk); | 1910 | clk_enable(pclk); |
1883 | usba_writel(udc, CTRL, 0); | 1911 | toggle_bias(0); |
1912 | usba_writel(udc, CTRL, USBA_DISABLE_MASK); | ||
1884 | clk_disable(pclk); | 1913 | clk_disable(pclk); |
1885 | 1914 | ||
1886 | usba_ep = kmalloc(sizeof(struct usba_ep) * pdata->num_ep, | 1915 | usba_ep = kmalloc(sizeof(struct usba_ep) * pdata->num_ep, |
diff --git a/drivers/usb/gadget/atmel_usba_udc.h b/drivers/usb/gadget/atmel_usba_udc.h index 08bf6f9aaf7e..f7baea307f0d 100644 --- a/drivers/usb/gadget/atmel_usba_udc.h +++ b/drivers/usb/gadget/atmel_usba_udc.h | |||
@@ -41,6 +41,15 @@ | |||
41 | #define USBA_EN_USBA (1 << 8) | 41 | #define USBA_EN_USBA (1 << 8) |
42 | #define USBA_DETACH (1 << 9) | 42 | #define USBA_DETACH (1 << 9) |
43 | #define USBA_REMOTE_WAKE_UP (1 << 10) | 43 | #define USBA_REMOTE_WAKE_UP (1 << 10) |
44 | #define USBA_PULLD_DIS (1 << 11) | ||
45 | |||
46 | #if defined(CONFIG_AVR32) | ||
47 | #define USBA_ENABLE_MASK USBA_EN_USBA | ||
48 | #define USBA_DISABLE_MASK 0 | ||
49 | #elif defined(CONFIG_ARCH_AT91) | ||
50 | #define USBA_ENABLE_MASK (USBA_EN_USBA | USBA_PULLD_DIS) | ||
51 | #define USBA_DISABLE_MASK USBA_DETACH | ||
52 | #endif /* CONFIG_ARCH_AT91 */ | ||
44 | 53 | ||
45 | /* Bitfields in FNUM */ | 54 | /* Bitfields in FNUM */ |
46 | #define USBA_MICRO_FRAME_NUM_OFFSET 0 | 55 | #define USBA_MICRO_FRAME_NUM_OFFSET 0 |