コード例 #1
0
ファイル: r8a66597-udc.c プロジェクト: 513855417/linux
static void r8a66597_usb_connect(struct r8a66597 *r8a66597)
{
	r8a66597_bset(r8a66597, CTRE, INTENB0);
	r8a66597_bset(r8a66597, BEMPE | BRDYE, INTENB0);

	r8a66597_bset(r8a66597, DPRPU, SYSCFG0);
}
コード例 #2
0
static int send_status_packet(struct r8a66597 *r8a66597,
			       unsigned long pipe)
{
	r8a66597_bset(r8a66597, SQSET, DCPCTR);
	r8a66597_mdfy(r8a66597, PID_NAK, PID, DCPCTR);

	if (usb_pipein(pipe)) {
		r8a66597_bset(r8a66597, R8A66597_DIR, DCPCFG);
		r8a66597_mdfy(r8a66597, ISEL, ISEL | CURPIPE, CFIFOSEL);
		r8a66597_reg_wait(r8a66597, CFIFOSEL, CURPIPE, 0);
		r8a66597_write(r8a66597, ~BEMP0, BEMPSTS);
		r8a66597_write(r8a66597, BCLR | BVAL, CFIFOCTR);
	} else {
		r8a66597_bclr(r8a66597, R8A66597_DIR, DCPCFG);
		r8a66597_mdfy(r8a66597, 0, ISEL | CURPIPE, CFIFOSEL);
		r8a66597_reg_wait(r8a66597, CFIFOSEL, CURPIPE, 0);
		r8a66597_write(r8a66597, BCLR, CFIFOCTR);
	}
	r8a66597_mdfy(r8a66597, PID_BUF, PID, DCPCTR);

	while (!(r8a66597_read(r8a66597, BEMPSTS) & 0x0001))
		if (ctrlc())
			return -1;

	return 0;
}
コード例 #3
0
/* this function must be called with interrupt disabled */
static void r8a66597_pipe_toggle(struct r8a66597 *r8a66597,
				 struct r8a66597_pipe *pipe, int toggle)
{
	if (toggle)
		r8a66597_bset(r8a66597, SQSET, pipe->pipectr);
	else
		r8a66597_bset(r8a66597, SQCLR, pipe->pipectr);
}
コード例 #4
0
static int r8a66597_clock_enable(struct r8a66597 *r8a66597)
{
	u16 tmp;
	int i = 0;

#if defined(CONFIG_SUPERH_ON_CHIP_R8A66597)
	do {
		r8a66597_write(r8a66597, SCKE, SYSCFG0);
		tmp = r8a66597_read(r8a66597, SYSCFG0);
		if (i++ > 1000) {
			printf("register access fail.\n");
			return -1;
		}
	} while ((tmp & SCKE) != SCKE);
	r8a66597_write(r8a66597, 0x04, 0x02);
#else
	do {
		r8a66597_write(r8a66597, USBE, SYSCFG0);
		tmp = r8a66597_read(r8a66597, SYSCFG0);
		if (i++ > 1000) {
			printf("register access fail.\n");
			return -1;
		}
	} while ((tmp & USBE) != USBE);
	r8a66597_bclr(r8a66597, USBE, SYSCFG0);
#if !defined(CONFIG_RZA_USB)
	r8a66597_mdfy(r8a66597, CONFIG_R8A66597_XTAL, XTAL, SYSCFG0);

	i = 0;
	r8a66597_bset(r8a66597, XCKE, SYSCFG0);
	do {
		udelay(1000);
		tmp = r8a66597_read(r8a66597, SYSCFG0);
		if (i++ > 500) {
			printf("register access fail.\n");
			return -1;
		}
	} while ((tmp & SCKE) != SCKE);
#else
	/*
	 * RZ/A Only:
	 * Bits XTAL(UCKSEL) and UPLLE in SYSCFG0 for USB0 controls both USB0
	 * and USB1, so we must always set the USB0 register
	 */
#if (CONFIG_R8A66597_XTAL == 1)
	setbits(le16, R8A66597_BASE0, XTAL);
#endif
	mdelay(1);
	setbits(le16, R8A66597_BASE0, UPLLE);
	mdelay(1);
	r8a66597_bset(r8a66597, SUSPM, SUSPMODE0);
#endif /* CONFIG_RZA_USB */
#endif	/* #if defined(CONFIG_SUPERH_ON_CHIP_R8A66597) */

	return 0;
}
コード例 #5
0
static void r8a66597_enable_port(struct r8a66597 *r8a66597, int port)
{
	u16 val;

	val = port ? DRPD : DCFM | DRPD;
	r8a66597_bset(r8a66597, val, get_syscfg_reg(port));
	r8a66597_bset(r8a66597, HSE, get_syscfg_reg(port));

	r8a66597_write(r8a66597, BURST | CPU_ADR_RD_WR, get_dmacfg_reg(port));
}
コード例 #6
0
static int enable_controller(struct r8a66597 *r8a66597)
{
	int ret, port;

	ret = r8a66597_clock_enable(r8a66597);
	if (ret < 0)
		return ret;

#if !defined(CONFIG_RZA_USB)
	r8a66597_bset(r8a66597, CONFIG_R8A66597_LDRV & LDRV, PINCFG);
#endif
	r8a66597_bset(r8a66597, USBE, SYSCFG0);

	r8a66597_bset(r8a66597, INTL, SOFCFG);
	r8a66597_write(r8a66597, 0, INTENB0);
	for (port = 0; port < R8A66597_MAX_ROOT_HUB; port++)
		r8a66597_write(r8a66597, 0, get_intenb_reg(port));

	r8a66597_bset(r8a66597, CONFIG_R8A66597_ENDIAN & BIGEND, CFIFOSEL);
	r8a66597_bset(r8a66597, CONFIG_R8A66597_ENDIAN & BIGEND, D0FIFOSEL);
	r8a66597_bset(r8a66597, CONFIG_R8A66597_ENDIAN & BIGEND, D1FIFOSEL);
	r8a66597_bset(r8a66597, TRNENSEL, SOFCFG);

	for (port = 0; port < R8A66597_MAX_ROOT_HUB; port++)
		r8a66597_enable_port(r8a66597, port);

	return 0;
}
コード例 #7
0
static int receive_bulk_packet(struct r8a66597 *r8a66597,
			       struct usb_device *dev,
			       unsigned long pipe,
			       void *buffer, int transfer_len)
{
	u16 tmp;
	u16 *buf;
	const u16 pipenum = BULK_IN_PIPENUM;
	int rcv_len;
	int maxpacket = dev->epmaxpacketin[usb_pipeendpoint(pipe)];

	R8A66597_DPRINT("%s\n", __func__);

	/* prepare */
	if (dev->act_len == 0) {
		r8a66597_mdfy(r8a66597, PID_NAK, PID,
				get_pipectr_addr(pipenum));
		r8a66597_write(r8a66597, ~(1 << pipenum), BRDYSTS);

		r8a66597_write(r8a66597, TRCLR, get_pipetre_addr(pipenum));
		r8a66597_write(r8a66597,
				(transfer_len + maxpacket - 1) / maxpacket,
				get_pipetrn_addr(pipenum));
		r8a66597_bset(r8a66597, TRENB, get_pipetre_addr(pipenum));

		r8a66597_mdfy(r8a66597, PID_BUF, PID,
				get_pipectr_addr(pipenum));
	}

	r8a66597_mdfy(r8a66597, MBW | pipenum, MBW | CURPIPE, CFIFOSEL);
	r8a66597_reg_wait(r8a66597, CFIFOSEL, CURPIPE, pipenum);

	while (!(r8a66597_read(r8a66597, BRDYSTS) & (1 << pipenum)))
		if (ctrlc())
			return -1;
	r8a66597_write(r8a66597, ~(1 << pipenum), BRDYSTS);

	tmp = r8a66597_read(r8a66597, CFIFOCTR);
	if ((tmp & FRDY) == 0) {
		printf("%s FRDY is not set. (%x)\n", __func__, tmp);
		return -1;
	}

	buf = (u16 *)(buffer + dev->act_len);
	rcv_len = tmp & DTLN;
	dev->act_len += rcv_len;

	if (buffer) {
		if (rcv_len == 0)
			r8a66597_write(r8a66597, BCLR, CFIFOCTR);
		else
			r8a66597_read_fifo(r8a66597, CFIFO, buf, rcv_len);
	}

	return 0;
}
コード例 #8
0
/* this function must be called with interrupt disabled */
static void enable_pipe_irq(struct r8a66597 *r8a66597, u16 pipenum,
			    unsigned long reg)
{
	u16 tmp;

	tmp = r8a66597_read(r8a66597, INTENB0);
	r8a66597_bclr(r8a66597, BEMPE | NRDYE | BRDYE, INTENB0);
	r8a66597_bset(r8a66597, 1 << pipenum, reg);
	r8a66597_write(r8a66597, tmp, INTENB0);
}
コード例 #9
0
/* this function must be called with interrupt disabled */
static void clear_all_buffer(struct r8a66597 *r8a66597,
			     struct r8a66597_pipe *pipe)
{
	u16 tmp;

