aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/host/r8a66597-hcd.c
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/r8a66597-hcd.c
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/r8a66597-hcd.c')
-rw-r--r--drivers/usb/host/r8a66597-hcd.c115
1 files changed, 78 insertions, 37 deletions
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);