5 * Support for i82365 and similar ISA-to-PCMCIA bridges
7 * Taken from Linux kernel sources, distributed under GPL2
9 * Software distributed under the License is distributed on an "AS
10 * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
11 * implied. See the License for the specific language governing
12 * rights and limitations under the License.
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.
18 * Ported by: Anselm Martin Hoffmeister, Stockholm Projekt Computer-Service, Sankt Augustin/Bonn, GERMANY
24 * ******************************
25 * PLEASE DO NOT YET WORK ON THIS
26 * ******************************
28 * I'm still fixing it up on every end, so we most probably would interfere
29 * at some point. If there's anything obvious or better, not-so-obvious,
30 * please contact me by e-mail: anselm (AT) hoffmeister (DOT) be *THANKS*
32 #include "../include/pcmcia.h"
33 #include "../include/pcmcia-opts.h"
34 #include "../include/i82365.h"
37 #error PCMCIA_I82365 only works with ISA defined - set CONFIG_ISA
40 typedef enum pcic_id
{
41 IS_I82365A
, IS_I82365B
, IS_I82365DF
,
42 IS_IBM
, IS_RF5Cx96
, IS_VLSI
, IS_VG468
, IS_VG469
,
43 IS_PD6710
, IS_PD672X
, IS_VT83C469
,
46 /* Flags for classifying groups of controllers */
47 #define IS_VADEM 0x0001
48 #define IS_CIRRUS 0x0002
50 #define IS_O2MICRO 0x0008
52 #define IS_TOPIC 0x0020
53 #define IS_RICOH 0x0040
54 #define IS_UNKNOWN 0x0400
55 #define IS_VG_PWR 0x0800
56 #define IS_DF_PWR 0x1000
58 #define IS_ALIVE 0x8000
60 typedef struct pcic_t
{
65 static pcic_t pcic
[] = {
66 { "Intel i82365sl A step", 0 },
67 { "Intel i82365sl B step", 0 },
68 { "Intel i82365sl DF", IS_DF_PWR
},
70 { "Ricoh RF5C296/396", 0 },
72 { "Vadem VG-468", IS_VADEM
},
73 { "Vadem VG-469", IS_VADEM
|IS_VG_PWR
},
74 { "Cirrus PD6710", IS_CIRRUS
},
75 { "Cirrus PD672x", IS_CIRRUS
},
76 { "VIA VT83C469", IS_CIRRUS
|IS_VIA
},
79 typedef struct cirrus_state_t
{
84 typedef struct vg46x_state_t
{
88 typedef struct socket_info_t
{
94 void (*handler
)(void *info
, u_int events
);
97 cirrus_state_t cirrus
;
102 //static socket_info_t socket[8];
104 int i365_base
= 0x3e0; // Default in Linux kernel
105 int cycle_time
= 120; // External clock time in ns, 120ns =~ 8.33 MHz
108 void phex ( unsigned char c
);
109 /*static int to_cycles(int ns)
111 return ns/cycle_time;
114 /*static int to_ns(int cycles)
116 return cycle_time*cycles;
120 static u_char
i365_get(u_short sock
, u_short reg
)
122 //unsigned long flags;
123 //spin_lock_irqsave(&bus_lock,flags);
125 ioaddr_t port
= pccsock
[sock
].ioaddr
;
127 reg
= I365_REG(pccsock
[sock
].internalid
, reg
);
128 outb(reg
, port
); val
= inb(port
+1);
129 //spin_unlock_irqrestore(&bus_lock,flags);
134 static void i365_set(u_short sock
, u_short reg
, u_char data
)
136 //unsigned long flags;
137 //spin_lock_irqsave(&bus_lock,flags);
139 ioaddr_t port
= pccsock
[sock
].ioaddr
;
140 u_char val
= I365_REG(pccsock
[sock
].internalid
, reg
);
141 outb(val
, port
); outb(data
, port
+1);
142 //spin_unlock_irqrestore(&bus_lock,flags);
146 void add_socket_i365(u_short port
, int psock
, int type
) {
147 pccsock
[pccsocks
].ioaddr
= port
;
148 pccsock
[pccsocks
].internalid
= psock
;
149 pccsock
[pccsocks
].type
= type
;
150 pccsock
[pccsocks
].flags
= pcic
[type
].flags
;
151 pccsock
[pccsocks
].drivernum
= mydriverid
;
152 pccsock
[pccsocks
].configoffset
= -1;
153 // Find out if a card in inside that socket
154 pccsock
[pccsocks
].status
= (( 12 == (i365_get(pccsocks
,I365_STATUS
)&12) ) ? HASCARD
: EMPTY
);
155 // *TODO* check if that's all
156 if ( 0 == (psock
& 1) ) {
157 printf ( "Found a PCMCIA controller (i82365) at io %x, type '%s'\n", port
, pcic
[type
].name
);
158 // pccsock[pccsocks].status == HASCARD? "holds card":"empty" );
164 void i365_bset(u_short sock
, u_short reg
, u_char mask
) {
165 u_char d
= i365_get(sock
, reg
);
167 i365_set(sock
, reg
, d
);
170 void i365_bclr(u_short sock
, u_short reg
, u_char mask
) {
171 u_char d
= i365_get(sock
, reg
);
173 i365_set(sock
, reg
, d
);
177 /*static void i365_bflip(u_short sock, u_short reg, u_char mask, int b)
179 u_char d = i365_get(sock, reg);
184 i365_set(sock, reg, d);
189 static u_short i365_get_pair(u_short sock, u_short reg)
192 a = i365_get(sock, reg);
193 b = i365_get(sock, reg+1);
199 static void i365_set_pair(u_short sock, u_short reg, u_short data)
201 i365_set(sock, reg, data & 0xff);
202 i365_set(sock, reg+1, data >> 8);
205 int identify_i365 ( u_short port
, u_short sock
) {
208 /* Use the next free entry in the socket table */
209 pccsock
[pccsocks
].ioaddr
= port
;
210 pccsock
[pccsocks
].internalid
= sock
;
211 // *TODO* wakeup a sleepy cirrus controller?
213 if ((val
= i365_get(pccsocks
, I365_IDENT
)) & 0x70)
217 type
= IS_I82365A
; break;
219 type
= IS_I82365B
; break;
221 type
= IS_I82365DF
; break;
222 case 0x88: case 0x89: case 0x8a:
223 type
= IS_IBM
; break;
225 /* Check for Vadem VG-468 chips */
228 i365_bset(pccsocks
, VG468_MISC
, VG468_MISC_VADEMREV
);
229 val
= i365_get(pccsocks
, I365_IDENT
);
230 if (val
& I365_IDENT_VADEM
) {
231 i365_bclr(pccsocks
, VG468_MISC
, VG468_MISC_VADEMREV
);
232 type
= ((val
& 7) >= 4) ? IS_VG469
: IS_VG468
;
235 /* Check for Ricoh chips */
236 val
= i365_get(pccsocks
, RF5C_CHIP_ID
);
237 if ((val
== RF5C_CHIP_RF5C296
) || (val
== RF5C_CHIP_RF5C396
)) type
= IS_RF5Cx96
;
239 /* Check for Cirrus CL-PD67xx chips */
240 i365_set(pccsocks
, PD67_CHIP_INFO
, 0);
241 val
= i365_get(pccsocks
, PD67_CHIP_INFO
);
242 if ((val
& PD67_INFO_CHIP_ID
) == PD67_INFO_CHIP_ID
) {
243 val
= i365_get(pccsocks
, PD67_CHIP_INFO
);
244 if ((val
& PD67_INFO_CHIP_ID
) == 0) {
245 type
= (val
& PD67_INFO_SLOTS
) ? IS_PD672X
: IS_PD6710
;
246 i365_set(pccsocks
, PD67_EXT_INDEX
, 0xe5);
247 if (i365_get(pccsocks
, PD67_EXT_INDEX
) != 0xe5) type
= IS_VT83C469
;
253 int init_i82365(void) {
254 int i
, j
, sock
, k
, ns
, id
;
255 //unsigned int ui,uj;
256 //unsigned char * upc;
259 // Change from kernel: No irq init, no check_region, no isapnp support
260 // No ignore socket, no extra sockets to check (so it's easier here :-/)
261 // Probably we don't need any of them; in case YOU do, SHOUT AT ME!
262 id
= identify_i365(i365_base
, 0);
263 if ((id
== IS_I82365DF
) && (identify_i365(i365_base
, 1) != id
)) {
264 for (i
= 0; i
< 4; i
++) {
265 port
= i365_base
+ ((i
& 1) << 2) + ((i
& 2) << 1);
267 if (identify_i365(port
, sock
) == IS_I82365DF
) {
268 add_socket_i365(port
, sock
, IS_VLSI
);
272 for (i
= 0; i
< 4; i
+= 2) {
273 port
= i365_base
+ 2*(i
>>2);
275 id
= identify_i365(port
, sock
);
276 if (id
< 0) continue;
278 for (j
= ns
= 0; j
< 2; j
++) {
279 /* Does the socket exist? */
280 if (identify_i365(port
, sock
+j
) < 0) continue;
281 /* Check for bad socket decode */
282 for (k
= 0; k
<= i82365s
; k
++)
283 i365_set(k
, I365_MEM(0)+I365_W_OFF
, k
);
284 for (k
= 0; k
<= i82365s
; k
++)
285 if (i365_get(k
, I365_MEM(0)+I365_W_OFF
) != k
)
287 if (k
<= i82365s
) break;
288 add_socket_i365(port
, sock
+j
, id
); ns
++;
300 /* printf ( "Selecting config 1: io 0x300 @byte 87*2.." );
302 i365_bclr(1, I365_ADDRWIN, 1 );
303 i365_set(1,I365_INTCTL, 0x65 ); //no-reset, memory-card
304 i365_set(1, I365_IO(0)+0, 0x20 );
305 i365_set(1, I365_IO(0)+1, 0x03 );
306 i365_set(1, I365_IO(0)+2, 0x3f );
307 i365_set(1, I365_IO(0)+3, 0x03 );
308 i365_set(1, 0x3a, 0x05 );
309 i365_set(1, 0x3b, 0x05 );
310 i365_set(1, 0x3c, 0x05 );
311 i365_set(1, 0x3d, 0x05 );
312 i365_set(1, 0x3e, 0x05 );
313 i365_set(1, 0x3f, 0x05 );
314 i365_set(1, 0x07, 0x0a );
315 i365_set(1, I365_ADDRWIN, 0x40 ); // 0x40
316 printf ( "!\n" ); getchar();
321 void phex ( unsigned char c
) {
322 unsigned char a
= 0, b
= 0;
324 if ( b
> 9 ) b
+= ('a'-'9'-1);
326 a
= ( c
& 0xf0 ) >> 4;
327 if ( a
> 9 ) a
+= ('a'-'9'-1);
329 printf ( "%c%c ", a
, b
);
333 int deinit_i82365(void) {
334 printf("Deinitializing i82365\n" );
338 /*static int i365_get_status(u_short sock, u_int *value)
342 status = i365_get(sock, I365_STATUS);
343 *value = ((status & I365_CS_DETECT) == I365_CS_DETECT)
346 if (i365_get(sock, I365_INTCTL) & I365_PC_IOCARD)
347 *value |= (status & I365_CS_STSCHG) ? 0 : SS_STSCHG;
349 *value |= (status & I365_CS_BVD1) ? 0 : SS_BATDEAD;
350 *value |= (status & I365_CS_BVD2) ? 0 : SS_BATWARN;
352 *value |= (status & I365_CS_WRPROT) ? SS_WRPROT : 0;
353 *value |= (status & I365_CS_READY) ? SS_READY : 0;
354 *value |= (status & I365_CS_POWERON) ? SS_POWERON : 0;
357 if (pccsock[sock].type == IS_VG469) {
358 status = i365_get(sock, VG469_VSENSE);
359 if (pccsock[sock].internalid & 1) {
360 *value |= (status & VG469_VSENSE_B_VS1) ? 0 : SS_3VCARD;
361 *value |= (status & VG469_VSENSE_B_VS2) ? 0 : SS_XVCARD;
363 *value |= (status & VG469_VSENSE_A_VS1) ? 0 : SS_3VCARD;
364 *value |= (status & VG469_VSENSE_A_VS2) ? 0 : SS_XVCARD;
369 printf("i82365: GetStatus(%d) = %#4.4x\n", sock, *value);
374 /*static int i365_set_socket(u_short sock, socket_state_t *state)
376 socket_info_t *t = &socket[sock];
379 printf("i82365: SetSocket(%d, flags %#3.3x, Vcc %d, Vpp %d, "
380 "io_irq %d, csc_mask %#2.2x)\n", sock, state->flags,
381 state->Vcc, state->Vpp, state->io_irq, state->csc_mask);
382 printf ("\nERROR:UNIMPLEMENTED\n" );
384 // First set global controller options
385 // set_bridge_state(sock); *TODO* check: need this here?
387 // IO card, RESET flag, IO interrupt
389 if (state->io_irq != t->cap.pci_irq) reg |= state->io_irq;
390 reg |= (state->flags & SS_RESET) ? 0 : I365_PC_RESET;
391 reg |= (state->flags & SS_IOCARD) ? I365_PC_IOCARD : 0;
392 i365_set(sock, I365_INTCTL, reg);
394 reg = I365_PWR_NORESET;
395 if (state->flags & SS_PWR_AUTO) reg |= I365_PWR_AUTO;
396 if (state->flags & SS_OUTPUT_ENA) reg |= I365_PWR_OUT;
398 if (t->flags & IS_CIRRUS) {
399 if (state->Vpp != 0) {
400 if (state->Vpp == 120)
401 reg |= I365_VPP1_12V;
402 else if (state->Vpp == state->Vcc)
406 if (state->Vcc != 0) {
408 if (state->Vcc == 33)
409 i365_bset(sock, PD67_MISC_CTL_1, PD67_MC1_VCC_3V);
410 else if (state->Vcc == 50)
411 i365_bclr(sock, PD67_MISC_CTL_1, PD67_MC1_VCC_3V);
414 } else if (t->flags & IS_VG_PWR) {
415 if (state->Vpp != 0) {
416 if (state->Vpp == 120)
417 reg |= I365_VPP1_12V;
418 else if (state->Vpp == state->Vcc)
422 if (state->Vcc != 0) {
424 if (state->Vcc == 33)
425 i365_bset(sock, VG469_VSELECT, VG469_VSEL_VCC);
426 else if (state->Vcc == 50)
427 i365_bclr(sock, VG469_VSELECT, VG469_VSEL_VCC);
430 } else if (t->flags & IS_DF_PWR) {
431 switch (state->Vcc) {
433 case 33: reg |= I365_VCC_3V; break;
434 case 50: reg |= I365_VCC_5V; break;
435 default: return -EINVAL;
437 switch (state->Vpp) {
439 case 50: reg |= I365_VPP1_5V; break;
440 case 120: reg |= I365_VPP1_12V; break;
441 default: return -EINVAL;
444 switch (state->Vcc) {
446 case 50: reg |= I365_VCC_5V; break;
447 default: return -EINVAL;
449 switch (state->Vpp) {
451 case 50: reg |= I365_VPP1_5V | I365_VPP2_5V; break;
452 case 120: reg |= I365_VPP1_12V | I365_VPP2_12V; break;
453 default: return -EINVAL;
457 if (reg != i365_get(sock, I365_POWER))
458 i365_set(sock, I365_POWER, reg);
460 // Chipset-specific functions
461 if (t->flags & IS_CIRRUS) {
463 i365_bflip(sock, PD67_MISC_CTL_1, PD67_MC1_SPKR_ENA,
464 state->flags & SS_SPKR_ENA);
467 // Card status change interrupt mask
468 reg = t->cs_irq << 4;
469 if (state->csc_mask & SS_DETECT) reg |= I365_CSC_DETECT;
470 if (state->flags & SS_IOCARD) {
471 if (state->csc_mask & SS_STSCHG) reg |= I365_CSC_STSCHG;
473 if (state->csc_mask & SS_BATDEAD) reg |= I365_CSC_BVD1;
474 if (state->csc_mask & SS_BATWARN) reg |= I365_CSC_BVD2;
475 if (state->csc_mask & SS_READY) reg |= I365_CSC_READY;
477 i365_set(sock, I365_CSCINT, reg);
478 i365_get(sock, I365_CSC);
484 /*static int i365_get_io_map(u_short sock, struct pccard_io_map *io)
486 u_char map, ioctl, addr;
487 printf ( "GETIOMAP unimplemented\n" ); return 0;
489 if (map > 1) return -EINVAL;
490 io->start = i365_get_pair(sock, I365_IO(map)+I365_W_START);
491 io->stop = i365_get_pair(sock, I365_IO(map)+I365_W_STOP);
492 ioctl = i365_get(sock, I365_IOCTL);
493 addr = i365_get(sock, I365_ADDRWIN);
494 io->speed = to_ns(ioctl & I365_IOCTL_WAIT(map)) ? 1 : 0;
495 io->flags = (addr & I365_ENA_IO(map)) ? MAP_ACTIVE : 0;
496 io->flags |= (ioctl & I365_IOCTL_0WS(map)) ? MAP_0WS : 0;
497 io->flags |= (ioctl & I365_IOCTL_16BIT(map)) ? MAP_16BIT : 0;
498 io->flags |= (ioctl & I365_IOCTL_IOCS16(map)) ? MAP_AUTOSZ : 0;
499 printf("i82365: GetIOMap(%d, %d) = %#2.2x, %d ns, "
500 "%#4.4x-%#4.4x\n", sock, map, io->flags, io->speed,
501 io->start, io->stop);
506 /*====================================================================*/
508 /*static int i365_set_io_map(u_short sock, struct pccard_io_map *io)
512 printf("i82365: SetIOMap(%d, %d, %#2.2x, %d ns, "
513 "%#4.4x-%#4.4x)\n", sock, io->map, io->flags,
514 io->speed, io->start, io->stop);
515 printf ( "UNIMPLEMENTED\n" );
518 //if ((map > 1) || (io->start > 0xffff) || (io->stop > 0xffff) ||
520 (io->stop < io->start)) return -EINVAL;
521 // Turn off the window before changing anything
522 if (i365_get(sock, I365_ADDRWIN) & I365_ENA_IO(map))
523 i365_bclr(sock, I365_ADDRWIN, I365_ENA_IO(map));
524 i365_set_pair(sock, I365_IO(map)+I365_W_START, io->start);
525 i365_set_pair(sock, I365_IO(map)+I365_W_STOP, io->stop);
526 ioctl = i365_get(sock, I365_IOCTL) & ~I365_IOCTL_MASK(map);
527 if (io->speed) ioctl |= I365_IOCTL_WAIT(map);
528 if (io->flags & MAP_0WS) ioctl |= I365_IOCTL_0WS(map);
529 if (io->flags & MAP_16BIT) ioctl |= I365_IOCTL_16BIT(map);
530 if (io->flags & MAP_AUTOSZ) ioctl |= I365_IOCTL_IOCS16(map);
531 i365_set(sock, I365_IOCTL, ioctl);
532 // Turn on the window if necessary
533 if (io->flags & MAP_ACTIVE)
534 i365_bset(sock, I365_ADDRWIN, I365_ENA_IO(map));
540 static int i365_set_mem_map(u_short sock, struct pccard_mem_map *mem)
545 printf("i82365: SetMemMap(%d, %d, %#2.2x, %d ns, %#5.5lx-%#5.5"
546 "lx, %#5.5x)\n", sock, mem->map, mem->flags, mem->speed,
547 mem->sys_start, mem->sys_stop, mem->card_start);
549 printf ( "UNIMPLEMENTED\n" );
552 if ((map > 4) || (mem->card_start > 0x3ffffff) ||
553 (mem->sys_start > mem->sys_stop) || (mem->speed > 1000))
555 if (!(socket[sock].flags & IS_PCI) &&
556 ((mem->sys_start > 0xffffff) || (mem->sys_stop > 0xffffff)))
559 // Turn off the window before changing anything
560 if (i365_get(sock, I365_ADDRWIN) & I365_ENA_MEM(map))
561 i365_bclr(sock, I365_ADDRWIN, I365_ENA_MEM(map));
563 base = I365_MEM(map);
564 i = (mem->sys_start >> 12) & 0x0fff;
565 if (mem->flags & MAP_16BIT) i |= I365_MEM_16BIT;
566 if (mem->flags & MAP_0WS) i |= I365_MEM_0WS;
567 i365_set_pair(sock, base+I365_W_START, i);
569 i = (mem->sys_stop >> 12) & 0x0fff;
570 switch (to_cycles(mem->speed)) {
572 case 1: i |= I365_MEM_WS0; break;
573 case 2: i |= I365_MEM_WS1; break;
574 default: i |= I365_MEM_WS1 | I365_MEM_WS0; break;
576 i365_set_pair(sock, base+I365_W_STOP, i);
578 i = ((mem->card_start - mem->sys_start) >> 12) & 0x3fff;
579 if (mem->flags & MAP_WRPROT) i |= I365_MEM_WRPROT;
580 if (mem->flags & MAP_ATTRIB) i |= I365_MEM_REG;
581 i365_set_pair(sock, base+I365_W_OFF, i);
583 // Turn on the window if necessary
584 if (mem->flags & MAP_ACTIVE)
585 i365_bset(sock, I365_ADDRWIN, I365_ENA_MEM(map));
587 } // i365_set_mem_map
591 int i82365_interfacer ( interface_func_t func
, int sockno
, int par1
, int par2
, void* par3
) {
595 struct pcc_config_t
* pccc
;
599 return init_i82365();
601 i365_set(sockno
, I365_ADDRWIN
, i365_get(sockno
, I365_ADDRWIN
) & 0x20 );
602 i365_set(sockno
, I365_INTCTL
, 0x05 );
604 i365_set(sockno
,I365_INTCTL
, 0x45 ); //no-reset, memory-card
607 i365_set(sockno
,I365_POWER
, 0xb1 );
608 i365_set(sockno
, I365_INTCTL
, 0x05 );
610 i365_set(sockno
,I365_INTCTL
, 0x45 ); //no-reset, memory-card
611 i365_set(sockno
, I365_ADDRWIN
, i365_get(sockno
, I365_ADDRWIN
) & 0x20 );
612 //i365_bclr(sockno, I365_ADDRWIN, 1 );
613 i365_set(sockno
, I365_MEM(0)+0, ( par1
>> 12 )& 0xff ); //start
614 i365_set(sockno
, I365_MEM(0)+1, ( par1
>> 20 ) & 0x0f );
615 i365_set(sockno
, I365_MEM(0)+2, ((par1
+ par2
- 1 ) >> 12 ) & 0xff ); //end
616 i365_set(sockno
, I365_MEM(0)+3, (( par1
+ par2
- 1 ) >> 20 ) & 0x0f );
617 i365_set(sockno
, I365_MEM(0)+4, ((0x4000000 - par1
) >> 12) & 0xff ); //offset low
618 i365_set(sockno
, I365_MEM(0)+5, 0x40 | (((0x40000000 - par1
) >> 12) & 0x3f));
619 i365_bset(sockno
, I365_ADDRWIN
, 1 );
620 if ( ! ( 1 & i365_get ( sockno
, I365_ADDRWIN
) ) ) return 1;
623 i365_set(sockno
, I365_ADDRWIN
, i365_get(sockno
, I365_ADDRWIN
) & 0x20 );
624 i365_set(sockno
,I365_INTCTL
, 0x45 ); //no-reset, memory-card
626 case SELECTCONFIG
: // Params: par1: config number; par3 config pointer pointer
627 if ( 0 > pccsock
[sockno
].configoffset
) return 1;
628 if ( NULL
== (pccc
= par3
) ) return 2;
629 // write config number to
630 upc
= ioremap ( MAP_ATTRMEM_TO
, MAP_ATTRMEM_LEN
);
631 if ( pccsock
[sockno
].configoffset
> MAP_ATTRMEM_LEN
) return 3;
632 if ( ( par1
& 0x7fffffc0 ) ) return 4;
633 if ( pccc
->index
!= par1
) return 5;
634 upc
[pccsock
[sockno
].configoffset
] = ( upc
[pccsock
[sockno
].configoffset
] & 0xc0 ) | ( par1
& 0x3f );
635 i365_set(sockno
, I365_IOCTL
, (i365_get(sockno
, I365_IOCTL
) & 0xfe) | 0x20 ); // 16bit autosize
636 i365_set(sockno
, I365_IO(0)+0, pccc
->iowin
& 0xff);
637 i365_set(sockno
, I365_IO(0)+1, (pccc
->iowin
>> 8) & 0xff);
638 i365_set(sockno
, I365_IO(0)+2, (pccc
->iowin
+pccc
->iolen
- 1) & 0xff);
639 i365_set(sockno
, I365_IO(0)+3, ((pccc
->iowin
+pccc
->iolen
- 1) >> 8) & 0xff);
640 // Disable mem mapping
641 i365_bclr(sockno
, I365_ADDRWIN
, 1);
642 i365_set(sockno
, I365_INTCTL
, 0x65);
643 i365_bset(sockno
, I365_ADDRWIN
,0x40);
646 return -1; // ERROR: Unknown function called
652 // cirrus_get_state/set/opts...
653 // vg46x_get_state/...
654 // get_bridge_state/...
656 #endif /* CONFIG_PCMCIA */