diff options
author | Yoshihiro Shimoda <shimoda.yoshihiro@renesas.com> | 2008-04-10 08:05:58 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2008-04-25 00:16:49 -0400 |
commit | 9424ea29658ce5bcdcf527ddf9617b9507ddf1aa (patch) | |
tree | b733f3cd7991d964810b32d7a555bdf9826a63e8 /drivers/usb/host/r8a66597-hcd.c | |
parent | 29fab0cd897519be9009ba8c898410ab83b378e9 (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.c | 115 |
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"); | |||
51 | static const char hcd_name[] = "r8a66597_hcd"; | 51 | static const char hcd_name[] = "r8a66597_hcd"; |
52 | 52 | ||
53 | /* module parameters */ | 53 | /* module parameters */ |
54 | #if !defined(CONFIG_SUPERH_ON_CHIP_R8A66597) | ||
54 | static unsigned short clock = XTAL12; | 55 | static unsigned short clock = XTAL12; |
55 | module_param(clock, ushort, 0644); | 56 | module_param(clock, ushort, 0644); |
56 | MODULE_PARM_DESC(clock, "input clock: 48MHz=32768, 24MHz=16384, 12MHz=0 " | 57 | MODULE_PARM_DESC(clock, "input clock: 48MHz=32768, 24MHz=16384, 12MHz=0 " |
57 | "(default=0)"); | 58 | "(default=0)"); |
59 | #endif | ||
58 | 60 | ||
59 | static unsigned short vif = LDRV; | 61 | static unsigned short vif = LDRV; |
60 | module_param(vif, ushort, 0644); | 62 | module_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 | ||
109 | static int enable_controller(struct r8a66597 *r8a66597) | 111 | static 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 | |||
153 | static 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 | |||
164 | static 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 | |||
177 | static 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 | |||
196 | static 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 | ||
167 | static void disable_controller(struct r8a66597 *r8a66597) | 225 | static 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 | ||
198 | static int get_parent_r8a66597_address(struct r8a66597 *r8a66597, | 238 | static 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); |