Skip to content

Commit

Permalink
atmel_usba_udc: move endpoint declarations into platform data.
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
stelian42 authored and Haavard Skinnemoen committed Apr 6, 2008
1 parent 8d12c32 commit 8d85531
Show file tree
Hide file tree
Showing 4 changed files with 105 additions and 42 deletions.
50 changes: 44 additions & 6 deletions arch/avr32/mach-at32ap/at32ap700x.c
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
#include <linux/platform_device.h>
#include <linux/dma-mapping.h>
#include <linux/spi/spi.h>
#include <linux/usb/atmel_usba_udc.h>

#include <asm/io.h>
#include <asm/irq.h>
Expand Down Expand Up @@ -1351,9 +1352,39 @@ static struct clk usba0_hclk = {
.index = 6,
};

#define EP(nam, idx, maxpkt, maxbk, dma, isoc) \
[idx] = { \
.name = nam, \
.index = idx, \
.fifo_size = maxpkt, \
.nr_banks = maxbk, \
.can_dma = dma, \
.can_isoc = isoc, \
}

static struct usba_ep_data at32_usba_ep[] __initdata = {
EP("ep0", 0, 64, 1, 0, 0),
EP("ep1", 1, 512, 2, 1, 1),
EP("ep2", 2, 512, 2, 1, 1),
EP("ep3-int", 3, 64, 3, 1, 0),
EP("ep4-int", 4, 64, 3, 1, 0),
EP("ep5", 5, 1024, 3, 1, 1),
EP("ep6", 6, 1024, 3, 1, 1),
};

#undef EP

struct platform_device *__init
at32_add_device_usba(unsigned int id, struct usba_platform_data *data)
{
/*
* pdata doesn't have room for any endpoints, so we need to
* append room for the ones we need right after it.
*/
struct {
struct usba_platform_data pdata;
struct usba_ep_data ep[7];
} usba_data;
struct platform_device *pdev;

if (id != 0)
Expand All @@ -1367,13 +1398,20 @@ at32_add_device_usba(unsigned int id, struct usba_platform_data *data)
ARRAY_SIZE(usba0_resource)))
goto out_free_pdev;

if (data) {
if (platform_device_add_data(pdev, data, sizeof(*data)))
goto out_free_pdev;
if (data)
usba_data.pdata.vbus_pin = data->vbus_pin;
else
usba_data.pdata.vbus_pin = -EINVAL;

if (data->vbus_pin != GPIO_PIN_NONE)
at32_select_gpio(data->vbus_pin, 0);
}
data = &usba_data.pdata;
data->num_ep = ARRAY_SIZE(at32_usba_ep);
memcpy(data->ep, at32_usba_ep, sizeof(at32_usba_ep));

if (platform_device_add_data(pdev, data, sizeof(usba_data)))
goto out_free_pdev;

if (data->vbus_pin >= 0)
at32_select_gpio(data->vbus_pin, 0);

usba0_pclk.dev = &pdev->dev;
usba0_hclk.dev = &pdev->dev;
Expand Down
71 changes: 38 additions & 33 deletions drivers/usb/gadget/atmel_usba_udc.c
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
#include <linux/platform_device.h>
#include <linux/usb/ch9.h>
#include <linux/usb/gadget.h>
#include <linux/usb/atmel_usba_udc.h>
#include <linux/delay.h>

#include <asm/gpio.h>
Expand All @@ -27,6 +28,7 @@


static struct usba_udc the_udc;
static struct usba_ep *usba_ep;

#ifdef CONFIG_USB_GADGET_DEBUG_FS
#include <linux/debugfs.h>
Expand Down Expand Up @@ -982,33 +984,6 @@ static const struct usb_gadget_ops usba_udc_ops = {
.set_selfpowered = usba_udc_set_selfpowered,
};

#define EP(nam, idx, maxpkt, maxbk, dma, isoc) \
{ \
.ep = { \
.ops = &usba_ep_ops, \
.name = nam, \
.maxpacket = maxpkt, \
}, \
.udc = &the_udc, \
.queue = LIST_HEAD_INIT(usba_ep[idx].queue), \
.fifo_size = maxpkt, \
.nr_banks = maxbk, \
.index = idx, \
.can_dma = dma, \
.can_isoc = isoc, \
}

static struct usba_ep usba_ep[] = {
EP("ep0", 0, 64, 1, 0, 0),
EP("ep1", 1, 512, 2, 1, 1),
EP("ep2", 2, 512, 2, 1, 1),
EP("ep3-int", 3, 64, 3, 1, 0),
EP("ep4-int", 4, 64, 3, 1, 0),
EP("ep5", 5, 1024, 3, 1, 1),
EP("ep6", 6, 1024, 3, 1, 1),
};
#undef EP

