diff options
-rw-r--r-- | drivers/pcmcia/topic.h | 17 | ||||
-rw-r--r-- | drivers/pcmcia/yenta_socket.c | 125 | ||||
-rw-r--r-- | drivers/pcmcia/yenta_socket.h | 8 |
3 files changed, 122 insertions, 28 deletions
diff --git a/drivers/pcmcia/topic.h b/drivers/pcmcia/topic.h index be420bb29113..edccfa5bb400 100644 --- a/drivers/pcmcia/topic.h +++ b/drivers/pcmcia/topic.h | |||
@@ -101,6 +101,8 @@ | |||
101 | #define TOPIC97_AVS_AUDIO_CONTROL 0x02 | 101 | #define TOPIC97_AVS_AUDIO_CONTROL 0x02 |
102 | #define TOPIC97_AVS_VIDEO_CONTROL 0x01 | 102 | #define TOPIC97_AVS_VIDEO_CONTROL 0x01 |
103 | 103 | ||
104 | #define TOPIC_EXCA_IF_CONTROL 0x3e /* 8 bit */ | ||
105 | #define TOPIC_EXCA_IFC_33V_ENA 0x01 | ||
104 | 106 | ||
105 | static void topic97_zoom_video(struct pcmcia_socket *sock, int onoff) | 107 | static void topic97_zoom_video(struct pcmcia_socket *sock, int onoff) |
106 | { | 108 | { |
@@ -137,4 +139,19 @@ static int topic97_override(struct yenta_socket *socket) | |||
137 | return 0; | 139 | return 0; |
138 | } | 140 | } |
139 | 141 | ||
142 | |||
143 | static int topic95_override(struct yenta_socket *socket) | ||
144 | { | ||
145 | u8 fctrl; | ||
146 | |||
147 | /* enable 3.3V support for 16bit cards */ | ||
148 | fctrl = exca_readb(socket, TOPIC_EXCA_IF_CONTROL); | ||
149 | exca_writeb(socket, TOPIC_EXCA_IF_CONTROL, fctrl | TOPIC_EXCA_IFC_33V_ENA); | ||
150 | |||
151 | /* tell yenta to use exca registers to power 16bit cards */ | ||
152 | socket->flags |= YENTA_16BIT_POWER_EXCA | YENTA_16BIT_POWER_DF; | ||
153 | |||
154 | return 0; | ||
155 | } | ||
156 | |||
140 | #endif /* _LINUX_TOPIC_H */ | 157 | #endif /* _LINUX_TOPIC_H */ |
diff --git a/drivers/pcmcia/yenta_socket.c b/drivers/pcmcia/yenta_socket.c index 62fd705203fb..0347a29f297b 100644 --- a/drivers/pcmcia/yenta_socket.c +++ b/drivers/pcmcia/yenta_socket.c | |||
@@ -184,22 +184,52 @@ static int yenta_get_status(struct pcmcia_socket *sock, unsigned int *value) | |||
184 | return 0; | 184 | return 0; |
185 | } | 185 | } |
186 | 186 | ||
187 | static int yenta_Vcc_power(u32 control) | 187 | static void yenta_get_power(struct yenta_socket *socket, socket_state_t *state) |
188 | { | 188 | { |
189 | switch (control & CB_SC_VCC_MASK) { | 189 | if (!(cb_readl(socket, CB_SOCKET_STATE) & CB_CBCARD) && |
190 | case CB_SC_VCC_5V: return 50; | 190 | (socket->flags & YENTA_16BIT_POWER_EXCA)) { |
191 | case CB_SC_VCC_3V: return 33; | 191 | u8 reg, vcc, vpp; |
192 | default: return 0; | 192 | |
193 | } | 193 | reg = exca_readb(socket, I365_POWER); |
194 | } | 194 | vcc = reg & I365_VCC_MASK; |
195 | vpp = reg & I365_VPP1_MASK; | ||
196 | state->Vcc = state->Vpp = 0; | ||
197 | |||
198 | if (socket->flags & YENTA_16BIT_POWER_DF) { | ||
199 | if (vcc == I365_VCC_3V) | ||
200 | state->Vcc = 33; | ||
201 | if (vcc == I365_VCC_5V) | ||
202 | state->Vcc = 50; | ||
203 | if (vpp == I365_VPP1_5V) | ||
204 | state->Vpp = state->Vcc; | ||
205 | if (vpp == I365_VPP1_12V) | ||
206 | state->Vpp = 120; | ||
207 | } else { | ||
208 | if (reg & I365_VCC_5V) { | ||
209 | state->Vcc = 50; | ||
210 | if (vpp == I365_VPP1_5V) | ||
211 | state->Vpp = 50; | ||
212 | if (vpp == I365_VPP1_12V) | ||
213 | state->Vpp = 120; | ||
214 | } | ||
215 | } | ||
216 | } else { | ||
217 | u32 control; | ||
195 | 218 | ||
196 | static int yenta_Vpp_power(u32 control) | 219 | control = cb_readl(socket, CB_SOCKET_CONTROL); |
197 | { | 220 | |
198 | switch (control & CB_SC_VPP_MASK) { | 221 | switch (control & CB_SC_VCC_MASK) { |
199 | case CB_SC_VPP_12V: return 120; | 222 | case CB_SC_VCC_5V: state->Vcc = 50; break; |
200 | case CB_SC_VPP_5V: return 50; | 223 | case CB_SC_VCC_3V: state->Vcc = 33; break; |
201 | case CB_SC_VPP_3V: return 33; | 224 | default: state->Vcc = 0; |
202 | default: return 0; | 225 | } |
226 | |||
227 | switch (control & CB_SC_VPP_MASK) { | ||
228 | case CB_SC_VPP_12V: state->Vpp = 120; break; | ||
229 | case CB_SC_VPP_5V: state->Vpp = 50; break; | ||
230 | case CB_SC_VPP_3V: state->Vpp = 33; break; | ||
231 | default: state->Vpp = 0; | ||
232 | } | ||
203 | } | 233 | } |
204 | } | 234 | } |
205 | 235 | ||
@@ -211,8 +241,7 @@ static int yenta_get_socket(struct pcmcia_socket *sock, socket_state_t *state) | |||
211 | 241 | ||
212 | control = cb_readl(socket, CB_SOCKET_CONTROL); | 242 | control = cb_readl(socket, CB_SOCKET_CONTROL); |
213 | 243 | ||
214 | state->Vcc = yenta_Vcc_power(control); | 244 | yenta_get_power(socket, state); |
215 | state->Vpp = yenta_Vpp_power(control); | ||
216 | state->io_irq = socket->io_irq; | 245 | state->io_irq = socket->io_irq; |
217 | 246 | ||
218 | if (cb_readl(socket, CB_SOCKET_STATE) & CB_CBCARD) { | 247 | if (cb_readl(socket, CB_SOCKET_STATE) & CB_CBCARD) { |
@@ -246,19 +275,54 @@ static int yenta_get_socket(struct pcmcia_socket *sock, socket_state_t *state) | |||
246 | 275 | ||
247 | static void yenta_set_power(struct yenta_socket *socket, socket_state_t *state) | 276 | static void yenta_set_power(struct yenta_socket *socket, socket_state_t *state) |
248 | { | 277 | { |
249 | u32 reg = 0; /* CB_SC_STPCLK? */ | 278 | /* some birdges require to use the ExCA registers to power 16bit cards */ |
250 | switch (state->Vcc) { | 279 | if (!(cb_readl(socket, CB_SOCKET_STATE) & CB_CBCARD) && |
251 | case 33: reg = CB_SC_VCC_3V; break; | 280 | (socket->flags & YENTA_16BIT_POWER_EXCA)) { |
252 | case 50: reg = CB_SC_VCC_5V; break; | 281 | u8 reg, old; |
253 | default: reg = 0; break; | 282 | reg = old = exca_readb(socket, I365_POWER); |
254 | } | 283 | reg &= ~(I365_VCC_MASK | I365_VPP1_MASK | I365_VPP2_MASK); |
255 | switch (state->Vpp) { | 284 | |
256 | case 33: reg |= CB_SC_VPP_3V; break; | 285 | /* i82365SL-DF style */ |
257 | case 50: reg |= CB_SC_VPP_5V; break; | 286 | if (socket->flags & YENTA_16BIT_POWER_DF) { |
258 | case 120: reg |= CB_SC_VPP_12V; break; | 287 | switch (state->Vcc) { |
288 | case 33: reg |= I365_VCC_3V; break; | ||
289 | case 50: reg |= I365_VCC_5V; break; | ||
290 | default: reg = 0; break; | ||
291 | } | ||
292 | switch (state->Vpp) { | ||
293 | case 33: | ||
294 | case 50: reg |= I365_VPP1_5V; break; | ||
295 | case 120: reg |= I365_VPP1_12V; break; | ||
296 | } | ||
297 | } else { | ||
298 | /* i82365SL-B style */ | ||
299 | switch (state->Vcc) { | ||
300 | case 50: reg |= I365_VCC_5V; break; | ||
301 | default: reg = 0; break; | ||
302 | } | ||
303 | switch (state->Vpp) { | ||
304 | case 50: reg |= I365_VPP1_5V | I365_VPP2_5V; break; | ||
305 | case 120: reg |= I365_VPP1_12V | I365_VPP2_12V; break; | ||
306 | } | ||
307 | } | ||
308 | |||
309 | if (reg != old) | ||
310 | exca_writeb(socket, I365_POWER, reg); | ||
311 | } else { | ||
312 | u32 reg = 0; /* CB_SC_STPCLK? */ | ||
313 | switch (state->Vcc) { | ||
314 | case 33: reg = CB_SC_VCC_3V; break; | ||
315 | case 50: reg = CB_SC_VCC_5V; break; | ||
316 | default: reg = 0; break; | ||
317 | } | ||
318 | switch (state->Vpp) { | ||
319 | case 33: reg |= CB_SC_VPP_3V; break; | ||
320 | case 50: reg |= CB_SC_VPP_5V; break; | ||
321 | case 120: reg |= CB_SC_VPP_12V; break; | ||
322 | } | ||
323 | if (reg != cb_readl(socket, CB_SOCKET_CONTROL)) | ||
324 | cb_writel(socket, CB_SOCKET_CONTROL, reg); | ||
259 | } | 325 | } |
260 | if (reg != cb_readl(socket, CB_SOCKET_CONTROL)) | ||
261 | cb_writel(socket, CB_SOCKET_CONTROL, reg); | ||
262 | } | 326 | } |
263 | 327 | ||
264 | static int yenta_set_socket(struct pcmcia_socket *sock, socket_state_t *state) | 328 | static int yenta_set_socket(struct pcmcia_socket *sock, socket_state_t *state) |
@@ -751,6 +815,7 @@ enum { | |||
751 | CARDBUS_TYPE_TI12XX, | 815 | CARDBUS_TYPE_TI12XX, |
752 | CARDBUS_TYPE_TI1250, | 816 | CARDBUS_TYPE_TI1250, |
753 | CARDBUS_TYPE_RICOH, | 817 | CARDBUS_TYPE_RICOH, |
818 | CARDBUS_TYPE_TOPIC95, | ||
754 | CARDBUS_TYPE_TOPIC97, | 819 | CARDBUS_TYPE_TOPIC97, |
755 | CARDBUS_TYPE_O2MICRO, | 820 | CARDBUS_TYPE_O2MICRO, |
756 | }; | 821 | }; |
@@ -789,6 +854,9 @@ static struct cardbus_type cardbus_type[] = { | |||
789 | .save_state = ricoh_save_state, | 854 | .save_state = ricoh_save_state, |
790 | .restore_state = ricoh_restore_state, | 855 | .restore_state = ricoh_restore_state, |
791 | }, | 856 | }, |
857 | [CARDBUS_TYPE_TOPIC95] = { | ||
858 | .override = topic95_override, | ||
859 | }, | ||
792 | [CARDBUS_TYPE_TOPIC97] = { | 860 | [CARDBUS_TYPE_TOPIC97] = { |
793 | .override = topic97_override, | 861 | .override = topic97_override, |
794 | }, | 862 | }, |
@@ -1196,6 +1264,7 @@ static struct pci_device_id yenta_table [] = { | |||
1196 | CB_ID(PCI_VENDOR_ID_RICOH, PCI_DEVICE_ID_RICOH_RL5C476, RICOH), | 1264 | CB_ID(PCI_VENDOR_ID_RICOH, PCI_DEVICE_ID_RICOH_RL5C476, RICOH), |
1197 | CB_ID(PCI_VENDOR_ID_RICOH, PCI_DEVICE_ID_RICOH_RL5C478, RICOH), | 1265 | CB_ID(PCI_VENDOR_ID_RICOH, PCI_DEVICE_ID_RICOH_RL5C478, RICOH), |
1198 | 1266 | ||
1267 | CB_ID(PCI_VENDOR_ID_TOSHIBA, PCI_DEVICE_ID_TOSHIBA_TOPIC95, TOPIC95), | ||
1199 | CB_ID(PCI_VENDOR_ID_TOSHIBA, PCI_DEVICE_ID_TOSHIBA_TOPIC97, TOPIC97), | 1268 | CB_ID(PCI_VENDOR_ID_TOSHIBA, PCI_DEVICE_ID_TOSHIBA_TOPIC97, TOPIC97), |
1200 | CB_ID(PCI_VENDOR_ID_TOSHIBA, PCI_DEVICE_ID_TOSHIBA_TOPIC100, TOPIC97), | 1269 | CB_ID(PCI_VENDOR_ID_TOSHIBA, PCI_DEVICE_ID_TOSHIBA_TOPIC100, TOPIC97), |
1201 | 1270 | ||
diff --git a/drivers/pcmcia/yenta_socket.h b/drivers/pcmcia/yenta_socket.h index 4e637eef2076..4e75e9e258cd 100644 --- a/drivers/pcmcia/yenta_socket.h +++ b/drivers/pcmcia/yenta_socket.h | |||
@@ -95,6 +95,12 @@ | |||
95 | */ | 95 | */ |
96 | #define CB_MEM_PAGE(map) (0x40 + (map)) | 96 | #define CB_MEM_PAGE(map) (0x40 + (map)) |
97 | 97 | ||
98 | |||
99 | /* control how 16bit cards are powered */ | ||
100 | #define YENTA_16BIT_POWER_EXCA 0x00000001 | ||
101 | #define YENTA_16BIT_POWER_DF 0x00000002 | ||
102 | |||
103 | |||
98 | struct yenta_socket; | 104 | struct yenta_socket; |
99 | 105 | ||
100 | struct cardbus_type { | 106 | struct cardbus_type { |
@@ -113,6 +119,8 @@ struct yenta_socket { | |||
113 | struct pcmcia_socket socket; | 119 | struct pcmcia_socket socket; |
114 | struct cardbus_type *type; | 120 | struct cardbus_type *type; |
115 | 121 | ||
122 | u32 flags; | ||
123 | |||
116 | /* for PCI interrupt probing */ | 124 | /* for PCI interrupt probing */ |
117 | unsigned int probe_status; | 125 | unsigned int probe_status; |
118 | 126 | ||