aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/avr32/mach-at32ap/at32ap700x.c50
-rw-r--r--drivers/usb/gadget/atmel_usba_udc.c71
-rw-r--r--include/asm-avr32/arch-at32ap/board.h4
-rw-r--r--include/linux/usb/atmel_usba_udc.h22
4 files changed, 105 insertions, 42 deletions
diff --git a/arch/avr32/mach-at32ap/at32ap700x.c b/arch/avr32/mach-at32ap/at32ap700x.c
index 7678fee9a88..cb47afc9fff 100644
--- a/arch/avr32/mach-at32ap/at32ap700x.c
+++ b/arch/avr32/mach-at32ap/at32ap700x.c
@@ -11,6 +11,7 @@
11#include <linux/platform_device.h> 11#include <linux/platform_device.h>
12#include <linux/dma-mapping.h> 12#include <linux/dma-mapping.h>
13#include <linux/spi/spi.h> 13#include <linux/spi/spi.h>
14#include <linux/usb/atmel_usba_udc.h>
14 15
15#include <asm/io.h> 16#include <asm/io.h>
16#include <asm/irq.h> 17#include <asm/irq.h>
@@ -1351,9 +1352,39 @@ static struct clk usba0_hclk = {
1351 .index = 6, 1352 .index = 6,
1352}; 1353};
1353 1354
1355#define EP(nam, idx, maxpkt, maxbk, dma, isoc) \
1356 [idx] = { \
1357 .name = nam, \
1358 .index = idx, \
1359 .fifo_size = maxpkt, \
1360 .nr_banks = maxbk, \
1361 .can_dma = dma, \
1362 .can_isoc = isoc, \
1363 }
1364
1365static struct usba_ep_data at32_usba_ep[] __initdata = {
1366 EP("ep0", 0, 64, 1, 0, 0),
1367 EP("ep1", 1, 512, 2, 1, 1),
1368 EP("ep2", 2, 512, 2, 1, 1),
1369 EP("ep3-int", 3, 64, 3, 1, 0),
1370 EP("ep4-int", 4, 64, 3, 1, 0),
1371 EP("ep5", 5, 1024, 3, 1, 1),
1372 EP("ep6", 6, 1024, 3, 1, 1),
1373};
1374
1375#undef EP
1376
1354struct platform_device *__init 1377struct platform_device *__init
1355at32_add_device_usba(unsigned int id, struct usba_platform_data *data) 1378at32_add_device_usba(unsigned int id, struct usba_platform_data *data)
1356{ 1379{
1380 /*
1381 * pdata doesn't have room for any endpoints, so we need to
1382 * append room for the ones we need right after it.
1383 */
1384 struct {
1385 struct usba_platform_data pdata;
1386 struct usba_ep_data ep[7];
1387 } usba_data;
1357 struct platform_device *pdev; 1388 struct platform_device *pdev;
1358 1389
1359 if (id != 0) 1390 if (id != 0)
@@ -1367,13 +1398,20 @@ at32_add_device_usba(unsigned int id, struct usba_platform_data *data)
1367 ARRAY_SIZE(usba0_resource))) 1398 ARRAY_SIZE(usba0_resource)))
1368 goto out_free_pdev; 1399 goto out_free_pdev;
1369 1400
1370 if (data) { 1401 if (data)
1371 if (platform_device_add_data(pdev, data, sizeof(*data))) 1402 usba_data.pdata.vbus_pin = data->vbus_pin;
1372 goto out_free_pdev; 1403 else
1404 usba_data.pdata.vbus_pin = -EINVAL;
1373 1405
1374 if (data->vbus_pin != GPIO_PIN_NONE) 1406 data = &usba_data.pdata;
1375 at32_select_gpio(data->vbus_pin, 0); 1407 data->num_ep = ARRAY_SIZE(at32_usba_ep);
1376 } 1408 memcpy(data->ep, at32_usba_ep, sizeof(at32_usba_ep));
1409
1410 if (platform_device_add_data(pdev, data, sizeof(usba_data)))
1411 goto out_free_pdev;
1412
1413 if (data->vbus_pin >= 0)
1414 at32_select_gpio(data->vbus_pin, 0);
1377 1415
1378 usba0_pclk.dev = &pdev->dev; 1416 usba0_pclk.dev = &pdev->dev;
1379 usba0_hclk.dev = &pdev->dev; 1417 usba0_hclk.dev = &pdev->dev;
diff --git a/drivers/usb/gadget/atmel_usba_udc.c b/drivers/usb/gadget/atmel_usba_udc.c
index 39d187fb038..71d3c5171f8 100644
--- a/drivers/usb/gadget/atmel_usba_udc.c
+++ b/drivers/usb/gadget/atmel_usba_udc.c
@@ -18,6 +18,7 @@
18#include <linux/platform_device.h> 18#include <linux/platform_device.h>
19#include <linux/usb/ch9.h> 19#include <linux/usb/ch9.h>
20#include <linux/usb/gadget.h> 20#include <linux/usb/gadget.h>
21#include <linux/usb/atmel_usba_udc.h>
21#include <linux/delay.h> 22#include <linux/delay.h>
22 23
23#include <asm/gpio.h> 24#include <asm/gpio.h>
@@ -27,6 +28,7 @@
27 28
28 29
29static struct usba_udc the_udc; 30static struct usba_udc the_udc;
31static struct usba_ep *usba_ep;
30 32
31#ifdef CONFIG_USB_GADGET_DEBUG_FS 33#ifdef CONFIG_USB_GADGET_DEBUG_FS
32#include <linux/debugfs.h> 34#include <linux/debugfs.h>
@@ -982,33 +984,6 @@ static const struct usb_gadget_ops usba_udc_ops = {
982 .set_selfpowered = usba_udc_set_selfpowered, 984 .set_selfpowered = usba_udc_set_selfpowered,
983}; 985};
984 986
985#define EP(nam, idx, maxpkt, maxbk, dma, isoc) \
986{ \
987 .ep = { \
988 .ops = &usba_ep_ops, \
989 .name = nam, \
990 .maxpacket = maxpkt, \
991 }, \
992 .udc = &the_udc, \
993 .queue = LIST_HEAD_INIT(usba_ep[idx].queue), \
994 .fifo_size = maxpkt, \
995 .nr_banks = maxbk, \
996 .index = idx, \
997 .can_dma = dma, \
998 .can_isoc = isoc, \
999}
1000
1001static struct usba_ep usba_ep[] = {
1002 EP("ep0", 0, 64, 1, 0, 0),
1003 EP("ep1", 1, 512, 2, 1, 1),
1004 EP("ep2", 2, 512, 2, 1, 1),
1005 EP("ep3-int", 3, 64, 3, 1, 0),
1006 EP("ep4-int", 4, 64, 3, 1, 0),
1007 EP("ep5", 5, 1024, 3, 1, 1),
1008 EP("ep6", 6, 1024, 3, 1, 1),
1009};
1010#undef EP
1011
1012static struct usb_endpoint_descriptor usba_ep0_desc = { 987static struct usb_endpoint_descriptor usba_ep0_desc = {
1013 .bLength = USB_DT_ENDPOINT_SIZE, 988 .bLength = USB_DT_ENDPOINT_SIZE,
1014 .bDescriptorType = USB_DT_ENDPOINT, 989 .bDescriptorType = USB_DT_ENDPOINT,
@@ -1027,7 +1002,6 @@ static void nop_release(struct device *dev)
1027static struct usba_udc the_udc = { 1002static struct usba_udc the_udc = {
1028 .gadget = { 1003 .gadget = {
1029 .ops = &usba_udc_ops, 1004 .ops = &usba_udc_ops,
1030 .ep0 = &usba_ep[0].ep,
1031 .ep_list = LIST_HEAD_INIT(the_udc.gadget.ep_list), 1005 .ep_list = LIST_HEAD_INIT(the_udc.gadget.ep_list),
1032 .is_dualspeed = 1, 1006 .is_dualspeed = 1,
1033 .name = "atmel_usba_udc", 1007 .name = "atmel_usba_udc",
@@ -1861,7 +1835,7 @@ static int __init usba_udc_probe(struct platform_device *pdev)
1861 1835
1862 regs = platform_get_resource(pdev, IORESOURCE_MEM, CTRL_IOMEM_ID); 1836 regs = platform_get_resource(pdev, IORESOURCE_MEM, CTRL_IOMEM_ID);
1863 fifo = platform_get_resource(pdev, IORESOURCE_MEM, FIFO_IOMEM_ID); 1837 fifo = platform_get_resource(pdev, IORESOURCE_MEM, FIFO_IOMEM_ID);
1864 if (!regs || !fifo) 1838 if (!regs || !fifo || !pdata)
1865 return -ENXIO; 1839 return -ENXIO;
1866 1840
1867 irq = platform_get_irq(pdev, 0); 1841 irq = platform_get_irq(pdev, 0);
@@ -1909,16 +1883,44 @@ static int __init usba_udc_probe(struct platform_device *pdev)
1909 usba_writel(udc, CTRL, 0); 1883 usba_writel(udc, CTRL, 0);
1910 clk_disable(pclk); 1884 clk_disable(pclk);
1911 1885
1886 usba_ep = kmalloc(sizeof(struct usba_ep) * pdata->num_ep,
1887 GFP_KERNEL);
1888 if (!usba_ep)
1889 goto err_alloc_ep;
1890
1891 the_udc.gadget.ep0 = &usba_ep[0].ep;
1892
1912 INIT_LIST_HEAD(&usba_ep[0].ep.ep_list); 1893 INIT_LIST_HEAD(&usba_ep[0].ep.ep_list);
1913 usba_ep[0].ep_regs = udc->regs + USBA_EPT_BASE(0); 1894 usba_ep[0].ep_regs = udc->regs + USBA_EPT_BASE(0);
1914 usba_ep[0].dma_regs = udc->regs + USBA_DMA_BASE(0); 1895 usba_ep[0].dma_regs = udc->regs + USBA_DMA_BASE(0);
1915 usba_ep[0].fifo = udc->fifo + USBA_FIFO_BASE(0); 1896 usba_ep[0].fifo = udc->fifo + USBA_FIFO_BASE(0);
1916 for (i = 1; i < ARRAY_SIZE(usba_ep); i++) { 1897 usba_ep[0].ep.ops = &usba_ep_ops;
1898 usba_ep[0].ep.name = pdata->ep[0].name;
1899 usba_ep[0].ep.maxpacket = pdata->ep[0].fifo_size;
1900 usba_ep[0].udc = &the_udc;
1901 INIT_LIST_HEAD(&usba_ep[0].queue);
1902 usba_ep[0].fifo_size = pdata->ep[0].fifo_size;
1903 usba_ep[0].nr_banks = pdata->ep[0].nr_banks;
1904 usba_ep[0].index = pdata->ep[0].index;
1905 usba_ep[0].can_dma = pdata->ep[0].can_dma;
1906 usba_ep[0].can_isoc = pdata->ep[0].can_isoc;
1907
1908 for (i = 1; i < pdata->num_ep; i++) {
1917 struct usba_ep *ep = &usba_ep[i]; 1909 struct usba_ep *ep = &usba_ep[i];
1918 1910
1919 ep->ep_regs = udc->regs + USBA_EPT_BASE(i); 1911 ep->ep_regs = udc->regs + USBA_EPT_BASE(i);
1920 ep->dma_regs = udc->regs + USBA_DMA_BASE(i); 1912 ep->dma_regs = udc->regs + USBA_DMA_BASE(i);
1921 ep->fifo = udc->fifo + USBA_FIFO_BASE(i); 1913 ep->fifo = udc->fifo + USBA_FIFO_BASE(i);
1914 ep->ep.ops = &usba_ep_ops;
1915 ep->ep.name = pdata->ep[i].name;
1916 ep->ep.maxpacket = pdata->ep[i].fifo_size;
1917 ep->udc = &the_udc;
1918 INIT_LIST_HEAD(&ep->queue);
1919 ep->fifo_size = pdata->ep[i].fifo_size;
1920 ep->nr_banks = pdata->ep[i].nr_banks;
1921 ep->index = pdata->ep[i].index;
1922 ep->can_dma = pdata->ep[i].can_dma;
1923 ep->can_isoc = pdata->ep[i].can_isoc;
1922 1924
1923 list_add_tail(&ep->ep.ep_list, &udc->gadget.ep_list); 1925 list_add_tail(&ep->ep.ep_list, &udc->gadget.ep_list);
1924 } 1926 }
@@ -1937,7 +1939,7 @@ static int __init usba_udc_probe(struct platform_device *pdev)
1937 goto err_device_add; 1939 goto err_device_add;
1938 } 1940 }
1939 1941
1940 if (pdata && pdata->vbus_pin >= 0) { 1942 if (pdata->vbus_pin >= 0) {
1941 if (!gpio_request(pdata->vbus_pin, "atmel_usba_udc")) { 1943 if (!gpio_request(pdata->vbus_pin, "atmel_usba_udc")) {
1942 udc->vbus_pin = pdata->vbus_pin; 1944 udc->vbus_pin = pdata->vbus_pin;
1943 1945
@@ -1957,7 +1959,7 @@ static int __init usba_udc_probe(struct platform_device *pdev)
1957 } 1959 }
1958 1960
1959 usba_init_debugfs(udc); 1961 usba_init_debugfs(udc);
1960 for (i = 1; i < ARRAY_SIZE(usba_ep); i++) 1962 for (i = 1; i < pdata->num_ep; i++)
1961 usba_ep_init_debugfs(udc, &usba_ep[i]); 1963 usba_ep_init_debugfs(udc, &usba_ep[i]);
1962 1964
1963 return 0; 1965 return 0;
@@ -1965,6 +1967,8 @@ static int __init usba_udc_probe(struct platform_device *pdev)
1965err_device_add: 1967err_device_add:
1966 free_irq(irq, udc); 1968 free_irq(irq, udc);
1967err_request_irq: 1969err_request_irq:
1970 kfree(usba_ep);
1971err_alloc_ep:
1968 iounmap(udc->fifo); 1972 iounmap(udc->fifo);
1969err_map_fifo: 1973err_map_fifo:
1970 iounmap(udc->regs); 1974 iounmap(udc->regs);
@@ -1982,10 +1986,11 @@ static int __exit usba_udc_remove(struct platform_device *pdev)
1982{ 1986{
1983 struct usba_udc *udc; 1987 struct usba_udc *udc;
1984 int i; 1988 int i;
1989 struct usba_platform_data *pdata = pdev->dev.platform_data;
1985 1990
1986 udc = platform_get_drvdata(pdev); 1991 udc = platform_get_drvdata(pdev);
1987 1992
1988 for (i = 1; i < ARRAY_SIZE(usba_ep); i++) 1993 for (i = 1; i < pdata->num_ep; i++)
1989 usba_ep_cleanup_debugfs(&usba_ep[i]); 1994 usba_ep_cleanup_debugfs(&usba_ep[i]);
1990 usba_cleanup_debugfs(udc); 1995 usba_cleanup_debugfs(udc);
1991 1996
diff --git a/include/asm-avr32/arch-at32ap/board.h b/include/asm-avr32/arch-at32ap/board.h
index 7597b0bd2f0..3fea2004f7d 100644
--- a/include/asm-avr32/arch-at32ap/board.h
+++ b/include/asm-avr32/arch-at32ap/board.h
@@ -38,9 +38,7 @@ struct platform_device *
38at32_add_device_lcdc(unsigned int id, struct atmel_lcdfb_info *data, 38at32_add_device_lcdc(unsigned int id, struct atmel_lcdfb_info *data,
39 unsigned long fbmem_start, unsigned long fbmem_len); 39 unsigned long fbmem_start, unsigned long fbmem_len);
40 40
41struct usba_platform_data { 41struct usba_platform_data;
42 int vbus_pin;
43};
44struct platform_device * 42struct platform_device *
45at32_add_device_usba(unsigned int id, struct usba_platform_data *data); 43at32_add_device_usba(unsigned int id, struct usba_platform_data *data);
46 44
diff --git a/include/linux/usb/atmel_usba_udc.h b/include/linux/usb/atmel_usba_udc.h
new file mode 100644
index 00000000000..6311fa2d9f8
--- /dev/null
+++ b/include/linux/usb/atmel_usba_udc.h
@@ -0,0 +1,22 @@
1/*
2 * Platform data definitions for Atmel USBA gadget driver.
3 */
4#ifndef __LINUX_USB_USBA_H
5#define __LINUX_USB_USBA_H
6
7struct usba_ep_data {
8 char *name;
9 int index;
10 int fifo_size;
11 int nr_banks;
12 int can_dma;
13 int can_isoc;
14};
15
16struct usba_platform_data {
17 int vbus_pin;
18 int num_ep;
19 struct usba_ep_data ep[0];
20};
21
22#endif /* __LINUX_USB_USBA_H */