static struct usb_endpoint_descriptor usba_ep0_desc = {
.bLength = USB_DT_ENDPOINT_SIZE,
.bDescriptorType = USB_DT_ENDPOINT,
Expand All @@ -1027,7 +1002,6 @@ static void nop_release(struct device *dev)
static struct usba_udc the_udc = {
.gadget = {
.ops = &usba_udc_ops,
.ep0 = &usba_ep[0].ep,
.ep_list = LIST_HEAD_INIT(the_udc.gadget.ep_list),
.is_dualspeed = 1,
.name = "atmel_usba_udc",
Expand Down Expand Up @@ -1861,7 +1835,7 @@ static int __init usba_udc_probe(struct platform_device *pdev)

regs = platform_get_resource(pdev, IORESOURCE_MEM, CTRL_IOMEM_ID);
fifo = platform_get_resource(pdev, IORESOURCE_MEM, FIFO_IOMEM_ID);
if (!regs || !fifo)
if (!regs || !fifo || !pdata)
return -ENXIO;

irq = platform_get_irq(pdev, 0);
Expand Down Expand Up @@ -1909,16 +1883,44 @@ static int __init usba_udc_probe(struct platform_device *pdev)
usba_writel(udc, CTRL, 0);
clk_disable(pclk);

usba_ep = kmalloc(sizeof(struct usba_ep) * pdata->num_ep,
GFP_KERNEL);
if (!usba_ep)
goto err_alloc_ep;

the_udc.gadget.ep0 = &usba_ep[0].ep;

INIT_LIST_HEAD(&usba_ep[0].ep.ep_list);
usba_ep[0].ep_regs = udc->regs + USBA_EPT_BASE(0);
usba_ep[0].dma_regs = udc->regs + USBA_DMA_BASE(0);
usba_ep[0].fifo = udc->fifo + USBA_FIFO_BASE(0);
for (i = 1; i < ARRAY_SIZE(usba_ep); i++) {
usba_ep[0].ep.ops = &usba_ep_ops;
usba_ep[0].ep.name = pdata->ep[0].name;
usba_ep[0].ep.maxpacket = pdata->ep[0].fifo_size;
usba_ep[0].udc = &the_udc;
INIT_LIST_HEAD(&usba_ep[0].queue);
usba_ep[0].fifo_size = pdata->ep[0].fifo_size;
usba_ep[0].nr_banks = pdata->ep[0].nr_banks;
usba_ep[0].index = pdata->ep[0].index;
usba_ep[0].can_dma = pdata->ep[0].can_dma;
usba_ep[0].can_isoc = pdata->ep[0].can_isoc;

for (i = 1; i < pdata->num_ep; i++) {
struct usba_ep *ep = &usba_ep[i];

ep->ep_regs = udc->regs + USBA_EPT_BASE(i);
ep->dma_regs = udc->regs + USBA_DMA_BASE(i);
ep->fifo = udc->fifo + USBA_FIFO_BASE(i);
ep->ep.ops = &usba_ep_ops;
ep->ep.name = pdata->ep[i].name;
ep->ep.maxpacket = pdata->ep[i].fifo_size;
ep->udc = &the_udc;
INIT_LIST_HEAD(&ep->queue);
ep->fifo_size = pdata->ep[i].fifo_size;
ep->nr_banks = pdata->ep[i].nr_banks;
ep->index = pdata->ep[i].index;
ep->can_dma = pdata->ep[i].can_dma;
ep->can_isoc = pdata->ep[i].can_isoc;

list_add_tail(&ep->ep.ep_list, &udc->gadget.ep_list);
}
Expand All @@ -1937,7 +1939,7 @@ static int __init usba_udc_probe(struct platform_device *pdev)
goto err_device_add;
}

if (pdata && pdata->vbus_pin >= 0) {
if (pdata->vbus_pin >= 0) {
if (!gpio_request(pdata->vbus_pin, "atmel_usba_udc")) {
udc->vbus_pin = pdata->vbus_pin;

Expand All @@ -1957,14 +1959,16 @@ static int __init usba_udc_probe(struct platform_device *pdev)
}

usba_init_debugfs(udc);
for (i = 1; i < ARRAY_SIZE(usba_ep); i++)
for (i = 1; i < pdata->num_ep; i++)
usba_ep_init_debugfs(udc, &usba_ep[i]);

return 0;

err_device_add:
free_irq(irq, udc);
err_request_irq:
kfree(usba_ep);
err_alloc_ep:
iounmap(udc->fifo);
err_map_fifo:
iounmap(udc->regs);
Expand All @@ -1982,10 +1986,11 @@ static int __exit usba_udc_remove(struct platform_device *pdev)
{
struct usba_udc *udc;
int i;
struct usba_platform_data *pdata = pdev->dev.platform_data;

udc = platform_get_drvdata(pdev);

for (i = 1; i < ARRAY_SIZE(usba_ep); i++)
for (i = 1; i < pdata->num_ep; i++)
usba_ep_cleanup_debugfs(&usba_ep[i]);
usba_cleanup_debugfs(udc);

Expand Down
4 changes: 1 addition & 3 deletions include/asm-avr32/arch-at32ap/board.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,9 +38,7 @@ struct platform_device *
at32_add_device_lcdc(unsigned int id, struct atmel_lcdfb_info *data,
unsigned long fbmem_start, unsigned long fbmem_len);

struct usba_platform_data {
int vbus_pin;
};
struct usba_platform_data;
struct platform_device *
at32_add_device_usba(unsigned int id, struct usba_platform_data *data);

Expand Down
22 changes: 22 additions & 0 deletions include/linux/usb/atmel_usba_udc.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
/*
* Platform data definitions for Atmel USBA gadget driver.
*/
#ifndef __LINUX_USB_USBA_H
#define __LINUX_USB_USBA_H

struct usba_ep_data {
char *name;
int index;
int fifo_size;
int nr_banks;
int can_dma;
int can_isoc;
};

struct usba_platform_data {
int vbus_pin;
int num_ep;
struct usba_ep_data ep[0];
};

#endif /* __LINUX_USB_USBA_H */

0 comments on commit 8d85531

Please sign in to comment.