aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/host
diff options
context:
space:
mode:
authorYoshihiro Shimoda <shimoda.yoshihiro@renesas.com>2008-04-10 08:05:58 -0400
committerGreg Kroah-Hartman <gregkh@suse.de>2008-04-25 00:16:49 -0400
commit9424ea29658ce5bcdcf527ddf9617b9507ddf1aa (patch)
treeb733f3cd7991d964810b32d7a555bdf9826a63e8 /drivers/usb/host
parent29fab0cd897519be9009ba8c898410ab83b378e9 (diff)
USB: r8a66597-hcd: Add support for SH7366 USB host
R8A66597 is similar to SH7366 USB 2.0 Host/Function module. It can support SH7366 USB host by changing several R8A66597 code. Signed-off-by: Yoshihiro Shimoda <shimoda.yoshihiro@renesas.com> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/usb/host')
-rw-r--r--drivers/usb/host/Kconfig6
-rw-r--r--drivers/usb/host/r8a66597-hcd.c115
-rw-r--r--drivers/usb/host/r8a66597.h45
3 files changed, 129 insertions, 37 deletions
diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig
index 27f295b78055..0b87480dd713 100644
--- a/drivers/usb/host/Kconfig
+++ b/drivers/usb/host/Kconfig
@@ -260,3 +260,9 @@ config USB_R8A66597_HCD
260 To compile this driver as a module, choose M here: the 260 To compile this driver as a module, choose M here: the
261 module will be called r8a66597-hcd. 261 module will be called r8a66597-hcd.
262 262
263config SUPERH_ON_CHIP_R8A66597
264 boolean "Enable SuperH on-chip USB like the R8A66597"
265 depends on USB_R8A66597_HCD && CPU_SUBTYPE_SH7366
266 help
267 Renesas SuperH processor has USB like the R8A66597.
268 This driver supported processor is SH7366.
diff --git a/drivers/usb/host/r8a66597-hcd.c b/drivers/usb/host/r8a66597-hcd.c
index bb48f42bd7ce..f4fa93dabdde 100644
--- a/drivers/usb/host/r8a66597-hcd.c
+++ b/drivers/usb/host/r8a66597-hcd.c
@@ -51,10 +51,12 @@ MODULE_ALIAS("platform:r8a66597_hcd");
51static const char hcd_name[] = "r8a66597_hcd"; 51static const char hcd_name[] = "r8a66597_hcd";
52 52
53/* module parameters */ 53/* module parameters */
54#if !defined(CONFIG_SUPERH_ON_CHIP_R8A66597)
54static unsigned short clock = XTAL12; 55static unsigned short clock = XTAL12;
55module_param(clock, ushort, 0644); 56module_param(clock, ushort, 0644);
56MODULE_PARM_DESC(clock, "input clock: 48MHz=32768, 24MHz=16384, 12MHz=0 " 57MODULE_PARM_DESC(clock, "input clock: 48MHz=32768, 24MHz=16384, 12MHz=0 "
57 "(default=0)"); 58 "(default=0)");
59#endif
58 60
59static unsigned short vif = LDRV; 61static unsigned short vif = LDRV;
60module_param(vif, ushort, 0644); 62module_param(vif, ushort, 0644);
@@ -106,11 +108,22 @@ static void set_devadd_reg(struct r8a66597 *r8a66597, u8 r8a66597_address,
106 r8a66597_write(r8a66597, val, devadd_reg); 108 r8a66597_write(r8a66597, val, devadd_reg);
107} 109}
108 110
109static int enable_controller(struct r8a66597 *r8a66597) 111static int r8a66597_clock_enable(struct r8a66597 *r8a66597)
110{ 112{
111 u16 tmp; 113 u16 tmp;
112 int i = 0; 114 int i = 0;
113 115
116#if defined(CONFIG_SUPERH_ON_CHIP_R8A66597)
117 do {
118 r8a66597_write(r8a66597, SCKE, SYSCFG0);
119 tmp = r8a66597_read(r8a66597, SYSCFG0);
120 if (i++ > 1000) {
121 err("register access fail.");
122 return -ENXIO;
123 }
124 } while ((tmp & SCKE) != SCKE);
125 r8a66597_write(r8a66597, 0x04, 0x02);
126#else
114 do { 127 do {
115 r8a66597_write(r8a66597, USBE, SYSCFG0); 128 r8a66597_write(r8a66597, USBE, SYSCFG0);
116 tmp = r8a66597_read(r8a66597, SYSCFG0); 129 tmp = r8a66597_read(r8a66597, SYSCFG0);
@@ -132,13 +145,63 @@ static int enable_controller(struct r8a66597 *r8a66597)
132 return -ENXIO; 145 return -ENXIO;
133 } 146 }
134 } while ((tmp & SCKE) != SCKE); 147 } while ((tmp & SCKE) != SCKE);
148#endif /* #if defined(CONFIG_SUPERH_ON_CHIP_R8A66597) */
149
150 return 0;
151}
152
153static void r8a66597_clock_disable(struct r8a66597 *r8a66597)
154{
155 r8a66597_bclr(r8a66597, SCKE, SYSCFG0);
156 udelay(1);
157#if !defined(CONFIG_SUPERH_ON_CHIP_R8A66597)
158 r8a66597_bclr(r8a66597, PLLC, SYSCFG0);
159 r8a66597_bclr(r8a66597, XCKE, SYSCFG0);
160 r8a66597_bclr(r8a66597, USBE, SYSCFG0);
161#endif
162}
163
164static void r8a66597_enable_port(struct r8a66597 *r8a66597, int port)
165{
166 u16 val;
167
168 val = port ? DRPD : DCFM | DRPD;
169 r8a66597_bset(r8a66597, val, get_syscfg_reg(port));
170 r8a66597_bset(r8a66597, HSE, get_syscfg_reg(port));
171
172 r8a66597_write(r8a66597, BURST | CPU_ADR_RD_WR, get_dmacfg_reg(port));
173 r8a66597_bclr(r8a66597, DTCHE, get_intenb_reg(port));
174 r8a66597_bset(r8a66597, ATTCHE, get_intenb_reg(port));
175}
176
177static void r8a66597_disable_port(struct r8a66597 *r8a66597, int port)
178{
179 u16 val, tmp;
135 180
136 r8a66597_bset(r8a66597, DCFM | DRPD, SYSCFG0); 181 r8a66597_write(r8a66597, 0, get_intenb_reg(port));
137 r8a66597_bset(r8a66597, DRPD, SYSCFG1); 182 r8a66597_write(r8a66597, 0, get_intsts_reg(port));
183
184 r8a66597_port_power(r8a66597, port, 0);
185
186 do {
187 tmp = r8a66597_read(r8a66597, SOFCFG) & EDGESTS;
188 udelay(640);
189 } while (tmp == EDGESTS);
190
191 val = port ? DRPD : DCFM | DRPD;
192 r8a66597_bclr(r8a66597, val, get_syscfg_reg(port));
193 r8a66597_bclr(r8a66597, HSE, get_syscfg_reg(port));
194}
195
196static int enable_controller(struct r8a66597 *r8a66597)
197{
198 int ret, port;
199
200 ret = r8a66597_clock_enable(r8a66597);
201 if (ret < 0)
202 return ret;
138 203
139 r8a66597_bset(r8a66597, vif & LDRV, PINCFG); 204 r8a66597_bset(r8a66597, vif & LDRV, PINCFG);
140 r8a66597_bset(r8a66597, HSE, SYSCFG0);
141 r8a66597_bset(r8a66597, HSE, SYSCFG1);
142 r8a66597_bset(r8a66597, USBE, SYSCFG0); 205 r8a66597_bset(r8a66597, USBE, SYSCFG0);
143 206
144 r8a66597_bset(r8a66597, BEMPE | NRDYE | BRDYE, INTENB0); 207 r8a66597_bset(r8a66597, BEMPE | NRDYE | BRDYE, INTENB0);
@@ -146,53 +209,30 @@ static int enable_controller(struct r8a66597 *r8a66597)
146 r8a66597_bset(r8a66597, BRDY0, BRDYENB); 209 r8a66597_bset(r8a66597, BRDY0, BRDYENB);
147 r8a66597_bset(r8a66597, BEMP0, BEMPENB); 210 r8a66597_bset(r8a66597, BEMP0, BEMPENB);
148 211
149 r8a66597_write(r8a66597, BURST | CPU_ADR_RD_WR, DMA0CFG);
150 r8a66597_write(r8a66597, BURST | CPU_ADR_RD_WR, DMA1CFG);
151
152 r8a66597_bset(r8a66597, endian & BIGEND, CFIFOSEL); 212 r8a66597_bset(r8a66597, endian & BIGEND, CFIFOSEL);
153 r8a66597_bset(r8a66597, endian & BIGEND, D0FIFOSEL); 213 r8a66597_bset(r8a66597, endian & BIGEND, D0FIFOSEL);
154 r8a66597_bset(r8a66597, endian & BIGEND, D1FIFOSEL); 214 r8a66597_bset(r8a66597, endian & BIGEND, D1FIFOSEL);
155
156 r8a66597_bset(r8a66597, TRNENSEL, SOFCFG); 215 r8a66597_bset(r8a66597, TRNENSEL, SOFCFG);
157 216
158 r8a66597_bset(r8a66597, SIGNE | SACKE, INTENB1); 217 r8a66597_bset(r8a66597, SIGNE | SACKE, INTENB1);
159 r8a66597_bclr(r8a66597, DTCHE, INTENB1); 218
160 r8a66597_bset(r8a66597, ATTCHE, INTENB1); 219 for (port = 0; port < R8A66597_MAX_ROOT_HUB; port++)
161 r8a66597_bclr(r8a66597, DTCHE, INTENB2); 220 r8a66597_enable_port(r8a66597, port);
162 r8a66597_bset(r8a66597, ATTCHE, INTENB2);
163 221
164 return 0; 222 return 0;
165} 223}
166 224
167static void disable_controller(struct r8a66597 *r8a66597) 225static void disable_controller(struct r8a66597 *r8a66597)
168{ 226{
169 u16 tmp; 227 int port;
170 228
171 r8a66597_write(r8a66597, 0, INTENB0); 229 r8a66597_write(r8a66597, 0, INTENB0);
172 r8a66597_write(r8a66597, 0, INTENB1);
173 r8a66597_write(r8a66597, 0, INTENB2);
174 r8a66597_write(r8a66597, 0, INTSTS0); 230 r8a66597_write(r8a66597, 0, INTSTS0);
175 r8a66597_write(r8a66597, 0, INTSTS1);
176 r8a66597_write(r8a66597, 0, INTSTS2);
177
178 r8a66597_port_power(r8a66597, 0, 0);
179 r8a66597_port_power(r8a66597, 1, 0);
180
181 do {
182 tmp = r8a66597_read(r8a66597, SOFCFG) & EDGESTS;
183 udelay(640);
184 } while (tmp == EDGESTS);
185 231
186 r8a66597_bclr(r8a66597, DCFM | DRPD, SYSCFG0); 232 for (port = 0; port < R8A66597_MAX_ROOT_HUB; port++)
187 r8a66597_bclr(r8a66597, DRPD, SYSCFG1); 233 r8a66597_disable_port(r8a66597, port);
188 r8a66597_bclr(r8a66597, HSE, SYSCFG0);
189 r8a66597_bclr(r8a66597, HSE, SYSCFG1);
190 234
191 r8a66597_bclr(r8a66597, SCKE, SYSCFG0); 235 r8a66597_clock_disable(r8a66597);
192 udelay(1);
193 r8a66597_bclr(r8a66597, PLLC, SYSCFG0);
194 r8a66597_bclr(r8a66597, XCKE, SYSCFG0);
195 r8a66597_bclr(r8a66597, USBE, SYSCFG0);
196} 236}
197 237
198static int get_parent_r8a66597_address(struct r8a66597 *r8a66597, 238static int get_parent_r8a66597_address(struct r8a66597 *r8a66597,
@@ -711,6 +751,7 @@ static void enable_r8a66597_pipe_dma(struct r8a66597 *r8a66597,
711 struct r8a66597_pipe *pipe, 751 struct r8a66597_pipe *pipe,
712 struct urb *urb) 752 struct urb *urb)
713{ 753{
754#if !defined(CONFIG_SUPERH_ON_CHIP_R8A66597)
714 int i; 755 int i;
715 struct r8a66597_pipe_info *info = &pipe->info; 756 struct r8a66597_pipe_info *info = &pipe->info;
716 757
@@ -738,6 +779,7 @@ static void enable_r8a66597_pipe_dma(struct r8a66597 *r8a66597,
738 break; 779 break;
739 } 780 }
740 } 781 }
782#endif /* #if defined(CONFIG_SUPERH_ON_CHIP_R8A66597) */
741} 783}
742 784
743/* this function must be called with interrupt disabled */ 785/* this function must be called with interrupt disabled */
@@ -1054,8 +1096,7 @@ static void prepare_status_packet(struct r8a66597 *r8a66597,
1054 r8a66597_mdfy(r8a66597, ISEL, ISEL | CURPIPE, CFIFOSEL); 1096 r8a66597_mdfy(r8a66597, ISEL, ISEL | CURPIPE, CFIFOSEL);
1055 r8a66597_reg_wait(r8a66597, CFIFOSEL, CURPIPE, 0); 1097 r8a66597_reg_wait(r8a66597, CFIFOSEL, CURPIPE, 0);
1056 r8a66597_write(r8a66597, ~BEMP0, BEMPSTS); 1098 r8a66597_write(r8a66597, ~BEMP0, BEMPSTS);
1057 r8a66597_write(r8a66597, BCLR, CFIFOCTR); 1099 r8a66597_write(r8a66597, BCLR | BVAL, CFIFOCTR);
1058 r8a66597_write(r8a66597, BVAL, CFIFOCTR);
1059 enable_irq_empty(r8a66597, 0); 1100 enable_irq_empty(r8a66597, 0);
1060 } else { 1101 } else {
1061 r8a66597_bclr(r8a66597, R8A66597_DIR, DCPCFG); 1102 r8a66597_bclr(r8a66597, R8A66597_DIR, DCPCFG);
diff --git a/drivers/usb/host/r8a66597.h b/drivers/usb/host/r8a66597.h
index f46f7dd944a1..84ee01417315 100644
--- a/drivers/usb/host/r8a66597.h
+++ b/drivers/usb/host/r8a66597.h
@@ -187,7 +187,11 @@
187#define REW 0x4000 /* b14: Buffer rewind */ 187#define REW 0x4000 /* b14: Buffer rewind */
188#define DCLRM 0x2000 /* b13: DMA buffer clear mode */ 188#define DCLRM 0x2000 /* b13: DMA buffer clear mode */
189#define DREQE 0x1000 /* b12: DREQ output enable */ 189#define DREQE 0x1000 /* b12: DREQ output enable */
190#if defined(CONFIG_SUPERH_ON_CHIP_R8A66597)
191#define MBW 0x0800
192#else
190#define MBW 0x0400 /* b10: Maximum bit width for FIFO access */ 193#define MBW 0x0400 /* b10: Maximum bit width for FIFO access */
194#endif
191#define MBW_8 0x0000 /* 8bit */ 195#define MBW_8 0x0000 /* 8bit */
192#define MBW_16 0x0400 /* 16bit */ 196#define MBW_16 0x0400 /* 16bit */
193#define BIGEND 0x0100 /* b8: Big endian mode */ 197#define BIGEND 0x0100 /* b8: Big endian mode */
@@ -395,7 +399,11 @@
395#define R8A66597_MAX_NUM_PIPE 10 399#define R8A66597_MAX_NUM_PIPE 10
396#define R8A66597_BUF_BSIZE 8 400#define R8A66597_BUF_BSIZE 8
397#define R8A66597_MAX_DEVICE 10 401#define R8A66597_MAX_DEVICE 10
402#if defined(CONFIG_SUPERH_ON_CHIP_R8A66597)
403#define R8A66597_MAX_ROOT_HUB 1
404#else
398#define R8A66597_MAX_ROOT_HUB 2 405#define R8A66597_MAX_ROOT_HUB 2
406#endif
399#define R8A66597_MAX_SAMPLING 5 407#define R8A66597_MAX_SAMPLING 5
400#define R8A66597_RH_POLL_TIME 10 408#define R8A66597_RH_POLL_TIME 10
401#define R8A66597_MAX_DMA_CHANNEL 2 409#define R8A66597_MAX_DMA_CHANNEL 2
@@ -530,8 +538,21 @@ static inline void r8a66597_read_fifo(struct r8a66597 *r8a66597,
530 unsigned long offset, u16 *buf, 538 unsigned long offset, u16 *buf,
531 int len) 539 int len)
532{ 540{
541#if defined(CONFIG_SUPERH_ON_CHIP_R8A66597)
542 unsigned long fifoaddr = r8a66597->reg + offset;
543 unsigned long count;
544
545 count = len / 4;
546 insl(fifoaddr, buf, count);
547
548 if (len & 0x00000003) {
549 unsigned long tmp = inl(fifoaddr);
550 memcpy((unsigned char *)buf + count * 4, &tmp, len & 0x03);
551 }
552#else
533 len = (len + 1) / 2; 553 len = (len + 1) / 2;
534 insw(r8a66597->reg + offset, buf, len); 554 insw(r8a66597->reg + offset, buf, len);
555#endif
535} 556}
536 557
537static inline void r8a66597_write(struct r8a66597 *r8a66597, u16 val, 558static inline void r8a66597_write(struct r8a66597 *r8a66597, u16 val,
@@ -545,6 +566,24 @@ static inline void r8a66597_write_fifo(struct r8a66597 *r8a66597,
545 int len) 566 int len)
546{ 567{
547 unsigned long fifoaddr = r8a66597->reg + offset; 568 unsigned long fifoaddr = r8a66597->reg + offset;
569#if defined(CONFIG_SUPERH_ON_CHIP_R8A66597)
570 unsigned long count;
571 unsigned char *pb;
572 int i;
573
574 count = len / 4;
575 outsl(fifoaddr, buf, count);
576
577 if (len & 0x00000003) {
578 pb = (unsigned char *)buf + count * 4;
579 for (i = 0; i < (len & 0x00000003); i++) {
580 if (r8a66597_read(r8a66597, CFIFOSEL) & BIGEND)
581 outb(pb[i], fifoaddr + i);
582 else
583 outb(pb[i], fifoaddr + 3 - i);
584 }
585 }
586#else
548 int odd = len & 0x0001; 587 int odd = len & 0x0001;
549 588
550 len = len / 2; 589 len = len / 2;
@@ -553,6 +592,7 @@ static inline void r8a66597_write_fifo(struct r8a66597 *r8a66597,
553 buf = &buf[len]; 592 buf = &buf[len];
554 outb((unsigned char)*buf, fifoaddr); 593 outb((unsigned char)*buf, fifoaddr);
555 } 594 }
595#endif
556} 596}
557 597
558static inline void r8a66597_mdfy(struct r8a66597 *r8a66597, 598static inline void r8a66597_mdfy(struct r8a66597 *r8a66597,
@@ -585,6 +625,11 @@ static inline unsigned long get_dvstctr_reg(int port)
585 return port == 0 ? DVSTCTR0 : DVSTCTR1; 625 return port == 0 ? DVSTCTR0 : DVSTCTR1;
586} 626}
587 627
628static inline unsigned long get_dmacfg_reg(int port)
629{
630 return port == 0 ? DMA0CFG : DMA1CFG;
631}
632
588static inline unsigned long get_intenb_reg(int port) 633static inline unsigned long get_intenb_reg(int port)
589{ 634{
590 return port == 0 ? INTENB1 : INTENB2; 635 return port == 0 ? INTENB1 : INTENB2;