aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorStelian Pop <stelian@popies.net>2008-03-04 18:00:00 -0500
committerHaavard Skinnemoen <haavard.skinnemoen@atmel.com>2008-04-06 17:15:08 -0400
commit8d855317fcf7fd9bd900d1e5ef1bea1b14bbe6af (patch)
tree50ac64812c3220088ea5b969ae07af7c1987ee5a
parent8d12c32c19a2719f6a96a23e94d95699c47e55d0 (diff)
atmel_usba_udc: move endpoint declarations into platform data.
The atmel_usba_udc driver is being used by several platforms and arches (avr32 and at91 ATM), and each platform may have different endpoint settings. The patch below moves the endpoint declarations into the platform data and make the necessary adjustments for AVR32 (improved by Haavard Skinnemoen <hskinnemoen@atmel.com>). Signed-off-by: Stelian Pop <stelian@popies.net> Acked-by: David Brownell <dbrownell@users.sourceforge.net> Signed-off-by: Haavard Skinnemoen <hskinnemoen@atmel.com>
-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 7678fee9a885..cb47afc9fffc 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 39d187fb038a..71d3c5171f89 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 7597b0bd2f01..3fea2004f7db 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 000000000000..6311fa2d9f82
--- /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 */