	if (!pipe || pipe->info.pipenum == 0)
		return;

	pipe_stop(r8a66597, pipe);
	r8a66597_bset(r8a66597, ACLRM, pipe->pipectr);
	tmp = r8a66597_read(r8a66597, pipe->pipectr);
	tmp = r8a66597_read(r8a66597, pipe->pipectr);
	tmp = r8a66597_read(r8a66597, pipe->pipectr);
	r8a66597_bclr(r8a66597, ACLRM, pipe->pipectr);
}
コード例 #10
0
static int r8a66597_clock_enable(struct r8a66597 *r8a66597)
{
	u16 tmp;
	int i = 0;

	if (r8a66597->pdata->on_chip) {
#ifdef CONFIG_HAVE_CLK
		clk_enable(r8a66597->clk);
#endif
		do {
			r8a66597_write(r8a66597, SCKE, SYSCFG0);
			tmp = r8a66597_read(r8a66597, SYSCFG0);
			if (i++ > 1000) {
				printk(KERN_ERR "r8a66597: reg access fail.\n");
				return -ENXIO;
			}
		} while ((tmp & SCKE) != SCKE);
		r8a66597_write(r8a66597, 0x04, 0x02);
	} else {
		do {
			r8a66597_write(r8a66597, USBE, SYSCFG0);
			tmp = r8a66597_read(r8a66597, SYSCFG0);
			if (i++ > 1000) {
				printk(KERN_ERR "r8a66597: reg access fail.\n");
				return -ENXIO;
			}
		} while ((tmp & USBE) != USBE);
		r8a66597_bclr(r8a66597, USBE, SYSCFG0);
		r8a66597_mdfy(r8a66597, get_xtal_from_pdata(r8a66597->pdata),
			      XTAL, SYSCFG0);

		i = 0;
		r8a66597_bset(r8a66597, XCKE, SYSCFG0);
		do {
			msleep(1);
			tmp = r8a66597_read(r8a66597, SYSCFG0);
			if (i++ > 500) {
				printk(KERN_ERR "r8a66597: reg access fail.\n");
				return -ENXIO;
			}
		} while ((tmp & SCKE) != SCKE);
	}

	return 0;
}
コード例 #11
0
static int receive_control_packet(struct r8a66597 *r8a66597,
				  struct usb_device *dev,
				  void *buffer, int transfer_len)
{
	u16 tmp;
	int rcv_len;

	/* FIXME: limit transfer size : 64byte or less */

	r8a66597_bclr(r8a66597, R8A66597_DIR, DCPCFG);
	r8a66597_mdfy(r8a66597, 0, ISEL | CURPIPE, CFIFOSEL);
	r8a66597_reg_wait(r8a66597, CFIFOSEL, CURPIPE, 0);
	r8a66597_bset(r8a66597, SQSET, DCPCTR);
	r8a66597_write(r8a66597, BCLR, CFIFOCTR);
	r8a66597_mdfy(r8a66597, PID_BUF, PID, DCPCTR);

	while (!(r8a66597_read(r8a66597, BRDYSTS) & 0x0001))
		if (ctrlc())
			return -1;
	r8a66597_write(r8a66597, ~0x0001, BRDYSTS);

	r8a66597_mdfy(r8a66597, MBW, MBW | CURPIPE, CFIFOSEL);
	r8a66597_reg_wait(r8a66597, CFIFOSEL, CURPIPE, 0);

	tmp = r8a66597_read(r8a66597, CFIFOCTR);
	if ((tmp & FRDY) == 0) {
		printf("%s FRDY is not set. (%x)\n", __func__, tmp);
		return -1;
	}

	rcv_len = tmp & DTLN;
	dev->act_len += rcv_len;

	r8a66597_mdfy(r8a66597, PID_NAK, PID, DCPCTR);

	if (buffer) {
		if (rcv_len == 0)
			r8a66597_write(r8a66597, BCLR, DCPCTR);
		else
			r8a66597_read_fifo(r8a66597, CFIFO, buffer, rcv_len);
	}

	return 0;
}
コード例 #12
0
static int r8a66597_clock_enable(struct r8a66597 *r8a66597)
{
	u16 tmp;
	int i = 0;

#if defined(CONFIG_SUPERH_ON_CHIP_R8A66597)
	do {
		r8a66597_write(r8a66597, SCKE, SYSCFG0);
		tmp = r8a66597_read(r8a66597, SYSCFG0);
		if (i++ > 1000) {
			printf("register access fail.\n");
			return -1;
		}
	} while ((tmp & SCKE) != SCKE);
	r8a66597_write(r8a66597, 0x04, 0x02);
#else
	do {
		r8a66597_write(r8a66597, USBE, SYSCFG0);
		tmp = r8a66597_read(r8a66597, SYSCFG0);
		if (i++ > 1000) {
			printf("register access fail.\n");
			return -1;
		}
	} while ((tmp & USBE) != USBE);
	r8a66597_bclr(r8a66597, USBE, SYSCFG0);
	r8a66597_mdfy(r8a66597, CONFIG_R8A66597_XTAL, XTAL, SYSCFG0);

	i = 0;
	r8a66597_bset(r8a66597, XCKE, SYSCFG0);
	do {
		udelay(1000);
		tmp = r8a66597_read(r8a66597, SYSCFG0);
		if (i++ > 500) {
			printf("register access fail.\n");
			return -1;
		}
	} while ((tmp & SCKE) != SCKE);
#endif	/* #if defined(CONFIG_SUPERH_ON_CHIP_R8A66597) */

	return 0;
}
コード例 #13
0
/* this function must be called with interrupt disabled */
static void enable_r8a66597_pipe_dma(struct r8a66597 *r8a66597,
				     struct r8a66597_device *dev,
				     struct r8a66597_pipe *pipe,
				     struct urb *urb)
{
	int i;
	struct r8a66597_pipe_info *info = &pipe->info;
	unsigned short mbw = mbw_value(r8a66597);

