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;
}
Example #2
0
static void set_pipe_reg_addr(struct r8a66597_pipe *pipe, u8 dma_ch)
{
	u16 pipenum = pipe->info.pipenum;
	const unsigned long fifoaddr[] = {D0FIFO, D1FIFO, CFIFO};
	const unsigned long fifosel[] = {D0FIFOSEL, D1FIFOSEL, CFIFOSEL};
	const unsigned long fifoctr[] = {D0FIFOCTR, D1FIFOCTR, CFIFOCTR};

	if (dma_ch > R8A66597_PIPE_NO_DMA)	/* dma fifo not use? */
		dma_ch = R8A66597_PIPE_NO_DMA;

	pipe->fifoaddr = fifoaddr[dma_ch];
	pipe->fifosel = fifosel[dma_ch];
	pipe->fifoctr = fifoctr[dma_ch];

	if (pipenum == 0)
		pipe->pipectr = DCPCTR;
	else
		pipe->pipectr = get_pipectr_addr(pipenum);

	if (check_bulk_or_isoc(pipenum)) {
		pipe->pipetre = get_pipetre_addr(pipenum);
		pipe->pipetrn = get_pipetrn_addr(pipenum);
	} else {
		pipe->pipetre = 0;
		pipe->pipetrn = 0;
	}
}
static void disable_controller(struct r8a66597 *r8a66597)
{
	int i;

	if (!(r8a66597_read(r8a66597, SYSCFG0) & USBE))
		return;

	r8a66597_write(r8a66597, 0, INTENB0);
	r8a66597_write(r8a66597, 0, INTSTS0);

	r8a66597_write(r8a66597, 0, D0FIFOSEL);
	r8a66597_write(r8a66597, 0, D1FIFOSEL);
	r8a66597_write(r8a66597, 0, DCPCFG);
	r8a66597_write(r8a66597, 0x40, DCPMAXP);
	r8a66597_write(r8a66597, 0, DCPCTR);

	for (i = 0; i <= 10; i++)
		r8a66597_write(r8a66597, 0, get_devadd_addr(i));
	for (i = 1; i <= 5; i++) {
		r8a66597_write(r8a66597, 0, get_pipetre_addr(i));
		r8a66597_write(r8a66597, 0, get_pipetrn_addr(i));
	}
	for (i = 1; i < R8A66597_MAX_NUM_PIPE; i++) {
		r8a66597_write(r8a66597, 0, get_pipectr_addr(i));
		r8a66597_write(r8a66597, i, PIPESEL);
		r8a66597_write(r8a66597, 0, PIPECFG);
		r8a66597_write(r8a66597, 0, PIPEBUF);
		r8a66597_write(r8a66597, 0, PIPEMAXP);
		r8a66597_write(r8a66597, 0, PIPEPERI);
	}

	for (i = 0; i < R8A66597_MAX_ROOT_HUB; i++)
		r8a66597_disable_port(r8a66597, i);

	r8a66597_clock_disable(r8a66597);
}