usb: Drop unused fotg210 gadget
This is not used and appears to be associated with the faraday board which has been removed. Drop the driver and Kconfig options. Signed-off-by: Simon Glass <sjg@chromium.org>
This commit is contained in:
		
							parent
							
								
									5eddad039b
								
							
						
					
					
						commit
						e9b4678bc7
					
				|  | @ -19,8 +19,7 @@ obj-$(CONFIG_USB_GADGET_ATMEL_USBA) += atmel_usba_udc.o | ||||||
| obj-$(CONFIG_USB_GADGET_BCM_UDC_OTG_PHY) += bcm_udc_otg_phy.o | obj-$(CONFIG_USB_GADGET_BCM_UDC_OTG_PHY) += bcm_udc_otg_phy.o | ||||||
| obj-$(CONFIG_USB_GADGET_DWC2_OTG) += dwc2_udc_otg.o | obj-$(CONFIG_USB_GADGET_DWC2_OTG) += dwc2_udc_otg.o | ||||||
| obj-$(CONFIG_USB_GADGET_DWC2_OTG_PHY) += dwc2_udc_otg_phy.o | obj-$(CONFIG_USB_GADGET_DWC2_OTG_PHY) += dwc2_udc_otg_phy.o | ||||||
| obj-$(CONFIG_USB_GADGET_FOTG210) += fotg210.o | 0obj-$(CONFIG_USB_GADGET_MAX3420) += max3420_udc.o | ||||||
| obj-$(CONFIG_USB_GADGET_MAX3420) += max3420_udc.o |  | ||||||
| ifndef CONFIG_SPL_BUILD | ifndef CONFIG_SPL_BUILD | ||||||
| obj-$(CONFIG_USB_GADGET_DOWNLOAD) += g_dnl.o | obj-$(CONFIG_USB_GADGET_DOWNLOAD) += g_dnl.o | ||||||
| obj-$(CONFIG_USB_FUNCTION_THOR) += f_thor.o | obj-$(CONFIG_USB_FUNCTION_THOR) += f_thor.o | ||||||
|  |  | ||||||
|  | @ -1,964 +0,0 @@ | ||||||
| // SPDX-License-Identifier: GPL-2.0+
 |  | ||||||
| /*
 |  | ||||||
|  * Faraday USB 2.0 OTG Controller |  | ||||||
|  * |  | ||||||
|  * (C) Copyright 2010 Faraday Technology |  | ||||||
|  * Dante Su <dantesu@faraday-tech.com> |  | ||||||
|  */ |  | ||||||
| 
 |  | ||||||
| #include <common.h> |  | ||||||
| #include <command.h> |  | ||||||
| #include <config.h> |  | ||||||
| #include <cpu_func.h> |  | ||||||
| #include <log.h> |  | ||||||
| #include <net.h> |  | ||||||
| #include <malloc.h> |  | ||||||
| #include <asm/io.h> |  | ||||||
| #include <linux/delay.h> |  | ||||||
| #include <linux/errno.h> |  | ||||||
| #include <linux/types.h> |  | ||||||
| #include <linux/usb/ch9.h> |  | ||||||
| #include <linux/usb/gadget.h> |  | ||||||
| 
 |  | ||||||
| #include <usb/fotg210.h> |  | ||||||
| 
 |  | ||||||
| #define CFG_NUM_ENDPOINTS		4 |  | ||||||
| #define CFG_EP0_MAX_PACKET_SIZE	64 |  | ||||||
| #define CFG_EPX_MAX_PACKET_SIZE	512 |  | ||||||
| 
 |  | ||||||
| #define CFG_CMD_TIMEOUT (CONFIG_SYS_HZ >> 2) /* 250 ms */ |  | ||||||
| 
 |  | ||||||
| struct fotg210_chip; |  | ||||||
| 
 |  | ||||||
| struct fotg210_ep { |  | ||||||
| 	struct usb_ep ep; |  | ||||||
| 
 |  | ||||||
| 	uint maxpacket; |  | ||||||
| 	uint id; |  | ||||||
| 	uint stopped; |  | ||||||
| 
 |  | ||||||
| 	struct list_head                      queue; |  | ||||||
| 	struct fotg210_chip                  *chip; |  | ||||||
| 	const struct usb_endpoint_descriptor *desc; |  | ||||||
| }; |  | ||||||
| 
 |  | ||||||
| struct fotg210_request { |  | ||||||
| 	struct usb_request req; |  | ||||||
| 	struct list_head   queue; |  | ||||||
| 	struct fotg210_ep *ep; |  | ||||||
| }; |  | ||||||
| 
 |  | ||||||
| struct fotg210_chip { |  | ||||||
| 	struct usb_gadget         gadget; |  | ||||||
| 	struct usb_gadget_driver *driver; |  | ||||||
| 	struct fotg210_regs      *regs; |  | ||||||
| 	uint8_t                   irq; |  | ||||||
| 	uint16_t                  addr; |  | ||||||
| 	int                       pullup; |  | ||||||
| 	enum usb_device_state     state; |  | ||||||
| 	struct fotg210_ep         ep[1 + CFG_NUM_ENDPOINTS]; |  | ||||||
| }; |  | ||||||
| 
 |  | ||||||
| static struct usb_endpoint_descriptor ep0_desc = { |  | ||||||
| 	.bLength = sizeof(struct usb_endpoint_descriptor), |  | ||||||
| 	.bDescriptorType = USB_DT_ENDPOINT, |  | ||||||
| 	.bEndpointAddress = USB_DIR_IN, |  | ||||||
| 	.bmAttributes = USB_ENDPOINT_XFER_CONTROL, |  | ||||||
| }; |  | ||||||
| 
 |  | ||||||
