Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

[PATCH] yenta: make ToPIC95 bridges work with 16bit cards

ToPIC95 brides (and maybe some other too) require to use the ExCA registers
to power up the socket if a 16bit card is pluged. allow socket drivers to
set a flag so that yenta does just that. also clean up yenta_get_status()
a bit to use the new yenta_get_power() function.

Side note: ToPIC97 bridges (at least in Rev.5 i have) don't require this.

Ryan Underwood <nemesis-lists@icequake.net> said:

According to the mail that David Hinds received from a Toshiba engineer,
ToPIC95 and 97 do require this, and ToPIC100 does not. Maybe you have a
later revision.

For all chips, 16-bit cards can be enabled through ExCA. So doesn't it
make sense just to make this the default behavior for all Toshiba chips,
to avoid corner cases showing up later?

Daniel responded:

I disagree with ryan to change anything for topic97 bridges. they work.
and I couldn't find (read google) any report of a topic97 breaking on
applying power with the CB registers.

I'm having several toshba notebooks at work (and home) with topic95,97,100
bridges. Only the ones with a topic95 didn't work.

Signed-off-by: Daniel Ritz <daniel.ritz@gmx.ch>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>

authored by

Daniel Ritz and committed by
Linus Torvalds
ea2f1590 36d57ac4

