static const char hcd_name[] = "r8a66597_hcd";
/* module parameters */
+#if !defined(CONFIG_SUPERH_ON_CHIP_R8A66597)
static unsigned short clock = XTAL12;
module_param(clock, ushort, 0644);
MODULE_PARM_DESC(clock, "input clock: 48MHz=32768, 24MHz=16384, 12MHz=0 "
"(default=0)");
+#endif
static unsigned short vif = LDRV;
module_param(vif, ushort, 0644);
r8a66597_write(r8a66597, val, devadd_reg);
}
-static int enable_controller(struct r8a66597 *r8a66597)
+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) {
+ err("register access fail.");
+ return -ENXIO;
+ }
+ } while ((tmp & SCKE) != SCKE);
+ r8a66597_write(r8a66597, 0x04, 0x02);
+#else
do {
r8a66597_write(r8a66597, USBE, SYSCFG0);
tmp = r8a66597_read(r8a66597, SYSCFG0);
return -ENXIO;
}
} while ((tmp & SCKE) != SCKE);
+#endif /* #if defined(CONFIG_SUPERH_ON_CHIP_R8A66597) */
+
+ return 0;
+}
- r8a66597_bset(r8a66597, DCFM | DRPD, SYSCFG0);
- r8a66597_bset(r8a66597, DRPD, SYSCFG1);
+static void r8a66597_clock_disable(struct r8a66597 *r8a66597)
+{
+ r8a66597_bclr(r8a66597, SCKE, SYSCFG0);
+ udelay(1);
+#if !defined(CONFIG_SUPERH_ON_CHIP_R8A66597)
+ r8a66597_bclr(r8a66597, PLLC, SYSCFG0);
+ r8a66597_bclr(r8a66597, XCKE, SYSCFG0);
+ r8a66597_bclr(r8a66597, USBE, SYSCFG0);
+#endif
+}
+
+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));
+ r8a66597_bclr(r8a66597, DTCHE, get_intenb_reg(port));
+ r8a66597_bset(r8a66597, ATTCHE, get_intenb_reg(port));
+}
+
+static void r8a66597_disable_port(struct r8a66597 *r8a66597, int port)
+{
+ u16 val, tmp;
+
+ r8a66597_write(r8a66597, 0, get_intenb_reg(port));
+ r8a66597_write(r8a66597, 0, get_intsts_reg(port));
+
+ r8a66597_port_power(r8a66597, port, 0);
+
+ do {
+ tmp = r8a66597_read(r8a66597, SOFCFG) & EDGESTS;
+ udelay(640);
+ } while (tmp == EDGESTS);
+
+ val = port ? DRPD : DCFM | DRPD;
+ r8a66597_bclr(r8a66597, val, get_syscfg_reg(port));
+ r8a66597_bclr(r8a66597, HSE, get_syscfg_reg(port));
+}
+
+static int enable_controller(struct r8a66597 *r8a66597)
+{
+ int ret, port;
+
+ ret = r8a66597_clock_enable(r8a66597);
+ if (ret < 0)
+ return ret;
r8a66597_bset(r8a66597, vif & LDRV, PINCFG);
- r8a66597_bset(r8a66597, HSE, SYSCFG0);
- r8a66597_bset(r8a66597, HSE, SYSCFG1);
r8a66597_bset(r8a66597, USBE, SYSCFG0);
r8a66597_bset(r8a66597, BEMPE | NRDYE | BRDYE, INTENB0);
r8a66597_bset(r8a66597, BRDY0, BRDYENB);
r8a66597_bset(r8a66597, BEMP0, BEMPENB);
- r8a66597_write(r8a66597, BURST | CPU_ADR_RD_WR, DMA0CFG);
- r8a66597_write(r8a66597, BURST | CPU_ADR_RD_WR, DMA1CFG);
-
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);
- r8a66597_bclr(r8a66597, DTCHE, INTENB1);
- r8a66597_bset(r8a66597, ATTCHE, INTENB1);
- r8a66597_bclr(r8a66597, DTCHE, INTENB2);
- r8a66597_bset(r8a66597, ATTCHE, INTENB2);
+
+ for (port = 0; port < R8A66597_MAX_ROOT_HUB; port++)
+ r8a66597_enable_port(r8a66597, port);
return 0;
}
static void disable_controller(struct r8a66597 *r8a66597)
{
- u16 tmp;
+ int port;
r8a66597_write(r8a66597, 0, INTENB0);
- r8a66597_write(r8a66597, 0, INTENB1);
- r8a66597_write(r8a66597, 0, INTENB2);
r8a66597_write(r8a66597, 0, INTSTS0);
- r8a66597_write(r8a66597, 0, INTSTS1);
- r8a66597_write(r8a66597, 0, INTSTS2);
- r8a66597_port_power(r8a66597, 0, 0);
- r8a66597_port_power(r8a66597, 1, 0);
+ for (port = 0; port < R8A66597_MAX_ROOT_HUB; port++)
+ r8a66597_disable_port(r8a66597, port);
- do {
- tmp = r8a66597_read(r8a66597, SOFCFG) & EDGESTS;
- udelay(640);
- } while (tmp == EDGESTS);
-
- r8a66597_bclr(r8a66597, DCFM | DRPD, SYSCFG0);
- r8a66597_bclr(r8a66597, DRPD, SYSCFG1);
- r8a66597_bclr(r8a66597, HSE, SYSCFG0);
- r8a66597_bclr(r8a66597, HSE, SYSCFG1);
-
- r8a66597_bclr(r8a66597, SCKE, SYSCFG0);
- udelay(1);
- r8a66597_bclr(r8a66597, PLLC, SYSCFG0);
- r8a66597_bclr(r8a66597, XCKE, SYSCFG0);
- r8a66597_bclr(r8a66597, USBE, SYSCFG0);
+ r8a66597_clock_disable(r8a66597);
}
static int get_parent_r8a66597_address(struct r8a66597 *r8a66597,
struct r8a66597_pipe *pipe,
struct urb *urb)
{
+#if !defined(CONFIG_SUPERH_ON_CHIP_R8A66597)
int i;
struct r8a66597_pipe_info *info = &pipe->info;
break;
}
}
+#endif /* #if defined(CONFIG_SUPERH_ON_CHIP_R8A66597) */
}
/* this function must be called with interrupt disabled */
}
/* this function must be called with interrupt disabled */
-static void r8a66597_usb_preconnect(struct r8a66597 *r8a66597, int port)
+static void r8a66597_check_syssts(struct r8a66597 *r8a66597, int port,
+ u16 syssts)
{
- r8a66597->root_hub[port].port |= (1 << USB_PORT_FEAT_CONNECTION)
- | (1 << USB_PORT_FEAT_C_CONNECTION);
+ if (syssts == SE0) {
+ r8a66597_bset(r8a66597, ATTCHE, get_intenb_reg(port));
+ return;
+ }
+
+ if (syssts == FS_JSTS)
+ r8a66597_bset(r8a66597, HSE, get_syscfg_reg(port));
+ else if (syssts == LS_JSTS)
+ r8a66597_bclr(r8a66597, HSE, get_syscfg_reg(port));
+
r8a66597_write(r8a66597, ~DTCH, get_intsts_reg(port));
r8a66597_bset(r8a66597, DTCHE, get_intenb_reg(port));
}
struct r8a66597_td *td)
{
int i;
- u16 *p = (u16 *)td->urb->setup_packet;
+ __le16 *p = (__le16 *)td->urb->setup_packet;
unsigned long setup_addr = USBREQ;
r8a66597_write(r8a66597, make_devsel(td->address) | td->maxpacket,
r8a66597_write(r8a66597, ~(SIGN | SACK), INTSTS1);
for (i = 0; i < 4; i++) {
- r8a66597_write(r8a66597, cpu_to_le16(p[i]), setup_addr);
+ r8a66597_write(r8a66597, le16_to_cpu(p[i]), setup_addr);
setup_addr += 2;
}
r8a66597_write(r8a66597, SUREQ, DCPCTR);
r8a66597_mdfy(r8a66597, ISEL, ISEL | CURPIPE, CFIFOSEL);
r8a66597_reg_wait(r8a66597, CFIFOSEL, CURPIPE, 0);
r8a66597_write(r8a66597, ~BEMP0, BEMPSTS);
- r8a66597_write(r8a66597, BCLR, CFIFOCTR);
- r8a66597_write(r8a66597, BVAL, CFIFOCTR);
+ r8a66597_write(r8a66597, BCLR | BVAL, CFIFOCTR);
enable_irq_empty(r8a66597, 0);
} else {
r8a66597_bclr(r8a66597, R8A66597_DIR, DCPCFG);
}
}
+static void r8a66597_root_hub_start_polling(struct r8a66597 *r8a66597)
+{
+ mod_timer(&r8a66597->rh_timer,
+ jiffies + msecs_to_jiffies(R8A66597_RH_POLL_TIME));
+}
+
static void start_root_hub_sampling(struct r8a66597 *r8a66597, int port)
{
struct r8a66597_root_hub *rh = &r8a66597->root_hub[port];
rh->old_syssts = r8a66597_read(r8a66597, get_syssts_reg(port)) & LNST;
rh->scount = R8A66597_MAX_SAMPLING;
- mod_timer(&r8a66597->rh_timer, jiffies + msecs_to_jiffies(50));
+ r8a66597->root_hub[port].port |= (1 << USB_PORT_FEAT_CONNECTION)
+ | (1 << USB_PORT_FEAT_C_CONNECTION);
+ r8a66597_root_hub_start_polling(r8a66597);
}
static irqreturn_t r8a66597_irq(struct usb_hcd *hcd)
if ((tmp & USBRST) == USBRST) {
r8a66597_mdfy(r8a66597, UACT, USBRST | UACT,
dvstctr_reg);
- mod_timer(&r8a66597->rh_timer,
- jiffies + msecs_to_jiffies(50));
+ r8a66597_root_hub_start_polling(r8a66597);
} else
r8a66597_usb_connect(r8a66597, port);
}
+ if (!(rh->port & (1 << USB_PORT_FEAT_CONNECTION))) {
+ r8a66597_write(r8a66597, ~ATTCH, get_intsts_reg(port));
+ r8a66597_bset(r8a66597, ATTCHE, get_intenb_reg(port));
+ }
+
if (rh->scount > 0) {
tmp = r8a66597_read(r8a66597, get_syssts_reg(port)) & LNST;
if (tmp == rh->old_syssts) {
rh->scount--;
- if (rh->scount == 0) {
- if (tmp == FS_JSTS) {
- r8a66597_bset(r8a66597, HSE,
- get_syscfg_reg(port));
- r8a66597_usb_preconnect(r8a66597, port);
- } else if (tmp == LS_JSTS) {
- r8a66597_bclr(r8a66597, HSE,
- get_syscfg_reg(port));
- r8a66597_usb_preconnect(r8a66597, port);
- } else if (tmp == SE0)
- r8a66597_bset(r8a66597, ATTCHE,
- get_intenb_reg(port));
- } else {
- mod_timer(&r8a66597->rh_timer,
- jiffies + msecs_to_jiffies(50));
- }
+ if (rh->scount == 0)
+ r8a66597_check_syssts(r8a66597, port, tmp);
+ else
+ r8a66597_root_hub_start_polling(r8a66597);
} else {
rh->scount = R8A66597_MAX_SAMPLING;
rh->old_syssts = tmp;
- mod_timer(&r8a66597->rh_timer,
- jiffies + msecs_to_jiffies(50));
+ r8a66597_root_hub_start_polling(r8a66597);
}
}
}
case GetPortStatus:
if (wIndex > R8A66597_MAX_ROOT_HUB)
goto error;
- *(u32 *)buf = cpu_to_le32(rh->port);
+ *(__le32 *)buf = cpu_to_le32(rh->port);
break;
case SetPortFeature:
if (wIndex > R8A66597_MAX_ROOT_HUB)