	/* pipe dma is only for external controlles */
	if (r8a66597->pdata->on_chip)
		return;

	if ((pipe->info.pipenum != 0) && (info->type != R8A66597_INT)) {
		for (i = 0; i < R8A66597_MAX_DMA_CHANNEL; i++) {
			if ((r8a66597->dma_map & (1 << i)) != 0)
				continue;

			dev_info(&dev->udev->dev,
				 "address %d, EndpointAddress 0x%02x use "
				 "DMA FIFO\n", usb_pipedevice(urb->pipe),
				 info->dir_in ?
				 	USB_ENDPOINT_DIR_MASK + info->epnum
					: info->epnum);

			r8a66597->dma_map |= 1 << i;
			dev->dma_map |= 1 << i;
			set_pipe_reg_addr(pipe, i);

			cfifo_change(r8a66597, 0);
			r8a66597_mdfy(r8a66597, mbw | pipe->info.pipenum,
				      mbw | CURPIPE, pipe->fifosel);

			r8a66597_reg_wait(r8a66597, pipe->fifosel, CURPIPE,
					  pipe->info.pipenum);
			r8a66597_bset(r8a66597, BCLR, pipe->fifoctr);
			break;
		}
	}
}
コード例 #14
0
static void pipe_buffer_setting(struct r8a66597 *r8a66597,
				struct usb_device *dev, unsigned long pipe)
{
	u16 val = 0;
	u16 pipenum, bufnum, maxpacket;

