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; }
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)); }
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; }
/* 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); }