aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBoris Brezillon <boris.brezillon@free-electrons.com>2015-01-14 11:22:02 -0500
committerNicolas Ferre <nicolas.ferre@atmel.com>2015-01-15 08:52:07 -0500
commitf0bceab4e3b528e799aba8fda8d2936fcfd41f1f (patch)
tree7093239025b63922fa6efff9f10834c9fcb8912d
parent422cde259ab62fcddcb3e50f44f761cf26982c1e (diff)
usb: gadget: at91_udc: Rework for multi-platform kernel support
cpu_is_at91xxx are a set of macros defined in mach/cpu.h and are here used to detect the SoC we are booting on. Use compatible string + a caps structure to replace those cpu_is_xxx tests. Remove all mach and asm headers (which are now unused). Signed-off-by: Boris Brezillon <boris.brezillon@free-electrons.com> Acked-by: Alexandre Belloni <alexandre.belloni@free-electrons.com> Acked-by: Felipe Balbi <balbi@ti.com> Signed-off-by: Nicolas Ferre <nicolas.ferre@atmel.com>
-rw-r--r--drivers/usb/gadget/udc/at91_udc.c288
-rw-r--r--drivers/usb/gadget/udc/at91_udc.h7
2 files changed, 218 insertions, 77 deletions
diff --git a/drivers/usb/gadget/udc/at91_udc.c b/drivers/usb/gadget/udc/at91_udc.c
index 4dba2c65dfd4..c0abb9bc76a9 100644
--- a/drivers/usb/gadget/udc/at91_udc.c
+++ b/drivers/usb/gadget/udc/at91_udc.c
@@ -31,16 +31,9 @@
31#include <linux/of.h> 31#include <linux/of.h>
32#include <linux/of_gpio.h> 32#include <linux/of_gpio.h>
33#include <linux/platform_data/atmel.h> 33#include <linux/platform_data/atmel.h>
34 34#include <linux/regmap.h>
35#include <asm/byteorder.h> 35#include <linux/mfd/syscon.h>
36#include <mach/hardware.h> 36#include <linux/mfd/syscon/atmel-matrix.h>
37#include <asm/io.h>
38#include <asm/irq.h>
39#include <asm/gpio.h>
40
41#include <mach/cpu.h>
42#include <mach/at91sam9261_matrix.h>
43#include <mach/at91_matrix.h>
44 37
45#include "at91_udc.h" 38#include "at91_udc.h"
46 39
@@ -915,8 +908,6 @@ static void clk_off(struct at91_udc *udc)
915 */ 908 */
916static void pullup(struct at91_udc *udc, int is_on) 909static void pullup(struct at91_udc *udc, int is_on)
917{ 910{
918 int active = !udc->board.pullup_active_low;
919
920 if (!udc->enabled || !udc->vbus) 911 if (!udc->enabled || !udc->vbus)
921 is_on = 0; 912 is_on = 0;
922 DBG("%sactive\n", is_on ? "" : "in"); 913 DBG("%sactive\n", is_on ? "" : "in");
@@ -925,40 +916,15 @@ static void pullup(struct at91_udc *udc, int is_on)
925 clk_on(udc); 916 clk_on(udc);
926 at91_udp_write(udc, AT91_UDP_ICR, AT91_UDP_RXRSM); 917 at91_udp_write(udc, AT91_UDP_ICR, AT91_UDP_RXRSM);
927 at91_udp_write(udc, AT91_UDP_TXVC, 0); 918 at91_udp_write(udc, AT91_UDP_TXVC, 0);
928 if (cpu_is_at91rm9200())
929 gpio_set_value(udc->board.pullup_pin, active);
930 else if (cpu_is_at91sam9260() || cpu_is_at91sam9263() || cpu_is_at91sam9g20()) {
931 u32 txvc = at91_udp_read(udc, AT91_UDP_TXVC);
932
933 txvc |= AT91_UDP_TXVC_PUON;
934 at91_udp_write(udc, AT91_UDP_TXVC, txvc);
935 } else if (cpu_is_at91sam9261() || cpu_is_at91sam9g10()) {
936 u32 usbpucr;
937
938 usbpucr = at91_matrix_read(AT91_MATRIX_USBPUCR);
939 usbpucr |= AT91_MATRIX_USBPUCR_PUON;
940 at91_matrix_write(AT91_MATRIX_USBPUCR, usbpucr);
941 }
942 } else { 919 } else {
943 stop_activity(udc); 920 stop_activity(udc);
944 at91_udp_write(udc, AT91_UDP_IDR, AT91_UDP_RXRSM); 921 at91_udp_write(udc, AT91_UDP_IDR, AT91_UDP_RXRSM);
945 at91_udp_write(udc, AT91_UDP_TXVC, AT91_UDP_TXVC_TXVDIS); 922 at91_udp_write(udc, AT91_UDP_TXVC, AT91_UDP_TXVC_TXVDIS);
946 if (cpu_is_at91rm9200())
947 gpio_set_value(udc->board.pullup_pin, !active);
948 else if (cpu_is_at91sam9260() || cpu_is_at91sam9263() || cpu_is_at91sam9g20()) {
949 u32 txvc = at91_udp_read(udc, AT91_UDP_TXVC);
950
951 txvc &= ~AT91_UDP_TXVC_PUON;
952 at91_udp_write(udc, AT91_UDP_TXVC, txvc);
953 } else if (cpu_is_at91sam9261() || cpu_is_at91sam9g10()) {
954 u32 usbpucr;
955
956 usbpucr = at91_matrix_read(AT91_MATRIX_USBPUCR);
957 usbpucr &= ~AT91_MATRIX_USBPUCR_PUON;
958 at91_matrix_write(AT91_MATRIX_USBPUCR, usbpucr);
959 }
960 clk_off(udc); 923 clk_off(udc);
961 } 924 }
925
926 if (udc->caps && udc->caps->pullup)
927 udc->caps->pullup(udc, is_on);
962} 928}
963 929
964/* vbus is here! turn everything on that's ready */ 930/* vbus is here! turn everything on that's ready */
@@ -1683,12 +1649,202 @@ static void at91udc_shutdown(struct platform_device *dev)
1683 spin_unlock_irqrestore(&udc->lock, flags); 1649 spin_unlock_irqrestore(&udc->lock, flags);
1684} 1650}
1685 1651
1686static void at91udc_of_init(struct at91_udc *udc, 1652static int at91rm9200_udc_init(struct at91_udc *udc)
1687 struct device_node *np) 1653{
1654 struct at91_ep *ep;
1655 int ret;
1656 int i;
1657
1658 for (i = 0; i < NUM_ENDPOINTS; i++) {
1659 ep = &udc->ep[i];
1660
1661 switch (i) {
1662 case 0:
1663 case 3:
1664 ep->maxpacket = 8;
1665 break;
1666 case 1 ... 2:
1667 ep->maxpacket = 64;
1668 break;
1669 case 4 ... 5:
1670 ep->maxpacket = 256;
1671 break;
1672 }
1673 }
1674
1675 if (!gpio_is_valid(udc->board.pullup_pin)) {
1676 DBG("no D+ pullup?\n");
1677 return -ENODEV;
1678 }
1679
1680 ret = devm_gpio_request(&udc->pdev->dev, udc->board.pullup_pin,
1681 "udc_pullup");
1682 if (ret) {
1683 DBG("D+ pullup is busy\n");
1684 return ret;
1685 }
1686
1687 gpio_direction_output(udc->board.pullup_pin,
1688 udc->board.pullup_active_low);
1689
1690 return 0;
1691}
1692
1693static void at91rm9200_udc_pullup(struct at91_udc *udc, int is_on)
1694{
1695 int active = !udc->board.pullup_active_low;
1696
1697 if (is_on)
1698 gpio_set_value(udc->board.pullup_pin, active);
1699 else
1700 gpio_set_value(udc->board.pullup_pin, !active);
1701}
1702
1703static const struct at91_udc_caps at91rm9200_udc_caps = {
1704 .init = at91rm9200_udc_init,
1705 .pullup = at91rm9200_udc_pullup,
1706};
1707
1708static int at91sam9260_udc_init(struct at91_udc *udc)
1709{
1710 struct at91_ep *ep;
1711 int i;
1712
1713 for (i = 0; i < NUM_ENDPOINTS; i++) {
1714 ep = &udc->ep[i];
1715
1716 switch (i) {
1717 case 0 ... 3:
1718 ep->maxpacket = 64;
1719 break;
1720 case 4 ... 5:
1721 ep->maxpacket = 512;
1722 break;
1723 }
1724 }
1725
1726 return 0;
1727}
1728
1729static void at91sam9260_udc_pullup(struct at91_udc *udc, int is_on)
1730{
1731 u32 txvc = at91_udp_read(udc, AT91_UDP_TXVC);
1732
1733 if (is_on)
1734 txvc |= AT91_UDP_TXVC_PUON;
1735 else
1736 txvc &= ~AT91_UDP_TXVC_PUON;
1737
1738 at91_udp_write(udc, AT91_UDP_TXVC, txvc);
1739}
1740
1741static const struct at91_udc_caps at91sam9260_udc_caps = {
1742 .init = at91sam9260_udc_init,
1743 .pullup = at91sam9260_udc_pullup,
1744};
1745
1746static int at91sam9261_udc_init(struct at91_udc *udc)
1747{
1748 struct at91_ep *ep;
1749 int i;
1750
1751 for (i = 0; i < NUM_ENDPOINTS; i++) {
1752 ep = &udc->ep[i];
1753
1754 switch (i) {
1755 case 0:
1756 ep->maxpacket = 8;
1757 break;
1758 case 1 ... 3:
1759 ep->maxpacket = 64;
1760 break;
1761 case 4 ... 5:
1762 ep->maxpacket = 256;
1763 break;
1764 }
1765 }
1766
1767 udc->matrix = syscon_regmap_lookup_by_phandle(udc->pdev->dev.of_node,
1768 "atmel,matrix");
1769 if (IS_ERR(udc->matrix))
1770 return PTR_ERR(udc->matrix);
1771
1772 return 0;
1773}
1774
1775static void at91sam9261_udc_pullup(struct at91_udc *udc, int is_on)
1776{
1777 u32 usbpucr = 0;
1778
1779 if (is_on)
1780 usbpucr = AT91_MATRIX_USBPUCR_PUON;
1781
1782 regmap_update_bits(udc->matrix, AT91SAM9261_MATRIX_USBPUCR,
1783 AT91_MATRIX_USBPUCR_PUON, usbpucr);
1784}
1785
1786static const struct at91_udc_caps at91sam9261_udc_caps = {
1787 .init = at91sam9261_udc_init,
1788 .pullup = at91sam9261_udc_pullup,
1789};
1790
1791static int at91sam9263_udc_init(struct at91_udc *udc)
1792{
1793 struct at91_ep *ep;
1794 int i;
1795
1796 for (i = 0; i < NUM_ENDPOINTS; i++) {
1797 ep = &udc->ep[i];
1798
1799 switch (i) {
1800 case 0:
1801 case 1:
1802 case 2:
1803 case 3:
1804 ep->maxpacket = 64;
1805 break;
1806 case 4:
1807 case 5:
1808 ep->maxpacket = 256;
1809 break;
1810 }
1811 }
1812
1813 return 0;
1814}
1815
1816static const struct at91_udc_caps at91sam9263_udc_caps = {
1817 .init = at91sam9263_udc_init,
1818 .pullup = at91sam9260_udc_pullup,
1819};
1820
1821static const struct of_device_id at91_udc_dt_ids[] = {
1822 {
1823 .compatible = "atmel,at91rm9200-udc",
1824 .data = &at91rm9200_udc_caps,
1825 },
1826 {
1827 .compatible = "atmel,at91sam9260-udc",
1828 .data = &at91sam9260_udc_caps,
1829 },
1830 {
1831 .compatible = "atmel,at91sam9261-udc",
1832 .data = &at91sam9261_udc_caps,
1833 },
1834 {
1835 .compatible = "atmel,at91sam9263-udc",
1836 .data = &at91sam9263_udc_caps,
1837 },
1838 { /* sentinel */ }
1839};
1840MODULE_DEVICE_TABLE(of, at91_udc_dt_ids);
1841
1842static void at91udc_of_init(struct at91_udc *udc, struct device_node *np)
1688{ 1843{
1689 struct at91_udc_data *board = &udc->board; 1844 struct at91_udc_data *board = &udc->board;
1690 u32 val; 1845 const struct of_device_id *match;
1691 enum of_gpio_flags flags; 1846 enum of_gpio_flags flags;
1847 u32 val;
1692 1848
1693 if (of_property_read_u32(np, "atmel,vbus-polled", &val) == 0) 1849 if (of_property_read_u32(np, "atmel,vbus-polled", &val) == 0)
1694 board->vbus_polled = 1; 1850 board->vbus_polled = 1;
@@ -1701,6 +1857,10 @@ static void at91udc_of_init(struct at91_udc *udc,
1701 &flags); 1857 &flags);
1702 1858
1703 board->pullup_active_low = (flags & OF_GPIO_ACTIVE_LOW) ? 1 : 0; 1859 board->pullup_active_low = (flags & OF_GPIO_ACTIVE_LOW) ? 1 : 0;
1860
1861 match = of_match_node(at91_udc_dt_ids, np);
1862 if (match)
1863 udc->caps = match->data;
1704} 1864}
1705 1865
1706static int at91udc_probe(struct platform_device *pdev) 1866static int at91udc_probe(struct platform_device *pdev)
@@ -1709,6 +1869,8 @@ static int at91udc_probe(struct platform_device *pdev)
1709 struct at91_udc *udc; 1869 struct at91_udc *udc;
1710 int retval; 1870 int retval;
1711 struct resource *res; 1871 struct resource *res;
1872 struct at91_ep *ep;
1873 int i;
1712 1874
1713 /* init software state */ 1875 /* init software state */
1714 udc = &controller; 1876 udc = &controller;
@@ -1718,40 +1880,19 @@ static int at91udc_probe(struct platform_device *pdev)
1718 udc->enabled = 0; 1880 udc->enabled = 0;
1719 spin_lock_init(&udc->lock); 1881 spin_lock_init(&udc->lock);
1720 1882
1721 /* rm9200 needs manual D+ pullup; off by default */
1722 if (cpu_is_at91rm9200()) {
1723 if (!gpio_is_valid(udc->board.pullup_pin)) {
1724 DBG("no D+ pullup?\n");
1725 return -ENODEV;
1726 }
1727 retval = devm_gpio_request(dev, udc->board.pullup_pin,
1728 "udc_pullup");
1729 if (retval) {
1730 DBG("D+ pullup is busy\n");
1731 return retval;
1732 }
1733 gpio_direction_output(udc->board.pullup_pin,
1734 udc->board.pullup_active_low);
1735 }
1736 1883
1737 /* newer chips have more FIFO memory than rm9200 */
1738 if (cpu_is_at91sam9260() || cpu_is_at91sam9g20()) {
1739 udc->ep[0].maxpacket = 64;
1740 udc->ep[3].maxpacket = 64;
1741 udc->ep[4].maxpacket = 512;
1742 udc->ep[5].maxpacket = 512;
1743 } else if (cpu_is_at91sam9261() || cpu_is_at91sam9g10()) {
1744 udc->ep[3].maxpacket = 64;
1745 } else if (cpu_is_at91sam9263()) {
1746 udc->ep[0].maxpacket = 64;
1747 udc->ep[3].maxpacket = 64;
1748 }
1749 1884
1750 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 1885 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
1751 udc->udp_baseaddr = devm_ioremap_resource(dev, res); 1886 udc->udp_baseaddr = devm_ioremap_resource(dev, res);
1752 if (IS_ERR(udc->udp_baseaddr)) 1887 if (IS_ERR(udc->udp_baseaddr))
1753 return PTR_ERR(udc->udp_baseaddr); 1888 return PTR_ERR(udc->udp_baseaddr);
1754 1889
1890 if (udc->caps && udc->caps->init) {
1891 retval = udc->caps->init(udc);
1892 if (retval)
1893 return retval;
1894 }
1895
1755 udc_reinit(udc); 1896 udc_reinit(udc);
1756 1897
1757 /* get interface and function clocks */ 1898 /* get interface and function clocks */
@@ -1920,13 +2061,6 @@ static int at91udc_resume(struct platform_device *pdev)
1920#define at91udc_resume NULL 2061#define at91udc_resume NULL
1921#endif 2062#endif
1922 2063
1923static const struct of_device_id at91_udc_dt_ids[] = {
1924 { .compatible = "atmel,at91rm9200-udc" },
1925 { /* sentinel */ }
1926};
1927
1928MODULE_DEVICE_TABLE(of, at91_udc_dt_ids);
1929
1930static struct platform_driver at91_udc_driver = { 2064static struct platform_driver at91_udc_driver = {
1931 .remove = __exit_p(at91udc_remove), 2065 .remove = __exit_p(at91udc_remove),
1932 .shutdown = at91udc_shutdown, 2066 .shutdown = at91udc_shutdown,
diff --git a/drivers/usb/gadget/udc/at91_udc.h b/drivers/usb/gadget/udc/at91_udc.h
index e647d1c2ada4..4fc0daa6587f 100644
--- a/drivers/usb/gadget/udc/at91_udc.h
+++ b/drivers/usb/gadget/udc/at91_udc.h
@@ -107,6 +107,11 @@ struct at91_ep {
107 unsigned fifo_bank:1; 107 unsigned fifo_bank:1;
108}; 108};
109 109
110struct at91_udc_caps {
111 int (*init)(struct at91_udc *udc);
112 void (*pullup)(struct at91_udc *udc, int is_on);
113};
114
110/* 115/*
111 * driver is non-SMP, and just blocks IRQs whenever it needs 116 * driver is non-SMP, and just blocks IRQs whenever it needs
112 * access protection for chip registers or driver state 117 * access protection for chip registers or driver state
@@ -115,6 +120,7 @@ struct at91_udc {
115 struct usb_gadget gadget; 120 struct usb_gadget gadget;
116 struct at91_ep ep[NUM_ENDPOINTS]; 121 struct at91_ep ep[NUM_ENDPOINTS];
117 struct usb_gadget_driver *driver; 122 struct usb_gadget_driver *driver;
123 const struct at91_udc_caps *caps;
118 unsigned vbus:1; 124 unsigned vbus:1;
119 unsigned enabled:1; 125 unsigned enabled:1;
120 unsigned clocked:1; 126 unsigned clocked:1;
@@ -134,6 +140,7 @@ struct at91_udc {
134 spinlock_t lock; 140 spinlock_t lock;
135 struct timer_list vbus_timer; 141 struct timer_list vbus_timer;
136 struct work_struct vbus_timer_work; 142 struct work_struct vbus_timer_work;
143 struct regmap *matrix;
137}; 144};
138 145
139static inline struct at91_udc *to_udc(struct usb_gadget *g) 146static inline struct at91_udc *to_udc(struct usb_gadget *g)