	if (usb_pipein(pipe)) {
		pipenum = BULK_IN_PIPENUM;
		bufnum = BULK_IN_BUFNUM;
		maxpacket = dev->epmaxpacketin[usb_pipeendpoint(pipe)];
	} else {
		pipenum = BULK_OUT_PIPENUM;
		bufnum = BULK_OUT_BUFNUM;
		maxpacket = dev->epmaxpacketout[usb_pipeendpoint(pipe)];
	}

	if (r8a66597->pipe_config & (1 << pipenum))
		return;
	r8a66597->pipe_config |= (1 << pipenum);

	r8a66597_bset(r8a66597, ACLRM, get_pipectr_addr(pipenum));
	r8a66597_bclr(r8a66597, ACLRM, get_pipectr_addr(pipenum));
	r8a66597_write(r8a66597, pipenum, PIPESEL);

	/* FIXME: This driver support bulk transfer only. */
	if (!usb_pipein(pipe))
		val |= R8A66597_DIR;
	else
		val |= R8A66597_SHTNAK;
	val |= R8A66597_BULK | R8A66597_DBLB | usb_pipeendpoint(pipe);
	r8a66597_write(r8a66597, val, PIPECFG);

	r8a66597_write(r8a66597, (8 << 10) | bufnum, PIPEBUF);
	r8a66597_write(r8a66597, make_devsel(usb_pipedevice(pipe)) |
				 maxpacket, PIPEMAXP);
	r8a66597_write(r8a66597, 0, PIPEPERI);
	r8a66597_write(r8a66597, SQCLR, get_pipectr_addr(pipenum));
}
コード例 #15
0
/* this function must be called with interrupt disabled */
static void pipe_buffer_setting(struct r8a66597 *r8a66597,
				struct r8a66597_pipe_info *info)
{
	u16 val = 0;

