Esempio n. 1
0
/**
 * elfin_in_epn - handle IN interrupt
 */
static void elfin_in_epn(struct elfin_udc *dev, u32 ep_idx)
{
	u32 csr;
	struct elfin_ep *ep = &dev->ep[ep_idx];
	struct elfin_request *req;

	csr = usb_read(ep->csr1, ep_index(ep));
	DPRINTK("%s: %d, csr %x\n", __FUNCTION__, ep_idx, csr);

	if (csr & S3C2410_UDC_ICSR1_SENTSTL) {
		printk("S3C2410_UDC_ICSR1_SENTSTL\n");
		usb_set(S3C2410_UDC_ICSR1_SENTSTL /*| S3C2410_UDC_ICSR1_SENDSTL */ ,
			ep->csr1, ep_index(ep));
		return;
	}

	if (!ep->desc) {
		DPRINTK("%s: NO EP DESC\n", __FUNCTION__);
		return;
	}

	if (list_empty(&ep->queue))
		req = 0;
	else
		req = list_entry(ep->queue.next, struct elfin_request, queue);

	DPRINTK("req: %p\n", req);

	if (!req)
		return;

	write_fifo(ep, req);
}
Esempio n. 2
0
int setdma_tx(struct s3c_ep *ep, struct s3c_request *req)
{
	u32 *buf, ctrl = 0;
	u32 length, pktcnt;
	u32 ep_num = ep_index(ep);
	u32 *p = the_controller->dma_buf[ep_index(ep)+1];

	buf = req->req.buf + req->req.actual;
	length = req->req.length - req->req.actual;

	if (ep_num == EP0_CON)
		length = min(length, (u32)ep_maxpacket(ep));

	ep->len = length;
	ep->dma_buf = buf;
	memcpy(p, ep->dma_buf, length);

	flush_dcache_range((unsigned long) p ,
			   (unsigned long) p + DMA_BUFFER_SIZE);

	if (length == 0)
		pktcnt = 1;
	else
		pktcnt = (length - 1)/(ep->ep.maxpacket) + 1;

	/* Flush the endpoint's Tx FIFO */
	writel(TX_FIFO_NUMBER(ep->fifo_num), &reg->grstctl);
	writel(TX_FIFO_NUMBER(ep->fifo_num) | TX_FIFO_FLUSH, &reg->grstctl);
	while (readl(&reg->grstctl) & TX_FIFO_FLUSH)
		;

	writel(the_controller->dma_addr[ep_index(ep)+1],
	       &reg->in_endp[ep_num].diepdma);
	writel(DIEPT_SIZ_PKT_CNT(pktcnt) | DIEPT_SIZ_XFER_SIZE(length),
	       &reg->in_endp[ep_num].dieptsiz);

	ctrl = readl(&reg->in_endp[ep_num].diepctl);

	/* Write the FIFO number to be used for this endpoint */
	ctrl &= DIEPCTL_TX_FIFO_NUM_MASK;
	ctrl |= DIEPCTL_TX_FIFO_NUM(ep->fifo_num);

	/* Clear reserved (Next EP) bits */
	ctrl = (ctrl&~(EP_MASK<<DEPCTL_NEXT_EP_BIT));

	writel(DEPCTL_EPENA|DEPCTL_CNAK|ctrl, &reg->in_endp[ep_num].diepctl);

	debug_cond(DEBUG_IN_EP,
		"%s:EP%d TX DMA start : DIEPDMA0 = 0x%x,"
		"DIEPTSIZ0 = 0x%x, DIEPCTL0 = 0x%x\n"
		"\tbuf = 0x%p, pktcnt = %d, xfersize = %d\n",
		__func__, ep_num,
		readl(&reg->in_endp[ep_num].diepdma),
		readl(&reg->in_endp[ep_num].dieptsiz),
		readl(&reg->in_endp[ep_num].diepctl),
		buf, pktcnt, length);

	return length;
}
Esempio n. 3
0
/** Read to request from FIFO (max read == bytes in fifo)
 *  Return:  0 = still running, 1 = completed, negative = errno
 */
