Commit 64cfd3f9645bebdadd4c867db5efcf8b7a568f77

Authored by Kuo-Jung Su
Committed by Marek Vasut
1 parent e82a316d7f

usb: gadget: add Faraday FOTG210 USB gadget support

The Faraday FOTG210 is an OTG chip which could operate
as either an EHCI Host or a USB Device at a time.

Signed-off-by: Kuo-Jung Su <dantesu@faraday-tech.com>
CC: Marek Vasut <marex@denx.de>

Showing 3 changed files with 957 additions and 0 deletions Side-by-side Diff

drivers/usb/gadget/Makefile
... ... @@ -35,6 +35,7 @@
35 35 # new USB gadget layer dependencies
36 36 ifdef CONFIG_USB_GADGET
37 37 COBJS-$(CONFIG_USB_GADGET_S3C_UDC_OTG) += s3c_udc_otg.o
  38 +COBJS-$(CONFIG_USB_GADGET_FOTG210) += fotg210.o
38 39 COBJS-$(CONFIG_USBDOWNLOAD_GADGET) += g_dnl.o
39 40 COBJS-$(CONFIG_DFU_FUNCTION) += f_dfu.o
40 41 endif
drivers/usb/gadget/fotg210.c
  1 +/*
  2 + * Faraday USB 2.0 OTG Controller
  3 + *
  4 + * (C) Copyright 2010 Faraday Technology
  5 + * Dante Su <dantesu@faraday-tech.com>
  6 + *
  7 + * This file is released under the terms of GPL v2 and any later version.
  8 + * See the file COPYING in the root directory of the source tree for details.
  9 + */
  10 +
  11 +#include <common.h>
  12 +#include <command.h>
  13 +#include <config.h>
  14 +#include <net.h>
  15 +#include <malloc.h>
  16 +#include <asm/io.h>
  17 +#include <asm/errno.h>
  18 +#include <linux/types.h>
  19 +#include <linux/usb/ch9.h>
  20 +#include <linux/usb/gadget.h>
  21 +
  22 +#include <usb/fotg210.h>
  23 +
  24 +#define CFG_NUM_ENDPOINTS 4
  25 +#define CFG_EP0_MAX_PACKET_SIZE 64
  26 +#define CFG_EPX_MAX_PACKET_SIZE 512
  27 +
  28 +#define CFG_CMD_TIMEOUT (CONFIG_SYS_HZ >> 2) /* 250 ms */
  29 +
  30 +struct fotg210_chip;
  31 +
  32 +struct fotg210_ep {
  33 + struct usb_ep ep;
  34 +
  35 + uint maxpacket;
  36 + uint id;
  37 + uint stopped;
  38 +
  39 + struct list_head queue;
  40 + struct fotg210_chip *chip;
  41 + const struct usb_endpoint_descriptor *desc;
  42 +};
  43 +
  44 +struct fotg210_request {
  45 + struct usb_request req;
  46 + struct list_head queue;
  47 + struct fotg210_ep *ep;
  48 +};
  49 +
  50 +struct fotg210_chip {
  51 + struct usb_gadget gadget;
  52 + struct usb_gadget_driver *driver;
  53 + struct fotg210_regs *regs;
  54 + uint8_t irq;
  55 + uint16_t addr;
  56 + int pullup;
  57 + enum usb_device_state state;
  58 + struct fotg210_ep ep[1 + CFG_NUM_ENDPOINTS];
  59 +};
  60 +
  61 +static struct usb_endpoint_descriptor ep0_desc = {
  62 + .bLength = sizeof(struct usb_endpoint_descriptor),
  63 + .bDescriptorType = USB_DT_ENDPOINT,
  64 + .bEndpointAddress = USB_DIR_IN,
  65 + .bmAttributes = USB_ENDPOINT_XFER_CONTROL,
  66 +};
  67 +
  68 +static inline int fifo_to_ep(struct fotg210_chip *chip, int id, int in)
  69 +{
  70 + return (id < 0) ? 0 : ((id & 0x03) + 1);
  71 +}
  72 +
  73 +static inline int ep_to_fifo(struct fotg210_chip *chip, int id)
  74 +{
  75 + return (id <= 0) ? -1 : ((id - 1) & 0x03);
  76 +}
  77 +
  78 +static inline int ep_reset(struct fotg210_chip *chip, uint8_t ep_addr)
  79 +{
  80 + int ep = ep_addr & USB_ENDPOINT_NUMBER_MASK;
  81 + struct fotg210_regs *regs = chip->regs;
  82 +
  83 + if (ep_addr & USB_DIR_IN) {
  84 + /* reset endpoint */
  85 + setbits_le32(&regs->iep[ep - 1], IEP_RESET);
  86 + mdelay(1);
  87 + clrbits_le32(&regs->iep[ep - 1], IEP_RESET);
  88 + /* clear endpoint stall */
  89 + clrbits_le32(&regs->iep[ep - 1], IEP_STALL);
  90 + } else {
  91 + /* reset endpoint */
  92 + setbits_le32(&regs->oep[ep - 1], OEP_RESET);
  93 + mdelay(1);
  94 + clrbits_le32(&regs->oep[ep - 1], OEP_RESET);
  95 + /* clear endpoint stall */
  96 + clrbits_le32(&regs->oep[ep - 1], OEP_STALL);
  97 + }
  98 +
  99 + return 0;
  100 +}
  101 +
  102 +static int fotg210_reset(struct fotg210_chip *chip)
  103 +{
  104 + struct fotg210_regs *regs = chip->regs;
  105 + uint32_t i;
  106 +
  107 + chip->state = USB_STATE_POWERED;
  108 +
  109 + /* chip enable */
  110 + writel(DEVCTRL_EN, &regs->dev_ctrl);
  111 +
  112 + /* device address reset */
  113 + chip->addr = 0;
  114 + writel(0, &regs->dev_addr);
  115 +
  116 + /* set idle counter to 7ms */
  117 + writel(7, &regs->idle);
  118 +
  119 + /* disable all interrupts */
  120 + writel(IMR_MASK, &regs->imr);
  121 + writel(GIMR_MASK, &regs->gimr);
  122 + writel(GIMR0_MASK, &regs->gimr0);
  123 + writel(GIMR1_MASK, &regs->gimr1);
  124 + writel(GIMR2_MASK, &regs->gimr2);
  125 +
  126 + /* clear interrupts */
  127 + writel(ISR_MASK, &regs->isr);
  128 + writel(0, &regs->gisr);
  129 + writel(0, &regs->gisr0);
  130 + writel(0, &regs->gisr1);
  131 + writel(0, &regs->gisr2);
  132 +
  133 + /* chip reset */
  134 + setbits_le32(&regs->dev_ctrl, DEVCTRL_RESET);
  135 + mdelay(10);
  136 + if (readl(&regs->dev_ctrl) & DEVCTRL_RESET) {
  137 + printf("fotg210: chip reset failed\n");
  138 + return -1;
  139 + }
  140 +
  141 + /* CX FIFO reset */
  142 + setbits_le32(&regs->cxfifo, CXFIFO_CXFIFOCLR);
  143 + mdelay(10);
  144 + if (readl(&regs->cxfifo) & CXFIFO_CXFIFOCLR) {
  145 + printf("fotg210: ep0 fifo reset failed\n");
  146 + return -1;
  147 + }
  148 +
  149 + /* create static ep-fifo map (EP1 <-> FIFO0, EP2 <-> FIFO1 ...) */
  150 + writel(EPMAP14_DEFAULT, &regs->epmap14);
  151 + writel(EPMAP58_DEFAULT, &regs->epmap58);
  152 + writel(FIFOMAP_DEFAULT, &regs->fifomap);
  153 + writel(0, &regs->fifocfg);
  154 + for (i = 0; i < 8; ++i) {
  155 + writel(CFG_EPX_MAX_PACKET_SIZE, &regs->iep[i]);
  156 + writel(CFG_EPX_MAX_PACKET_SIZE, &regs->oep[i]);
  157 + }
  158 +
  159 + /* FIFO reset */
  160 + for (i = 0; i < 4; ++i) {
  161 + writel(FIFOCSR_RESET, &regs->fifocsr[i]);
  162 + mdelay(10);
  163 + if (readl(&regs->fifocsr[i]) & FIFOCSR_RESET) {
  164 + printf("fotg210: fifo%d reset failed\n", i);
  165 + return -1;
  166 + }
  167 + }
  168 +
  169 + /* enable only device interrupt and triggered at level-high */
  170 + writel(IMR_IRQLH | IMR_HOST | IMR_OTG, &regs->imr);
  171 + writel(ISR_MASK, &regs->isr);
  172 + /* disable EP0 IN/OUT interrupt */
  173 + writel(GIMR0_CXOUT | GIMR0_CXIN, &regs->gimr0);
  174 + /* disable EPX IN+SPK+OUT interrupts */
  175 + writel(GIMR1_MASK, &regs->gimr1);
  176 + /* disable wakeup+idle+dma+zlp interrupts */
  177 + writel(GIMR2_WAKEUP | GIMR2_IDLE | GIMR2_DMAERR | GIMR2_DMAFIN
  178 + | GIMR2_ZLPRX | GIMR2_ZLPTX, &regs->gimr2);
  179 + /* enable all group interrupt */
  180 + writel(0, &regs->gimr);
  181 +
  182 + /* suspend delay = 3 ms */
  183 + writel(3, &regs->idle);
  184 +
  185 + /* turn-on device interrupts */
  186 + setbits_le32(&regs->dev_ctrl, DEVCTRL_GIRQ_EN);
  187 +
  188 + return 0;
  189 +}
  190 +
  191 +static inline int fotg210_cxwait(struct fotg210_chip *chip, uint32_t mask)
  192 +{
  193 + struct fotg210_regs *regs = chip->regs;
  194 + int ret = -1;
  195 + ulong ts;
  196 +
  197 + for (ts = get_timer(0); get_timer(ts) < CFG_CMD_TIMEOUT; ) {
  198 + if ((readl(&regs->cxfifo) & mask) != mask)
  199 + continue;
  200 + ret = 0;
  201 + break;
  202 + }
  203 +
  204 + if (ret)
  205 + printf("fotg210: cx/ep0 timeout\n");
  206 +
  207 + return ret;
  208 +}
  209 +
  210 +static int fotg210_dma(struct fotg210_ep *ep, struct fotg210_request *req)
  211 +{
  212 + struct fotg210_chip *chip = ep->chip;
  213 + struct fotg210_regs *regs = chip->regs;
  214 + uint32_t tmp, ts;
  215 + uint8_t *buf = req->req.buf + req->req.actual;
  216 + uint32_t len = req->req.length - req->req.actual;
  217 + int fifo = ep_to_fifo(chip, ep->id);
  218 + int ret = -EBUSY;
  219 +
  220 + /* 1. init dma buffer */
  221 + if (len > ep->maxpacket)
  222 + len = ep->maxpacket;
  223 +
  224 + /* 2. wait for dma ready (hardware) */
  225 + for (ts = get_timer(0); get_timer(ts) < CFG_CMD_TIMEOUT; ) {
  226 + if (!(readl(&regs->dma_ctrl) & DMACTRL_START)) {
  227 + ret = 0;
  228 + break;
  229 + }
  230 + }
  231 + if (ret) {
  232 + printf("fotg210: dma busy\n");
  233 + req->req.status = ret;
  234 + return ret;
  235 + }
  236 +
  237 + /* 3. DMA target setup */
  238 + if (ep->desc->bEndpointAddress & USB_DIR_IN)
  239 + flush_dcache_range((ulong)buf, (ulong)buf + len);
  240 + else
  241 + invalidate_dcache_range((ulong)buf, (ulong)buf + len);
  242 +
  243 + writel(virt_to_phys(buf), &regs->dma_addr);
  244 +
  245 + if (ep->desc->bEndpointAddress & USB_DIR_IN) {
  246 + if (ep->id == 0) {
  247 + /* Wait until cx/ep0 fifo empty */
  248 + fotg210_cxwait(chip, CXFIFO_CXFIFOE);
  249 + writel(DMAFIFO_CX, &regs->dma_fifo);
  250 + } else {
  251 + /* Wait until epx fifo empty */
  252 + fotg210_cxwait(chip, CXFIFO_FIFOE(fifo));
  253 + writel(DMAFIFO_FIFO(fifo), &regs->dma_fifo);
  254 + }
  255 + writel(DMACTRL_LEN(len) | DMACTRL_MEM2FIFO, &regs->dma_ctrl);
  256 + } else {
  257 + uint32_t blen;
  258 +
  259 + if (ep->id == 0) {
  260 + writel(DMAFIFO_CX, &regs->dma_fifo);
  261 + do {
  262 + blen = CXFIFO_BYTES(readl(&regs->cxfifo));
  263 + } while (blen < len);
  264 + } else {
  265 + writel(DMAFIFO_FIFO(fifo), &regs->dma_fifo);
  266 + blen = FIFOCSR_BYTES(readl(&regs->fifocsr[fifo]));
  267 + }
  268 + len = (len < blen) ? len : blen;
  269 + writel(DMACTRL_LEN(len) | DMACTRL_FIFO2MEM, &regs->dma_ctrl);
  270 + }
  271 +
  272 + /* 4. DMA start */
  273 + setbits_le32(&regs->dma_ctrl, DMACTRL_START);
  274 +
  275 + /* 5. DMA wait */
  276 + ret = -EBUSY;
  277 + for (ts = get_timer(0); get_timer(ts) < CFG_CMD_TIMEOUT; ) {
  278 + tmp = readl(&regs->gisr2);
  279 + /* DMA complete */
  280 + if (tmp & GISR2_DMAFIN) {
  281 + ret = 0;
  282 + break;
  283 + }
  284 + /* DMA error */
  285 + if (tmp & GISR2_DMAERR) {
  286 + printf("fotg210: dma error\n");
  287 + break;
  288 + }
  289 + /* resume, suspend, reset */
  290 + if (tmp & (GISR2_RESUME | GISR2_SUSPEND | GISR2_RESET)) {
  291 + printf("fotg210: dma reset by host\n");
  292 + break;
  293 + }
  294 + }
  295 +
  296 + /* 7. DMA target reset */
  297 + if (ret)
  298 + writel(DMACTRL_ABORT | DMACTRL_CLRFF, &regs->dma_ctrl);
  299 +
  300 + writel(0, &regs->gisr2);
  301 + writel(0, &regs->dma_fifo);
  302 +
  303 + req->req.status = ret;
  304 + if (!ret)
  305 + req->req.actual += len;
  306 + else
  307 + printf("fotg210: ep%d dma error(code=%d)\n", ep->id, ret);
  308 +
  309 + return len;
  310 +}
  311 +
  312 +/*
  313 + * result of setup packet
  314 + */
  315 +#define CX_IDLE 0
  316 +#define CX_FINISH 1
  317 +#define CX_STALL 2
  318 +
  319 +static void fotg210_setup(struct fotg210_chip *chip)
  320 +{
  321 + int id, ret = CX_IDLE;
  322 + uint32_t tmp[2];
  323 + struct usb_ctrlrequest *req = (struct usb_ctrlrequest *)tmp;
  324 + struct fotg210_regs *regs = chip->regs;
  325 +
  326 + /*
  327 + * If this is the first Cx 8 byte command,
  328 + * we can now query USB mode (high/full speed; USB 2.0/USB 1.0)
  329 + */
  330 + if (chip->state == USB_STATE_POWERED) {
  331 + chip->state = USB_STATE_DEFAULT;
  332 + if (readl(&regs->otgcsr) & OTGCSR_DEV_B) {
  333 + /* Mini-B */
  334 + if (readl(&regs->dev_ctrl) & DEVCTRL_HS) {
  335 + puts("fotg210: HS\n");
  336 + chip->gadget.speed = USB_SPEED_HIGH;
  337 + /* SOF mask timer = 1100 ticks */
  338 + writel(SOFMTR_TMR(1100), &regs->sof_mtr);
  339 + } else {
  340 + puts("fotg210: FS\n");
  341 + chip->gadget.speed = USB_SPEED_FULL;
  342 + /* SOF mask timer = 10000 ticks */
  343 + writel(SOFMTR_TMR(10000), &regs->sof_mtr);
  344 + }
  345 + } else {
  346 + printf("fotg210: mini-A?\n");
  347 + }
  348 + }
  349 +
  350 + /* switch data port to ep0 */
  351 + writel(DMAFIFO_CX, &regs->dma_fifo);
  352 + /* fetch 8 bytes setup packet */
  353 + tmp[0] = readl(&regs->ep0_data);
  354 + tmp[1] = readl(&regs->ep0_data);
  355 + /* release data port */
  356 + writel(0, &regs->dma_fifo);
  357 +
  358 + if (req->bRequestType & USB_DIR_IN)
  359 + ep0_desc.bEndpointAddress = USB_DIR_IN;
  360 + else
  361 + ep0_desc.bEndpointAddress = USB_DIR_OUT;
  362 +
  363 + ret = CX_IDLE;
  364 +
  365 + if ((req->bRequestType & USB_TYPE_MASK) == USB_TYPE_STANDARD) {
  366 + switch (req->bRequest) {
  367 + case USB_REQ_SET_CONFIGURATION:
  368 + debug("fotg210: set_cfg(%d)\n", req->wValue & 0x00FF);
  369 + if (!(req->wValue & 0x00FF)) {
  370 + chip->state = USB_STATE_ADDRESS;
  371 + writel(chip->addr, &regs->dev_addr);
  372 + } else {
  373 + chip->state = USB_STATE_CONFIGURED;
  374 + writel(chip->addr | DEVADDR_CONF,
  375 + &regs->dev_addr);
  376 + }
  377 + ret = CX_IDLE;
  378 + break;
  379 +
  380 + case USB_REQ_SET_ADDRESS:
  381 + debug("fotg210: set_addr(0x%04X)\n", req->wValue);
  382 + chip->state = USB_STATE_ADDRESS;
  383 + chip->addr = req->wValue & DEVADDR_ADDR_MASK;
  384 + ret = CX_FINISH;
  385 + writel(chip->addr, &regs->dev_addr);
  386 + break;
  387 +
  388 + case USB_REQ_CLEAR_FEATURE:
  389 + debug("fotg210: clr_feature(%d, %d)\n",
  390 + req->bRequestType & 0x03, req->wValue);
  391 + switch (req->wValue) {
  392 + case 0: /* [Endpoint] halt */
  393 + ep_reset(chip, req->wIndex);
  394 + ret = CX_FINISH;
  395 + break;
  396 + case 1: /* [Device] remote wake-up */
  397 + case 2: /* [Device] test mode */
  398 + default:
  399 + ret = CX_STALL;
  400 + break;
  401 + }
  402 + break;
  403 +
  404 + case USB_REQ_SET_FEATURE:
  405 + debug("fotg210: set_feature(%d, %d)\n",
  406 + req->wValue, req->wIndex & 0xf);
  407 + switch (req->wValue) {
  408 + case 0: /* Endpoint Halt */
  409 + id = req->wIndex & 0xf;
  410 + setbits_le32(&regs->iep[id - 1], IEP_STALL);
  411 + setbits_le32(&regs->oep[id - 1], OEP_STALL);
  412 + ret = CX_FINISH;
  413 + break;
  414 + case 1: /* Remote Wakeup */
  415 + case 2: /* Test Mode */
  416 + default:
  417 + ret = CX_STALL;
  418 + break;
  419 + }
  420 + break;
  421 +
  422 + case USB_REQ_GET_STATUS:
  423 + debug("fotg210: get_status\n");
  424 + ret = CX_STALL;
  425 + break;
  426 +
  427 + case USB_REQ_SET_DESCRIPTOR:
  428 + debug("fotg210: set_descriptor\n");
  429 + ret = CX_STALL;
  430 + break;
  431 +
  432 + case USB_REQ_SYNCH_FRAME:
  433 + debug("fotg210: sync frame\n");
  434 + ret = CX_STALL;
  435 + break;
  436 + }
  437 + } /* if ((req->bRequestType & USB_TYPE_MASK) == USB_TYPE_STANDARD) */
  438 +
  439 + if (ret == CX_IDLE && chip->driver->setup) {
  440 + if (chip->driver->setup(&chip->gadget, req) < 0)
  441 + ret = CX_STALL;
  442 + else
  443 + ret = CX_FINISH;
  444 + }
  445 +
  446 + switch (ret) {
  447 + case CX_FINISH:
  448 + setbits_le32(&regs->cxfifo, CXFIFO_CXFIN);
  449 + break;
  450 +
  451 + case CX_STALL:
  452 + setbits_le32(&regs->cxfifo, CXFIFO_CXSTALL | CXFIFO_CXFIN);
  453 + printf("fotg210: cx_stall!\n");
  454 + break;
  455 +
  456 + case CX_IDLE:
  457 + debug("fotg210: cx_idle?\n");
  458 + default:
  459 + break;
  460 + }
  461 +}
  462 +
  463 +/*
  464 + * fifo - FIFO id
  465 + * zlp - zero length packet
  466 + */
  467 +static void fotg210_recv(struct fotg210_chip *chip, int ep_id)
  468 +{
  469 + struct fotg210_regs *regs = chip->regs;
  470 + struct fotg210_ep *ep = chip->ep + ep_id;
  471 + struct fotg210_request *req;
  472 + int len;
  473 +
  474 + if (ep->stopped || (ep->desc->bEndpointAddress & USB_DIR_IN)) {
  475 + printf("fotg210: ep%d recv, invalid!\n", ep->id);
  476 + return;
  477 + }
  478 +
  479 + if (list_empty(&ep->queue)) {
  480 + printf("fotg210: ep%d recv, drop!\n", ep->id);
  481 + return;
  482 + }
  483 +
  484 + req = list_first_entry(&ep->queue, struct fotg210_request, queue);
  485 + len = fotg210_dma(ep, req);
  486 + if (len < ep->ep.maxpacket || req->req.length <= req->req.actual) {
  487 + list_del_init(&req->queue);
  488 + if (req->req.complete)
  489 + req->req.complete(&ep->ep, &req->req);
  490 + }
  491 +
  492 + if (ep->id > 0 && list_empty(&ep->queue)) {
  493 + setbits_le32(&regs->gimr1,
  494 + GIMR1_FIFO_RX(ep_to_fifo(chip, ep->id)));
  495 + }
  496 +}
  497 +
  498 +/*
  499 + * USB Gadget Layer
  500 + */
  501 +static int fotg210_ep_enable(
  502 + struct usb_ep *_ep, const struct usb_endpoint_descriptor *desc)
  503 +{
  504 + struct fotg210_ep *ep = container_of(_ep, struct fotg210_ep, ep);
  505 + struct fotg210_chip *chip = ep->chip;
  506 + struct fotg210_regs *regs = chip->regs;
  507 + int id = ep_to_fifo(chip, ep->id);
  508 + int in = (desc->bEndpointAddress & USB_DIR_IN) ? 1 : 0;
  509 +
  510 + if (!_ep || !desc
  511 + || desc->bDescriptorType != USB_DT_ENDPOINT
  512 + || le16_to_cpu(desc->wMaxPacketSize) == 0) {
  513 + printf("fotg210: bad ep or descriptor\n");
  514 + return -EINVAL;
  515 + }
  516 +
  517 + ep->desc = desc;
  518 + ep->stopped = 0;
  519 +
  520 + if (in)
  521 + setbits_le32(&regs->fifomap, FIFOMAP(id, FIFOMAP_IN));
  522 +
  523 + switch (desc->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) {
  524 + case USB_ENDPOINT_XFER_CONTROL:
  525 + return -EINVAL;
  526 +
  527 + case USB_ENDPOINT_XFER_ISOC:
  528 + setbits_le32(&regs->fifocfg,
  529 + FIFOCFG(id, FIFOCFG_EN | FIFOCFG_ISOC));
  530 + break;
  531 +
  532 + case USB_ENDPOINT_XFER_BULK:
  533 + setbits_le32(&regs->fifocfg,
  534 + FIFOCFG(id, FIFOCFG_EN | FIFOCFG_BULK));
  535 + break;
  536 +
  537 + case USB_ENDPOINT_XFER_INT:
  538 + setbits_le32(&regs->fifocfg,
  539 + FIFOCFG(id, FIFOCFG_EN | FIFOCFG_INTR));
  540 + break;
  541 + }
  542 +
  543 + return 0;
  544 +}
  545 +
  546 +static int fotg210_ep_disable(struct usb_ep *_ep)
  547 +{
  548 + struct fotg210_ep *ep = container_of(_ep, struct fotg210_ep, ep);
  549 + struct fotg210_chip *chip = ep->chip;
  550 + struct fotg210_regs *regs = chip->regs;
  551 + int id = ep_to_fifo(chip, ep->id);
  552 +
  553 + ep->desc = NULL;
  554 + ep->stopped = 1;
  555 +
  556 + clrbits_le32(&regs->fifocfg, FIFOCFG(id, FIFOCFG_CFG_MASK));
  557 + clrbits_le32(&regs->fifomap, FIFOMAP(id, FIFOMAP_DIR_MASK));
  558 +
  559 + return 0;
  560 +}
  561 +
  562 +static struct usb_request *fotg210_ep_alloc_request(
  563 + struct usb_ep *_ep, gfp_t gfp_flags)
  564 +{
  565 + struct fotg210_request *req = malloc(sizeof(*req));
  566 +
  567 + if (req) {
  568 + memset(req, 0, sizeof(*req));
  569 + INIT_LIST_HEAD(&req->queue);
  570 + }
  571 + return &req->req;
  572 +}
  573 +
  574 +static void fotg210_ep_free_request(
  575 + struct usb_ep *_ep, struct usb_request *_req)
  576 +{
  577 + struct fotg210_request *req;
  578 +
  579 + req = container_of(_req, struct fotg210_request, req);
  580 + free(req);
  581 +}
  582 +
  583 +static int fotg210_ep_queue(
  584 + struct usb_ep *_ep, struct usb_request *_req, gfp_t gfp_flags)
  585 +{
  586 + struct fotg210_ep *ep = container_of(_ep, struct fotg210_ep, ep);
  587 + struct fotg210_chip *chip = ep->chip;
  588 + struct fotg210_regs *regs = chip->regs;
  589 + struct fotg210_request *req;
  590 +
  591 + req = container_of(_req, struct fotg210_request, req);
  592 + if (!_req || !_req->complete || !_req->buf
  593 + || !list_empty(&req->queue)) {
  594 + printf("fotg210: invalid request to ep%d\n", ep->id);
  595 + return -EINVAL;
  596 + }
  597 +
  598 + if (!chip || chip->state == USB_STATE_SUSPENDED) {
  599 + printf("fotg210: request while chip suspended\n");
  600 + return -EINVAL;
  601 + }
  602 +
  603 + req->req.actual = 0;
  604 + req->req.status = -EINPROGRESS;
  605 +
  606 + if (req->req.length == 0) {
  607 + req->req.status = 0;
  608 + if (req->req.complete)
  609 + req->req.complete(&ep->ep, &req->req);
  610 + return 0;
  611 + }
  612 +
  613 + if (ep->id == 0) {
  614 + do {
  615 + int len = fotg210_dma(ep, req);
  616 + if (len < ep->ep.maxpacket)
  617 + break;
  618 + if (ep->desc->bEndpointAddress & USB_DIR_IN)
  619 + udelay(100);
  620 + } while (req->req.length > req->req.actual);
  621 + } else {
  622 + if (ep->desc->bEndpointAddress & USB_DIR_IN) {
  623 + do {
  624 + int len = fotg210_dma(ep, req);
  625 + if (len < ep->ep.maxpacket)
  626 + break;
  627 + } while (req->req.length > req->req.actual);
  628 + } else {
  629 + list_add_tail(&req->queue, &ep->queue);
  630 + clrbits_le32(&regs->gimr1,
  631 + GIMR1_FIFO_RX(ep_to_fifo(chip, ep->id)));
  632 + }
  633 + }
  634 +
  635 + if (ep->id == 0 || (ep->desc->bEndpointAddress & USB_DIR_IN)) {
  636 + if (req->req.complete)
  637 + req->req.complete(&ep->ep, &req->req);
  638 + }
  639 +
  640 + return 0;
  641 +}
  642 +
  643 +static int fotg210_ep_dequeue(struct usb_ep *_ep, struct usb_request *_req)
  644 +{
  645 + struct fotg210_ep *ep = container_of(_ep, struct fotg210_ep, ep);
  646 + struct fotg210_request *req;
  647 +
  648 + /* make sure it's actually queued on this endpoint */
  649 + list_for_each_entry(req, &ep->queue, queue) {
  650 + if (&req->req == _req)
  651 + break;
  652 + }
  653 + if (&req->req != _req)
  654 + return -EINVAL;
  655 +
  656 + /* remove the request */
  657 + list_del_init(&req->queue);
  658 +
  659 + /* update status & invoke complete callback */
  660 + if (req->req.status == -EINPROGRESS) {
  661 + req->req.status = -ECONNRESET;
  662 + if (req->req.complete)
  663 + req->req.complete(_ep, &req->req);
  664 + }
  665 +
  666 + return 0;
  667 +}
  668 +
  669 +static int fotg210_ep_halt(struct usb_ep *_ep, int halt)
  670 +{
  671 + struct fotg210_ep *ep = container_of(_ep, struct fotg210_ep, ep);
  672 + struct fotg210_chip *chip = ep->chip;
  673 + struct fotg210_regs *regs = chip->regs;
  674 + int ret = -1;
  675 +
  676 + debug("fotg210: ep%d halt=%d\n", ep->id, halt);
  677 +
  678 + /* Endpoint STALL */
  679 + if (ep->id > 0 && ep->id <= CFG_NUM_ENDPOINTS) {
  680 + if (halt) {
  681 + /* wait until all ep fifo empty */
  682 + fotg210_cxwait(chip, 0xf00);
  683 + /* stall */
  684 + if (ep->desc->bEndpointAddress & USB_DIR_IN) {
  685 + setbits_le32(&regs->iep[ep->id - 1],
  686 + IEP_STALL);
  687 + } else {
  688 + setbits_le32(&regs->oep[ep->id - 1],
  689 + OEP_STALL);
  690 + }
  691 + } else {
  692 + if (ep->desc->bEndpointAddress & USB_DIR_IN) {
  693 + clrbits_le32(&regs->iep[ep->id - 1],
  694 + IEP_STALL);
  695 + } else {
  696 + clrbits_le32(&regs->oep[ep->id - 1],
  697 + OEP_STALL);
  698 + }
  699 + }
  700 + ret = 0;
  701 + }
  702 +
  703 + return ret;
  704 +}
  705 +
  706 +/*
  707 + * activate/deactivate link with host.
  708 + */
  709 +static void pullup(struct fotg210_chip *chip, int is_on)
  710 +{
  711 + struct fotg210_regs *regs = chip->regs;
  712 +
  713 + if (is_on) {
  714 + if (!chip->pullup) {
  715 + chip->state = USB_STATE_POWERED;
  716 + chip->pullup = 1;
  717 + /* enable the chip */
  718 + setbits_le32(&regs->dev_ctrl, DEVCTRL_EN);
  719 + /* clear unplug bit (BIT0) */
  720 + clrbits_le32(&regs->phy_tmsr, PHYTMSR_UNPLUG);
  721 + }
  722 + } else {
  723 + chip->state = USB_STATE_NOTATTACHED;
  724 + chip->pullup = 0;
  725 + chip->addr = 0;
  726 + writel(chip->addr, &regs->dev_addr);
  727 + /* set unplug bit (BIT0) */
  728 + setbits_le32(&regs->phy_tmsr, PHYTMSR_UNPLUG);
  729 + /* disable the chip */
  730 + clrbits_le32(&regs->dev_ctrl, DEVCTRL_EN);
  731 + }
  732 +}
  733 +
  734 +static int fotg210_pullup(struct usb_gadget *_gadget, int is_on)
  735 +{
  736 + struct fotg210_chip *chip;
  737 +
  738 + chip = container_of(_gadget, struct fotg210_chip, gadget);
  739 +
  740 + debug("fotg210: pullup=%d\n", is_on);
  741 +
  742 + pullup(chip, is_on);
  743 +
  744 + return 0;
  745 +}
  746 +
  747 +static int fotg210_get_frame(struct usb_gadget *_gadget)
  748 +{
  749 + struct fotg210_chip *chip;
  750 + struct fotg210_regs *regs;
  751 +
  752 + chip = container_of(_gadget, struct fotg210_chip, gadget);
  753 + regs = chip->regs;
  754 +
  755 + return SOFFNR_FNR(readl(&regs->sof_fnr));
  756 +}
  757 +
  758 +static struct usb_gadget_ops fotg210_gadget_ops = {
  759 + .get_frame = fotg210_get_frame,
  760 + .pullup = fotg210_pullup,
  761 +};
  762 +
  763 +static struct usb_ep_ops fotg210_ep_ops = {
  764 + .enable = fotg210_ep_enable,
  765 + .disable = fotg210_ep_disable,
  766 + .queue = fotg210_ep_queue,
  767 + .dequeue = fotg210_ep_dequeue,
  768 + .set_halt = fotg210_ep_halt,
  769 + .alloc_request = fotg210_ep_alloc_request,
  770 + .free_request = fotg210_ep_free_request,
  771 +};
  772 +
  773 +static struct fotg210_chip controller = {
  774 + .regs = (void __iomem *)CONFIG_FOTG210_BASE,
  775 + .gadget = {
  776 + .name = "fotg210_udc",
  777 + .ops = &fotg210_gadget_ops,
  778 + .ep0 = &controller.ep[0].ep,
  779 + .speed = USB_SPEED_UNKNOWN,
  780 + .is_dualspeed = 1,
  781 + .is_otg = 0,
  782 + .is_a_peripheral = 0,
  783 + .b_hnp_enable = 0,
  784 + .a_hnp_support = 0,
  785 + .a_alt_hnp_support = 0,
  786 + },
  787 + .ep[0] = {
  788 + .id = 0,
  789 + .ep = {
  790 + .name = "ep0",
  791 + .ops = &fotg210_ep_ops,
  792 + },
  793 + .desc = &ep0_desc,
  794 + .chip = &controller,
  795 + .maxpacket = CFG_EP0_MAX_PACKET_SIZE,
  796 + },
  797 + .ep[1] = {
  798 + .id = 1,
  799 + .ep = {
  800 + .name = "ep1",
  801 + .ops = &fotg210_ep_ops,
  802 + },
  803 + .chip = &controller,
  804 + .maxpacket = CFG_EPX_MAX_PACKET_SIZE,
  805 + },
  806 + .ep[2] = {
  807 + .id = 2,
  808 + .ep = {
  809 + .name = "ep2",
  810 + .ops = &fotg210_ep_ops,
  811 + },
  812 + .chip = &controller,
  813 + .maxpacket = CFG_EPX_MAX_PACKET_SIZE,
  814 + },
  815 + .ep[3] = {
  816 + .id = 3,
  817 + .ep = {
  818 + .name = "ep3",
  819 + .ops = &fotg210_ep_ops,
  820 + },
  821 + .chip = &controller,
  822 + .maxpacket = CFG_EPX_MAX_PACKET_SIZE,
  823 + },
  824 + .ep[4] = {
  825 + .id = 4,
  826 + .ep = {
  827 + .name = "ep4",
  828 + .ops = &fotg210_ep_ops,
  829 + },
  830 + .chip = &controller,
  831 + .maxpacket = CFG_EPX_MAX_PACKET_SIZE,
  832 + },
  833 +};
  834 +
  835 +int usb_gadget_handle_interrupts(void)
  836 +{
  837 + struct fotg210_chip *chip = &controller;
  838 + struct fotg210_regs *regs = chip->regs;
  839 + uint32_t id, st, isr, gisr;
  840 +
  841 + isr = readl(&regs->isr) & (~readl(&regs->imr));
  842 + gisr = readl(&regs->gisr) & (~readl(&regs->gimr));
  843 + if (!(isr & ISR_DEV) || !gisr)
  844 + return 0;
  845 +
  846 + writel(ISR_DEV, &regs->isr);
  847 +
  848 + /* CX interrupts */
  849 + if (gisr & GISR_GRP0) {
  850 + st = readl(&regs->gisr0);
  851 + writel(0, &regs->gisr0);
  852 +
  853 + if (st & GISR0_CXERR)
  854 + printf("fotg210: cmd error\n");
  855 +
  856 + if (st & GISR0_CXABORT)
  857 + printf("fotg210: cmd abort\n");
  858 +
  859 + if (st & GISR0_CXSETUP) /* setup */
  860 + fotg210_setup(chip);
  861 + else if (st & GISR0_CXEND) /* command finish */
  862 + setbits_le32(&regs->cxfifo, CXFIFO_CXFIN);
  863 + }
  864 +
  865 + /* FIFO interrupts */
  866 + if (gisr & GISR_GRP1) {
  867 + st = readl(&regs->gisr1);
  868 + for (id = 0; id < 4; ++id) {
  869 + if (st & GISR1_RX_FIFO(id))
  870 + fotg210_recv(chip, fifo_to_ep(chip, id, 0));
  871 + }
  872 + }
  873 +
  874 + /* Device Status Interrupts */
  875 + if (gisr & GISR_GRP2) {
  876 + st = readl(&regs->gisr2);
  877 + writel(0, &regs->gisr2);
  878 +
  879 + if (st & GISR2_RESET)
  880 + printf("fotg210: reset by host\n");
  881 + else if (st & GISR2_SUSPEND)
  882 + printf("fotg210: suspend/removed\n");
  883 + else if (st & GISR2_RESUME)
  884 + printf("fotg210: resume\n");
  885 +
  886 + /* Errors */
  887 + if (st & GISR2_ISOCERR)
  888 + printf("fotg210: iso error\n");
  889 + if (st & GISR2_ISOCABT)
  890 + printf("fotg210: iso abort\n");
  891 + if (st & GISR2_DMAERR)
  892 + printf("fotg210: dma error\n");
  893 + }
  894 +
  895 + return 0;
  896 +}
  897 +
  898 +int usb_gadget_register_driver(struct usb_gadget_driver *driver)
  899 +{
  900 + int i, ret = 0;
  901 + struct fotg210_chip *chip = &controller;
  902 +
  903 + if (!driver || !driver->bind || !driver->setup) {
  904 + puts("fotg210: bad parameter.\n");
  905 + return -EINVAL;
  906 + }
  907 +
  908 + INIT_LIST_HEAD(&chip->gadget.ep_list);
  909 + for (i = 0; i < CFG_NUM_ENDPOINTS + 1; ++i) {
  910 + struct fotg210_ep *ep = chip->ep + i;
  911 +
  912 + ep->ep.maxpacket = ep->maxpacket;
  913 + INIT_LIST_HEAD(&ep->queue);
  914 +
  915 + if (ep->id == 0) {
  916 + ep->stopped = 0;
  917 + } else {
  918 + ep->stopped = 1;
  919 + list_add_tail(&ep->ep.ep_list, &chip->gadget.ep_list);
  920 + }
  921 + }
  922 +
  923 + if (fotg210_reset(chip)) {
  924 + puts("fotg210: reset failed.\n");
  925 + return -EINVAL;
  926 + }
  927 +
  928 + ret = driver->bind(&chip->gadget);
  929 + if (ret) {
  930 + debug("fotg210: driver->bind() returned %d\n", ret);
  931 + return ret;
  932 + }
  933 + chip->driver = driver;
  934 +
  935 + return ret;
  936 +}
  937 +
  938 +int usb_gadget_unregister_driver(struct usb_gadget_driver *driver)
  939 +{
  940 + struct fotg210_chip *chip = &controller;
  941 +
  942 + driver->unbind(&chip->gadget);
  943 + chip->driver = NULL;
  944 +
  945 + pullup(chip, 0);
  946 +
  947 + return 0;
  948 +}
drivers/usb/gadget/gadget_chips.h
... ... @@ -150,6 +150,12 @@
150 150 #define gadget_is_mv(g) 0
151 151 #endif
152 152  
  153 +#ifdef CONFIG_USB_GADGET_FOTG210
  154 +#define gadget_is_fotg210(g) (!strcmp("fotg210_udc", (g)->name))
  155 +#else
  156 +#define gadget_is_fotg210(g) 0
  157 +#endif
  158 +
153 159 /*
154 160 * CONFIG_USB_GADGET_SX2
155 161 * CONFIG_USB_GADGET_AU1X00
... ... @@ -215,6 +221,8 @@
215 221 return 0x20;
216 222 else if (gadget_is_mv(gadget))
217 223 return 0x21;
  224 + else if (gadget_is_fotg210(gadget))
  225 + return 0x22;
218 226 return -ENOENT;
219 227 }