	if (info->pipenum == 0)
		return;

	r8a66597_bset(r8a66597, ACLRM, get_pipectr_addr(info->pipenum));
	r8a66597_bclr(r8a66597, ACLRM, get_pipectr_addr(info->pipenum));
	r8a66597_write(r8a66597, info->pipenum, PIPESEL);
	if (!info->dir_in)
		val |= R8A66597_DIR;
	if (info->type == R8A66597_BULK && info->dir_in)
		val |= R8A66597_DBLB | R8A66597_SHTNAK;
	val |= info->type | info->epnum;
	r8a66597_write(r8a66597, val, PIPECFG);

	r8a66597_write(r8a66597, (info->buf_bsize << 10) | (info->bufnum),
		       PIPEBUF);
	r8a66597_write(r8a66597, make_devsel(info->address) | info->maxpacket,
		       PIPEMAXP);
	r8a66597_write(r8a66597, info->interval, PIPEPERI);
}
コード例 #16
0
static int enable_controller(struct r8a66597 *r8a66597)
{
	int ret, port;
	u16 vif = r8a66597->pdata->vif ? LDRV : 0;
	u16 irq_sense = r8a66597->irq_sense_low ? INTL : 0;
	u16 endian = r8a66597->pdata->endian ? BIGEND : 0;

	ret = r8a66597_clock_enable(r8a66597);
	if (ret < 0)
		return ret;

	r8a66597_bset(r8a66597, vif & LDRV, PINCFG);
	r8a66597_bset(r8a66597, USBE, SYSCFG0);

	r8a66597_bset(r8a66597, BEMPE | NRDYE | BRDYE, INTENB0);
	r8a66597_bset(r8a66597, irq_sense & INTL, SOFCFG);
	r8a66597_bset(r8a66597, BRDY0, BRDYENB);
	r8a66597_bset(r8a66597, BEMP0, BEMPENB);

	r8a66597_bset(r8a66597, endian & BIGEND, CFIFOSEL);
	r8a66597_bset(r8a66597, endian & BIGEND, D0FIFOSEL);
	r8a66597_bset(r8a66597, endian & BIGEND, D1FIFOSEL);
	r8a66597_bset(r8a66597, TRNENSEL, SOFCFG);

	r8a66597_bset(r8a66597, SIGNE | SACKE, INTENB1);

	for (port = 0; port < r8a66597->max_root_hub; port++)
		r8a66597_enable_port(r8a66597, port);

	return 0;
}