+122 -28
+17
drivers/pcmcia/topic.h
··· 101 101 #define TOPIC97_AVS_AUDIO_CONTROL 0x02 102 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 107 static void topic97_zoom_video(struct pcmcia_socket *sock, int onoff) 106 108 { ··· 136 134 { 137 135 /* ToPIC97/100 support ZV */ 138 136 socket->socket.zoom_video = topic97_zoom_video; 137 + return 0; 138 + } 139 + 140 + 141 + static int topic95_override(struct yenta_socket *socket) 142 + { 143 + u8 fctrl; 144 + 145 + /* enable 3.3V support for 16bit cards */ 146 + fctrl = exca_readb(socket, TOPIC_EXCA_IF_CONTROL); 147 + exca_writeb(socket, TOPIC_EXCA_IF_CONTROL, fctrl | TOPIC_EXCA_IFC_33V_ENA); 148 + 149 + /* tell yenta to use exca registers to power 16bit cards */ 150 + socket->flags |= YENTA_16BIT_POWER_EXCA | YENTA_16BIT_POWER_DF; 151 + 139 152 return 0; 140 153 } 141 154
+97 -28
drivers/pcmcia/yenta_socket.c
··· 184 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) { 190 - case CB_SC_VCC_5V: return 50; 191 - case CB_SC_VCC_3V: return 33; 192 - default: return 0; 193 - } 194 - } 189 + if (!(cb_readl(socket, CB_SOCKET_STATE) & CB_CBCARD) && 190 + (socket->flags & YENTA_16BIT_POWER_EXCA)) { 191 + u8 reg, vcc, vpp; 195 192 196 - static int yenta_Vpp_power(u32 control) 197 - { 198 - switch (control & CB_SC_VPP_MASK) { 199 - case CB_SC_VPP_12V: return 120; 200 - case CB_SC_VPP_5V: return 50; 201 - case CB_SC_VPP_3V: return 33; 202 - default: return 0; 193 + reg = exca_readb(socket, I365_POWER); 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; 218 + 219 + control = cb_readl(socket, CB_SOCKET_CONTROL); 220 + 221 + switch (control & CB_SC_VCC_MASK) { 222 + case CB_SC_VCC_5V: state->Vcc = 50; break; 223 + case CB_SC_VCC_3V: state->Vcc = 33; break; 224 + default: state->Vcc = 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 ··· 241 211 242 212 control = cb_readl(socket, CB_SOCKET_CONTROL); 243 213 244 - state->Vcc = yenta_Vcc_power(control); 245 - state->Vpp = yenta_Vpp_power(control); 214 + yenta_get_power(socket, state); 246 215 state->io_irq = socket->io_irq; 247 216 248 217 if (cb_readl(socket, CB_SOCKET_STATE) & CB_CBCARD) { ··· 275 246 276 247 static void yenta_set_power(struct yenta_socket *socket, socket_state_t *state) 277 248 { 278 - u32 reg = 0; /* CB_SC_STPCLK? */ 279 - switch (state->Vcc) { 280 - case 33: reg = CB_SC_VCC_3V; break; 281 - case 50: reg = CB_SC_VCC_5V; break; 282 - default: reg = 0; break; 249 + /* some birdges require to use the ExCA registers to power 16bit cards */ 250 + if (!(cb_readl(socket, CB_SOCKET_STATE) & CB_CBCARD) && 251 + (socket->flags & YENTA_16BIT_POWER_EXCA)) { 252 + u8 reg, old; 253 + reg = old = exca_readb(socket, I365_POWER); 254 + reg &= ~(I365_VCC_MASK | I365_VPP1_MASK | I365_VPP2_MASK); 255 + 256 + /* i82365SL-DF style */ 257 + if (socket->flags & YENTA_16BIT_POWER_DF) { 258 + switch (state->Vcc) { 259 + case 33: reg |= I365_VCC_3V; break; 260 + case 50: reg |= I365_VCC_5V; break; 261 + default: reg = 0; break; 262 + } 263 + switch (state->Vpp) { 264 + case 33: 265 + case 50: reg |= I365_VPP1_5V; break; 266 + case 120: reg |= I365_VPP1_12V; break; 267 + } 268 + } else { 269 + /* i82365SL-B style */ 270 + switch (state->Vcc) { 271 + case 50: reg |= I365_VCC_5V; break; 272 + default: reg = 0; break; 273 + } 274 + switch (state->Vpp) { 275 + case 50: reg |= I365_VPP1_5V | I365_VPP2_5V; break; 276 + case 120: reg |= I365_VPP1_12V | I365_VPP2_12V; break; 277 + } 278 + } 279 + 280 + if (reg != old) 281 + exca_writeb(socket, I365_POWER, reg); 282 + } else { 283 + u32 reg = 0; /* CB_SC_STPCLK? */ 284 + switch (state->Vcc) { 285 + case 33: reg = CB_SC_VCC_3V; break; 286 + case 50: reg = CB_SC_VCC_5V; break; 287 + default: reg = 0; break; 288 + } 289 + switch (state->Vpp) { 290 + case 33: reg |= CB_SC_VPP_3V; break; 291 + case 50: reg |= CB_SC_VPP_5V; break; 292 + case 120: reg |= CB_SC_VPP_12V; break; 293 + } 294 + if (reg != cb_readl(socket, CB_SOCKET_CONTROL)) 295 + cb_writel(socket, CB_SOCKET_CONTROL, reg); 283 296 } 284 - switch (state->Vpp) { 285 - case 33: reg |= CB_SC_VPP_3V; break; 286 - case 50: reg |= CB_SC_VPP_5V; break; 287 - case 120: reg |= CB_SC_VPP_12V; break; 288 - } 289 - if (reg != cb_readl(socket, CB_SOCKET_CONTROL)) 290 - cb_writel(socket, CB_SOCKET_CONTROL, reg); 291 297 } 292 298 293 299 static int yenta_set_socket(struct pcmcia_socket *sock, socket_state_t *state) ··· 815 751 CARDBUS_TYPE_TI12XX, 816 752 CARDBUS_TYPE_TI1250, 817 753 CARDBUS_TYPE_RICOH, 754 + CARDBUS_TYPE_TOPIC95, 818 755 CARDBUS_TYPE_TOPIC97, 819 756 CARDBUS_TYPE_O2MICRO, 820 757 }; ··· 853 788 .override = ricoh_override, 854 789 .save_state = ricoh_save_state, 855 790 .restore_state = ricoh_restore_state, 791 + }, 792 + [CARDBUS_TYPE_TOPIC95] = { 793 + .override = topic95_override, 856 794 }, 857 795 [CARDBUS_TYPE_TOPIC97] = { 858 796 .override = topic97_override, ··· 1264 1196 CB_ID(PCI_VENDOR_ID_RICOH, PCI_DEVICE_ID_RICOH_RL5C476, RICOH), 1265 1197 CB_ID(PCI_VENDOR_ID_RICOH, PCI_DEVICE_ID_RICOH_RL5C478, RICOH), 1266 1198 1199 + CB_ID(PCI_VENDOR_ID_TOSHIBA, PCI_DEVICE_ID_TOSHIBA_TOPIC95, TOPIC95), 1267 1200 CB_ID(PCI_VENDOR_ID_TOSHIBA, PCI_DEVICE_ID_TOSHIBA_TOPIC97, TOPIC97), 1268 1201 CB_ID(PCI_VENDOR_ID_TOSHIBA, PCI_DEVICE_ID_TOSHIBA_TOPIC100, TOPIC97), 1269 1202
+8
drivers/pcmcia/yenta_socket.h
··· 95 95 */ 96 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 104 struct yenta_socket; 99 105 100 106 struct cardbus_type { ··· 118 112 119 113 struct pcmcia_socket socket; 120 114 struct cardbus_type *type; 115 + 116 + u32 flags; 121 117 122 118 /* for PCI interrupt probing */ 123 119 unsigned int probe_status;