static int read_fifo(struct elfin_ep *ep, struct elfin_request *req)
{
	u32 csr;
	u8 *buf;
	unsigned bufferspace, count, is_short;
	void* fifo = ep->fifo;

	/* make sure there's a packet in the FIFO. */
	csr = usb_read(ep->csr1, ep_index(ep));
	if (!(csr & S3C2410_UDC_OCSR1_PKTRDY)) {
		DPRINTK("%s: Packet NOT ready!\n", __FUNCTION__);
		return -EINVAL;
	}

	buf = req->req.buf + req->req.actual;
	prefetchw(buf);
	bufferspace = req->req.length - req->req.actual;

	/* read all bytes from this packet */
	count = (( (usb_read(S3C2410_UDC_OUT_FIFO_CNT2_REG, ep_index(ep)) & 0xff ) << 8) | (usb_read(S3C2410_UDC_OUT_FIFO_CNT1_REG, ep_index(ep)) & 0xff));
	req->req.actual += min(count, bufferspace);

	is_short = (count < ep->ep.maxpacket);
	DPRINTK("read %s %02x, %d bytes%s req %p %d/%d\n",
	      ep->ep.name, csr, count,
	      is_short ? "/S" : "", req, req->req.actual, req->req.length);

	while (likely(count-- != 0)) {
		u8 byte = (u8) __raw_readl(fifo);

		if (unlikely(bufferspace == 0)) {
			/* this happens when the driver's buffer
			 * is smaller than what the host sent.
			 * discard the extra data.
			 */
			if (req->req.status != -EOVERFLOW)
				printk("%s overflow %d\n", ep->ep.name, count);
			req->req.status = -EOVERFLOW;
		} else {
			*buf++ = byte;
			bufferspace--;
		}
	}

	usb_clear(S3C2410_UDC_OCSR1_PKTRDY, ep->csr1, ep_index(ep));

	/* completion */
	if (is_short || req->req.actual == req->req.length) {
		done(ep, req, 0);
		return 1;
	}

	/* finished that packet.  the next one may be waiting... */
	return 0;
}
Esempio n. 4
0
static int udc_read_fifo(struct udc_ep *ep, struct udc_req *req)
{
	struct udc *udc = ep->dev;
	void __iomem *fifo = ep->fifo;
	u16 *buf, word;
	int buflen, count, length, bytes;
	u32 offset;
	u16 esr;
	int is_last = 0;

	offset = ep_index(ep) ? UDC_ESR : UDC_EP0SR;
	esr = readw(udc->regs + offset);
	if (!(esr & UDC_ESR_RX_SUCCESS))
		return -EINVAL;

	buf = req->buf + req->actual;
	buflen = req->length - req->actual;

	count = readw(udc->regs + UDC_BRCR);
	length = count * 2;
	if (esr & (ep_index(ep) ? UDC_ESR_LWO : UDC_EP0SR_EP0_LWO))
		length -= 1;

	bytes = min(length, buflen);

	req->actual += bytes;
	is_last = (length < ep->maxpacket);

	while (count--) {
		word = readw(fifo);
		if (buflen) {
			*buf++ = word;
			buflen -= 2;
		} else {
			req->status = -EOVERFLOW;
		}
	}

	if (!ep_index(ep)) {
		writew(UDC_ESR_RX_SUCCESS, udc->regs + UDC_EP0SR);

		/* undocumented bits in ep0sr that signal last data */
		is_last |= (esr & (1 << 15)) || (esr & (1 << 12));
	}

	is_last |= (req->actual == req->length);

	if (is_last)
		udc_complete_req(ep, req, 0);

	return is_last;
}
Esempio n. 5
0
/** Write request to FIFO (max write == maxp size)
 *  Return:  0 = still running, 1 = completed, negative = errno
 *  NOTE: INDEX register must be set for EP
 */
static int write_fifo(struct lh7a40x_ep *ep, struct lh7a40x_request *req)
{
	u32 max;
	u32 csr;

	max = le16_to_cpu(ep->desc->wMaxPacketSize);

	csr = usb_read(ep->csr1);
	DEBUG("CSR: %x %d\n", csr, csr & USB_IN_CSR1_FIFO_NOT_EMPTY);

	if (!(csr & USB_IN_CSR1_FIFO_NOT_EMPTY)) {
		unsigned count;
		int is_last, is_short;

		count = write_packet(ep, req, max);
		usb_set(USB_IN_CSR1_IN_PKT_RDY, ep->csr1);

		/* last packet is usually short (or a zlp) */
		if (unlikely(count != max))
			is_last = is_short = 1;
		else {
			if (likely(req->req.length != req->req.actual)
			    || req->req.zero)
				is_last = 0;
			else
				is_last = 1;
			/* interrupt/iso maxpacket may not fill the fifo */
			is_short = unlikely(max < ep_maxpacket(ep));
		}

		DEBUG("%s: wrote %s %d bytes%s%s %d left %p\n", __FUNCTION__,
		      ep->ep.name, count,
		      is_last ? "/L" : "", is_short ? "/S" : "",
		      req->req.length - req->req.actual, req);

		/* requests complete when all IN data is in the FIFO */
		if (is_last) {
			done(ep, req, 0);
			if (list_empty(&ep->queue)) {
				pio_irq_disable(ep_index(ep));
			}
			return 1;
		}
	} else {
		DEBUG("Hmm.. %d ep FIFO is not empty!\n", ep_index(ep));
	}

	return 0;
}
Esempio n. 6
0
/* Inline code */
static __inline__ int write_packet(struct s3c_ep *ep,
				   struct s3c_request *req, int max)
{
	u16 *buf;
	int length, count;
	u32 fifo = ep->fifo;

	buf = req->req.buf + req->req.actual;
	prefetch(buf);

	length = req->req.length - req->req.actual;
	length = min(length, max);
	req->req.actual += length;

	DEBUG("%s: Write %d (max %d), fifo=0x%x\n",
		__FUNCTION__, length, max, fifo);

	usb_write(length, (u32) S3C_UDC_BYTE_WRITE_CNT_REG, ep_index(ep));


	for (count=0;count<length;count+=2) {
	  		__raw_writel(*buf++, fifo);
	}
	
	return length;
}
Esempio n. 7
0
static int setdma_rx(struct s3c_ep *ep, struct s3c_request *req)
{
	u32 *buf, ctrl;
	u32 length, pktcnt;
	u32 ep_num = ep_index(ep);

	buf = req->req.buf + req->req.actual;
	prefetchw(buf);

	length = req->req.length - req->req.actual;
	dma_cache_maint(buf, length, DMA_FROM_DEVICE);

	if(length == 0)
		pktcnt = 1;
	else
		pktcnt = (length - 1)/(ep->ep.maxpacket) + 1;

	ctrl =  readl(S3C_UDC_OTG_DOEPCTL(ep_num));

	writel(virt_to_phys(buf), S3C_UDC_OTG_DOEPDMA(ep_num));
	writel((pktcnt<<19)|(length<<0), S3C_UDC_OTG_DOEPTSIZ(ep_num));
	writel(DEPCTL_EPENA|DEPCTL_CNAK|ctrl, S3C_UDC_OTG_DOEPCTL(ep_num));

	DEBUG_OUT_EP("%s: EP%d RX DMA start : DOEPDMA = 0x%x, DOEPTSIZ = 0x%x, DOEPCTL = 0x%x\n"
			"\tbuf = 0x%p, pktcnt = %d, xfersize = %d\n",
			__func__, ep_num,
			readl(S3C_UDC_OTG_DOEPDMA(ep_num)),
			readl(S3C_UDC_OTG_DOEPTSIZ(ep_num)),
			readl(S3C_UDC_OTG_DOEPCTL(ep_num)),
			buf, pktcnt, length);
	return 0;

}
Esempio n. 8
0
/** Read to request from FIFO (max read == bytes in fifo)
 *  Return:  0 = still running, 1 = completed, negative = errno
 *  NOTE: INDEX register must be set for EP
 */
