Commit | Line | Data |
---|---|---|
1da177e4 LT |
1 | /* |
2 | * ti113x.h 1.16 1999/10/25 20:03:34 | |
3 | * | |
4 | * The contents of this file are subject to the Mozilla Public License | |
5 | * Version 1.1 (the "License"); you may not use this file except in | |
6 | * compliance with the License. You may obtain a copy of the License | |
7 | * at http://www.mozilla.org/MPL/ | |
8 | * | |
9 | * Software distributed under the License is distributed on an "AS IS" | |
10 | * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See | |
11 | * the License for the specific language governing rights and | |
12 | * limitations under the License. | |
13 | * | |
14 | * The initial developer of the original code is David A. Hinds | |
15 | * <dahinds@users.sourceforge.net>. Portions created by David A. Hinds | |
16 | * are Copyright (C) 1999 David A. Hinds. All Rights Reserved. | |
17 | * | |
18 | * Alternatively, the contents of this file may be used under the | |
19 | * terms of the GNU General Public License version 2 (the "GPL"), in which | |
20 | * case the provisions of the GPL are applicable instead of the | |
21 | * above. If you wish to allow the use of your version of this file | |
22 | * only under the terms of the GPL and not to allow others to use | |
23 | * your version of this file under the MPL, indicate your decision by | |
24 | * deleting the provisions above and replace them with the notice and | |
25 | * other provisions required by the GPL. If you do not delete the | |
26 | * provisions above, a recipient may use your version of this file | |
27 | * under either the MPL or the GPL. | |
28 | */ | |
29 | ||
30 | #ifndef _LINUX_TI113X_H | |
31 | #define _LINUX_TI113X_H | |
32 | ||
1da177e4 LT |
33 | |
34 | /* Register definitions for TI 113X PCI-to-CardBus bridges */ | |
35 | ||
36 | /* System Control Register */ | |
37 | #define TI113X_SYSTEM_CONTROL 0x0080 /* 32 bit */ | |
38 | #define TI113X_SCR_SMIROUTE 0x04000000 | |
39 | #define TI113X_SCR_SMISTATUS 0x02000000 | |
40 | #define TI113X_SCR_SMIENB 0x01000000 | |
41 | #define TI113X_SCR_VCCPROT 0x00200000 | |
42 | #define TI113X_SCR_REDUCEZV 0x00100000 | |
43 | #define TI113X_SCR_CDREQEN 0x00080000 | |
44 | #define TI113X_SCR_CDMACHAN 0x00070000 | |
45 | #define TI113X_SCR_SOCACTIVE 0x00002000 | |
46 | #define TI113X_SCR_PWRSTREAM 0x00000800 | |
47 | #define TI113X_SCR_DELAYUP 0x00000400 | |
48 | #define TI113X_SCR_DELAYDOWN 0x00000200 | |
49 | #define TI113X_SCR_INTERROGATE 0x00000100 | |
50 | #define TI113X_SCR_CLKRUN_SEL 0x00000080 | |
51 | #define TI113X_SCR_PWRSAVINGS 0x00000040 | |
52 | #define TI113X_SCR_SUBSYSRW 0x00000020 | |
53 | #define TI113X_SCR_CB_DPAR 0x00000010 | |
54 | #define TI113X_SCR_CDMA_EN 0x00000008 | |
55 | #define TI113X_SCR_ASYNC_IRQ 0x00000004 | |
56 | #define TI113X_SCR_KEEPCLK 0x00000002 | |
57 | #define TI113X_SCR_CLKRUN_ENA 0x00000001 | |
58 | ||
59 | #define TI122X_SCR_SER_STEP 0xc0000000 | |
60 | #define TI122X_SCR_INTRTIE 0x20000000 | |
6c1a10db | 61 | #define TIXX21_SCR_TIEALL 0x10000000 |
1da177e4 LT |
62 | #define TI122X_SCR_CBRSVD 0x00400000 |
63 | #define TI122X_SCR_MRBURSTDN 0x00008000 | |
64 | #define TI122X_SCR_MRBURSTUP 0x00004000 | |
65 | #define TI122X_SCR_RIMUX 0x00000001 | |
66 | ||
67 | /* Multimedia Control Register */ | |
68 | #define TI1250_MULTIMEDIA_CTL 0x0084 /* 8 bit */ | |
69 | #define TI1250_MMC_ZVOUTEN 0x80 | |
70 | #define TI1250_MMC_PORTSEL 0x40 | |
71 | #define TI1250_MMC_ZVEN1 0x02 | |
72 | #define TI1250_MMC_ZVEN0 0x01 | |
73 | ||
74 | #define TI1250_GENERAL_STATUS 0x0085 /* 8 bit */ | |
75 | #define TI1250_GPIO0_CONTROL 0x0088 /* 8 bit */ | |
76 | #define TI1250_GPIO1_CONTROL 0x0089 /* 8 bit */ | |
77 | #define TI1250_GPIO2_CONTROL 0x008a /* 8 bit */ | |
78 | #define TI1250_GPIO3_CONTROL 0x008b /* 8 bit */ | |
79 | #define TI1250_GPIO_MODE_MASK 0xc0 | |
80 | ||
81 | /* IRQMUX/MFUNC Register */ | |
82 | #define TI122X_MFUNC 0x008c /* 32 bit */ | |
83 | #define TI122X_MFUNC0_MASK 0x0000000f | |
84 | #define TI122X_MFUNC1_MASK 0x000000f0 | |
85 | #define TI122X_MFUNC2_MASK 0x00000f00 | |
86 | #define TI122X_MFUNC3_MASK 0x0000f000 | |
87 | #define TI122X_MFUNC4_MASK 0x000f0000 | |
88 | #define TI122X_MFUNC5_MASK 0x00f00000 | |
89 | #define TI122X_MFUNC6_MASK 0x0f000000 | |
90 | ||
91 | #define TI122X_MFUNC0_INTA 0x00000002 | |
92 | #define TI125X_MFUNC0_INTB 0x00000001 | |
93 | #define TI122X_MFUNC1_INTB 0x00000020 | |
94 | #define TI122X_MFUNC3_IRQSER 0x00001000 | |
95 | ||
96 | ||
97 | /* Retry Status Register */ | |
98 | #define TI113X_RETRY_STATUS 0x0090 /* 8 bit */ | |
99 | #define TI113X_RSR_PCIRETRY 0x80 | |
100 | #define TI113X_RSR_CBRETRY 0x40 | |
101 | #define TI113X_RSR_TEXP_CBB 0x20 | |
102 | #define TI113X_RSR_MEXP_CBB 0x10 | |
103 | #define TI113X_RSR_TEXP_CBA 0x08 | |
104 | #define TI113X_RSR_MEXP_CBA 0x04 | |
105 | #define TI113X_RSR_TEXP_PCI 0x02 | |
106 | #define TI113X_RSR_MEXP_PCI 0x01 | |
107 | ||
108 | /* Card Control Register */ | |
109 | #define TI113X_CARD_CONTROL 0x0091 /* 8 bit */ | |
110 | #define TI113X_CCR_RIENB 0x80 | |
111 | #define TI113X_CCR_ZVENABLE 0x40 | |
112 | #define TI113X_CCR_PCI_IRQ_ENA 0x20 | |
113 | #define TI113X_CCR_PCI_IREQ 0x10 | |
114 | #define TI113X_CCR_PCI_CSC 0x08 | |
115 | #define TI113X_CCR_SPKROUTEN 0x02 | |
116 | #define TI113X_CCR_IFG 0x01 | |
117 | ||
118 | #define TI1220_CCR_PORT_SEL 0x20 | |
119 | #define TI122X_CCR_AUD2MUX 0x04 | |
120 | ||
121 | /* Device Control Register */ | |
122 | #define TI113X_DEVICE_CONTROL 0x0092 /* 8 bit */ | |
123 | #define TI113X_DCR_5V_FORCE 0x40 | |
124 | #define TI113X_DCR_3V_FORCE 0x20 | |
125 | #define TI113X_DCR_IMODE_MASK 0x06 | |
126 | #define TI113X_DCR_IMODE_ISA 0x02 | |
127 | #define TI113X_DCR_IMODE_SERIAL 0x04 | |
128 | ||
129 | #define TI12XX_DCR_IMODE_PCI_ONLY 0x00 | |
130 | #define TI12XX_DCR_IMODE_ALL_SERIAL 0x06 | |
131 | ||
132 | /* Buffer Control Register */ | |
133 | #define TI113X_BUFFER_CONTROL 0x0093 /* 8 bit */ | |
134 | #define TI113X_BCR_CB_READ_DEPTH 0x08 | |
135 | #define TI113X_BCR_CB_WRITE_DEPTH 0x04 | |
136 | #define TI113X_BCR_PCI_READ_DEPTH 0x02 | |
137 | #define TI113X_BCR_PCI_WRITE_DEPTH 0x01 | |
138 | ||
139 | /* Diagnostic Register */ | |
140 | #define TI1250_DIAGNOSTIC 0x0093 /* 8 bit */ | |
141 | #define TI1250_DIAG_TRUE_VALUE 0x80 | |
142 | #define TI1250_DIAG_PCI_IREQ 0x40 | |
143 | #define TI1250_DIAG_PCI_CSC 0x20 | |
144 | #define TI1250_DIAG_ASYNC_CSC 0x01 | |
145 | ||
146 | /* DMA Registers */ | |
147 | #define TI113X_DMA_0 0x0094 /* 32 bit */ | |
148 | #define TI113X_DMA_1 0x0098 /* 32 bit */ | |
149 | ||
150 | /* ExCA IO offset registers */ | |
151 | #define TI113X_IO_OFFSET(map) (0x36+((map)<<1)) | |
152 | ||
153 | /* EnE test register */ | |
154 | #define ENE_TEST_C9 0xc9 /* 8bit */ | |
155 | #define ENE_TEST_C9_TLTENABLE 0x02 | |
8c3520d4 DR |
156 | #define ENE_TEST_C9_PFENABLE_F0 0x04 |
157 | #define ENE_TEST_C9_PFENABLE_F1 0x08 | |
14540c6d | 158 | #define ENE_TEST_C9_PFENABLE (ENE_TEST_C9_PFENABLE_F0 | ENE_TEST_C9_PFENABLE_F1) |
8c3520d4 DR |
159 | #define ENE_TEST_C9_WPDISALBLE_F0 0x40 |
160 | #define ENE_TEST_C9_WPDISALBLE_F1 0x80 | |
161 | #define ENE_TEST_C9_WPDISALBLE (ENE_TEST_C9_WPDISALBLE_F0 | ENE_TEST_C9_WPDISALBLE_F1) | |
1da177e4 | 162 | |
1da177e4 LT |
163 | /* |
164 | * Texas Instruments CardBus controller overrides. | |
165 | */ | |
166 | #define ti_sysctl(socket) ((socket)->private[0]) | |
167 | #define ti_cardctl(socket) ((socket)->private[1]) | |
168 | #define ti_devctl(socket) ((socket)->private[2]) | |
169 | #define ti_diag(socket) ((socket)->private[3]) | |
170 | #define ti_mfunc(socket) ((socket)->private[4]) | |
171 | #define ene_test_c9(socket) ((socket)->private[5]) | |
172 | ||
173 | /* | |
174 | * These are the TI specific power management handlers. | |
175 | */ | |
176 | static void ti_save_state(struct yenta_socket *socket) | |
177 | { | |
178 | ti_sysctl(socket) = config_readl(socket, TI113X_SYSTEM_CONTROL); | |
179 | ti_mfunc(socket) = config_readl(socket, TI122X_MFUNC); | |
180 | ti_cardctl(socket) = config_readb(socket, TI113X_CARD_CONTROL); | |
181 | ti_devctl(socket) = config_readb(socket, TI113X_DEVICE_CONTROL); | |
182 | ti_diag(socket) = config_readb(socket, TI1250_DIAGNOSTIC); | |
183 | ||
184 | if (socket->dev->vendor == PCI_VENDOR_ID_ENE) | |
185 | ene_test_c9(socket) = config_readb(socket, ENE_TEST_C9); | |
186 | } | |
187 | ||
188 | static void ti_restore_state(struct yenta_socket *socket) | |
189 | { | |
190 | config_writel(socket, TI113X_SYSTEM_CONTROL, ti_sysctl(socket)); | |
191 | config_writel(socket, TI122X_MFUNC, ti_mfunc(socket)); | |
192 | config_writeb(socket, TI113X_CARD_CONTROL, ti_cardctl(socket)); | |
193 | config_writeb(socket, TI113X_DEVICE_CONTROL, ti_devctl(socket)); | |
194 | config_writeb(socket, TI1250_DIAGNOSTIC, ti_diag(socket)); | |
195 | ||
196 | if (socket->dev->vendor == PCI_VENDOR_ID_ENE) | |
197 | config_writeb(socket, ENE_TEST_C9, ene_test_c9(socket)); | |
198 | } | |
199 | ||
200 | /* | |
201 | * Zoom video control for TI122x/113x chips | |
202 | */ | |
203 | ||
204 | static void ti_zoom_video(struct pcmcia_socket *sock, int onoff) | |
205 | { | |
206 | u8 reg; | |
207 | struct yenta_socket *socket = container_of(sock, struct yenta_socket, socket); | |
208 | ||
209 | /* If we don't have a Zoom Video switch this is harmless, | |
210 | we just tristate the unused (ZV) lines */ | |
211 | reg = config_readb(socket, TI113X_CARD_CONTROL); | |
212 | if (onoff) | |
213 | /* Zoom zoom, we will all go together, zoom zoom, zoom zoom */ | |
214 | reg |= TI113X_CCR_ZVENABLE; | |
215 | else | |
216 | reg &= ~TI113X_CCR_ZVENABLE; | |
217 | config_writeb(socket, TI113X_CARD_CONTROL, reg); | |
218 | } | |
219 | ||
220 | /* | |
221 | * The 145x series can also use this. They have an additional | |
222 | * ZV autodetect mode we don't use but don't actually need. | |
223 | * FIXME: manual says its in func0 and func1 but disagrees with | |
224 | * itself about this - do we need to force func0, if so we need | |
225 | * to know a lot more about socket pairings in pcmcia_socket than | |
226 | * we do now.. uggh. | |
227 | */ | |
228 | ||
229 | static void ti1250_zoom_video(struct pcmcia_socket *sock, int onoff) | |
230 | { | |
231 | struct yenta_socket *socket = container_of(sock, struct yenta_socket, socket); | |
232 | int shift = 0; | |
233 | u8 reg; | |
234 | ||
235 | ti_zoom_video(sock, onoff); | |
236 | ||
237 | reg = config_readb(socket, TI1250_MULTIMEDIA_CTL); | |
238 | reg |= TI1250_MMC_ZVOUTEN; /* ZV bus enable */ | |
239 | ||
240 | if(PCI_FUNC(socket->dev->devfn)==1) | |
241 | shift = 1; | |
242 | ||
243 | if(onoff) | |
244 | { | |
245 | reg &= ~(1<<6); /* Clear select bit */ | |
246 | reg |= shift<<6; /* Favour our socket */ | |
247 | reg |= 1<<shift; /* Socket zoom video on */ | |
248 | } | |
249 | else | |
250 | { | |
251 | reg &= ~(1<<6); /* Clear select bit */ | |
252 | reg |= (1^shift)<<6; /* Favour other socket */ | |
253 | reg &= ~(1<<shift); /* Socket zoon video off */ | |
254 | } | |
255 | ||
256 | config_writeb(socket, TI1250_MULTIMEDIA_CTL, reg); | |
257 | } | |
258 | ||
259 | static void ti_set_zv(struct yenta_socket *socket) | |
260 | { | |
261 | if(socket->dev->vendor == PCI_VENDOR_ID_TI) | |
262 | { | |
263 | switch(socket->dev->device) | |
264 | { | |
265 | /* There may be more .. */ | |
266 | case PCI_DEVICE_ID_TI_1220: | |
267 | case PCI_DEVICE_ID_TI_1221: | |
268 | case PCI_DEVICE_ID_TI_1225: | |
269 | case PCI_DEVICE_ID_TI_4510: | |
270 | socket->socket.zoom_video = ti_zoom_video; | |
271 | break; | |
272 | case PCI_DEVICE_ID_TI_1250: | |
273 | case PCI_DEVICE_ID_TI_1251A: | |
274 | case PCI_DEVICE_ID_TI_1251B: | |
275 | case PCI_DEVICE_ID_TI_1450: | |
276 | socket->socket.zoom_video = ti1250_zoom_video; | |
277 | } | |
278 | } | |
279 | } | |
280 | ||
281 | ||
282 | /* | |
283 | * Generic TI init - TI has an extension for the | |
284 | * INTCTL register that sets the PCI CSC interrupt. | |
285 | * Make sure we set it correctly at open and init | |
286 | * time | |
287 | * - override: disable the PCI CSC interrupt. This makes | |
288 | * it possible to use the CSC interrupt to probe the | |
289 | * ISA interrupts. | |
290 | * - init: set the interrupt to match our PCI state. | |
291 | * This makes us correctly get PCI CSC interrupt | |
292 | * events. | |
293 | */ | |
294 | static int ti_init(struct yenta_socket *socket) | |
295 | { | |
296 | u8 new, reg = exca_readb(socket, I365_INTCTL); | |
297 | ||
298 | new = reg & ~I365_INTR_ENA; | |
0d3a940d | 299 | if (socket->dev->irq) |
1da177e4 LT |
300 | new |= I365_INTR_ENA; |
301 | if (new != reg) | |
302 | exca_writeb(socket, I365_INTCTL, new); | |
303 | return 0; | |
304 | } | |
305 | ||
306 | static int ti_override(struct yenta_socket *socket) | |
307 | { | |
308 | u8 new, reg = exca_readb(socket, I365_INTCTL); | |
309 | ||
310 | new = reg & ~I365_INTR_ENA; | |
311 | if (new != reg) | |
312 | exca_writeb(socket, I365_INTCTL, new); | |
313 | ||
314 | ti_set_zv(socket); | |
315 | ||
316 | return 0; | |
317 | } | |
318 | ||
0d3a940d JK |
319 | static void ti113x_use_isa_irq(struct yenta_socket *socket) |
320 | { | |
321 | int isa_irq = -1; | |
322 | u8 intctl; | |
323 | u32 isa_irq_mask = 0; | |
324 | ||
325 | if (!isa_probe) | |
326 | return; | |
327 | ||
328 | /* get a free isa int */ | |
329 | isa_irq_mask = yenta_probe_irq(socket, isa_interrupts); | |
330 | if (!isa_irq_mask) | |
331 | return; /* no useable isa irq found */ | |
332 | ||
333 | /* choose highest available */ | |
334 | for (; isa_irq_mask; isa_irq++) | |
335 | isa_irq_mask >>= 1; | |
336 | socket->cb_irq = isa_irq; | |
337 | ||
338 | exca_writeb(socket, I365_CSCINT, (isa_irq << 4)); | |
339 | ||
340 | intctl = exca_readb(socket, I365_INTCTL); | |
341 | intctl &= ~(I365_INTR_ENA | I365_IRQ_MASK); /* CSC Enable */ | |
342 | exca_writeb(socket, I365_INTCTL, intctl); | |
343 | ||
344 | dev_info(&socket->dev->dev, | |
345 | "Yenta TI113x: using isa irq %d for CardBus\n", isa_irq); | |
346 | } | |
347 | ||
348 | ||
1da177e4 LT |
349 | static int ti113x_override(struct yenta_socket *socket) |
350 | { | |
351 | u8 cardctl; | |
352 | ||
353 | cardctl = config_readb(socket, TI113X_CARD_CONTROL); | |
354 | cardctl &= ~(TI113X_CCR_PCI_IRQ_ENA | TI113X_CCR_PCI_IREQ | TI113X_CCR_PCI_CSC); | |
0d3a940d | 355 | if (socket->dev->irq) |
1da177e4 | 356 | cardctl |= TI113X_CCR_PCI_IRQ_ENA | TI113X_CCR_PCI_CSC | TI113X_CCR_PCI_IREQ; |
0d3a940d JK |
357 | else |
358 | ti113x_use_isa_irq(socket); | |
359 | ||
1da177e4 LT |
360 | config_writeb(socket, TI113X_CARD_CONTROL, cardctl); |
361 | ||
362 | return ti_override(socket); | |
363 | } | |
364 | ||
365 | ||
366 | /* irqrouting for func0, probes PCI interrupt and ISA interrupts */ | |
367 | static void ti12xx_irqroute_func0(struct yenta_socket *socket) | |
368 | { | |
369 | u32 mfunc, mfunc_old, devctl; | |
370 | u8 gpio3, gpio3_old; | |
371 | int pci_irq_status; | |
372 | ||
373 | mfunc = mfunc_old = config_readl(socket, TI122X_MFUNC); | |
374 | devctl = config_readb(socket, TI113X_DEVICE_CONTROL); | |
dd797d81 DB |
375 | dev_printk(KERN_INFO, &socket->dev->dev, |
376 | "TI: mfunc 0x%08x, devctl 0x%02x\n", mfunc, devctl); | |
1da177e4 LT |
377 | |
378 | /* make sure PCI interrupts are enabled before probing */ | |
379 | ti_init(socket); | |
380 | ||
381 | /* test PCI interrupts first. only try fixing if return value is 0! */ | |
382 | pci_irq_status = yenta_probe_cb_irq(socket); | |
383 | if (pci_irq_status) | |
384 | goto out; | |
385 | ||
386 | /* | |
387 | * We're here which means PCI interrupts are _not_ delivered. try to | |
388 | * find the right setting (all serial or parallel) | |
389 | */ | |
dd797d81 DB |
390 | dev_printk(KERN_INFO, &socket->dev->dev, |
391 | "TI: probing PCI interrupt failed, trying to fix\n"); | |
1da177e4 LT |
392 | |
393 | /* for serial PCI make sure MFUNC3 is set to IRQSER */ | |
394 | if ((devctl & TI113X_DCR_IMODE_MASK) == TI12XX_DCR_IMODE_ALL_SERIAL) { | |
395 | switch (socket->dev->device) { | |
396 | case PCI_DEVICE_ID_TI_1250: | |
397 | case PCI_DEVICE_ID_TI_1251A: | |
398 | case PCI_DEVICE_ID_TI_1251B: | |
399 | case PCI_DEVICE_ID_TI_1450: | |
400 | case PCI_DEVICE_ID_TI_1451A: | |
401 | case PCI_DEVICE_ID_TI_4450: | |
402 | case PCI_DEVICE_ID_TI_4451: | |
403 | /* these chips have no IRQSER setting in MFUNC3 */ | |
404 | break; | |
405 | ||
406 | default: | |
407 | mfunc = (mfunc & ~TI122X_MFUNC3_MASK) | TI122X_MFUNC3_IRQSER; | |
408 | ||
409 | /* write down if changed, probe */ | |
410 | if (mfunc != mfunc_old) { | |
411 | config_writel(socket, TI122X_MFUNC, mfunc); | |
412 | ||
413 | pci_irq_status = yenta_probe_cb_irq(socket); | |
414 | if (pci_irq_status == 1) { | |
dd797d81 DB |
415 | dev_printk(KERN_INFO, &socket->dev->dev, |
416 | "TI: all-serial interrupts ok\n"); | |
1da177e4 LT |
417 | mfunc_old = mfunc; |
418 | goto out; | |
419 | } | |
420 | ||
421 | /* not working, back to old value */ | |
422 | mfunc = mfunc_old; | |
423 | config_writel(socket, TI122X_MFUNC, mfunc); | |
424 | ||
425 | if (pci_irq_status == -1) | |
426 | goto out; | |
427 | } | |
428 | } | |
429 | ||
430 | /* serial PCI interrupts not working fall back to parallel */ | |
dd797d81 DB |
431 | dev_printk(KERN_INFO, &socket->dev->dev, |
432 | "TI: falling back to parallel PCI interrupts\n"); | |
1da177e4 LT |
433 | devctl &= ~TI113X_DCR_IMODE_MASK; |
434 | devctl |= TI113X_DCR_IMODE_SERIAL; /* serial ISA could be right */ | |
435 | config_writeb(socket, TI113X_DEVICE_CONTROL, devctl); | |
436 | } | |
437 | ||
438 | /* parallel PCI interrupts: route INTA */ | |
439 | switch (socket->dev->device) { | |
440 | case PCI_DEVICE_ID_TI_1250: | |
441 | case PCI_DEVICE_ID_TI_1251A: | |
442 | case PCI_DEVICE_ID_TI_1251B: | |
443 | case PCI_DEVICE_ID_TI_1450: | |
444 | /* make sure GPIO3 is set to INTA */ | |
445 | gpio3 = gpio3_old = config_readb(socket, TI1250_GPIO3_CONTROL); | |
446 | gpio3 &= ~TI1250_GPIO_MODE_MASK; | |
447 | if (gpio3 != gpio3_old) | |
448 | config_writeb(socket, TI1250_GPIO3_CONTROL, gpio3); | |
449 | break; | |
450 | ||
451 | default: | |
452 | gpio3 = gpio3_old = 0; | |
453 | ||
454 | mfunc = (mfunc & ~TI122X_MFUNC0_MASK) | TI122X_MFUNC0_INTA; | |
455 | if (mfunc != mfunc_old) | |
456 | config_writel(socket, TI122X_MFUNC, mfunc); | |
457 | } | |
458 | ||
459 | /* time to probe again */ | |
460 | pci_irq_status = yenta_probe_cb_irq(socket); | |
461 | if (pci_irq_status == 1) { | |
462 | mfunc_old = mfunc; | |
dd797d81 DB |
463 | dev_printk(KERN_INFO, &socket->dev->dev, |
464 | "TI: parallel PCI interrupts ok\n"); | |
1da177e4 LT |
465 | } else { |
466 | /* not working, back to old value */ | |
467 | mfunc = mfunc_old; | |
468 | config_writel(socket, TI122X_MFUNC, mfunc); | |
469 | if (gpio3 != gpio3_old) | |
470 | config_writeb(socket, TI1250_GPIO3_CONTROL, gpio3_old); | |
471 | } | |
472 | ||
473 | out: | |
474 | if (pci_irq_status < 1) { | |
475 | socket->cb_irq = 0; | |
dd797d81 DB |
476 | dev_printk(KERN_INFO, &socket->dev->dev, |
477 | "Yenta TI: no PCI interrupts. Fish. " | |
478 | "Please report.\n"); | |
1da177e4 LT |
479 | } |
480 | } | |
481 | ||
482 | ||
c835a388 DR |
483 | /* changes the irq of func1 to match that of func0 */ |
484 | static int ti12xx_align_irqs(struct yenta_socket *socket, int *old_irq) | |
485 | { | |
486 | struct pci_dev *func0; | |
487 | ||
488 | /* find func0 device */ | |
489 | func0 = pci_get_slot(socket->dev->bus, socket->dev->devfn & ~0x07); | |
490 | if (!func0) | |
491 | return 0; | |
492 | ||
493 | if (old_irq) | |
494 | *old_irq = socket->cb_irq; | |
495 | socket->cb_irq = socket->dev->irq = func0->irq; | |
496 | ||
497 | pci_dev_put(func0); | |
498 | ||
499 | return 1; | |
500 | } | |
501 | ||
1da177e4 LT |
502 | /* |
503 | * ties INTA and INTB together. also changes the devices irq to that of | |
504 | * the function 0 device. call from func1 only. | |
505 | * returns 1 if INTRTIE changed, 0 otherwise. | |
506 | */ | |
507 | static int ti12xx_tie_interrupts(struct yenta_socket *socket, int *old_irq) | |
508 | { | |
1da177e4 | 509 | u32 sysctl; |
c835a388 | 510 | int ret; |
1da177e4 LT |
511 | |
512 | sysctl = config_readl(socket, TI113X_SYSTEM_CONTROL); | |
513 | if (sysctl & TI122X_SCR_INTRTIE) | |
514 | return 0; | |
515 | ||
c835a388 DR |
516 | /* align */ |
517 | ret = ti12xx_align_irqs(socket, old_irq); | |
518 | if (!ret) | |
1da177e4 LT |
519 | return 0; |
520 | ||
c835a388 | 521 | /* tie */ |
1da177e4 LT |
522 | sysctl |= TI122X_SCR_INTRTIE; |
523 | config_writel(socket, TI113X_SYSTEM_CONTROL, sysctl); | |
524 | ||
1da177e4 LT |
525 | return 1; |
526 | } | |
527 | ||
528 | /* undo what ti12xx_tie_interrupts() did */ | |
529 | static void ti12xx_untie_interrupts(struct yenta_socket *socket, int old_irq) | |
530 | { | |
531 | u32 sysctl = config_readl(socket, TI113X_SYSTEM_CONTROL); | |
532 | sysctl &= ~TI122X_SCR_INTRTIE; | |
533 | config_writel(socket, TI113X_SYSTEM_CONTROL, sysctl); | |
534 | ||
535 | socket->cb_irq = socket->dev->irq = old_irq; | |
536 | } | |
537 | ||
538 | /* | |
539 | * irqrouting for func1, plays with INTB routing | |
540 | * only touches MFUNC for INTB routing. all other bits are taken | |
541 | * care of in func0 already. | |
542 | */ | |
543 | static void ti12xx_irqroute_func1(struct yenta_socket *socket) | |
544 | { | |
c835a388 | 545 | u32 mfunc, mfunc_old, devctl, sysctl; |
1da177e4 LT |
546 | int pci_irq_status; |
547 | ||
548 | mfunc = mfunc_old = config_readl(socket, TI122X_MFUNC); | |
549 | devctl = config_readb(socket, TI113X_DEVICE_CONTROL); | |
dd797d81 DB |
550 | dev_printk(KERN_INFO, &socket->dev->dev, |
551 | "TI: mfunc 0x%08x, devctl 0x%02x\n", | |
552 | mfunc, devctl); | |
1da177e4 | 553 | |
c835a388 DR |
554 | /* if IRQs are configured as tied, align irq of func1 with func0 */ |
555 | sysctl = config_readl(socket, TI113X_SYSTEM_CONTROL); | |
556 | if (sysctl & TI122X_SCR_INTRTIE) | |
557 | ti12xx_align_irqs(socket, NULL); | |
558 | ||
1da177e4 LT |
559 | /* make sure PCI interrupts are enabled before probing */ |
560 | ti_init(socket); | |
561 | ||
562 | /* test PCI interrupts first. only try fixing if return value is 0! */ | |
563 | pci_irq_status = yenta_probe_cb_irq(socket); | |
564 | if (pci_irq_status) | |
565 | goto out; | |
566 | ||
567 | /* | |
568 | * We're here which means PCI interrupts are _not_ delivered. try to | |
569 | * find the right setting | |
570 | */ | |
dd797d81 DB |
571 | dev_printk(KERN_INFO, &socket->dev->dev, |
572 | "TI: probing PCI interrupt failed, trying to fix\n"); | |
1da177e4 LT |
573 | |
574 | /* if all serial: set INTRTIE, probe again */ | |
575 | if ((devctl & TI113X_DCR_IMODE_MASK) == TI12XX_DCR_IMODE_ALL_SERIAL) { | |
576 | int old_irq; | |
577 | ||
578 | if (ti12xx_tie_interrupts(socket, &old_irq)) { | |
579 | pci_irq_status = yenta_probe_cb_irq(socket); | |
580 | if (pci_irq_status == 1) { | |
dd797d81 DB |
581 | dev_printk(KERN_INFO, &socket->dev->dev, |
582 | "TI: all-serial interrupts, tied ok\n"); | |
1da177e4 LT |
583 | goto out; |
584 | } | |
585 | ||
586 | ti12xx_untie_interrupts(socket, old_irq); | |
587 | } | |
588 | } | |
589 | /* parallel PCI: route INTB, probe again */ | |
590 | else { | |
591 | int old_irq; | |
592 | ||
593 | switch (socket->dev->device) { | |
594 | case PCI_DEVICE_ID_TI_1250: | |
595 | /* the 1250 has one pin for IRQSER/INTB depending on devctl */ | |
596 | break; | |
597 | ||
598 | case PCI_DEVICE_ID_TI_1251A: | |
599 | case PCI_DEVICE_ID_TI_1251B: | |
600 | case PCI_DEVICE_ID_TI_1450: | |
601 | /* | |
602 | * those have a pin for IRQSER/INTB plus INTB in MFUNC0 | |
603 | * we alread probed the shared pin, now go for MFUNC0 | |
604 | */ | |
605 | mfunc = (mfunc & ~TI122X_MFUNC0_MASK) | TI125X_MFUNC0_INTB; | |
606 | break; | |
607 | ||
608 | default: | |
609 | mfunc = (mfunc & ~TI122X_MFUNC1_MASK) | TI122X_MFUNC1_INTB; | |
610 | break; | |
611 | } | |
612 | ||
613 | /* write, probe */ | |
614 | if (mfunc != mfunc_old) { | |
615 | config_writel(socket, TI122X_MFUNC, mfunc); | |
616 | ||
617 | pci_irq_status = yenta_probe_cb_irq(socket); | |
618 | if (pci_irq_status == 1) { | |
dd797d81 DB |
619 | dev_printk(KERN_INFO, &socket->dev->dev, |
620 | "TI: parallel PCI interrupts ok\n"); | |
1da177e4 LT |
621 | goto out; |
622 | } | |
623 | ||
624 | mfunc = mfunc_old; | |
625 | config_writel(socket, TI122X_MFUNC, mfunc); | |
626 | ||
627 | if (pci_irq_status == -1) | |
628 | goto out; | |
629 | } | |
dd797d81 | 630 | |
1da177e4 LT |
631 | /* still nothing: set INTRTIE */ |
632 | if (ti12xx_tie_interrupts(socket, &old_irq)) { | |
633 | pci_irq_status = yenta_probe_cb_irq(socket); | |
634 | if (pci_irq_status == 1) { | |
dd797d81 DB |
635 | dev_printk(KERN_INFO, &socket->dev->dev, |
636 | "TI: parallel PCI interrupts, tied ok\n"); | |
1da177e4 LT |
637 | goto out; |
638 | } | |
639 | ||
640 | ti12xx_untie_interrupts(socket, old_irq); | |
641 | } | |
642 | } | |
643 | ||
644 | out: | |
645 | if (pci_irq_status < 1) { | |
646 | socket->cb_irq = 0; | |
dd797d81 DB |
647 | dev_printk(KERN_INFO, &socket->dev->dev, |
648 | "TI: no PCI interrupts. Fish. Please report.\n"); | |
1da177e4 LT |
649 | } |
650 | } | |
651 | ||
fa912bcb DR |
652 | |
653 | /* Returns true value if the second slot of a two-slot controller is empty */ | |
654 | static int ti12xx_2nd_slot_empty(struct yenta_socket *socket) | |
655 | { | |
656 | struct pci_dev *func; | |
657 | struct yenta_socket *slot2; | |
658 | int devfn; | |
659 | unsigned int state; | |
660 | int ret = 1; | |
6c1a10db | 661 | u32 sysctl; |
fa912bcb DR |
662 | |
663 | /* catch the two-slot controllers */ | |
664 | switch (socket->dev->device) { | |
665 | case PCI_DEVICE_ID_TI_1220: | |
666 | case PCI_DEVICE_ID_TI_1221: | |
667 | case PCI_DEVICE_ID_TI_1225: | |
668 | case PCI_DEVICE_ID_TI_1251A: | |
669 | case PCI_DEVICE_ID_TI_1251B: | |
670 | case PCI_DEVICE_ID_TI_1420: | |
671 | case PCI_DEVICE_ID_TI_1450: | |
672 | case PCI_DEVICE_ID_TI_1451A: | |
673 | case PCI_DEVICE_ID_TI_1520: | |
674 | case PCI_DEVICE_ID_TI_1620: | |
675 | case PCI_DEVICE_ID_TI_4520: | |
676 | case PCI_DEVICE_ID_TI_4450: | |
677 | case PCI_DEVICE_ID_TI_4451: | |
678 | /* | |
679 | * there are way more, but they need to be added in yenta_socket.c | |
680 | * and pci_ids.h first anyway. | |
681 | */ | |
682 | break; | |
683 | ||
59e35ba1 | 684 | case PCI_DEVICE_ID_TI_XX12: |
6c1a10db DR |
685 | case PCI_DEVICE_ID_TI_X515: |
686 | case PCI_DEVICE_ID_TI_X420: | |
687 | case PCI_DEVICE_ID_TI_X620: | |
688 | case PCI_DEVICE_ID_TI_XX21_XX11: | |
689 | case PCI_DEVICE_ID_TI_7410: | |
690 | case PCI_DEVICE_ID_TI_7610: | |
691 | /* | |
692 | * those are either single or dual slot CB with additional functions | |
693 | * like 1394, smartcard reader, etc. check the TIEALL flag for them | |
694 | * the TIEALL flag binds the IRQ of all functions toghether. | |
695 | * we catch the single slot variants later. | |
696 | */ | |
697 | sysctl = config_readl(socket, TI113X_SYSTEM_CONTROL); | |
698 | if (sysctl & TIXX21_SCR_TIEALL) | |
699 | return 0; | |
700 | ||
701 | break; | |
702 | ||
fa912bcb DR |
703 | /* single-slot controllers have the 2nd slot empty always :) */ |
704 | default: | |
705 | return 1; | |
706 | } | |
707 | ||
708 | /* get other slot */ | |
709 | devfn = socket->dev->devfn & ~0x07; | |
710 | func = pci_get_slot(socket->dev->bus, | |
711 | (socket->dev->devfn & 0x07) ? devfn : devfn | 0x01); | |
712 | if (!func) | |
713 | return 1; | |
714 | ||
6c1a10db DR |
715 | /* |
716 | * check that the device id of both slots match. this is needed for the | |
717 | * XX21 and the XX11 controller that share the same device id for single | |
718 | * and dual slot controllers. return '2nd slot empty'. we already checked | |
719 | * if the interrupt is tied to another function. | |
720 | */ | |
721 | if (socket->dev->device != func->device) | |
722 | goto out; | |
723 | ||
fa912bcb DR |
724 | slot2 = pci_get_drvdata(func); |
725 | if (!slot2) | |
726 | goto out; | |
727 | ||
728 | /* check state */ | |
05f43d48 | 729 | yenta_get_status(&slot2->socket, &state); |
fa912bcb DR |
730 | if (state & SS_DETECT) { |
731 | ret = 0; | |
732 | goto out; | |
733 | } | |
734 | ||
735 | out: | |
736 | pci_dev_put(func); | |
737 | return ret; | |
738 | } | |
739 | ||
740 | /* | |
741 | * TI specifiy parts for the power hook. | |
742 | * | |
743 | * some TI's with some CB's produces interrupt storm on power on. it has been | |
744 | * seen with atheros wlan cards on TI1225 and TI1410. solution is simply to | |
745 | * disable any CB interrupts during this time. | |
746 | */ | |
747 | static int ti12xx_power_hook(struct pcmcia_socket *sock, int operation) | |
748 | { | |
749 | struct yenta_socket *socket = container_of(sock, struct yenta_socket, socket); | |
750 | u32 mfunc, devctl, sysctl; | |
751 | u8 gpio3; | |
752 | ||
753 | /* only POWER_PRE and POWER_POST are interesting */ | |
754 | if ((operation != HOOK_POWER_PRE) && (operation != HOOK_POWER_POST)) | |
755 | return 0; | |
756 | ||
757 | devctl = config_readb(socket, TI113X_DEVICE_CONTROL); | |
758 | sysctl = config_readl(socket, TI113X_SYSTEM_CONTROL); | |
759 | mfunc = config_readl(socket, TI122X_MFUNC); | |
760 | ||
761 | /* | |
762 | * all serial/tied: only disable when modparm set. always doing it | |
763 | * would mean a regression for working setups 'cos it disables the | |
764 | * interrupts for both both slots on 2-slot controllers | |
765 | * (and users of single slot controllers where it's save have to | |
766 | * live with setting the modparm, most don't have to anyway) | |
767 | */ | |
768 | if (((devctl & TI113X_DCR_IMODE_MASK) == TI12XX_DCR_IMODE_ALL_SERIAL) && | |
769 | (pwr_irqs_off || ti12xx_2nd_slot_empty(socket))) { | |
770 | switch (socket->dev->device) { | |
771 | case PCI_DEVICE_ID_TI_1250: | |
772 | case PCI_DEVICE_ID_TI_1251A: | |
773 | case PCI_DEVICE_ID_TI_1251B: | |
774 | case PCI_DEVICE_ID_TI_1450: | |
775 | case PCI_DEVICE_ID_TI_1451A: | |
776 | case PCI_DEVICE_ID_TI_4450: | |
777 | case PCI_DEVICE_ID_TI_4451: | |
778 | /* these chips have no IRQSER setting in MFUNC3 */ | |
779 | break; | |
780 | ||
781 | default: | |
782 | if (operation == HOOK_POWER_PRE) | |
783 | mfunc = (mfunc & ~TI122X_MFUNC3_MASK); | |
784 | else | |
785 | mfunc = (mfunc & ~TI122X_MFUNC3_MASK) | TI122X_MFUNC3_IRQSER; | |
786 | } | |
787 | ||
788 | return 0; | |
789 | } | |
790 | ||
791 | /* do the job differently for func0/1 */ | |
792 | if ((PCI_FUNC(socket->dev->devfn) == 0) || | |
793 | ((sysctl & TI122X_SCR_INTRTIE) && | |
794 | (pwr_irqs_off || ti12xx_2nd_slot_empty(socket)))) { | |
795 | /* some bridges are different */ | |
796 | switch (socket->dev->device) { | |
797 | case PCI_DEVICE_ID_TI_1250: | |
798 | case PCI_DEVICE_ID_TI_1251A: | |
799 | case PCI_DEVICE_ID_TI_1251B: | |
800 | case PCI_DEVICE_ID_TI_1450: | |
801 | /* those oldies use gpio3 for INTA */ | |
802 | gpio3 = config_readb(socket, TI1250_GPIO3_CONTROL); | |
803 | if (operation == HOOK_POWER_PRE) | |
804 | gpio3 = (gpio3 & ~TI1250_GPIO_MODE_MASK) | 0x40; | |
805 | else | |
806 | gpio3 &= ~TI1250_GPIO_MODE_MASK; | |
807 | config_writeb(socket, TI1250_GPIO3_CONTROL, gpio3); | |
808 | break; | |
809 | ||
810 | default: | |
811 | /* all new bridges are the same */ | |
812 | if (operation == HOOK_POWER_PRE) | |
813 | mfunc &= ~TI122X_MFUNC0_MASK; | |
814 | else | |
815 | mfunc |= TI122X_MFUNC0_INTA; | |
816 | config_writel(socket, TI122X_MFUNC, mfunc); | |
817 | } | |
818 | } else { | |
819 | switch (socket->dev->device) { | |
820 | case PCI_DEVICE_ID_TI_1251A: | |
821 | case PCI_DEVICE_ID_TI_1251B: | |
822 | case PCI_DEVICE_ID_TI_1450: | |
823 | /* those have INTA elsewhere and INTB in MFUNC0 */ | |
824 | if (operation == HOOK_POWER_PRE) | |
825 | mfunc &= ~TI122X_MFUNC0_MASK; | |
826 | else | |
827 | mfunc |= TI125X_MFUNC0_INTB; | |
828 | config_writel(socket, TI122X_MFUNC, mfunc); | |
829 | ||
830 | break; | |
831 | ||
832 | default: | |
833 | /* all new bridges are the same */ | |
834 | if (operation == HOOK_POWER_PRE) | |
835 | mfunc &= ~TI122X_MFUNC1_MASK; | |
836 | else | |
837 | mfunc |= TI122X_MFUNC1_INTB; | |
838 | config_writel(socket, TI122X_MFUNC, mfunc); | |
839 | } | |
840 | } | |
841 | ||
842 | return 0; | |
843 | } | |
844 | ||
1da177e4 LT |
845 | static int ti12xx_override(struct yenta_socket *socket) |
846 | { | |
847 | u32 val, val_orig; | |
848 | ||
849 | /* make sure that memory burst is active */ | |
850 | val_orig = val = config_readl(socket, TI113X_SYSTEM_CONTROL); | |
851 | if (disable_clkrun && PCI_FUNC(socket->dev->devfn) == 0) { | |
dd797d81 DB |
852 | dev_printk(KERN_INFO, &socket->dev->dev, |
853 | "Disabling CLKRUN feature\n"); | |
1da177e4 LT |
854 | val |= TI113X_SCR_KEEPCLK; |
855 | } | |
856 | if (!(val & TI122X_SCR_MRBURSTUP)) { | |
dd797d81 DB |
857 | dev_printk(KERN_INFO, &socket->dev->dev, |
858 | "Enabling burst memory read transactions\n"); | |
1da177e4 LT |
859 | val |= TI122X_SCR_MRBURSTUP; |
860 | } | |
861 | if (val_orig != val) | |
862 | config_writel(socket, TI113X_SYSTEM_CONTROL, val); | |
863 | ||
1da177e4 LT |
864 | /* |
865 | * Yenta expects controllers to use CSCINT to route | |
866 | * CSC interrupts to PCI rather than INTVAL. | |
867 | */ | |
868 | val = config_readb(socket, TI1250_DIAGNOSTIC); | |
dd797d81 DB |
869 | dev_printk(KERN_INFO, &socket->dev->dev, |
870 | "Using %s to route CSC interrupts to PCI\n", | |
871 | (val & TI1250_DIAG_PCI_CSC) ? "CSCINT" : "INTVAL"); | |
872 | dev_printk(KERN_INFO, &socket->dev->dev, | |
873 | "Routing CardBus interrupts to %s\n", | |
874 | (val & TI1250_DIAG_PCI_IREQ) ? "PCI" : "ISA"); | |
1da177e4 LT |
875 | |
876 | /* do irqrouting, depending on function */ | |
877 | if (PCI_FUNC(socket->dev->devfn) == 0) | |
878 | ti12xx_irqroute_func0(socket); | |
879 | else | |
880 | ti12xx_irqroute_func1(socket); | |
881 | ||
fa912bcb DR |
882 | /* install power hook */ |
883 | socket->socket.power_hook = ti12xx_power_hook; | |
884 | ||
1da177e4 LT |
885 | return ti_override(socket); |
886 | } | |
887 | ||
888 | ||
889 | static int ti1250_override(struct yenta_socket *socket) | |
890 | { | |
891 | u8 old, diag; | |
892 | ||
893 | old = config_readb(socket, TI1250_DIAGNOSTIC); | |
894 | diag = old & ~(TI1250_DIAG_PCI_CSC | TI1250_DIAG_PCI_IREQ); | |
895 | if (socket->cb_irq) | |
896 | diag |= TI1250_DIAG_PCI_CSC | TI1250_DIAG_PCI_IREQ; | |
897 | ||
898 | if (diag != old) { | |
dd797d81 DB |
899 | dev_printk(KERN_INFO, &socket->dev->dev, |
900 | "adjusting diagnostic: %02x -> %02x\n", | |
901 | old, diag); | |
1da177e4 LT |
902 | config_writeb(socket, TI1250_DIAGNOSTIC, diag); |
903 | } | |
904 | ||
905 | return ti12xx_override(socket); | |
906 | } | |
907 | ||
8c3520d4 DR |
908 | |
909 | /** | |
910 | * EnE specific part. EnE bridges are register compatible with TI bridges but | |
911 | * have their own test registers and more important their own little problems. | |
912 | * Some fixup code to make everybody happy (TM). | |
913 | */ | |
914 | ||
63e7ebd0 | 915 | #ifdef CONFIG_YENTA_ENE_TUNE |
78187865 | 916 | /* |
8c3520d4 DR |
917 | * set/clear various test bits: |
918 | * Defaults to clear the bit. | |
919 | * - mask (u8) defines what bits to change | |
920 | * - bits (u8) is the values to change them to | |
921 | * -> it's | |
922 | * current = (current & ~mask) | bits | |
923 | */ | |
924 | /* pci ids of devices that wants to have the bit set */ | |
925 | #define DEVID(_vend,_dev,_subvend,_subdev,mask,bits) { \ | |
926 | .vendor = _vend, \ | |
927 | .device = _dev, \ | |
928 | .subvendor = _subvend, \ | |
929 | .subdevice = _subdev, \ | |
930 | .driver_data = ((mask) << 8 | (bits)), \ | |
931 | } | |
932 | static struct pci_device_id ene_tune_tbl[] = { | |
933 | /* Echo Audio products based on motorola DSP56301 and DSP56361 */ | |
934 | DEVID(PCI_VENDOR_ID_MOTOROLA, 0x1801, 0xECC0, PCI_ANY_ID, | |
935 | ENE_TEST_C9_TLTENABLE | ENE_TEST_C9_PFENABLE, ENE_TEST_C9_TLTENABLE), | |
936 | DEVID(PCI_VENDOR_ID_MOTOROLA, 0x3410, 0xECC0, PCI_ANY_ID, | |
937 | ENE_TEST_C9_TLTENABLE | ENE_TEST_C9_PFENABLE, ENE_TEST_C9_TLTENABLE), | |
938 | ||
939 | {} | |
940 | }; | |
941 | ||
942 | static void ene_tune_bridge(struct pcmcia_socket *sock, struct pci_bus *bus) | |
943 | { | |
944 | struct yenta_socket *socket = container_of(sock, struct yenta_socket, socket); | |
945 | struct pci_dev *dev; | |
946 | struct pci_device_id *id = NULL; | |
947 | u8 test_c9, old_c9, mask, bits; | |
948 | ||
949 | list_for_each_entry(dev, &bus->devices, bus_list) { | |
950 | id = (struct pci_device_id *) pci_match_id(ene_tune_tbl, dev); | |
951 | if (id) | |
952 | break; | |
953 | } | |
954 | ||
955 | test_c9 = old_c9 = config_readb(socket, ENE_TEST_C9); | |
956 | if (id) { | |
957 | mask = (id->driver_data >> 8) & 0xFF; | |
958 | bits = id->driver_data & 0xFF; | |
959 | ||
960 | test_c9 = (test_c9 & ~mask) | bits; | |
961 | } | |
962 | else | |
963 | /* default to clear TLTEnable bit, old behaviour */ | |
964 | test_c9 &= ~ENE_TEST_C9_TLTENABLE; | |
965 | ||
dd797d81 DB |
966 | dev_printk(KERN_INFO, &socket->dev->dev, |
967 | "EnE: chaning testregister 0xC9, %02x -> %02x\n", | |
968 | old_c9, test_c9); | |
8c3520d4 DR |
969 | config_writeb(socket, ENE_TEST_C9, test_c9); |
970 | } | |
971 | ||
8c3520d4 DR |
972 | static int ene_override(struct yenta_socket *socket) |
973 | { | |
974 | /* install tune_bridge() function */ | |
975 | socket->socket.tune_bridge = ene_tune_bridge; | |
976 | ||
977 | return ti1250_override(socket); | |
978 | } | |
c2059b2e DV |
979 | #else |
980 | # define ene_override ti1250_override | |
63e7ebd0 | 981 | #endif /* !CONFIG_YENTA_ENE_TUNE */ |
8c3520d4 | 982 | |
1da177e4 LT |
983 | #endif /* _LINUX_TI113X_H */ |
984 |