| static inline int fifo_to_ep(struct fotg210_chip *chip, int id, int in) |  | ||||||
| { |  | ||||||
| 	return (id < 0) ? 0 : ((id & 0x03) + 1); |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| static inline int ep_to_fifo(struct fotg210_chip *chip, int id) |  | ||||||
| { |  | ||||||
| 	return (id <= 0) ? -1 : ((id - 1) & 0x03); |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| static inline int ep_reset(struct fotg210_chip *chip, uint8_t ep_addr) |  | ||||||
| { |  | ||||||
| 	int ep = ep_addr & USB_ENDPOINT_NUMBER_MASK; |  | ||||||
| 	struct fotg210_regs *regs = chip->regs; |  | ||||||
| 
 |  | ||||||
| 	if (ep_addr & USB_DIR_IN) { |  | ||||||
| 		/* reset endpoint */ |  | ||||||
| 		setbits_le32(®s->iep[ep - 1], IEP_RESET); |  | ||||||
| 		mdelay(1); |  | ||||||
| 		clrbits_le32(®s->iep[ep - 1], IEP_RESET); |  | ||||||
| 		/* clear endpoint stall */ |  | ||||||
| 		clrbits_le32(®s->iep[ep - 1], IEP_STALL); |  | ||||||
| 	} else { |  | ||||||
| 		/* reset endpoint */ |  | ||||||
| 		setbits_le32(®s->oep[ep - 1], OEP_RESET); |  | ||||||
| 		mdelay(1); |  | ||||||
| 		clrbits_le32(®s->oep[ep - 1], OEP_RESET); |  | ||||||
| 		/* clear endpoint stall */ |  | ||||||
| 		clrbits_le32(®s->oep[ep - 1], OEP_STALL); |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	return 0; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| static int fotg210_reset(struct fotg210_chip *chip) |  | ||||||
| { |  | ||||||
| 	struct fotg210_regs *regs = chip->regs; |  | ||||||
| 	uint32_t i; |  | ||||||
| 
 |  | ||||||
| 	chip->state = USB_STATE_POWERED; |  | ||||||
| 
 |  | ||||||
| 	/* chip enable */ |  | ||||||
| 	writel(DEVCTRL_EN, ®s->dev_ctrl); |  | ||||||
| 
 |  | ||||||
| 	/* device address reset */ |  | ||||||
| 	chip->addr = 0; |  | ||||||
| 	writel(0, ®s->dev_addr); |  | ||||||
| 
 |  | ||||||
| 	/* set idle counter to 7ms */ |  | ||||||
| 	writel(7, ®s->idle); |  | ||||||
| 
 |  | ||||||
| 	/* disable all interrupts */ |  | ||||||
| 	writel(IMR_MASK, ®s->imr); |  | ||||||
| 	writel(GIMR_MASK, ®s->gimr); |  | ||||||
| 	writel(GIMR0_MASK, ®s->gimr0); |  | ||||||
| 	writel(GIMR1_MASK, ®s->gimr1); |  | ||||||
| 	writel(GIMR2_MASK, ®s->gimr2); |  | ||||||
| 
 |  | ||||||
| 	/* clear interrupts */ |  | ||||||
| 	writel(ISR_MASK, ®s->isr); |  | ||||||
| 	writel(0, ®s->gisr); |  | ||||||
| 	writel(0, ®s->gisr0); |  | ||||||
| 	writel(0, ®s->gisr1); |  | ||||||
| 	writel(0, ®s->gisr2); |  | ||||||
| 
 |  | ||||||
| 	/* chip reset */ |  | ||||||
| 	setbits_le32(®s->dev_ctrl, DEVCTRL_RESET); |  | ||||||
| 	mdelay(10); |  | ||||||
| 	if (readl(®s->dev_ctrl) & DEVCTRL_RESET) { |  | ||||||
| 		printf("fotg210: chip reset failed\n"); |  | ||||||
| 		return -1; |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	/* CX FIFO reset */ |  | ||||||
| 	setbits_le32(®s->cxfifo, CXFIFO_CXFIFOCLR); |  | ||||||
| 	mdelay(10); |  | ||||||
| 	if (readl(®s->cxfifo) & CXFIFO_CXFIFOCLR) { |  | ||||||
| 		printf("fotg210: ep0 fifo reset failed\n"); |  | ||||||
| 		return -1; |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	/* create static ep-fifo map (EP1 <-> FIFO0, EP2 <-> FIFO1 ...) */ |  | ||||||
| 	writel(EPMAP14_DEFAULT, ®s->epmap14); |  | ||||||
| 	writel(EPMAP58_DEFAULT, ®s->epmap58); |  | ||||||
| 	writel(FIFOMAP_DEFAULT, ®s->fifomap); |  | ||||||
| 	writel(0, ®s->fifocfg); |  | ||||||
| 	for (i = 0; i < 8; ++i) { |  | ||||||
| 		writel(CFG_EPX_MAX_PACKET_SIZE, ®s->iep[i]); |  | ||||||
| 		writel(CFG_EPX_MAX_PACKET_SIZE, ®s->oep[i]); |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	/* FIFO reset */ |  | ||||||
| 	for (i = 0; i < 4; ++i) { |  | ||||||
| 		writel(FIFOCSR_RESET, ®s->fifocsr[i]); |  | ||||||
| 		mdelay(10); |  | ||||||
| 		if (readl(®s->fifocsr[i]) & FIFOCSR_RESET) { |  | ||||||
| 			printf("fotg210: fifo%d reset failed\n", i); |  | ||||||
| 			return -1; |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	/* enable only device interrupt and triggered at level-high */ |  | ||||||
| 	writel(IMR_IRQLH | IMR_HOST | IMR_OTG, ®s->imr); |  | ||||||
| 	writel(ISR_MASK, ®s->isr); |  | ||||||
| 	/* disable EP0 IN/OUT interrupt */ |  | ||||||
| 	writel(GIMR0_CXOUT | GIMR0_CXIN, ®s->gimr0); |  | ||||||
| 	/* disable EPX IN+SPK+OUT interrupts */ |  | ||||||
| 	writel(GIMR1_MASK, ®s->gimr1); |  | ||||||
| 	/* disable wakeup+idle+dma+zlp interrupts */ |  | ||||||
| 	writel(GIMR2_WAKEUP | GIMR2_IDLE | GIMR2_DMAERR | GIMR2_DMAFIN |  | ||||||
| 		| GIMR2_ZLPRX | GIMR2_ZLPTX, ®s->gimr2); |  | ||||||
| 	/* enable all group interrupt */ |  | ||||||
| 	writel(0, ®s->gimr); |  | ||||||
| 
 |  | ||||||
| 	/* suspend delay = 3 ms */ |  | ||||||
| 	writel(3, ®s->idle); |  | ||||||
| 
 |  | ||||||
| 	/* turn-on device interrupts */ |  | ||||||
| 	setbits_le32(®s->dev_ctrl, DEVCTRL_GIRQ_EN); |  | ||||||
| 
 |  | ||||||
| 	return 0; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| static inline int fotg210_cxwait(struct fotg210_chip *chip, uint32_t mask) |  | ||||||
| { |  | ||||||
| 	struct fotg210_regs *regs = chip->regs; |  | ||||||
| 	int ret = -1; |  | ||||||
| 	ulong ts; |  | ||||||
| 
 |  | ||||||
| 	for (ts = get_timer(0); get_timer(ts) < CFG_CMD_TIMEOUT; ) { |  | ||||||
| 		if ((readl(®s->cxfifo) & mask) != mask) |  | ||||||
| 			continue; |  | ||||||
| 		ret = 0; |  | ||||||
| 		break; |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	if (ret) |  | ||||||
| 		printf("fotg210: cx/ep0 timeout\n"); |  | ||||||
| 
 |  | ||||||
| 	return ret; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| static int fotg210_dma(struct fotg210_ep *ep, struct fotg210_request *req) |  | ||||||
| { |  | ||||||
| 	struct fotg210_chip *chip = ep->chip; |  | ||||||
| 	struct fotg210_regs *regs = chip->regs; |  | ||||||
| 	uint32_t tmp, ts; |  | ||||||
| 	uint8_t *buf  = req->req.buf + req->req.actual; |  | ||||||
| 	uint32_t len  = req->req.length - req->req.actual; |  | ||||||
| 	int fifo = ep_to_fifo(chip, ep->id); |  | ||||||
| 	int ret = -EBUSY; |  | ||||||
| 
 |  | ||||||
| 	/* 1. init dma buffer */ |  | ||||||
| 	if (len > ep->maxpacket) |  | ||||||
| 		len = ep->maxpacket; |  | ||||||
| 
 |  | ||||||
| 	/* 2. wait for dma ready (hardware) */ |  | ||||||
| 	for (ts = get_timer(0); get_timer(ts) < CFG_CMD_TIMEOUT; ) { |  | ||||||
| 		if (!(readl(®s->dma_ctrl) & DMACTRL_START)) { |  | ||||||
| 			ret = 0; |  | ||||||
| 			break; |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| 	if (ret) { |  | ||||||
| 		printf("fotg210: dma busy\n"); |  | ||||||
| 		req->req.status = ret; |  | ||||||
| 		return ret; |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	/* 3. DMA target setup */ |  | ||||||
| 	if (ep->desc->bEndpointAddress & USB_DIR_IN) |  | ||||||
| 		flush_dcache_range((ulong)buf, (ulong)buf + len); |  | ||||||
| 	else |  | ||||||
| 		invalidate_dcache_range((ulong)buf, (ulong)buf + len); |  | ||||||
| 
 |  | ||||||
| 	writel(virt_to_phys(buf), ®s->dma_addr); |  | ||||||
| 
 |  | ||||||
| 	if (ep->desc->bEndpointAddress & USB_DIR_IN) { |  | ||||||
| 		if (ep->id == 0) { |  | ||||||
| 			/* Wait until cx/ep0 fifo empty */ |  | ||||||
| 			fotg210_cxwait(chip, CXFIFO_CXFIFOE); |  | ||||||
| 			udelay(1); |  | ||||||
| 			writel(DMAFIFO_CX, ®s->dma_fifo); |  | ||||||
| 		} else { |  | ||||||
| 			/* Wait until epx fifo empty */ |  | ||||||
| 			fotg210_cxwait(chip, CXFIFO_FIFOE(fifo)); |  | ||||||
| 			writel(DMAFIFO_FIFO(fifo), ®s->dma_fifo); |  | ||||||
| 		} |  | ||||||
| 		writel(DMACTRL_LEN(len) | DMACTRL_MEM2FIFO, ®s->dma_ctrl); |  | ||||||
| 	} else { |  | ||||||
| 		uint32_t blen; |  | ||||||
| 
 |  | ||||||
| 		if (ep->id == 0) { |  | ||||||
| 			writel(DMAFIFO_CX, ®s->dma_fifo); |  | ||||||
| 			do { |  | ||||||
| 				blen = CXFIFO_BYTES(readl(®s->cxfifo)); |  | ||||||
| 			} while (blen < len); |  | ||||||
| 		} else { |  | ||||||
| 			writel(DMAFIFO_FIFO(fifo), ®s->dma_fifo); |  | ||||||
| 			blen = FIFOCSR_BYTES(readl(®s->fifocsr[fifo])); |  | ||||||
| 		} |  | ||||||
| 		len  = (len < blen) ? len : blen; |  | ||||||
| 		writel(DMACTRL_LEN(len) | DMACTRL_FIFO2MEM, ®s->dma_ctrl); |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	/* 4. DMA start */ |  | ||||||
| 	setbits_le32(®s->dma_ctrl, DMACTRL_START); |  | ||||||
| 
 |  | ||||||
| 	/* 5. DMA wait */ |  | ||||||
| 	ret = -EBUSY; |  | ||||||
| 	for (ts = get_timer(0); get_timer(ts) < CFG_CMD_TIMEOUT; ) { |  | ||||||
| 		tmp = readl(®s->gisr2); |  | ||||||
| 		/* DMA complete */ |  | ||||||
| 		if (tmp & GISR2_DMAFIN) { |  | ||||||
| 			ret = 0; |  | ||||||
| 			break; |  | ||||||
| 		} |  | ||||||
| 		/* DMA error */ |  | ||||||
| 		if (tmp & GISR2_DMAERR) { |  | ||||||
| 			printf("fotg210: dma error\n"); |  | ||||||
| 			break; |  | ||||||
| 		} |  | ||||||
| 		/* resume, suspend, reset */ |  | ||||||
| 		if (tmp & (GISR2_RESUME | GISR2_SUSPEND | GISR2_RESET)) { |  | ||||||
| 			printf("fotg210: dma reset by host\n"); |  | ||||||
| 			break; |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	/* 7. DMA target reset */ |  | ||||||
| 	if (ret) |  | ||||||
| 		writel(DMACTRL_ABORT | DMACTRL_CLRFF, ®s->dma_ctrl); |  | ||||||
| 
 |  | ||||||
| 	writel(0, ®s->gisr2); |  | ||||||
| 	writel(0, ®s->dma_fifo); |  | ||||||
| 
 |  | ||||||
| 	req->req.status = ret; |  | ||||||
| 	if (!ret) |  | ||||||
| 		req->req.actual += len; |  | ||||||
| 	else |  | ||||||
| 		printf("fotg210: ep%d dma error(code=%d)\n", ep->id, ret); |  | ||||||
| 
 |  | ||||||
| 	return len; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| /*
 |  | ||||||
|  * result of setup packet |  | ||||||
|  */ |  | ||||||
| #define CX_IDLE		0 |  | ||||||
| #define CX_FINISH	1 |  | ||||||
| #define CX_STALL	2 |  | ||||||
| 
 |  | ||||||
| static void fotg210_setup(struct fotg210_chip *chip) |  | ||||||
| { |  | ||||||
| 	int id, ret = CX_IDLE; |  | ||||||
| 	uint32_t tmp[2]; |  | ||||||
| 	struct usb_ctrlrequest *req = (struct usb_ctrlrequest *)tmp; |  | ||||||
| 	struct fotg210_regs *regs = chip->regs; |  | ||||||
| 
 |  | ||||||
| 	/*
 |  | ||||||
| 	 * If this is the first Cx 8 byte command, |  | ||||||
| 	 * we can now query USB mode (high/full speed; USB 2.0/USB 1.0) |  | ||||||
| 	 */ |  | ||||||
| 	if (chip->state == USB_STATE_POWERED) { |  | ||||||
| 		chip->state = USB_STATE_DEFAULT; |  | ||||||
| 		if (readl(®s->otgcsr) & OTGCSR_DEV_B) { |  | ||||||
| 			/* Mini-B */ |  | ||||||
| 			if (readl(®s->dev_ctrl) & DEVCTRL_HS) { |  | ||||||
| 				puts("fotg210: HS\n"); |  | ||||||
| 				chip->gadget.speed = USB_SPEED_HIGH; |  | ||||||
| 				/* SOF mask timer = 1100 ticks */ |  | ||||||
| 				writel(SOFMTR_TMR(1100), ®s->sof_mtr); |  | ||||||
| 			} else { |  | ||||||
| 				puts("fotg210: FS\n"); |  | ||||||
| 				chip->gadget.speed = USB_SPEED_FULL; |  | ||||||
| 				/* SOF mask timer = 10000 ticks */ |  | ||||||
| 				writel(SOFMTR_TMR(10000), ®s->sof_mtr); |  | ||||||
| 			} |  | ||||||
| 		} else { |  | ||||||
| 			printf("fotg210: mini-A?\n"); |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	/* switch data port to ep0 */ |  | ||||||
| 	writel(DMAFIFO_CX, ®s->dma_fifo); |  | ||||||
| 	/* fetch 8 bytes setup packet */ |  | ||||||
| 	tmp[0] = readl(®s->ep0_data); |  | ||||||
| 	tmp[1] = readl(®s->ep0_data); |  | ||||||
| 	/* release data port */ |  | ||||||
| 	writel(0, ®s->dma_fifo); |  | ||||||
| 
 |  | ||||||
| 	if (req->bRequestType & USB_DIR_IN) |  | ||||||
| 		ep0_desc.bEndpointAddress = USB_DIR_IN; |  | ||||||
| 	else |  | ||||||
| 		ep0_desc.bEndpointAddress = USB_DIR_OUT; |  | ||||||
| 
 |  | ||||||
| 	ret = CX_IDLE; |  | ||||||
| 
 |  | ||||||
| 	if ((req->bRequestType & USB_TYPE_MASK) == USB_TYPE_STANDARD) { |  | ||||||
| 		switch (req->bRequest) { |  | ||||||
| 		case USB_REQ_SET_CONFIGURATION: |  | ||||||
| 			debug("fotg210: set_cfg(%d)\n", req->wValue & 0x00FF); |  | ||||||
| 			if (!(req->wValue & 0x00FF)) { |  | ||||||
| 				chip->state = USB_STATE_ADDRESS; |  | ||||||
| 				writel(chip->addr, ®s->dev_addr); |  | ||||||
| 			} else { |  | ||||||
| 				chip->state = USB_STATE_CONFIGURED; |  | ||||||
| 				writel(chip->addr | DEVADDR_CONF, |  | ||||||
| 					®s->dev_addr); |  | ||||||
| 			} |  | ||||||
| 			ret = CX_IDLE; |  | ||||||
| 			break; |  | ||||||
| 
 |  | ||||||
| 		case USB_REQ_SET_ADDRESS: |  | ||||||
| 			debug("fotg210: set_addr(0x%04X)\n", req->wValue); |  | ||||||
| 			chip->state = USB_STATE_ADDRESS; |  | ||||||
| 			chip->addr  = req->wValue & DEVADDR_ADDR_MASK; |  | ||||||
| 			ret = CX_FINISH; |  | ||||||
| 			writel(chip->addr, ®s->dev_addr); |  | ||||||
| 			break; |  | ||||||
| 
 |  | ||||||
| 		case USB_REQ_CLEAR_FEATURE: |  | ||||||
| 			debug("fotg210: clr_feature(%d, %d)\n", |  | ||||||
| 				req->bRequestType & 0x03, req->wValue); |  | ||||||
| 			switch (req->wValue) { |  | ||||||
| 			case 0:    /* [Endpoint] halt */ |  | ||||||
| 				ep_reset(chip, req->wIndex); |  | ||||||
| 				ret = CX_FINISH; |  | ||||||
| 				break; |  | ||||||
| 			case 1:    /* [Device] remote wake-up */ |  | ||||||
| 			case 2:    /* [Device] test mode */ |  | ||||||
| 			default: |  | ||||||
| 				ret = CX_STALL; |  | ||||||
| 				break; |  | ||||||
| 			} |  | ||||||
| 			break; |  | ||||||
| 
 |  | ||||||
| 		case USB_REQ_SET_FEATURE: |  | ||||||
| 			debug("fotg210: set_feature(%d, %d)\n", |  | ||||||
| 				req->wValue, req->wIndex & 0xf); |  | ||||||
| 			switch (req->wValue) { |  | ||||||
| 			case 0:    /* Endpoint Halt */ |  | ||||||
| 				id = req->wIndex & 0xf; |  | ||||||
| 				setbits_le32(®s->iep[id - 1], IEP_STALL); |  | ||||||
| 				setbits_le32(®s->oep[id - 1], OEP_STALL); |  | ||||||
| 				ret = CX_FINISH; |  | ||||||
| 				break; |  | ||||||
| 			case 1:    /* Remote Wakeup */ |  | ||||||
| 			case 2:    /* Test Mode */ |  | ||||||
| 			default: |  | ||||||
| 				ret = CX_STALL; |  | ||||||
| 				break; |  | ||||||
| 			} |  | ||||||
| 			break; |  | ||||||
| 
 |  | ||||||
| 		case USB_REQ_GET_STATUS: |  | ||||||
| 			debug("fotg210: get_status\n"); |  | ||||||
| 			ret = CX_STALL; |  | ||||||
| 			break; |  | ||||||
| 
 |  | ||||||
| 		case USB_REQ_SET_DESCRIPTOR: |  | ||||||
| 			debug("fotg210: set_descriptor\n"); |  | ||||||
| 			ret = CX_STALL; |  | ||||||
| 			break; |  | ||||||
| 
 |  | ||||||
| 		case USB_REQ_SYNCH_FRAME: |  | ||||||
| 			debug("fotg210: sync frame\n"); |  | ||||||
| 			ret = CX_STALL; |  | ||||||
| 			break; |  | ||||||
| 		} |  | ||||||
| 	} /* if ((req->bRequestType & USB_TYPE_MASK) == USB_TYPE_STANDARD) */ |  | ||||||
| 
 |  | ||||||
| 	if (ret == CX_IDLE && chip->driver->setup) { |  | ||||||
| 		if (chip->driver->setup(&chip->gadget, req) < 0) |  | ||||||
| 			ret = CX_STALL; |  | ||||||
| 		else |  | ||||||
| 			ret = CX_FINISH; |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	switch (ret) { |  | ||||||
| 	case CX_FINISH: |  | ||||||
| 		setbits_le32(®s->cxfifo, CXFIFO_CXFIN); |  | ||||||
| 		break; |  | ||||||
| 
 |  | ||||||
| 	case CX_STALL: |  | ||||||
| 		setbits_le32(®s->cxfifo, CXFIFO_CXSTALL | CXFIFO_CXFIN); |  | ||||||
| 		printf("fotg210: cx_stall!\n"); |  | ||||||
| 		break; |  | ||||||
| 
 |  | ||||||
| 	case CX_IDLE: |  | ||||||
| 		debug("fotg210: cx_idle?\n"); |  | ||||||
| 	default: |  | ||||||
| 		break; |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| /*
 |  | ||||||
|  * fifo - FIFO id |  | ||||||
|  * zlp  - zero length packet |  | ||||||
|  */ |  | ||||||
| static void fotg210_recv(struct fotg210_chip *chip, int ep_id) |  | ||||||
| { |  | ||||||
| 	struct fotg210_regs *regs = chip->regs; |  | ||||||
| 	struct fotg210_ep *ep = chip->ep + ep_id; |  | ||||||
| 	struct fotg210_request *req; |  | ||||||
| 	int len; |  | ||||||
| 
 |  | ||||||
| 	if (ep->stopped || (ep->desc->bEndpointAddress & USB_DIR_IN)) { |  | ||||||
| 		printf("fotg210: ep%d recv, invalid!\n", ep->id); |  | ||||||
| 		return; |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	if (list_empty(&ep->queue)) { |  | ||||||
| 		printf("fotg210: ep%d recv, drop!\n", ep->id); |  | ||||||
| 		return; |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	req = list_first_entry(&ep->queue, struct fotg210_request, queue); |  | ||||||
| 	len = fotg210_dma(ep, req); |  | ||||||
| 	if (len < ep->ep.maxpacket || req->req.length <= req->req.actual) { |  | ||||||
| 		list_del_init(&req->queue); |  | ||||||
| 		if (req->req.complete) |  | ||||||
| 			req->req.complete(&ep->ep, &req->req); |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	if (ep->id > 0 && list_empty(&ep->queue)) { |  | ||||||
| 		setbits_le32(®s->gimr1, |  | ||||||
| 			GIMR1_FIFO_RX(ep_to_fifo(chip, ep->id))); |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| /*
 |  | ||||||
|  * USB Gadget Layer |  | ||||||
|  */ |  | ||||||
| static int fotg210_ep_enable( |  | ||||||
| 	struct usb_ep *_ep, const struct usb_endpoint_descriptor *desc) |  | ||||||
| { |  | ||||||
| 	struct fotg210_ep *ep = container_of(_ep, struct fotg210_ep, ep); |  | ||||||
| 	struct fotg210_chip *chip = ep->chip; |  | ||||||
| 	struct fotg210_regs *regs = chip->regs; |  | ||||||
| 	int id = ep_to_fifo(chip, ep->id); |  | ||||||
| 	int in = (desc->bEndpointAddress & USB_DIR_IN) ? 1 : 0; |  | ||||||
| 
 |  | ||||||
| 	if (!_ep || !desc |  | ||||||
| 		|| desc->bDescriptorType != USB_DT_ENDPOINT |  | ||||||
| 		|| le16_to_cpu(desc->wMaxPacketSize) == 0) { |  | ||||||
| 		printf("fotg210: bad ep or descriptor\n"); |  | ||||||
| 		return -EINVAL; |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	ep->desc = desc; |  | ||||||
| 	ep->stopped = 0; |  | ||||||
| 
 |  | ||||||
| 	if (in) |  | ||||||
| 		setbits_le32(®s->fifomap, FIFOMAP(id, FIFOMAP_IN)); |  | ||||||
| 
 |  | ||||||
| 	switch (desc->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) { |  | ||||||
| 	case USB_ENDPOINT_XFER_CONTROL: |  | ||||||
| 		return -EINVAL; |  | ||||||
| 
 |  | ||||||
| 	case USB_ENDPOINT_XFER_ISOC: |  | ||||||
| 		setbits_le32(®s->fifocfg, |  | ||||||
| 			FIFOCFG(id, FIFOCFG_EN | FIFOCFG_ISOC)); |  | ||||||
| 		break; |  | ||||||
| 
 |  | ||||||
| 	case USB_ENDPOINT_XFER_BULK: |  | ||||||
| 		setbits_le32(®s->fifocfg, |  | ||||||
| 			FIFOCFG(id, FIFOCFG_EN | FIFOCFG_BULK)); |  | ||||||
| 		break; |  | ||||||
| 
 |  | ||||||
| 	case USB_ENDPOINT_XFER_INT: |  | ||||||
| 		setbits_le32(®s->fifocfg, |  | ||||||
| 			FIFOCFG(id, FIFOCFG_EN | FIFOCFG_INTR)); |  | ||||||
| 		break; |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	return 0; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| static int fotg210_ep_disable(struct usb_ep *_ep) |  | ||||||
| { |  | ||||||
| 	struct fotg210_ep *ep = container_of(_ep, struct fotg210_ep, ep); |  | ||||||
| 	struct fotg210_chip *chip = ep->chip; |  | ||||||
| 	struct fotg210_regs *regs = chip->regs; |  | ||||||
| 	int id = ep_to_fifo(chip, ep->id); |  | ||||||
| 
 |  | ||||||
| 	ep->desc = NULL; |  | ||||||
| 	ep->stopped = 1; |  | ||||||
| 
 |  | ||||||
| 	clrbits_le32(®s->fifocfg, FIFOCFG(id, FIFOCFG_CFG_MASK)); |  | ||||||
| 	clrbits_le32(®s->fifomap, FIFOMAP(id, FIFOMAP_DIR_MASK)); |  | ||||||
| 
 |  | ||||||
| 	return 0; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| static struct usb_request *fotg210_ep_alloc_request( |  | ||||||
| 	struct usb_ep *_ep, gfp_t gfp_flags) |  | ||||||
| { |  | ||||||
| 	struct fotg210_request *req = malloc(sizeof(*req)); |  | ||||||
| 
 |  | ||||||
| 	if (req) { |  | ||||||
| 		memset(req, 0, sizeof(*req)); |  | ||||||
| 		INIT_LIST_HEAD(&req->queue); |  | ||||||
| 	} |  | ||||||
| 	return &req->req; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| static void fotg210_ep_free_request( |  | ||||||
| 	struct usb_ep *_ep, struct usb_request *_req) |  | ||||||
| { |  | ||||||
| 	struct fotg210_request *req; |  | ||||||
| 
 |  | ||||||
| 	req = container_of(_req, struct fotg210_request, req); |  | ||||||
| 	free(req); |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| static int fotg210_ep_queue( |  | ||||||
| 	struct usb_ep *_ep, struct usb_request *_req, gfp_t gfp_flags) |  | ||||||
| { |  | ||||||
| 	struct fotg210_ep *ep = container_of(_ep, struct fotg210_ep, ep); |  | ||||||
| 	struct fotg210_chip *chip = ep->chip; |  | ||||||
| 	struct fotg210_regs *regs = chip->regs; |  | ||||||
| 	struct fotg210_request *req; |  | ||||||
| 
 |  | ||||||
| 	req = container_of(_req, struct fotg210_request, req); |  | ||||||
| 	if (!_req || !_req->complete || !_req->buf |  | ||||||
| 		|| !list_empty(&req->queue)) { |  | ||||||
| 		printf("fotg210: invalid request to ep%d\n", ep->id); |  | ||||||
| 		return -EINVAL; |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	if (!chip || chip->state == USB_STATE_SUSPENDED) { |  | ||||||
| 		printf("fotg210: request while chip suspended\n"); |  | ||||||
| 		return -EINVAL; |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	req->req.actual = 0; |  | ||||||
| 	req->req.status = -EINPROGRESS; |  | ||||||
| 
 |  | ||||||
| 	if (req->req.length == 0) { |  | ||||||
| 		req->req.status = 0; |  | ||||||
| 		if (req->req.complete) |  | ||||||
| 			req->req.complete(&ep->ep, &req->req); |  | ||||||
| 		return 0; |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	if (ep->id == 0) { |  | ||||||
| 		do { |  | ||||||
| 			int len = fotg210_dma(ep, req); |  | ||||||
| 			if (len < ep->ep.maxpacket) |  | ||||||
| 				break; |  | ||||||
| 			if (ep->desc->bEndpointAddress & USB_DIR_IN) |  | ||||||
| 				udelay(100); |  | ||||||
| 		} while (req->req.length > req->req.actual); |  | ||||||
| 	} else { |  | ||||||
| 		if (ep->desc->bEndpointAddress & USB_DIR_IN) { |  | ||||||
| 			do { |  | ||||||
| 				int len = fotg210_dma(ep, req); |  | ||||||
| 				if (len < ep->ep.maxpacket) |  | ||||||
| 					break; |  | ||||||
| 			} while (req->req.length > req->req.actual); |  | ||||||
| 		} else { |  | ||||||
| 			list_add_tail(&req->queue, &ep->queue); |  | ||||||
| 			clrbits_le32(®s->gimr1, |  | ||||||
| 				GIMR1_FIFO_RX(ep_to_fifo(chip, ep->id))); |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	if (ep->id == 0 || (ep->desc->bEndpointAddress & USB_DIR_IN)) { |  | ||||||
| 		if (req->req.complete) |  | ||||||
| 			req->req.complete(&ep->ep, &req->req); |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	return 0; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| static int fotg210_ep_dequeue(struct usb_ep *_ep, struct usb_request *_req) |  | ||||||
| { |  | ||||||
| 	struct fotg210_ep *ep = container_of(_ep, struct fotg210_ep, ep); |  | ||||||
| 	struct fotg210_request *req; |  | ||||||
| 
 |  | ||||||
| 	/* make sure it's actually queued on this endpoint */ |  | ||||||
| 	list_for_each_entry(req, &ep->queue, queue) { |  | ||||||
| 		if (&req->req == _req) |  | ||||||
| 			break; |  | ||||||
| 	} |  | ||||||
| 	if (&req->req != _req) |  | ||||||
| 		return -EINVAL; |  | ||||||
| 
 |  | ||||||
| 	/* remove the request */ |  | ||||||
| 	list_del_init(&req->queue); |  | ||||||
| 
 |  | ||||||
| 	/* update status & invoke complete callback */ |  | ||||||
| 	if (req->req.status == -EINPROGRESS) { |  | ||||||
| 		req->req.status = -ECONNRESET; |  | ||||||
| 		if (req->req.complete) |  | ||||||
| 			req->req.complete(_ep, &req->req); |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	return 0; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| static int fotg210_ep_halt(struct usb_ep *_ep, int halt) |  | ||||||
| { |  | ||||||
| 	struct fotg210_ep *ep = container_of(_ep, struct fotg210_ep, ep); |  | ||||||
| 	struct fotg210_chip *chip = ep->chip; |  | ||||||
| 	struct fotg210_regs *regs = chip->regs; |  | ||||||
| 	int ret = -1; |  | ||||||
| 
 |  | ||||||
| 	debug("fotg210: ep%d halt=%d\n", ep->id, halt); |  | ||||||
| 
 |  | ||||||
| 	/* Endpoint STALL */ |  | ||||||
| 	if (ep->id > 0 && ep->id <= CFG_NUM_ENDPOINTS) { |  | ||||||
| 		if (halt) { |  | ||||||
| 			/* wait until all ep fifo empty */ |  | ||||||
| 			fotg210_cxwait(chip, 0xf00); |  | ||||||
| 			/* stall */ |  | ||||||
| 			if (ep->desc->bEndpointAddress & USB_DIR_IN) { |  | ||||||
| 				setbits_le32(®s->iep[ep->id - 1], |  | ||||||
| 					IEP_STALL); |  | ||||||
| 			} else { |  | ||||||
| 				setbits_le32(®s->oep[ep->id - 1], |  | ||||||
| 					OEP_STALL); |  | ||||||
| 			} |  | ||||||
| 		} else { |  | ||||||
| 			if (ep->desc->bEndpointAddress & USB_DIR_IN) { |  | ||||||
| 				clrbits_le32(®s->iep[ep->id - 1], |  | ||||||
| 					IEP_STALL); |  | ||||||
| 			} else { |  | ||||||
| 				clrbits_le32(®s->oep[ep->id - 1], |  | ||||||
| 					OEP_STALL); |  | ||||||
| 			} |  | ||||||
| 		} |  | ||||||
| 		ret = 0; |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	return ret; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| /*
 |  | ||||||
|  * activate/deactivate link with host. |  | ||||||
|  */ |  | ||||||
| static void pullup(struct fotg210_chip *chip, int is_on) |  | ||||||
| { |  | ||||||
| 	struct fotg210_regs *regs = chip->regs; |  | ||||||
| 
 |  | ||||||
| 	if (is_on) { |  | ||||||
| 		if (!chip->pullup) { |  | ||||||
| 			chip->state = USB_STATE_POWERED; |  | ||||||
| 			chip->pullup = 1; |  | ||||||
| 			/* enable the chip */ |  | ||||||
| 			setbits_le32(®s->dev_ctrl, DEVCTRL_EN); |  | ||||||
| 			/* clear unplug bit (BIT0) */ |  | ||||||
| 			clrbits_le32(®s->phy_tmsr, PHYTMSR_UNPLUG); |  | ||||||
| 		} |  | ||||||
| 	} else { |  | ||||||
| 		chip->state = USB_STATE_NOTATTACHED; |  | ||||||
| 		chip->pullup = 0; |  | ||||||
| 		chip->addr = 0; |  | ||||||
| 		writel(chip->addr, ®s->dev_addr); |  | ||||||
| 		/* set unplug bit (BIT0) */ |  | ||||||
| 		setbits_le32(®s->phy_tmsr, PHYTMSR_UNPLUG); |  | ||||||
| 		/* disable the chip */ |  | ||||||
| 		clrbits_le32(®s->dev_ctrl, DEVCTRL_EN); |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| static int fotg210_pullup(struct usb_gadget *_gadget, int is_on) |  | ||||||
| { |  | ||||||
| 	struct fotg210_chip *chip; |  | ||||||
| 
 |  | ||||||
| 	chip = container_of(_gadget, struct fotg210_chip, gadget); |  | ||||||
| 
 |  | ||||||
| 	debug("fotg210: pullup=%d\n", is_on); |  | ||||||
| 
 |  | ||||||
| 	pullup(chip, is_on); |  | ||||||
| 
 |  | ||||||
| 	return 0; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| static int fotg210_get_frame(struct usb_gadget *_gadget) |  | ||||||
| { |  | ||||||
| 	struct fotg210_chip *chip; |  | ||||||
| 	struct fotg210_regs *regs; |  | ||||||
| 
 |  | ||||||
| 	chip = container_of(_gadget, struct fotg210_chip, gadget); |  | ||||||
| 	regs = chip->regs; |  | ||||||
| 
 |  | ||||||
| 	return SOFFNR_FNR(readl(®s->sof_fnr)); |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| static struct usb_gadget_ops fotg210_gadget_ops = { |  | ||||||
| 	.get_frame = fotg210_get_frame, |  | ||||||
| 	.pullup = fotg210_pullup, |  | ||||||
| }; |  | ||||||
| 
 |  | ||||||
| static struct usb_ep_ops fotg210_ep_ops = { |  | ||||||
| 	.enable         = fotg210_ep_enable, |  | ||||||
| 	.disable        = fotg210_ep_disable, |  | ||||||
| 	.queue          = fotg210_ep_queue, |  | ||||||
| 	.dequeue        = fotg210_ep_dequeue, |  | ||||||
| 	.set_halt       = fotg210_ep_halt, |  | ||||||
| 	.alloc_request  = fotg210_ep_alloc_request, |  | ||||||
| 	.free_request   = fotg210_ep_free_request, |  | ||||||
| }; |  | ||||||
| 
 |  | ||||||
| static struct fotg210_chip controller = { |  | ||||||
| 	.regs = (void __iomem *)CONFIG_FOTG210_BASE, |  | ||||||
| 	.gadget = { |  | ||||||
| 		.name = "fotg210_udc", |  | ||||||
| 		.ops = &fotg210_gadget_ops, |  | ||||||
| 		.ep0 = &controller.ep[0].ep, |  | ||||||
| 		.speed = USB_SPEED_UNKNOWN, |  | ||||||
| 		.is_dualspeed = 1, |  | ||||||
| 		.is_otg = 0, |  | ||||||
| 		.is_a_peripheral = 0, |  | ||||||
| 		.b_hnp_enable = 0, |  | ||||||
| 		.a_hnp_support = 0, |  | ||||||
| 		.a_alt_hnp_support = 0, |  | ||||||
| 	}, |  | ||||||
| 	.ep[0] = { |  | ||||||
| 		.id = 0, |  | ||||||
| 		.ep = { |  | ||||||
| 			.name  = "ep0", |  | ||||||
| 			.ops   = &fotg210_ep_ops, |  | ||||||
| 		}, |  | ||||||
| 		.desc      = &ep0_desc, |  | ||||||
| 		.chip      = &controller, |  | ||||||
| 		.maxpacket = CFG_EP0_MAX_PACKET_SIZE, |  | ||||||
| 	}, |  | ||||||
| 	.ep[1] = { |  | ||||||
| 		.id = 1, |  | ||||||
| 		.ep = { |  | ||||||
| 			.name  = "ep1", |  | ||||||
| 			.ops   = &fotg210_ep_ops, |  | ||||||
| 		}, |  | ||||||
| 		.chip      = &controller, |  | ||||||
| 		.maxpacket = CFG_EPX_MAX_PACKET_SIZE, |  | ||||||
| 	}, |  | ||||||
| 	.ep[2] = { |  | ||||||
| 		.id = 2, |  | ||||||
| 		.ep = { |  | ||||||
| 			.name  = "ep2", |  | ||||||
| 			.ops   = &fotg210_ep_ops, |  | ||||||
| 		}, |  | ||||||
| 		.chip      = &controller, |  | ||||||
| 		.maxpacket = CFG_EPX_MAX_PACKET_SIZE, |  | ||||||
| 	}, |  | ||||||
| 	.ep[3] = { |  | ||||||
| 		.id = 3, |  | ||||||
| 		.ep = { |  | ||||||
| 			.name  = "ep3", |  | ||||||
| 			.ops   = &fotg210_ep_ops, |  | ||||||
| 		}, |  | ||||||
| 		.chip      = &controller, |  | ||||||
| 		.maxpacket = CFG_EPX_MAX_PACKET_SIZE, |  | ||||||
| 	}, |  | ||||||
| 	.ep[4] = { |  | ||||||
| 		.id = 4, |  | ||||||
| 		.ep = { |  | ||||||
| 			.name  = "ep4", |  | ||||||
| 			.ops   = &fotg210_ep_ops, |  | ||||||
| 		}, |  | ||||||
| 		.chip      = &controller, |  | ||||||
| 		.maxpacket = CFG_EPX_MAX_PACKET_SIZE, |  | ||||||
| 	}, |  | ||||||
| }; |  | ||||||
| 
 |  | ||||||
| int usb_gadget_handle_interrupts(int index) |  | ||||||
| { |  | ||||||
| 	struct fotg210_chip *chip = &controller; |  | ||||||
| 	struct fotg210_regs *regs = chip->regs; |  | ||||||
| 	uint32_t id, st, isr, gisr; |  | ||||||
| 
 |  | ||||||
| 	isr  = readl(®s->isr) & (~readl(®s->imr)); |  | ||||||
| 	gisr = readl(®s->gisr) & (~readl(®s->gimr)); |  | ||||||
| 	if (!(isr & ISR_DEV) || !gisr) |  | ||||||
| 		return 0; |  | ||||||
| 
 |  | ||||||
| 	writel(ISR_DEV, ®s->isr); |  | ||||||
| 
 |  | ||||||
| 	/* CX interrupts */ |  | ||||||
| 	if (gisr & GISR_GRP0) { |  | ||||||
| 		st = readl(®s->gisr0); |  | ||||||
| 		/*
 |  | ||||||
| 		 * Write 1 and then 0 works for both W1C & RW. |  | ||||||
| 		 * |  | ||||||
| 		 * HW v1.11.0+: It's a W1C register (write 1 clear) |  | ||||||
| 		 * HW v1.10.0-: It's a R/W register (write 0 clear) |  | ||||||
| 		 */ |  | ||||||
| 		writel(st & GISR0_CXABORT, ®s->gisr0); |  | ||||||
| 		writel(0, ®s->gisr0); |  | ||||||
| 
 |  | ||||||
| 		if (st & GISR0_CXERR) |  | ||||||
| 			printf("fotg210: cmd error\n"); |  | ||||||
| 
 |  | ||||||
| 		if (st & GISR0_CXABORT) |  | ||||||
| 			printf("fotg210: cmd abort\n"); |  | ||||||
| 
 |  | ||||||
| 		if (st & GISR0_CXSETUP)    /* setup */ |  | ||||||
| 			fotg210_setup(chip); |  | ||||||
| 		else if (st & GISR0_CXEND) /* command finish */ |  | ||||||
| 			setbits_le32(®s->cxfifo, CXFIFO_CXFIN); |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	/* FIFO interrupts */ |  | ||||||
| 	if (gisr & GISR_GRP1) { |  | ||||||
| 		st = readl(®s->gisr1); |  | ||||||
| 		for (id = 0; id < 4; ++id) { |  | ||||||
| 			if (st & GISR1_RX_FIFO(id)) |  | ||||||
| 				fotg210_recv(chip, fifo_to_ep(chip, id, 0)); |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	/* Device Status Interrupts */ |  | ||||||
| 	if (gisr & GISR_GRP2) { |  | ||||||
| 		st = readl(®s->gisr2); |  | ||||||
| 		/*
 |  | ||||||
| 		 * Write 1 and then 0 works for both W1C & RW. |  | ||||||
| 		 * |  | ||||||
| 		 * HW v1.11.0+: It's a W1C register (write 1 clear) |  | ||||||
| 		 * HW v1.10.0-: It's a R/W register (write 0 clear) |  | ||||||
| 		 */ |  | ||||||
| 		writel(st, ®s->gisr2); |  | ||||||
| 		writel(0, ®s->gisr2); |  | ||||||
| 
 |  | ||||||
| 		if (st & GISR2_RESET) |  | ||||||
| 			printf("fotg210: reset by host\n"); |  | ||||||
| 		else if (st & GISR2_SUSPEND) |  | ||||||
| 			printf("fotg210: suspend/removed\n"); |  | ||||||
| 		else if (st & GISR2_RESUME) |  | ||||||
| 			printf("fotg210: resume\n"); |  | ||||||
| 
 |  | ||||||
| 		/* Errors */ |  | ||||||
| 		if (st & GISR2_ISOCERR) |  | ||||||
| 			printf("fotg210: iso error\n"); |  | ||||||
| 		if (st & GISR2_ISOCABT) |  | ||||||
| 			printf("fotg210: iso abort\n"); |  | ||||||
| 		if (st & GISR2_DMAERR) |  | ||||||
| 			printf("fotg210: dma error\n"); |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	return 0; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| int usb_gadget_register_driver(struct usb_gadget_driver *driver) |  | ||||||
| { |  | ||||||
| 	int i, ret = 0; |  | ||||||
| 	struct fotg210_chip *chip = &controller; |  | ||||||
| 
 |  | ||||||
| 	if (!driver    || !driver->bind || !driver->setup) { |  | ||||||
| 		puts("fotg210: bad parameter.\n"); |  | ||||||
| 		return -EINVAL; |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	INIT_LIST_HEAD(&chip->gadget.ep_list); |  | ||||||
| 	for (i = 0; i < CFG_NUM_ENDPOINTS + 1; ++i) { |  | ||||||
| 		struct fotg210_ep *ep = chip->ep + i; |  | ||||||
| 
 |  | ||||||
| 		ep->ep.maxpacket = ep->maxpacket; |  | ||||||
| 		INIT_LIST_HEAD(&ep->queue); |  | ||||||
| 
 |  | ||||||
| 		if (ep->id == 0) { |  | ||||||
| 			ep->stopped = 0; |  | ||||||
| 		} else { |  | ||||||
| 			ep->stopped = 1; |  | ||||||
| 			list_add_tail(&ep->ep.ep_list, &chip->gadget.ep_list); |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	if (fotg210_reset(chip)) { |  | ||||||
| 		puts("fotg210: reset failed.\n"); |  | ||||||
| 		return -EINVAL; |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	ret = driver->bind(&chip->gadget); |  | ||||||
| 	if (ret) { |  | ||||||
| 		debug("fotg210: driver->bind() returned %d\n", ret); |  | ||||||
| 		return ret; |  | ||||||
| 	} |  | ||||||
| 	chip->driver = driver; |  | ||||||
| 
 |  | ||||||
| 	return ret; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| int usb_gadget_unregister_driver(struct usb_gadget_driver *driver) |  | ||||||
| { |  | ||||||
| 	struct fotg210_chip *chip = &controller; |  | ||||||
| 
 |  | ||||||
| 	driver->unbind(&chip->gadget); |  | ||||||
| 	chip->driver = NULL; |  | ||||||
| 
 |  | ||||||
| 	pullup(chip, 0); |  | ||||||
| 
 |  | ||||||
| 	return 0; |  | ||||||
| } |  | ||||||
|  | @ -117,12 +117,6 @@ | ||||||
| #define gadget_is_ci(g)        0 | #define gadget_is_ci(g)        0 | ||||||
| #endif | #endif | ||||||
| 
 | 
 | ||||||
| #ifdef CONFIG_USB_GADGET_FOTG210 |  | ||||||
| #define gadget_is_fotg210(g)        (!strcmp("fotg210_udc", (g)->name)) |  | ||||||
| #else |  | ||||||
| #define gadget_is_fotg210(g)        0 |  | ||||||
| #endif |  | ||||||
| 
 |  | ||||||
| #ifdef CONFIG_USB_DWC3_GADGET | #ifdef CONFIG_USB_DWC3_GADGET | ||||||
| #define gadget_is_dwc3(g)        (!strcmp("dwc3-gadget", (g)->name)) | #define gadget_is_dwc3(g)        (!strcmp("dwc3-gadget", (g)->name)) | ||||||
| #else | #else | ||||||
|  | @ -202,8 +196,6 @@ static inline int usb_gadget_controller_number(struct usb_gadget *gadget) | ||||||
| 		return 0x20; | 		return 0x20; | ||||||
| 	else if (gadget_is_ci(gadget)) | 	else if (gadget_is_ci(gadget)) | ||||||
| 		return 0x21; | 		return 0x21; | ||||||
| 	else if (gadget_is_fotg210(gadget)) |  | ||||||
| 		return 0x22; |  | ||||||
| 	else if (gadget_is_dwc3(gadget)) | 	else if (gadget_is_dwc3(gadget)) | ||||||
| 		return 0x23; | 		return 0x23; | ||||||
| 	else if (gadget_is_cdns3(gadget)) | 	else if (gadget_is_cdns3(gadget)) | ||||||
|  |  | ||||||
|  | @ -1,362 +0,0 @@ | ||||||
| /* SPDX-License-Identifier: GPL-2.0+ */ |  | ||||||
| /*
 |  | ||||||
|  * Faraday USB 2.0 OTG Controller |  | ||||||
|  * |  | ||||||
|  * (C) Copyright 2010 Faraday Technology |  | ||||||
|  * Dante Su <dantesu@faraday-tech.com> |  | ||||||
|  */ |  | ||||||
| 
 |  | ||||||
| #ifndef _FOTG210_H |  | ||||||
| #define _FOTG210_H |  | ||||||
| 
 |  | ||||||
| struct fotg210_regs { |  | ||||||
| 	/* USB Host Controller */ |  | ||||||
| 	struct { |  | ||||||
| 		uint32_t data[4]; |  | ||||||
| 	} hccr;			/* 0x00 - 0x0f: hccr */ |  | ||||||
| 	struct { |  | ||||||
| 		uint32_t data[9]; |  | ||||||
| 	} hcor;			/* 0x10 - 0x33: hcor */ |  | ||||||
| 	uint32_t rsvd1[3]; |  | ||||||
| 	uint32_t miscr;	/* 0x40: Miscellaneous Register */ |  | ||||||
| 	uint32_t rsvd2[15]; |  | ||||||
| 	/* USB OTG Controller */ |  | ||||||
| 	uint32_t otgcsr;/* 0x80: OTG Control Status Register */ |  | ||||||
| 	uint32_t otgisr;/* 0x84: OTG Interrupt Status Register */ |  | ||||||
| 	uint32_t otgier;/* 0x88: OTG Interrupt Enable Register */ |  | ||||||
| 	uint32_t rsvd3[13]; |  | ||||||
| 	uint32_t isr;	/* 0xC0: Global Interrupt Status Register */ |  | ||||||
| 	uint32_t imr;	/* 0xC4: Global Interrupt Mask Register */ |  | ||||||
| 	uint32_t rsvd4[14]; |  | ||||||
| 	/* USB Device Controller */ |  | ||||||
| 	uint32_t dev_ctrl;/* 0x100: Device Control Register */ |  | ||||||
| 	uint32_t dev_addr;/* 0x104: Device Address Register */ |  | ||||||
| 	uint32_t dev_test;/* 0x108: Device Test Register */ |  | ||||||
| 	uint32_t sof_fnr; /* 0x10c: SOF Frame Number Register */ |  | ||||||
| 	uint32_t sof_mtr; /* 0x110: SOF Mask Timer Register */ |  | ||||||
| 	uint32_t phy_tmsr;/* 0x114: PHY Test Mode Selector Register */ |  | ||||||
| 	uint32_t rsvd5[2]; |  | ||||||
| 	uint32_t cxfifo;/* 0x120: CX FIFO Register */ |  | ||||||
| 	uint32_t idle;	/* 0x124: IDLE Counter Register */ |  | ||||||
| 	uint32_t rsvd6[2]; |  | ||||||
| 	uint32_t gimr;	/* 0x130: Group Interrupt Mask Register */ |  | ||||||
| 	uint32_t gimr0; /* 0x134: Group Interrupt Mask Register 0 */ |  | ||||||
| 	uint32_t gimr1; /* 0x138: Group Interrupt Mask Register 1 */ |  | ||||||
| 	uint32_t gimr2; /* 0x13c: Group Interrupt Mask Register 2 */ |  | ||||||
| 	uint32_t gisr;	/* 0x140: Group Interrupt Status Register */ |  | ||||||
| 	uint32_t gisr0; /* 0x144: Group Interrupt Status Register 0 */ |  | ||||||
| 	uint32_t gisr1; /* 0x148: Group Interrupt Status Register 1 */ |  | ||||||
| 	uint32_t gisr2; /* 0x14c: Group Interrupt Status Register 2 */ |  | ||||||
| 	uint32_t rxzlp; /* 0x150: Receive Zero-Length-Packet Register */ |  | ||||||
| 	uint32_t txzlp; /* 0x154: Transfer Zero-Length-Packet Register */ |  | ||||||
| 	uint32_t isoeasr;/* 0x158: ISOC Error/Abort Status Register */ |  | ||||||
| 	uint32_t rsvd7[1]; |  | ||||||
| 	uint32_t iep[8]; /* 0x160 - 0x17f: IN Endpoint Register */ |  | ||||||
| 	uint32_t oep[8]; /* 0x180 - 0x19f: OUT Endpoint Register */ |  | ||||||
| 	uint32_t epmap14;/* 0x1a0: Endpoint Map Register (EP1 ~ 4) */ |  | ||||||
| 	uint32_t epmap58;/* 0x1a4: Endpoint Map Register (EP5 ~ 8) */ |  | ||||||
| 	uint32_t fifomap;/* 0x1a8: FIFO Map Register */ |  | ||||||
| 	uint32_t fifocfg; /* 0x1ac: FIFO Configuration Register */ |  | ||||||
| 	uint32_t fifocsr[4];/* 0x1b0 - 0x1bf: FIFO Control Status Register */ |  | ||||||
| 	uint32_t dma_fifo; /* 0x1c0: DMA Target FIFO Register */ |  | ||||||
| 	uint32_t rsvd8[1]; |  | ||||||
| 	uint32_t dma_ctrl; /* 0x1c8: DMA Control Register */ |  | ||||||
| 	uint32_t dma_addr; /* 0x1cc: DMA Address Register */ |  | ||||||
| 	uint32_t ep0_data; /* 0x1d0: EP0 Setup Packet PIO Register */ |  | ||||||
| }; |  | ||||||
| 
 |  | ||||||
| /* Miscellaneous Register */ |  | ||||||
| #define MISCR_SUSPEND  (1 << 6) /* Put transceiver in suspend mode */ |  | ||||||
| #define MISCR_EOF2(x)  (((x) & 0x3) << 4) /* EOF 2 Timing */ |  | ||||||
| #define MISCR_EOF1(x)  (((x) & 0x3) << 2) /* EOF 1 Timing */ |  | ||||||
| #define MISCR_ASST(x)  (((x) & 0x3) << 0) /* Async. Sched. Sleep Timer */ |  | ||||||
| 
 |  | ||||||
| /* OTG Control Status Register */ |  | ||||||
| #define OTGCSR_SPD_HIGH     (2 << 22) /* Speed of the attached device (host) */ |  | ||||||
| #define OTGCSR_SPD_LOW      (1 << 22) |  | ||||||
| #define OTGCSR_SPD_FULL     (0 << 22) |  | ||||||
| #define OTGCSR_SPD_MASK     (3 << 22) |  | ||||||
| #define OTGCSR_SPD_SHIFT    22 |  | ||||||
| #define OTGCSR_SPD(x)       (((x) >> 22) & 0x03) |  | ||||||
| #define OTGCSR_DEV_A        (0 << 21) /* Acts as A-device */ |  | ||||||
| #define OTGCSR_DEV_B        (1 << 21) /* Acts as B-device */ |  | ||||||
| #define OTGCSR_ROLE_H       (0 << 20) /* Acts as Host */ |  | ||||||
| #define OTGCSR_ROLE_D       (1 << 20) /* Acts as Device */ |  | ||||||
| #define OTGCSR_A_VBUS_VLD   (1 << 19) /* A-device VBUS Valid */ |  | ||||||
| #define OTGCSR_A_SESS_VLD   (1 << 18) /* A-device Session Valid */ |  | ||||||
| #define OTGCSR_B_SESS_VLD   (1 << 17) /* B-device Session Valid */ |  | ||||||
| #define OTGCSR_B_SESS_END   (1 << 16) /* B-device Session End */ |  | ||||||
| #define OTGCSR_HFT_LONG     (1 << 11) /* HDISCON noise filter = 270 us*/ |  | ||||||
| #define OTGCSR_HFT          (0 << 11) /* HDISCON noise filter = 135 us*/ |  | ||||||
| #define OTGCSR_VFT_LONG     (1 << 10) /* VBUS noise filter = 472 us*/ |  | ||||||
| #define OTGCSR_VFT          (0 << 10) /* VBUS noise filter = 135 us*/ |  | ||||||
| #define OTGCSR_IDFT_LONG    (1 << 9)  /* ID noise filter = 4 ms*/ |  | ||||||
| #define OTGCSR_IDFT         (0 << 9)  /* ID noise filter = 3 ms*/ |  | ||||||
| #define OTGCSR_A_SRPR_VBUS  (0 << 8)  /* A-device: SRP responds to VBUS */ |  | ||||||
| #define OTGCSR_A_SRPR_DATA  (1 << 8)  /* A-device: SRP responds to DATA-LINE */ |  | ||||||
| #define OTGCSR_A_SRP_EN     (1 << 7)  /* A-device SRP detection enabled */ |  | ||||||
| #define OTGCSR_A_HNP        (1 << 6)  /* Set role=A-device with HNP enabled */ |  | ||||||
| #define OTGCSR_A_BUSDROP    (1 << 5)  /* A-device drop bus (power-down) */ |  | ||||||
| #define OTGCSR_A_BUSREQ     (1 << 4)  /* A-device request bus */ |  | ||||||
| #define OTGCSR_B_VBUS_DISC  (1 << 2)  /* B-device discharges VBUS */ |  | ||||||
| #define OTGCSR_B_HNP        (1 << 1)  /* B-device enable HNP */ |  | ||||||
| #define OTGCSR_B_BUSREQ     (1 << 0)  /* B-device request bus */ |  | ||||||
| 
 |  | ||||||
| /* OTG Interrupt Status Register */ |  | ||||||
| #define OTGISR_APRM         (1 << 12) /* Mini-A plug removed */ |  | ||||||
| #define OTGISR_BPRM         (1 << 11) /* Mini-B plug removed */ |  | ||||||
| #define OTGISR_OVD          (1 << 10) /* over-current detected */ |  | ||||||
| #define OTGISR_IDCHG        (1 << 9)  /* ID(A/B) changed */ |  | ||||||
| #define OTGISR_RLCHG        (1 << 8)  /* Role(Host/Device) changed */ |  | ||||||
| #define OTGISR_BSESSEND     (1 << 6)  /* B-device Session End */ |  | ||||||
| #define OTGISR_AVBUSERR     (1 << 5)  /* A-device VBUS Error */ |  | ||||||
| #define OTGISR_ASRP         (1 << 4)  /* A-device SRP detected */ |  | ||||||
| #define OTGISR_BSRP         (1 << 0)  /* B-device SRP complete */ |  | ||||||
| 
 |  | ||||||
| /* OTG Interrupt Enable Register */ |  | ||||||
| #define OTGIER_APRM         (1 << 12) /* Mini-A plug removed */ |  | ||||||
| #define OTGIER_BPRM         (1 << 11) /* Mini-B plug removed */ |  | ||||||
| #define OTGIER_OVD          (1 << 10) /* over-current detected */ |  | ||||||
| #define OTGIER_IDCHG        (1 << 9)  /* ID(A/B) changed */ |  | ||||||
| #define OTGIER_RLCHG        (1 << 8)  /* Role(Host/Device) changed */ |  | ||||||
| #define OTGIER_BSESSEND     (1 << 6)  /* B-device Session End */ |  | ||||||
| #define OTGIER_AVBUSERR     (1 << 5)  /* A-device VBUS Error */ |  | ||||||
| #define OTGIER_ASRP         (1 << 4)  /* A-device SRP detected */ |  | ||||||
| #define OTGIER_BSRP         (1 << 0)  /* B-device SRP complete */ |  | ||||||
| 
 |  | ||||||
| /* Global Interrupt Status Register (W1C) */ |  | ||||||
| #define ISR_HOST            (1 << 2)  /* USB Host interrupt */ |  | ||||||
| #define ISR_OTG             (1 << 1)  /* USB OTG interrupt */ |  | ||||||
| #define ISR_DEV             (1 << 0)  /* USB Device interrupt */ |  | ||||||
| #define ISR_MASK            0x07 |  | ||||||
| 
 |  | ||||||
| /* Global Interrupt Mask Register */ |  | ||||||
| #define IMR_IRQLH           (1 << 3)  /* Interrupt triggered at level-high */ |  | ||||||
| #define IMR_IRQLL           (0 << 3)  /* Interrupt triggered at level-low */ |  | ||||||
| #define IMR_HOST            (1 << 2)  /* USB Host interrupt */ |  | ||||||
| #define IMR_OTG             (1 << 1)  /* USB OTG interrupt */ |  | ||||||
| #define IMR_DEV             (1 << 0)  /* USB Device interrupt */ |  | ||||||
| #define IMR_MASK            0x0f |  | ||||||
| 
 |  | ||||||
| /* Device Control Register */ |  | ||||||
| #define DEVCTRL_FS_FORCED   (1 << 9)  /* Forced to be Full-Speed Mode */ |  | ||||||
| #define DEVCTRL_HS          (1 << 6)  /* High Speed Mode */ |  | ||||||
| #define DEVCTRL_FS          (0 << 6)  /* Full Speed Mode */ |  | ||||||
| #define DEVCTRL_EN          (1 << 5)  /* Chip Enable */ |  | ||||||
| #define DEVCTRL_RESET       (1 << 4)  /* Chip Software Reset */ |  | ||||||
| #define DEVCTRL_SUSPEND     (1 << 3)  /* Enter Suspend Mode */ |  | ||||||
| #define DEVCTRL_GIRQ_EN     (1 << 2)  /* Global Interrupt Enabled */ |  | ||||||
| #define DEVCTRL_HALFSPD     (1 << 1)  /* Half speed mode for FPGA test */ |  | ||||||
| #define DEVCTRL_RWAKEUP     (1 << 0)  /* Enable remote wake-up */ |  | ||||||
| 
 |  | ||||||
| /* Device Address Register */ |  | ||||||
| #define DEVADDR_CONF        (1 << 7)  /* SET_CONFIGURATION has been executed */ |  | ||||||
| #define DEVADDR_ADDR(x)     ((x) & 0x7f) |  | ||||||
| #define DEVADDR_ADDR_MASK   0x7f |  | ||||||
| 
 |  | ||||||
| /* Device Test Register */ |  | ||||||
| #define DEVTEST_NOSOF       (1 << 6)  /* Do not generate SOF */ |  | ||||||
| #define DEVTEST_TST_MODE    (1 << 5)  /* Enter Test Mode */ |  | ||||||
| #define DEVTEST_TST_NOTS    (1 << 4)  /* Do not toggle sequence */ |  | ||||||
| #define DEVTEST_TST_NOCRC   (1 << 3)  /* Do not append CRC */ |  | ||||||
| #define DEVTEST_TST_CLREA   (1 << 2)  /* Clear External Side Address */ |  | ||||||
| #define DEVTEST_TST_CXLP    (1 << 1)  /* EP0 loopback test */ |  | ||||||
| #define DEVTEST_TST_CLRFF   (1 << 0)  /* Clear FIFO */ |  | ||||||
| 
 |  | ||||||
| /* SOF Frame Number Register */ |  | ||||||
| #define SOFFNR_UFN(x)       (((x) >> 11) & 0x7) /* SOF Micro-Frame Number */ |  | ||||||
| #define SOFFNR_FNR(x)       ((x) & 0x7ff) /* SOF Frame Number */ |  | ||||||
| 
 |  | ||||||
| /* SOF Mask Timer Register */ |  | ||||||
| #define SOFMTR_TMR(x)       ((x) & 0xffff) |  | ||||||
| 
 |  | ||||||
| /* PHY Test Mode Selector Register */ |  | ||||||
| #define PHYTMSR_TST_PKT     (1 << 4) /* Packet send test */ |  | ||||||
| #define PHYTMSR_TST_SE0NAK  (1 << 3) /* High-Speed quiescent state */ |  | ||||||
| #define PHYTMSR_TST_KSTA    (1 << 2) /* High-Speed K state */ |  | ||||||
| #define PHYTMSR_TST_JSTA    (1 << 1) /* High-Speed J state */ |  | ||||||
| #define PHYTMSR_UNPLUG      (1 << 0) /* Enable soft-detachment */ |  | ||||||
| 
 |  | ||||||
| /* CX FIFO Register */ |  | ||||||
| #define CXFIFO_BYTES(x)     (((x) >> 24) & 0x7f) /* CX/EP0 FIFO byte count */ |  | ||||||
| #define CXFIFO_FIFOE(x)     (1 << (((x) & 0x03) + 8)) /* EPx FIFO empty */ |  | ||||||
| #define CXFIFO_FIFOE_FIFO0  (1 << 8) |  | ||||||
| #define CXFIFO_FIFOE_FIFO1  (1 << 9) |  | ||||||
| #define CXFIFO_FIFOE_FIFO2  (1 << 10) |  | ||||||
| #define CXFIFO_FIFOE_FIFO3  (1 << 11) |  | ||||||
| #define CXFIFO_FIFOE_MASK   (0x0f << 8) |  | ||||||
| #define CXFIFO_CXFIFOE      (1 << 5) /* CX FIFO empty */ |  | ||||||
| #define CXFIFO_CXFIFOF      (1 << 4) /* CX FIFO full */ |  | ||||||
| #define CXFIFO_CXFIFOCLR    (1 << 3) /* CX FIFO clear */ |  | ||||||
| #define CXFIFO_CXSTALL      (1 << 2) /* CX Stall */ |  | ||||||
| #define CXFIFO_TSTPKTFIN    (1 << 1) /* Test packet data transfer finished */ |  | ||||||
| #define CXFIFO_CXFIN        (1 << 0) /* CX data transfer finished */ |  | ||||||
| 
 |  | ||||||
| /* IDLE Counter Register */ |  | ||||||
| #define IDLE_MS(x)          ((x) & 0x07) /* PHY suspend delay = x ms */ |  | ||||||
| 
 |  | ||||||
| /* Group Interrupt Mask(Disable) Register */ |  | ||||||
| #define GIMR_GRP2           (1 << 2) /* Disable interrupt group 2 */ |  | ||||||
| #define GIMR_GRP1           (1 << 1) /* Disable interrupt group 1 */ |  | ||||||
| #define GIMR_GRP0           (1 << 0) /* Disable interrupt group 0 */ |  | ||||||
| #define GIMR_MASK           0x07 |  | ||||||
| 
 |  | ||||||
| /* Group Interrupt Mask(Disable) Register 0 (CX) */ |  | ||||||
| #define GIMR0_CXABORT       (1 << 5) /* CX command abort interrupt */ |  | ||||||
| #define GIMR0_CXERR         (1 << 4) /* CX command error interrupt */ |  | ||||||
| #define GIMR0_CXEND         (1 << 3) /* CX command end interrupt */ |  | ||||||
| #define GIMR0_CXOUT         (1 << 2) /* EP0-OUT packet interrupt */ |  | ||||||
| #define GIMR0_CXIN          (1 << 1) /* EP0-IN packet interrupt */ |  | ||||||
| #define GIMR0_CXSETUP       (1 << 0) /* EP0-SETUP packet interrupt */ |  | ||||||
| #define GIMR0_MASK          0x3f |  | ||||||
| 
 |  | ||||||
| /* Group Interrupt Mask(Disable) Register 1 (FIFO) */ |  | ||||||
| #define GIMR1_FIFO_IN(x)    (1 << (((x) & 3) + 16))    /* FIFOx IN */ |  | ||||||
| #define GIMR1_FIFO_TX(x)    GIMR1_FIFO_IN(x) |  | ||||||
| #define GIMR1_FIFO_OUT(x)   (1 << (((x) & 3) * 2))     /* FIFOx OUT */ |  | ||||||
| #define GIMR1_FIFO_SPK(x)   (1 << (((x) & 3) * 2 + 1)) /* FIFOx SHORT PACKET */ |  | ||||||
| #define GIMR1_FIFO_RX(x)    (GIMR1_FIFO_OUT(x) | GIMR1_FIFO_SPK(x)) |  | ||||||
| #define GIMR1_MASK          0xf00ff |  | ||||||
| 
 |  | ||||||
| /* Group Interrupt Mask(Disable) Register 2 (Device) */ |  | ||||||
| #define GIMR2_WAKEUP        (1 << 10) /* Device waked up */ |  | ||||||
| #define GIMR2_IDLE          (1 << 9)  /* Device idle */ |  | ||||||
| #define GIMR2_DMAERR        (1 << 8)  /* DMA error */ |  | ||||||
| #define GIMR2_DMAFIN        (1 << 7)  /* DMA finished */ |  | ||||||
| #define GIMR2_ZLPRX         (1 << 6)  /* Zero-Length-Packet Rx Interrupt */ |  | ||||||
| #define GIMR2_ZLPTX         (1 << 5)  /* Zero-Length-Packet Tx Interrupt */ |  | ||||||
| #define GIMR2_ISOCABT       (1 << 4)  /* ISOC Abort Interrupt */ |  | ||||||
| #define GIMR2_ISOCERR       (1 << 3)  /* ISOC Error Interrupt */ |  | ||||||
| #define GIMR2_RESUME        (1 << 2)  /* Resume state change Interrupt */ |  | ||||||
| #define GIMR2_SUSPEND       (1 << 1)  /* Suspend state change Interrupt */ |  | ||||||
| #define GIMR2_RESET         (1 << 0)  /* Reset Interrupt */ |  | ||||||
| #define GIMR2_MASK          0x7ff |  | ||||||
| 
 |  | ||||||
| /* Group Interrupt Status Register */ |  | ||||||
| #define GISR_GRP2           (1 << 2) /* Interrupt group 2 */ |  | ||||||
| #define GISR_GRP1           (1 << 1) /* Interrupt group 1 */ |  | ||||||
| #define GISR_GRP0           (1 << 0) /* Interrupt group 0 */ |  | ||||||
| 
 |  | ||||||
| /* Group Interrupt Status Register 0 (CX) */ |  | ||||||
| #define GISR0_CXABORT       (1 << 5) /* CX command abort interrupt */ |  | ||||||
| #define GISR0_CXERR         (1 << 4) /* CX command error interrupt */ |  | ||||||
| #define GISR0_CXEND         (1 << 3) /* CX command end interrupt */ |  | ||||||
| #define GISR0_CXOUT         (1 << 2) /* EP0-OUT packet interrupt */ |  | ||||||
| #define GISR0_CXIN          (1 << 1) /* EP0-IN packet interrupt */ |  | ||||||
| #define GISR0_CXSETUP       (1 << 0) /* EP0-SETUP packet interrupt */ |  | ||||||
| 
 |  | ||||||
| /* Group Interrupt Status Register 1 (FIFO) */ |  | ||||||
| #define GISR1_IN_FIFO(x)    (1 << (((x) & 0x03) + 16))    /* FIFOx IN */ |  | ||||||
| #define GISR1_OUT_FIFO(x)   (1 << (((x) & 0x03) * 2))     /* FIFOx OUT */ |  | ||||||
| #define GISR1_SPK_FIFO(x)   (1 << (((x) & 0x03) * 2 + 1)) /* FIFOx SPK */ |  | ||||||
| #define GISR1_RX_FIFO(x)    (3 << (((x) & 0x03) * 2))     /* FIFOx OUT/SPK */ |  | ||||||
| 
 |  | ||||||
| /* Group Interrupt Status Register 2 (Device) */ |  | ||||||
| #define GISR2_WAKEUP        (1 << 10) /* Device waked up */ |  | ||||||
| #define GISR2_IDLE          (1 << 9)  /* Device idle */ |  | ||||||
| #define GISR2_DMAERR        (1 << 8)  /* DMA error */ |  | ||||||
| #define GISR2_DMAFIN        (1 << 7)  /* DMA finished */ |  | ||||||
| #define GISR2_ZLPRX         (1 << 6)  /* Zero-Length-Packet Rx Interrupt */ |  | ||||||
| #define GISR2_ZLPTX         (1 << 5)  /* Zero-Length-Packet Tx Interrupt */ |  | ||||||
| #define GISR2_ISOCABT       (1 << 4)  /* ISOC Abort Interrupt */ |  | ||||||
| #define GISR2_ISOCERR       (1 << 3)  /* ISOC Error Interrupt */ |  | ||||||
| #define GISR2_RESUME        (1 << 2)  /* Resume state change Interrupt */ |  | ||||||
| #define GISR2_SUSPEND       (1 << 1)  /* Suspend state change Interrupt */ |  | ||||||
| #define GISR2_RESET         (1 << 0)  /* Reset Interrupt */ |  | ||||||
| 
 |  | ||||||
| /* Receive Zero-Length-Packet Register */ |  | ||||||
| #define RXZLP_EP(x)         (1 << ((x) - 1)) /* EPx ZLP rx interrupt */ |  | ||||||
| 
 |  | ||||||
| /* Transfer Zero-Length-Packet Register */ |  | ||||||
| #define TXZLP_EP(x)         (1 << ((x) - 1)) /* EPx ZLP tx interrupt */ |  | ||||||
| 
 |  | ||||||
| /* ISOC Error/Abort Status Register */ |  | ||||||
| #define ISOEASR_EP(x)       (0x10001 << ((x) - 1)) /* EPx ISOC Error/Abort */ |  | ||||||
| 
 |  | ||||||
| /* IN Endpoint Register */ |  | ||||||
| #define IEP_SENDZLP         (1 << 15)     /* Send Zero-Length-Packet */ |  | ||||||
| #define IEP_TNRHB(x)        (((x) & 0x03) << 13) \ |  | ||||||
| 	/* Transaction Number for High-Bandwidth EP(ISOC) */ |  | ||||||
| #define IEP_RESET           (1 << 12)     /* Reset Toggle Sequence */ |  | ||||||
| #define IEP_STALL           (1 << 11)     /* Stall */ |  | ||||||
| #define IEP_MAXPS(x)        ((x) & 0x7ff) /* Max. packet size */ |  | ||||||
| 
 |  | ||||||
| /* OUT Endpoint Register */ |  | ||||||
| #define OEP_RESET           (1 << 12)     /* Reset Toggle Sequence */ |  | ||||||
| #define OEP_STALL           (1 << 11)     /* Stall */ |  | ||||||
| #define OEP_MAXPS(x)        ((x) & 0x7ff) /* Max. packet size */ |  | ||||||
| 
 |  | ||||||
| /* Endpoint Map Register (EP1 ~ EP4) */ |  | ||||||
| #define EPMAP14_SET_IN(ep, fifo) \ |  | ||||||
| 	((fifo) & 3) << (((ep) - 1) << 3 + 0) |  | ||||||
| #define EPMAP14_SET_OUT(ep, fifo) \ |  | ||||||
| 	((fifo) & 3) << (((ep) - 1) << 3 + 4) |  | ||||||
| #define EPMAP14_SET(ep, in, out) \ |  | ||||||
| 	do { \ |  | ||||||
| 		EPMAP14_SET_IN(ep, in); \ |  | ||||||
| 		EPMAP14_SET_OUT(ep, out); \ |  | ||||||
| 	} while (0) |  | ||||||
| 
 |  | ||||||
| #define EPMAP14_DEFAULT     0x33221100 /* EP1->FIFO0, EP2->FIFO1... */ |  | ||||||
| 
 |  | ||||||
| /* Endpoint Map Register (EP5 ~ EP8) */ |  | ||||||
| #define EPMAP58_SET_IN(ep, fifo) \ |  | ||||||
| 	((fifo) & 3) << (((ep) - 5) << 3 + 0) |  | ||||||
| #define EPMAP58_SET_OUT(ep, fifo) \ |  | ||||||
| 	((fifo) & 3) << (((ep) - 5) << 3 + 4) |  | ||||||
| #define EPMAP58_SET(ep, in, out) \ |  | ||||||
| 	do { \ |  | ||||||
| 		EPMAP58_SET_IN(ep, in); \ |  | ||||||
| 		EPMAP58_SET_OUT(ep, out); \ |  | ||||||
| 	} while (0) |  | ||||||
| 
 |  | ||||||
| #define EPMAP58_DEFAULT     0x00000000 /* All EPx->FIFO0 */ |  | ||||||
| 
 |  | ||||||
| /* FIFO Map Register */ |  | ||||||
| #define FIFOMAP_BIDIR       (2 << 4) |  | ||||||
| #define FIFOMAP_IN          (1 << 4) |  | ||||||
| #define FIFOMAP_OUT         (0 << 4) |  | ||||||
| #define FIFOMAP_DIR_MASK    0x30 |  | ||||||
| #define FIFOMAP_EP(x)       ((x) & 0x0f) |  | ||||||
| #define FIFOMAP_EP_MASK     0x0f |  | ||||||
| #define FIFOMAP_CFG_MASK    0x3f |  | ||||||
| #define FIFOMAP_DEFAULT     0x04030201 /* FIFO0->EP1, FIFO1->EP2... */ |  | ||||||
| #define FIFOMAP(fifo, cfg)  (((cfg) & 0x3f) << (((fifo) & 3) << 3)) |  | ||||||
| 
 |  | ||||||
| /* FIFO Configuration Register */ |  | ||||||
| #define FIFOCFG_EN          (1 << 5) |  | ||||||
| #define FIFOCFG_BLKSZ_1024  (1 << 4) |  | ||||||
| #define FIFOCFG_BLKSZ_512   (0 << 4) |  | ||||||
| #define FIFOCFG_3BLK        (2 << 2) |  | ||||||
| #define FIFOCFG_2BLK        (1 << 2) |  | ||||||
| #define FIFOCFG_1BLK        (0 << 2) |  | ||||||
| #define FIFOCFG_NBLK_MASK   3 |  | ||||||
| #define FIFOCFG_NBLK_SHIFT  2 |  | ||||||
| #define FIFOCFG_INTR        (3 << 0) |  | ||||||
| #define FIFOCFG_BULK        (2 << 0) |  | ||||||
| #define FIFOCFG_ISOC        (1 << 0) |  | ||||||
| #define FIFOCFG_RSVD        (0 << 0)  /* Reserved */ |  | ||||||
| #define FIFOCFG_TYPE_MASK   3 |  | ||||||
| #define FIFOCFG_TYPE_SHIFT  0 |  | ||||||
| #define FIFOCFG_CFG_MASK    0x3f |  | ||||||
| #define FIFOCFG(fifo, cfg)  (((cfg) & 0x3f) << (((fifo) & 3) << 3)) |  | ||||||
| 
 |  | ||||||
| /* FIFO Control Status Register */ |  | ||||||
| #define FIFOCSR_RESET       (1 << 12) /* FIFO Reset */ |  | ||||||
| #define FIFOCSR_BYTES(x)    ((x) & 0x7ff) /* Length(bytes) for OUT-EP/FIFO */ |  | ||||||
| 
 |  | ||||||
| /* DMA Target FIFO Register */ |  | ||||||
| #define DMAFIFO_CX          (1 << 4) /* DMA FIFO = CX FIFO */ |  | ||||||
| #define DMAFIFO_FIFO(x)     (1 << ((x) & 0x3)) /* DMA FIFO = FIFOx */ |  | ||||||
| 
 |  | ||||||
| /* DMA Control Register */ |  | ||||||
| #define DMACTRL_LEN(x)      (((x) & 0x1ffff) << 8) /* DMA length (Bytes) */ |  | ||||||
| #define DMACTRL_LEN_SHIFT   8 |  | ||||||
| #define DMACTRL_CLRFF       (1 << 4) /* Clear FIFO upon DMA abort */ |  | ||||||
| #define DMACTRL_ABORT       (1 << 3) /* DMA abort */ |  | ||||||
| #define DMACTRL_IO2IO       (1 << 2) /* IO to IO */ |  | ||||||
| #define DMACTRL_FIFO2MEM    (0 << 1) /* FIFO to Memory */ |  | ||||||
| #define DMACTRL_MEM2FIFO    (1 << 1) /* Memory to FIFO */ |  | ||||||
| #define DMACTRL_START       (1 << 0) /* DMA start */ |  | ||||||
| 
 |  | ||||||
| #endif |  | ||||||
		Loading…
	
		Reference in New Issue