diff options
Diffstat (limited to 'drivers/pcmcia/yenta_socket.c')
| -rw-r--r-- | drivers/pcmcia/yenta_socket.c | 125 |
1 files changed, 97 insertions, 28 deletions
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 | ||
