Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 93353
b: refs/heads/master
c: 9424ea2
h: refs/heads/master
i:
  93351: 6b5e35d
v: v3
  • Loading branch information
Yoshihiro Shimoda authored and Greg Kroah-Hartman committed Apr 25, 2008
1 parent e9b0532 commit c4b6b53
Show file tree
Hide file tree
Showing 4 changed files with 130 additions and 38 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 29fab0cd897519be9009ba8c898410ab83b378e9
refs/heads/master: 9424ea29658ce5bcdcf527ddf9617b9507ddf1aa
6 changes: 6 additions & 0 deletions trunk/drivers/usb/host/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -260,3 +260,9 @@ config USB_R8A66597_HCD
To compile this driver as a module, choose M here: the
module will be called r8a66597-hcd.

config SUPERH_ON_CHIP_R8A66597
boolean "Enable SuperH on-chip USB like the R8A66597"
depends on USB_R8A66597_HCD && CPU_SUBTYPE_SH7366
help
Renesas SuperH processor has USB like the R8A66597.
This driver supported processor is SH7366.
115 changes: 78 additions & 37 deletions trunk/drivers/usb/host/r8a66597-hcd.c
Original file line number Diff line number Diff line change
Expand Up @@ -51,10 +51,12 @@ MODULE_ALIAS("platform:r8a66597_hcd");
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);
Expand Down Expand Up @@ -106,11 +108,22 @@ static void set_devadd_reg(struct r8a66597 *r8a66597, u8 r8a66597_address,
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);
Expand All @@ -132,67 +145,94 @@ static int enable_controller(struct r8a66597 *r8a66597)
return -ENXIO;
}
} while ((tmp & SCKE) != SCKE);
#endif /* #if defined(CONFIG_SUPERH_ON_CHIP_R8A66597) */

return 0;
}

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_bset(r8a66597, DCFM | DRPD, SYSCFG0);
r8a66597_bset(r8a66597, DRPD, SYSCFG1);
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, irq_sense & INTL, SOFCFG);
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);

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);
for (port = 0; port < R8A66597_MAX_ROOT_HUB; port++)
r8a66597_disable_port(r8a66597, port);

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,
Expand Down Expand Up @@ -711,6 +751,7 @@ static void enable_r8a66597_pipe_dma(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;

Expand Down Expand Up @@ -738,6 +779,7 @@ static void enable_r8a66597_pipe_dma(struct r8a66597 *r8a66597,
break;
}
}
#endif /* #if defined(CONFIG_SUPERH_ON_CHIP_R8A66597) */
}

/* this function must be called with interrupt disabled */
Expand Down Expand Up @@ -1054,8 +1096,7 @@ static void prepare_status_packet(struct r8a66597 *r8a66597,
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);
Expand Down
45 changes: 45 additions & 0 deletions trunk/drivers/usb/host/r8a66597.h
Original file line number Diff line number Diff line change
Expand Up @@ -187,7 +187,11 @@
#define REW 0x4000 /* b14: Buffer rewind */
#define DCLRM 0x2000 /* b13: DMA buffer clear mode */
#define DREQE 0x1000 /* b12: DREQ output enable */
#if defined(CONFIG_SUPERH_ON_CHIP_R8A66597)
#define MBW 0x0800
#else
#define MBW 0x0400 /* b10: Maximum bit width for FIFO access */
#endif
#define MBW_8 0x0000 /* 8bit */
#define MBW_16 0x0400 /* 16bit */
#define BIGEND 0x0100 /* b8: Big endian mode */
Expand Down Expand Up @@ -395,7 +399,11 @@
#define R8A66597_MAX_NUM_PIPE 10
#define R8A66597_BUF_BSIZE 8
#define R8A66597_MAX_DEVICE 10
#if defined(CONFIG_SUPERH_ON_CHIP_R8A66597)
#define R8A66597_MAX_ROOT_HUB 1
#else
#define R8A66597_MAX_ROOT_HUB 2
#endif
#define R8A66597_MAX_SAMPLING 5
#define R8A66597_RH_POLL_TIME 10
#define R8A66597_MAX_DMA_CHANNEL 2
Expand Down Expand Up @@ -530,8 +538,21 @@ static inline void r8a66597_read_fifo(struct r8a66597 *r8a66597,
unsigned long offset, u16 *buf,
int len)
{
#if defined(CONFIG_SUPERH_ON_CHIP_R8A66597)
unsigned long fifoaddr = r8a66597->reg + offset;
unsigned long count;

count = len / 4;
insl(fifoaddr, buf, count);

if (len & 0x00000003) {
unsigned long tmp = inl(fifoaddr);
memcpy((unsigned char *)buf + count * 4, &tmp, len & 0x03);
}
#else
len = (len + 1) / 2;
insw(r8a66597->reg + offset, buf, len);
#endif
}

static inline void r8a66597_write(struct r8a66597 *r8a66597, u16 val,
Expand All @@ -545,6 +566,24 @@ static inline void r8a66597_write_fifo(struct r8a66597 *r8a66597,
int len)
{
unsigned long fifoaddr = r8a66597->reg + offset;
#if defined(CONFIG_SUPERH_ON_CHIP_R8A66597)
unsigned long count;
unsigned char *pb;
int i;

count = len / 4;
outsl(fifoaddr, buf, count);

if (len & 0x00000003) {
pb = (unsigned char *)buf + count * 4;
for (i = 0; i < (len & 0x00000003); i++) {
if (r8a66597_read(r8a66597, CFIFOSEL) & BIGEND)
outb(pb[i], fifoaddr + i);
else
outb(pb[i], fifoaddr + 3 - i);
}
}
#else
int odd = len & 0x0001;

len = len / 2;
Expand All @@ -553,6 +592,7 @@ static inline void r8a66597_write_fifo(struct r8a66597 *r8a66597,
buf = &buf[len];
outb((unsigned char)*buf, fifoaddr);
}
#endif
}

static inline void r8a66597_mdfy(struct r8a66597 *r8a66597,
Expand Down Expand Up @@ -585,6 +625,11 @@ static inline unsigned long get_dvstctr_reg(int port)
return port == 0 ? DVSTCTR0 : DVSTCTR1;
}

static inline unsigned long get_dmacfg_reg(int port)
{
return port == 0 ? DMA0CFG : DMA1CFG;
}

static inline unsigned long get_intenb_reg(int port)
{
return port == 0 ? INTENB1 : INTENB2;
Expand Down

0 comments on commit c4b6b53

Please sign in to comment.