static int read_fifo(struct lh7a40x_ep *ep, struct lh7a40x_request *req)
{
	u32 csr;
	u8 *buf;
	unsigned bufferspace, count, is_short;
	volatile u32 *fifo = (volatile u32 *)ep->fifo;

	/* make sure there's a packet in the FIFO. */
	csr = usb_read(ep->csr1);
	if (!(csr & USB_OUT_CSR1_OUT_PKT_RDY)) {
		DEBUG("%s: Packet NOT ready!\n", __func__);
		return -EINVAL;
	}

	buf = req->req.buf + req->req.actual;
	prefetchw(buf);
	bufferspace = req->req.length - req->req.actual;

	/* read all bytes from this packet */
	count = usb_read(USB_OUT_FIFO_WC1);
	req->req.actual += min(count, bufferspace);

	is_short = (count < ep->ep.maxpacket);
	DEBUG("read %s %02x, %d bytes%s req %p %d/%d\n",
	      ep->ep.name, csr, count,
	      is_short ? "/S" : "", req, req->req.actual, req->req.length);

	while (likely(count-- != 0)) {
		u8 byte = (u8) (*fifo & 0xff);

		if (unlikely(bufferspace == 0)) {
			/* this happens when the driver's buffer
			 * is smaller than what the host sent.
			 * discard the extra data.
			 */
			if (req->req.status != -EOVERFLOW)
				printk(KERN_WARNING "%s overflow %d\n",
				       ep->ep.name, count);
			req->req.status = -EOVERFLOW;
		} else {
			*buf++ = byte;
			bufferspace--;
		}
	}

	usb_clear(USB_OUT_CSR1_OUT_PKT_RDY, ep->csr1);

	/* completion */
	if (is_short || req->req.actual == req->req.length) {
		done(ep, req, 0);
		usb_set(USB_OUT_CSR1_FIFO_FLUSH, ep->csr1);

		if (list_empty(&ep->queue))
			pio_irq_disable(ep_index(ep));
		return 1;
	}

	/* finished that packet.  the next one may be waiting... */
	return 0;
}
Esempio n. 9
0
static void usb_send(int n)
{
    int max_pkt_size, len;
    int i;
    unsigned char *p;

#ifdef LCD_DEBUG
    if (endpoints[n].halt[DIR_TX])
        log_char('H');
    if (!endpoints[n].out_in_progress)
        log_char('$');
#endif

    if (endpoints[n].halt[DIR_TX]
        || !endpoints[n].enabled[DIR_TX]
        || !endpoints[n].out_in_progress)
        return;

    if (endpoints[n].out_ptr < 0)
    {
        endpoints[n].out_in_progress = 0;
        if (endpoints[n].out_done)
            (*(endpoints[n].out_done))(n, endpoints[n].out_buf,
                                       endpoints[n].out_len);
        return;
    }
    
    if (usb_out_buffer_full(n))
    {
        log_char('F');
        return;
    }
    
    usb_select_endpoint(ep_index(n, DIR_TX));
    max_pkt_size = endpoints[n].max_pkt_size[DIR_TX];
    len = endpoints[n].out_len - endpoints[n].out_ptr;
    if (len > max_pkt_size)
        len = max_pkt_size;

    log_char('0' + (len % 10));
    ISP1582_BUFLEN = len;
    p = endpoints[n].out_buf + endpoints[n].out_ptr;
    i = 0;
    while (len - i >= 2) {
        ISP1582_DATA = p[i] | (p[i + 1] << 8);
        i += 2;
    }
    if (i < len)
        ISP1582_DATA = p[i];

    endpoints[n].out_ptr += len;

/*
    if (endpoints[n].out_ptr == endpoints[n].out_len
        && len < max_pkt_size)
*/
    if (endpoints[n].out_ptr == endpoints[n].out_len)
        endpoints[n].out_ptr = -1;
}
Esempio n. 10
0
static int setdma_tx(struct s3c_ep *ep, struct s3c_request *req)
{
	u32 *buf, ctrl = 0;
	u32 length, pktcnt;
	u32 ep_num = ep_index(ep);
	struct device *dev = &the_controller->dev->dev;

	buf = req->req.buf + req->req.actual;
	prefetch(buf);
	length = req->req.length - req->req.actual;

	if (ep_num == EP0_CON)
		length = min(length, (u32)ep_maxpacket(ep));

	req->req.actual += length;
	req->req.dma = dma_map_single(dev, buf,
			length, DMA_TO_DEVICE);
	req->mapped = 1;

	if (length == 0)
		pktcnt = 1;
	else
		pktcnt = (length - 1)/(ep->ep.maxpacket) + 1;

#ifdef DED_TX_FIFO
	/* Flush the endpoint's Tx FIFO */
	writel(ep_num<<6, S3C_UDC_OTG_GRSTCTL);
	writel((ep_num<<6)|0x20, S3C_UDC_OTG_GRSTCTL);
	while (readl(S3C_UDC_OTG_GRSTCTL) & 0x20)
		;

	/* Write the FIFO number to be used for this endpoint */
	ctrl = readl(S3C_UDC_OTG_DIEPCTL(ep_num));
	ctrl &= ~DEPCTL_TXFNUM_MASK;;
	ctrl |= (ep_num << DEPCTL_TXFNUM_BIT);
	writel(ctrl , S3C_UDC_OTG_DIEPCTL(ep_num));
#endif

	writel(virt_to_phys(buf), S3C_UDC_OTG_DIEPDMA(ep_num));
	writel((pktcnt<<19)|(length<<0), S3C_UDC_OTG_DIEPTSIZ(ep_num));
	ctrl = readl(S3C_UDC_OTG_DIEPCTL(ep_num));
	writel(DEPCTL_EPENA|DEPCTL_CNAK|ctrl, S3C_UDC_OTG_DIEPCTL(ep_num));

#ifndef DED_TX_FIFO
	ctrl = readl(S3C_UDC_OTG_DIEPCTL(EP0_CON));
	ctrl = (ctrl&~(EP_MASK<<DEPCTL_NEXT_EP_BIT))|(ep_num<<DEPCTL_NEXT_EP_BIT);
	writel(ctrl, S3C_UDC_OTG_DIEPCTL(EP0_CON));
#endif

	DEBUG_IN_EP("%s:EP%d TX DMA start : DIEPDMA0 = 0x%x, DIEPTSIZ0 = 0x%x, DIEPCTL0 = 0x%x\n"
			"\tbuf = 0x%p, pktcnt = %d, xfersize = %d\n",
			__func__, ep_num,
			readl(S3C_UDC_OTG_DIEPDMA(ep_num)),
			readl(S3C_UDC_OTG_DIEPTSIZ(ep_num)),
			readl(S3C_UDC_OTG_DIEPCTL(ep_num)),
			buf, pktcnt, length);

	return length;
}
Esempio n. 11
0
static int usb_out_buffer_full(int ep)
{
    usb_select_endpoint(ep_index(ep, DIR_TX));
    if (ISP1582_EPTYPE & 4)
        return (ISP1582_BUFSTAT & 3) == 3;
    else
        return (ISP1582_BUFSTAT & 3) != 0;
}
Esempio n. 12
0
static void complete_rx(struct s3c_udc *dev, u8 ep_num)
{
	struct s3c_ep *ep = &dev->ep[ep_num];
	struct s3c_request *req = NULL;
	u32 ep_tsr = 0, xfer_size = 0, is_short = 0;
	u32 *p = the_controller->dma_buf[ep_index(ep)+1];

	if (list_empty(&ep->queue)) {
		debug_cond(DEBUG_OUT_EP != 0,
			   "%s: RX DMA done : NULL REQ on OUT EP-%d\n",
			   __func__, ep_num);
		return;

	}

	req = list_entry(ep->queue.next, struct s3c_request, queue);
	ep_tsr = readl(&reg->out_endp[ep_num].doeptsiz);

	if (ep_num == EP0_CON)
		xfer_size = (ep_tsr & DOEPT_SIZ_XFER_SIZE_MAX_EP0);
	else
		xfer_size = (ep_tsr & DOEPT_SIZ_XFER_SIZE_MAX_EP);

	xfer_size = ep->len - xfer_size;

	invalidate_dcache_range((unsigned long) p,
				(unsigned long) p + DMA_BUFFER_SIZE);

	memcpy(ep->dma_buf, p, ep->len);

	req->req.actual += min(xfer_size, req->req.length - req->req.actual);
	is_short = (xfer_size < ep->ep.maxpacket);

	debug_cond(DEBUG_OUT_EP != 0,
		   "%s: RX DMA done : ep = %d, rx bytes = %d/%d, "
		   "is_short = %d, DOEPTSIZ = 0x%x, remained bytes = %d\n",
		   __func__, ep_num, req->req.actual, req->req.length,
		   is_short, ep_tsr, xfer_size);

	if (is_short || req->req.actual == req->req.length) {
		if (ep_num == EP0_CON && dev->ep0state == DATA_STATE_RECV) {
			debug_cond(DEBUG_OUT_EP != 0, "	=> Send ZLP\n");
			s3c_udc_ep0_zlp(dev);
			/* packet will be completed in complete_tx() */
			dev->ep0state = WAIT_FOR_IN_COMPLETE;
		} else {
			done(ep, req, 0);

			if (!list_empty(&ep->queue)) {
				req = list_entry(ep->queue.next,
					struct s3c_request, queue);
				debug_cond(DEBUG_OUT_EP != 0,
					   "%s: Next Rx request start...\n",
					   __func__);
				setdma_rx(ep, req);
			}
		}
	} else
Esempio n. 13
0
/** Write request to FIFO (max write == maxp size)
 *  Return:  0 = still running, 1 = completed, negative = errno
 */
static int write_fifo(struct elfin_ep *ep, struct elfin_request *req)
{
	u32 max;
	unsigned count;
	int is_last, is_short;

	max = le16_to_cpu(ep->desc->wMaxPacketSize);

	count = write_packet(ep, req, max);

	/* last packet is usually short (or a zlp) */
	if (unlikely(count != max))
		is_last = is_short = 1;
	else {
		if (likely(req->req.length != req->req.actual)
		    || req->req.zero)
			is_last = 0;
		else
			is_last = 1;
		/* interrupt/iso maxpacket may not fill the fifo */
		is_short = unlikely(max < ep_maxpacket(ep));
	}

	/* requests complete when all IN data is in the FIFO */
	if (is_last) {
		if(!ep_index(ep)){	// EP0 must not come here
			BUG();
			//usb_set(S3C2410_UDC_EP0_CSR_IPKRDY | S3C2410_UDC_EP0_CSR_DE, 
			//		S3C2410_UDC_EP0_CSR_REG, 0);
		}else{
			usb_set(S3C2410_UDC_ICSR1_PKTRDY, ep->csr1, ep_index(ep));
		}
		done(ep, req, 0);
		return 1;
	} else{
		usb_set(S3C2410_UDC_ICSR1_PKTRDY, ep->csr1, ep_index(ep));
	}

	DEBUG_EP0("%s: wrote %s %d bytes%s%s %d left %p\n", __FUNCTION__,
	      ep->ep.name, count,
	      is_last ? "/L" : "", is_short ? "/S" : "",
	      req->req.length - req->req.actual, req);

	return 0;
}
Esempio n. 14
0
static int setdma_rx(struct s3c_ep *ep, struct s3c_request *req)
{
	u32 *buf, ctrl;
	u32 length, pktcnt;
	u32 ep_num = ep_index(ep);

	buf = req->req.buf + req->req.actual;

	length = min(req->req.length - req->req.actual, (int)ep->ep.maxpacket);

	ep->len = length;
	ep->dma_buf = buf;

	invalidate_dcache_range((unsigned long) ep->dev->dma_buf[ep_num],
				(unsigned long) ep->dev->dma_buf[ep_num]
				+ DMA_BUFFER_SIZE);

	if (length == 0)
		pktcnt = 1;
	else
		pktcnt = (length - 1)/(ep->ep.maxpacket) + 1;

	pktcnt = 1;
	ctrl =  readl(&reg->out_endp[ep_num].doepctl);

	writel(the_controller->dma_addr[ep_index(ep)+1],
	       &reg->out_endp[ep_num].doepdma);
	writel(DOEPT_SIZ_PKT_CNT(pktcnt) | DOEPT_SIZ_XFER_SIZE(length),
	       &reg->out_endp[ep_num].doeptsiz);
	writel(DEPCTL_EPENA|DEPCTL_CNAK|ctrl, &reg->out_endp[ep_num].doepctl);

	debug_cond(DEBUG_OUT_EP != 0,
		   "%s: EP%d RX DMA start : DOEPDMA = 0x%x,"
		   "DOEPTSIZ = 0x%x, DOEPCTL = 0x%x\n"
		   "\tbuf = 0x%p, pktcnt = %d, xfersize = %d\n",
		   __func__, ep_num,
		   readl(&reg->out_endp[ep_num].doepdma),
		   readl(&reg->out_endp[ep_num].doeptsiz),
		   readl(&reg->out_endp[ep_num].doepctl),
		   buf, pktcnt, length);
	return 0;

}
Esempio n. 15
0
static void usb_setup_set_configuration(int value)
{
    switch (value)
    {
        case 0:
            usb_disable_endpoint(ep_index(1, DIR_RX));
            usb_disable_endpoint(ep_index(1, DIR_TX));
            usb_state = STATE_ADDRESS;
            usb_status_ack(DIR_TX);
            break;
        case 1:
            usb_setup_interface();
            usb_state = STATE_CONFIGURED;
            usb_status_ack(DIR_TX);
            break;
        default:
            usb_request_error();
    }
}
Esempio n. 16
0
/** Write request to FIFO (max write == maxp size)
 *  Return:  0 = still running, 1 = completed, negative = errno
 */
static int write_fifo(struct s3c_ep *ep, struct s3c_request *req)
{
	u32 max;
	unsigned count;
	int is_last = 0, is_short = 0;

#if TX_DMA_MODE
	if(tx_dmaStart) return 0;
	if ((req->req.actual == 0) && (req->req.length > ep->ep.maxpacket) && (!tx_dmaStart)) {

		DEBUG("TX_DMA_Start:: %s: read %s, bytes req %p %d/%d\n",
		__FUNCTION__, ep->ep.name, req, req->req.actual, req->req.length);

		usb_set(S3C_DMA_ENABLE,
				(u32) S3C_UDC_FCON_REG, ep_index(ep));

		usb_write(ep->ep.maxpacket, (u32) S3C_UDC_MAXP_REG, ep_index(ep));
		usb_write(ep->ep.maxpacket, (u32) S3C_UDC_BYTE_WRITE_CNT_REG, ep_index(ep));
		
		usb_set((u16)req->req.length,
				(u32) S3C_UDC_DMA_TOTAL_CNT1_REG, ep_index(ep));
		
		usb_set((u16)((req->req.length)>>16),
				(u32) S3C_UDC_DMA_TOTAL_CNT2_REG, ep_index(ep));

		usb_set(virt_to_phys(req->req.buf),
				(u32) S3C_UDC_DMA_MEM_BASE_ADDR_REG, ep_index(ep));
		
		usb_set(ep->ep.maxpacket,
				(u32) S3C_UDC_DMA_CNT_REG, ep_index(ep));
		
		usb_set(ep->ep.maxpacket,
				(u32) S3C_UDC_DMA_FIFO_CNT_REG, ep_index(ep));

		usb_set(S3C_MAX_BURST_INCR16,
				(u32) S3C_UDC_DMA_IF_CON_REG, ep_index(ep));

		usb_set(S3C_DMA_FLY_ENABLE|S3C_DMA_TX_START|S3C_USB_DMA_MODE,
				(u32) S3C_UDC_DMA_CON_REG, ep_index(ep));
		tx_dmaStart = 1;

		udelay(600);
		
	}
Esempio n. 17
0
static void usb_setup(int reset)
{
    int i;

    for (i = 0; i < N_ENDPOINTS; i++)
        endpoints[i].enabled[0] = endpoints[i].enabled[1] = 0;

    ISP1582_UNLOCK = ISP1582_UNLOCK_CODE;
    if (!reset)
        ISP1582_MODE = 0x88; /* CLKAON | GLINTENA */
    ISP1582_INTCONF = 0x57;
    ISP1582_INTEN = 0xd39;

    ISP1582_ADDRESS = reset ? 0x80: 0;

    usb_setup_endpoint(ep_index(0, DIR_RX), 64, 0);
    usb_setup_endpoint(ep_index(0, DIR_TX), 64, 0);
    
    ISP1582_MODE |= 1; /* SOFTCT on */

    usb_state = STATE_DEFAULT;
    usb_remote_wakeup = 0;
}
Esempio n. 18
0
static void elfin_out_epn(struct elfin_udc *dev, u32 ep_idx)
{
	struct elfin_ep *ep = &dev->ep[ep_idx];
	struct elfin_request *req;

	DPRINTK("%s: %d\n", __FUNCTION__, ep_idx);

	if (ep->desc) {
		u32 csr;
		csr = usb_read(ep->csr1, ep_index(ep));

		while ((csr = usb_read(ep->csr1, ep_index(ep))) 
				& (S3C2410_UDC_OCSR1_PKTRDY | S3C2410_UDC_OCSR1_SENTSTL)) {

			DPRINTK("%s: %x\n", __FUNCTION__, csr);

			if (csr & S3C2410_UDC_OCSR1_SENTSTL) {
				DPRINTK("%s: stall sent, flush fifo\n",
				      __FUNCTION__);
			/* usb_set(USB_OUT_CSR1_FIFO_FLUSH, ep->csr1, ep_index(ep)); */
			} else if (csr & S3C2410_UDC_OCSR1_PKTRDY) {
				if (list_empty(&ep->queue))
					req = 0;
				else
					req = list_entry(ep->queue.next,
						       struct elfin_request, queue);

				if (!req) {
					//printk("%s: NULL REQ %d\n",
					 //      __FUNCTION__, ep_idx);
					break;
				} else {
					read_fifo(ep, req);
				}
			}
		}
	} else {
static int setdma_rx(struct s3c_ep *ep, struct s3c_request *req)
{
	u32 *buf, ctrl;
	u32 length, pktcnt;
	u32 ep_num = ep_index(ep);

	buf = req->req.buf + req->req.actual;

	length = min(req->req.length - req->req.actual, (int)ep->ep.maxpacket);

	ep->len = length;
	ep->dma_buf = buf;

	if (length == 0)
		pktcnt = 1;
	else
		pktcnt = (length - 1)/(ep->ep.maxpacket) + 1;

	pktcnt = 1;
	ctrl =  readl(&reg->out_endp[ep_num].doepctl);

	writel(the_controller->dma_addr[ep_index(ep)+1],
	       &reg->out_endp[ep_num].doepdma);
	writel((pktcnt<<19)|(length<<0), &reg->out_endp[ep_num].doeptsiz);
	writel(DEPCTL_EPENA|DEPCTL_CNAK|ctrl, &reg->out_endp[ep_num].doepctl);

	DEBUG_OUT_EP("%s: EP%d RX DMA start : DOEPDMA = 0x%x,"
		     "DOEPTSIZ = 0x%x, DOEPCTL = 0x%x\n"
		     "\tbuf = 0x%p, pktcnt = %d, xfersize = %d\n",
		     __func__, ep_num,
		     readl(&reg->out_endp[ep_num].doepdma),
		     readl(&reg->out_endp[ep_num].doeptsiz),
		     readl(&reg->out_endp[ep_num].doepctl),
		     buf, pktcnt, length);
	return 0;

}
Esempio n. 20
0
static int setdma_tx(struct s3c_ep *ep, struct s3c_request *req)
{
	u32 *buf, ctrl = 0;
	u32 length, pktcnt;
	u32 ep_num = ep_index(ep);

	buf = req->req.buf + req->req.actual;
	prefetch(buf);
	length = req->req.length - req->req.actual;

	if (ep_num == EP0_CON) {
		length = min(length, (u32)ep_maxpacket(ep));
	}

	req->req.actual += length;
	dma_cache_maint(buf, length, DMA_TO_DEVICE);

	if (length == 0)
		pktcnt = 1;
	else
		pktcnt = (length - 1)/(ep->ep.maxpacket) + 1;

#ifdef DED_TX_FIFO
	/* Write the FIFO number to be used for this endpoint */
	ctrl = readl(S3C_UDC_OTG_DIEPCTL(ep_num));
	ctrl &= ~DEPCTL_TXFNUM_MASK;;
	ctrl |= (ep_num << DEPCTL_TXFNUM_BIT);
	writel(ctrl , S3C_UDC_OTG_DIEPCTL(ep_num));
#endif

	writel(virt_to_phys(buf), S3C_UDC_OTG_DIEPDMA(ep_num));
	writel((pktcnt<<19)|(length<<0), S3C_UDC_OTG_DIEPTSIZ(ep_num));
	ctrl = readl(S3C_UDC_OTG_DIEPCTL(ep_num));
	writel(DEPCTL_EPENA|DEPCTL_CNAK|ctrl, S3C_UDC_OTG_DIEPCTL(ep_num));

	ctrl = readl(S3C_UDC_OTG_DIEPCTL(EP0_CON));
	ctrl = (ctrl&~(EP_MASK<<DEPCTL_NEXT_EP_BIT))|(ep_num<<DEPCTL_NEXT_EP_BIT);
	writel(ctrl, S3C_UDC_OTG_DIEPCTL(EP0_CON));

	DEBUG_IN_EP("%s:EP%d TX DMA start : DIEPDMA0 = 0x%x, DIEPTSIZ0 = 0x%x, DIEPCTL0 = 0x%x\n"
			"\tbuf = 0x%p, pktcnt = %d, xfersize = %d\n",
			__func__, ep_num,
			readl(S3C_UDC_OTG_DIEPDMA(ep_num)),
			readl(S3C_UDC_OTG_DIEPTSIZ(ep_num)),
			readl(S3C_UDC_OTG_DIEPCTL(ep_num)),
			buf, pktcnt, length);

	return length;
}
Esempio n. 21
0
static void udc_complete_req(struct udc_ep *ep,
		struct udc_req *req, int status)
{
	struct udc *udc = ep->dev;

	list_del_init(&req->queue);
	req->status = status;

	if (!ep_index(ep)) {
		udc->ep0_state = WAIT_FOR_SETUP;
		ep->address &= ~USB_DIR_IN;
	}

	if (req->complete)
		req->complete(ep, req);
}
/** Write request to FIFO (max write == maxp size)
 *  Return:  0 = still running, 1 = completed, negative = errno
 */
static int write_fifo(struct s3c_ep *ep, struct s3c_request *req)
{
	u32 max, gintmsk;
	unsigned count;
	int is_last = 0, is_short = 0;

	gintmsk = readl(S3C_UDC_OTG_GINTMSK);

	max = le16_to_cpu(ep->desc->wMaxPacketSize);
	count = write_packet(ep, req, max);

	/* last packet is usually short (or a zlp) */
	if (unlikely(count != max))
		is_last = is_short = 1;
	else {
		if (likely(req->req.length != req->req.actual)
		    || req->req.zero)
			is_last = 0;
		else
			is_last = 1;
		/* interrupt/iso maxpacket may not fill the fifo */
		is_short = unlikely(max < ep_maxpacket(ep));
	}

	DEBUG_IN_EP("%s: wrote %s %d bytes%s%s req %p %d/%d\n",
			__FUNCTION__,
      			ep->ep.name, count,
     	 		is_last ? "/L" : "", is_short ? "/S" : "",
      			req, req->req.actual, req->req.length);

	/* requests complete when all IN data is in the FIFO */
	if (is_last) {
		if(!ep_index(ep)){
			printk("%s: --> Error EP0 must not come here!\n",
				__FUNCTION__);
			BUG();
		}
		writel(gintmsk&(~INT_NP_TX_FIFO_EMPTY), S3C_UDC_OTG_GINTMSK);
		done(ep, req, 0);
		return 1;
	}

	/* Unmask USB OTG 2.0 interrupt source : INT_NP_TX_FIFO_EMPTY */
	writel(gintmsk | INT_NP_TX_FIFO_EMPTY, S3C_UDC_OTG_GINTMSK);
	return 0;
}
Esempio n. 23
0
/*
 * 	nuke - dequeue ALL requests
 */
void nuke(struct lh7a40x_ep *ep, int status)
{
	struct lh7a40x_request *req;

	DEBUG("%s, %p\n", __FUNCTION__, ep);

	/* Flush FIFO */
	flush(ep);

	/* called with irqs blocked */
	while (!list_empty(&ep->queue)) {
		req = list_entry(ep->queue.next, struct lh7a40x_request, queue);
		done(ep, req, status);
	}

	/* Disable IRQ if EP is enabled (has descriptor) */
	if (ep->desc)
		pio_irq_disable(ep_index(ep));
}
Esempio n. 24
0
static int setdma_rx(struct s3c_ep *ep, struct s3c_request *req)
{
	u32 *buf, ctrl;
	u32 length, pktcnt;
	u32 ep_num = ep_index(ep);
	struct s3c_udc *udc = ep->dev;
	struct device *dev = &udc->dev->dev;

	aligned_map_buf(req, ep_is_in(ep));
	buf = req->req.buf + req->req.actual;
	prefetchw(buf);

	length = req->req.length - req->req.actual;

	req->req.dma = dma_map_single(dev, buf,
				length, DMA_FROM_DEVICE);
	req->mapped = 1;

	if (length == 0)
		pktcnt = 1;
	else
		pktcnt = (length - 1)/(ep->ep.maxpacket) + 1;

	ctrl =  __raw_readl(udc->regs + S3C_UDC_OTG_DOEPCTL(ep_num));

	__raw_writel(virt_to_phys(buf),
		udc->regs + S3C_UDC_OTG_DOEPDMA(ep_num));
	__raw_writel((pktcnt<<19) | (length<<0),
		udc->regs + S3C_UDC_OTG_DOEPTSIZ(ep_num));
	__raw_writel(DEPCTL_EPENA | DEPCTL_CNAK | ctrl,
		udc->regs + S3C_UDC_OTG_DOEPCTL(ep_num));

	DEBUG_OUT_EP("%s: EP%d RX DMA start : DOEPDMA = 0x%x,"
			"DOEPTSIZ = 0x%x, DOEPCTL = 0x%x\n"
			"\tbuf = 0x%p, pktcnt = %d, xfersize = %d\n",
			__func__, ep_num,
			__raw_readl(udc->regs + S3C_UDC_OTG_DOEPDMA(ep_num)),
			__raw_readl(udc->regs + S3C_UDC_OTG_DOEPTSIZ(ep_num)),
			__raw_readl(udc->regs + S3C_UDC_OTG_DOEPCTL(ep_num)),
			buf, pktcnt, length);
	return 0;
}
Esempio n. 25
0
static int setdma_rx(struct dwc2_ep *ep, struct dwc2_request *req)
{
	u32 *buf, ctrl;
	u32 length, pktcnt;
	u32 ep_num = ep_index(ep);

	buf = req->req.buf + req->req.actual;
	length = min_t(u32, req->req.length - req->req.actual,
		       ep_num ? DMA_BUFFER_SIZE : ep->ep.maxpacket);

	ep->len = length;
	ep->dma_buf = buf;

	if (ep_num == EP0_CON || length == 0)
		pktcnt = 1;
	else
		pktcnt = (length - 1)/(ep->ep.maxpacket) + 1;

	ctrl =  readl(&reg->out_endp[ep_num].doepctl);

	invalidate_dcache_range((unsigned long) ep->dma_buf,
				(unsigned long) ep->dma_buf +
				ROUND(ep->len, CONFIG_SYS_CACHELINE_SIZE));

	writel((unsigned long) ep->dma_buf, &reg->out_endp[ep_num].doepdma);
	writel(DOEPT_SIZ_PKT_CNT(pktcnt) | DOEPT_SIZ_XFER_SIZE(length),
	       &reg->out_endp[ep_num].doeptsiz);
	writel(DEPCTL_EPENA|DEPCTL_CNAK|ctrl, &reg->out_endp[ep_num].doepctl);

	debug_cond(DEBUG_OUT_EP != 0,
		   "%s: EP%d RX DMA start : DOEPDMA = 0x%x,"
		   "DOEPTSIZ = 0x%x, DOEPCTL = 0x%x\n"
		   "\tbuf = 0x%p, pktcnt = %d, xfersize = %d\n",
		   __func__, ep_num,
		   readl(&reg->out_endp[ep_num].doepdma),
		   readl(&reg->out_endp[ep_num].doeptsiz),
		   readl(&reg->out_endp[ep_num].doepctl),
		   buf, pktcnt, length);
	return 0;

}
Esempio n. 26
0
static void usb_receive(int n)
{
    int len;

    if (endpoints[n].halt[DIR_RX]
        || !endpoints[n].enabled[DIR_RX]
        || endpoints[n].in_min_len < 0
        || !endpoints[n].in_ack)
        return;

    endpoints[n].in_ack = 0;

    usb_select_endpoint(ep_index(n, DIR_RX));

    len = usb_get_packet(endpoints[n].in_buf + endpoints[n].in_ptr,
                         endpoints[n].in_max_len - endpoints[n].in_ptr);
    endpoints[n].in_ptr += len;
    if (endpoints[n].in_ptr >= endpoints[n].in_min_len) {
        endpoints[n].in_min_len = -1;
        if (endpoints[n].in_done)
            (*(endpoints[n].in_done))(n, endpoints[n].in_buf,
                                      endpoints[n].in_ptr);
    }
}
Esempio n. 27
0
static void usb_data_stage_enable(int dir)
{
    usb_select_endpoint(ep_index(0, dir));
    ISP1582_CTRLFUN |= 4;
}
Esempio n. 28
0
static void usb_request_error(void)
{
    usb_stall_endpoint(ep_index(0, DIR_TX));
    usb_stall_endpoint(ep_index(0, DIR_RX));
}
/* Inline code */
static __inline__ int write_packet(struct s3c_ep *ep,
				   struct s3c_request *req, int max)
{
	u32 *buf;
	int length, count;
	u32 fifo = ep->fifo, in_ctrl;

	buf = req->req.buf + req->req.actual;
	prefetch(buf);

	length = req->req.length - req->req.actual;
	length = min(length, max);
	req->req.actual += length;

	DEBUG("%s: Write %d (max %d), fifo=0x%x\n",
		__FUNCTION__, length, max, fifo);

	if(ep_index(ep) == EP0_CON) {
		writel((1<<19)|(length<<0), (u32) S3C_UDC_OTG_DIEPTSIZ0);

		in_ctrl =  readl(S3C_UDC_OTG_DIEPCTL0);
		writel(DEPCTL_EPENA|DEPCTL_CNAK|(EP2_IN<<11)| in_ctrl, (u32) S3C_UDC_OTG_DIEPCTL0);

		DEBUG_EP0("%s:(DIEPTSIZ0):0x%x, (DIEPCTL0):0x%x, (GNPTXSTS):0x%x\n", __FUNCTION__,
			readl(S3C_UDC_OTG_DIEPTSIZ0),readl(S3C_UDC_OTG_DIEPCTL0),
			readl(S3C_UDC_OTG_GNPTXSTS));

		udelay(30);

	} else if ((ep_index(ep) == EP2_IN)) {
		writel((1<<19)|(length<<0), S3C_UDC_OTG_DIEPTSIZ2);

		in_ctrl =  readl(S3C_UDC_OTG_DIEPCTL2);
		writel(DEPCTL_EPENA|DEPCTL_CNAK|(EP2_IN<<11)| in_ctrl, (u32) S3C_UDC_OTG_DIEPCTL2);

		DEBUG_IN_EP("%s:(DIEPTSIZ2):0x%x, (DIEPCTL2):0x%x, (GNPTXSTS):0x%x\n", __FUNCTION__,
			readl(S3C_UDC_OTG_DIEPTSIZ2),readl(S3C_UDC_OTG_DIEPCTL2),
			readl(S3C_UDC_OTG_GNPTXSTS));

		udelay(30);

	} else if ((ep_index(ep) == EP3_IN)) {

		if (set_interface_first == 1) {
			DEBUG_IN_EP("%s: first packet write skipped after set_interface\n", __FUNCTION__);
			set_interface_first = 0;
			return length;
		}

		writel((1<<19)|(length<<0), S3C_UDC_OTG_DIEPTSIZ3);

		in_ctrl =  readl(S3C_UDC_OTG_DIEPCTL3);
		writel(DEPCTL_EPENA|DEPCTL_CNAK|(EP2_IN<<11)| in_ctrl, (u32) S3C_UDC_OTG_DIEPCTL3);

		DEBUG_IN_EP("%s:(DIEPTSIZ3):0x%x, (DIEPCTL3):0x%x, (GNPTXSTS):0x%x\n", __FUNCTION__,
			readl(S3C_UDC_OTG_DIEPTSIZ3),readl(S3C_UDC_OTG_DIEPCTL3),
			readl(S3C_UDC_OTG_GNPTXSTS));

		udelay(30);

	} else {
		printk("%s: --> Error Unused Endpoint!!\n",
			__FUNCTION__);
		BUG();
	}

	for (count = 0; count < length; count += 4)
	  	writel(*buf++, fifo);

	return length;
}
Esempio n. 30
0
static void usb_setup_interface(void)
{
    usb_setup_endpoint(ep_index(1, DIR_RX), 64, TYPE_BULK);
    usb_setup_endpoint(ep_index(1, DIR_TX), 64, TYPE_BULK);
}