예제 #1
0
static int send_setup_packet(struct r8a66597 *r8a66597, struct usb_device *dev,
			     struct devrequest *setup)
{
	int i;
	unsigned short *p = (unsigned short *)setup;
	unsigned long setup_addr = USBREQ;
	u16 intsts1;
	int timeout = 3000;
#if defined(CONFIG_RZA_USB)
	u16 dcpctr;
#endif
	u16 devsel = setup->request == USB_REQ_SET_ADDRESS ? 0 : dev->devnum;

	r8a66597_write(r8a66597, make_devsel(devsel) |
				 (8 << dev->maxpacketsize), DCPMAXP);
	r8a66597_write(r8a66597, ~(SIGN | SACK), INTSTS1);

#if defined(CONFIG_RZA_USB)
	dcpctr = r8a66597_read(r8a66597, DCPCTR);
	if ((dcpctr & PID) == PID_BUF) {
		if (readw_poll_timeout(r8a66597->reg + DCPCTR, dcpctr,
				       dcpctr & BSTS, 1000) < 0) {
			printf("DCPCTR BSTS timeout!\n");
			return -ETIMEDOUT;
		}
	}
#endif

	for (i = 0; i < 4; i++) {
		r8a66597_write(r8a66597, le16_to_cpu(p[i]), setup_addr);
		setup_addr += 2;
	}
	r8a66597_write(r8a66597, ~0x0001, BRDYSTS);
	r8a66597_write(r8a66597, SUREQ, DCPCTR);

	while (1) {
		intsts1 = r8a66597_read(r8a66597, INTSTS1);
		if (intsts1 & SACK)
			break;
		if (intsts1 & SIGN) {
			printf("setup packet send error\n");
			return -1;
		}
		if (timeout-- < 0) {
			printf("setup packet timeout\n");
			return -1;
		}
		udelay(500);
	}

	return 0;
}
예제 #2
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));
}
예제 #3
0
static int send_setup_packet(struct r8a66597 *r8a66597, struct usb_device *dev,
			     struct devrequest *setup)
{
	int i;
	unsigned short *p = (unsigned short *)setup;
	unsigned long setup_addr = USBREQ;
	u16 intsts1;
	int timeout = 3000;
	u16 devsel = setup->request == USB_REQ_SET_ADDRESS ? 0 : dev->devnum;

	r8a66597_write(r8a66597, make_devsel(devsel) |
				 (8 << dev->maxpacketsize), DCPMAXP);
	r8a66597_write(r8a66597, ~(SIGN | SACK), INTSTS1);

	for (i = 0; i < 4; i++) {
		r8a66597_write(r8a66597, le16_to_cpu(p[i]), setup_addr);
		setup_addr += 2;
	}
	r8a66597_write(r8a66597, ~0x0001, BRDYSTS);
	r8a66597_write(r8a66597, SUREQ, DCPCTR);

	while (1) {
		intsts1 = r8a66597_read(r8a66597, INTSTS1);
		if (intsts1 & SACK)
			break;
		if (intsts1 & SIGN) {
			printf("setup packet send error\n");
			return -1;
		}
		if (timeout-- < 0) {
			printf("setup packet timeout\n");
			return -1;
		}
		udelay(500);
	}

	return 0;
}
예제 #4
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);
}