more changes on original files
[linux-2.4.git] / drivers / pcmcia / i82092.c
1 /* 
2  * Driver for Intel I82092AA PCI-PCMCIA bridge.
3  *
4  * (C) 2001-2003 Red Hat, Inc.
5  *
6  * Author: Arjan Van De Ven <arjanv@redhat.com> 
7  * Loosely based on i82365.c from the pcmcia-cs package
8  *
9  * $Id: i82092.c,v 1.16 2003/04/15 16:36:42 dwmw2 Exp $
10  */
11
12 #include <linux/kernel.h>
13 #include <linux/config.h>
14 #include <linux/module.h>
15 #include <linux/pci.h>
16 #include <linux/init.h>
17 #include <linux/sched.h>
18 #include <linux/tqueue.h>
19
20 #include <pcmcia/cs_types.h>
21 #include <pcmcia/ss.h>
22 #include <pcmcia/cs.h>
23
24 #include <asm/system.h>
25 #include <asm/io.h>
26
27 #include "i82092aa.h"
28 #include "i82365.h"
29
30 MODULE_LICENSE("GPL");
31 MODULE_AUTHOR("Red Hat, Inc. - Arjan Van De Ven <arjanv@redhat.com>");
32 MODULE_DESCRIPTION("Socket driver for Intel i82092AA PCI-PCMCIA bridge");
33
34 /* Extra i82092-specific register */
35 #define I365_CPAGE 0x26
36
37 /* PCI core routines */
38 static struct pci_device_id i82092aa_pci_ids[] = {
39         {
40               vendor:PCI_VENDOR_ID_INTEL,
41               device:PCI_DEVICE_ID_INTEL_82092AA_0,
42               subvendor:PCI_ANY_ID,
43               subdevice:PCI_ANY_ID,
44               class: 0, class_mask:0,
45
46          },
47          {} 
48 };
49
50 static struct pci_driver i82092aa_pci_drv = {
51         name:           "i82092aa",
52         id_table:       i82092aa_pci_ids,
53         probe:          i82092aa_pci_probe,
54         remove:         __devexit_p(i82092aa_pci_remove),
55         suspend:        NULL,
56         resume:         NULL 
57 };
58
59
60 /* the pccard structure and its functions */
61 static struct pccard_operations i82092aa_operations = {
62         init:                   i82092aa_init,
63         suspend:                i82092aa_suspend,
64         register_callback:      i82092aa_register_callback,
65         inquire_socket:         i82092aa_inquire_socket,   
66         get_status:             i82092aa_get_status,
67         get_socket:             i82092aa_get_socket,
68         set_socket:             i82092aa_set_socket,
69         get_io_map:             i82092aa_get_io_map,
70         set_io_map:             i82092aa_set_io_map,
71         get_mem_map:            i82092aa_get_mem_map,
72         set_mem_map:            i82092aa_set_mem_map,
73         proc_setup:             i82092aa_proc_setup,
74 };
75
76 /* The card can do upto 4 sockets, allocate a structure for each of them */
77
78 struct socket_info {
79         int     card_state;     /*  0 = no socket,
80                                     1 = empty socket, 
81                                     2 = card but not initialized,
82                                     3 = operational card */
83         unsigned long io_base;  /* base io address of the socket */
84         socket_cap_t cap;
85
86         unsigned int pending_events; /* Pending events on this interface */
87         
88         void    (*handler)(void *info, u_int events); 
89                                 /* callback to the driver of the card */
90         void    *info;          /* to be passed to the handler */
91         
92         struct pci_dev *dev;    /* The PCI device for the socket */
93 };
94
95 #define MAX_SOCKETS 4
96 static struct socket_info sockets[MAX_SOCKETS];
97 static int socket_count;  /* shortcut */
98
99 int membase = -1;
100 int isa_setup;
101
102 MODULE_PARM(membase, "i");
103 MODULE_PARM(isa_setup, "i");
104
105 static int __init i82092aa_pci_probe(struct pci_dev *dev, const struct pci_device_id *id)
106 {
107         unsigned char configbyte;
108         struct pci_dev *parent;
109         int i;
110         
111         enter("i82092aa_pci_probe");
112         
113         if (pci_enable_device(dev))
114                 return -EIO;
115
116         /* Since we have no memory BARs some firmware we may not
117            have had PCI_COMMAND_MEM enabled, yet the device needs
118            it. */
119         pci_read_config_byte(dev, PCI_COMMAND, &configbyte);
120         if (!(configbyte | PCI_COMMAND_MEMORY)) {
121                 dprintk(KERN_DEBUG "Enabling PCI_COMMAND_MEMORY\n");
122                 configbyte |= PCI_COMMAND_MEMORY;
123                 pci_write_config_byte(dev, PCI_COMMAND, configbyte);
124         }
125
126         pci_read_config_byte(dev, 0x40, &configbyte);  /* PCI Configuration Control */
127         switch(configbyte&6) {
128                 case 0:
129                         printk(KERN_INFO "i82092aa: configured as a 2 socket device.\n");
130                         socket_count = 2;
131                         break;
132                 case 2:
133                         printk(KERN_INFO "i82092aa: configured as a 1 socket device.\n");
134                         socket_count = 1;
135                         break;
136                 case 4:
137                 case 6:
138                         printk(KERN_INFO "i82092aa: configured as a 4 socket device.\n");
139                         socket_count = 4;
140                         break;
141                         
142                 default:
143                         printk(KERN_ERR "i82092aa: Oops, you did something we didn't think of.\n");
144                         return -EIO;
145                         break;
146         }
147         
148         if (membase == -1) {
149                 for (i = 0; i < 4; i++) {
150                         if ((dev->bus->resource[i]->flags & (IORESOURCE_MEM|IORESOURCE_READONLY|IORESOURCE_CACHEABLE|IORESOURCE_SHADOWABLE))
151                             == IORESOURCE_MEM) {
152                                 membase = dev->bus->resource[i]->start >> 24;
153                                 goto mem_ok;
154                         }
155                 }
156                 printk(KERN_WARNING "No suitable memory range for i82092aa found\n");
157                 return -ENOSPC;
158         }
159  mem_ok:
160         if (membase)
161                 printk(KERN_NOTICE "i82092 memory base address set to 0x%02x000000\n", membase);
162
163         /* If we're down the end of the PCI bus chain where ISA cycles don't get sent, then
164            only 1/4 of the I/O address space is going to be usable, unless we make sure that
165            the NO_ISA bit in the Bridge Control register of all upstream busses is cleared.
166            Since some PCMCIA cards (most serial ports, for example) will decode 10 bits and
167            respond only to addresses where bits 8 and 9 are non-zero, we need to do this. */
168         for (parent = dev->bus->self; 
169              parent && (parent->class>>8) == PCI_CLASS_BRIDGE_PCI;
170              parent = parent->bus->self) {
171                 uint16_t brctl;
172
173                 if (pci_read_config_word(parent, PCI_BRIDGE_CONTROL, &brctl)) {
174                         printk(KERN_WARNING "Error reading bridge control word from device %s\n", parent->slot_name);
175                         continue;
176                 }
177
178                 if (!(brctl & PCI_BRIDGE_CTL_NO_ISA))
179                         continue;
180
181                 if (isa_setup) {
182                         printk(KERN_NOTICE "PCI bridge %s has NOISA bit set. Clearing to allow full PCMCIA operation\n",
183                                parent->slot_name);
184                         brctl &= ~PCI_BRIDGE_CTL_NO_ISA;
185                         if (pci_write_config_word(parent, PCI_BRIDGE_CONTROL, brctl))
186                                 printk(KERN_WARNING "Error writing bridge control word from device %s\n", parent->slot_name);
187                 } else {
188                         printk(KERN_NOTICE "PCI bridge %s has NOISA bit set. Some I/O addresses for PCMCIA cards will not work.\n",
189                                parent->slot_name);
190                         printk(KERN_NOTICE "Perhaps use 'isa_setup=1' option to i82092.o?\n");
191                         break;
192                 }
193         }                       
194                                 
195         for (i = 0;i<socket_count;i++) {
196                 sockets[i].card_state = 1; /* 1 = present but empty */
197                 sockets[i].io_base = (dev->resource[0].start & ~1);
198                  if (sockets[i].io_base > 0) 
199                         request_region(sockets[i].io_base, 2, "i82092aa");
200                  
201                 
202                 sockets[i].cap.features |= SS_CAP_PCCARD | SS_CAP_PAGE_REGS;
203                 sockets[i].cap.map_size = 0x1000;
204                 sockets[i].cap.irq_mask = 0;
205                 sockets[i].cap.pci_irq  = dev->irq;
206
207                 /* Trick the resource code into doing the right thing... */
208                 sockets[i].cap.cb_dev = dev;
209                 
210                 if (card_present(i)) {
211                         sockets[i].card_state = 3;
212                         dprintk(KERN_DEBUG "i82092aa: slot %i is occupied\n",i);
213                 } else {
214                         dprintk(KERN_DEBUG "i82092aa: slot %i is vacant\n",i);
215                 }
216         }
217                 
218         /* Now, specifiy that all interrupts are to be done as PCI interrupts */
219         configbyte = 0xFF; /* bitmask, one bit per event, 1 = PCI interrupt, 0 = ISA interrupt */
220         pci_write_config_byte(dev, 0x50, configbyte); /* PCI Interrupt Routing Register */
221
222
223         /* Register the interrupt handler */
224         dprintk(KERN_DEBUG "Requesting interrupt %i \n",dev->irq);
225         if (request_irq(dev->irq, i82092aa_interrupt, SA_SHIRQ, "i82092aa", i82092aa_interrupt)) {
226                 printk(KERN_ERR "i82092aa: Failed to register IRQ %d, aborting\n", dev->irq);
227                 return -EIO;
228         }
229                  
230         
231         if (register_ss_entry(socket_count, &i82092aa_operations) != 0)
232                 printk(KERN_NOTICE "i82092aa: register_ss_entry() failed\n");
233
234         leave("i82092aa_pci_probe");
235         return 0;
236 }
237
238 static void __devexit i82092aa_pci_remove(struct pci_dev *dev)
239 {
240         enter("i82092aa_pci_remove");
241         
242         free_irq(dev->irq, i82092aa_interrupt);
243
244         leave("i82092aa_pci_remove");
245 }
246
247 static spinlock_t port_lock = SPIN_LOCK_UNLOCKED;
248
249 /* basic value read/write functions */
250
251 static unsigned char indirect_read(int socket, unsigned short reg)
252 {
253         unsigned long port;
254         unsigned char val;
255         unsigned long flags;
256         spin_lock_irqsave(&port_lock,flags);
257         reg += socket * 0x40;
258         port = sockets[socket].io_base;
259         outb(reg,port);
260         val = inb(port+1);
261         spin_unlock_irqrestore(&port_lock,flags);
262         return val;
263 }
264
265 static unsigned short indirect_read16(int socket, unsigned short reg)
266 {
267         unsigned long port;
268         unsigned short tmp;
269         unsigned long flags;
270         spin_lock_irqsave(&port_lock,flags);
271         reg  = reg + socket * 0x40;
272         port = sockets[socket].io_base;
273         outb(reg,port);
274         tmp = inb(port+1);
275         reg++;
276         outb(reg,port);
277         tmp = tmp | (inb(port+1)<<8);
278         spin_unlock_irqrestore(&port_lock,flags);
279         return tmp;
280 }
281
282 static void indirect_write(int socket, unsigned short reg, unsigned char value)
283 {
284         unsigned long port;
285         unsigned long flags;
286         spin_lock_irqsave(&port_lock,flags);
287         reg = reg + socket * 0x40;
288         port = sockets[socket].io_base; 
289         outb(reg,port);
290         outb(value,port+1);
291         spin_unlock_irqrestore(&port_lock,flags);
292 }
293
294 static void indirect_setbit(int socket, unsigned short reg, unsigned char mask)
295 {
296         unsigned long port;
297         unsigned char val;
298         unsigned long flags;
299         spin_lock_irqsave(&port_lock,flags);
300         reg = reg + socket * 0x40;
301         port = sockets[socket].io_base; 
302         outb(reg,port);
303         val = inb(port+1);
304         val |= mask;
305         outb(reg,port);
306         outb(val,port+1);
307         spin_unlock_irqrestore(&port_lock,flags);
308 }
309
310
311 static void indirect_resetbit(int socket, unsigned short reg, unsigned char mask)
312 {
313         unsigned long port;
314         unsigned char val;
315         unsigned long flags;
316         spin_lock_irqsave(&port_lock,flags);
317         reg = reg + socket * 0x40;
318         port = sockets[socket].io_base; 
319         outb(reg,port);
320         val = inb(port+1);
321         val &= ~mask;
322         outb(reg,port);
323         outb(val,port+1);
324         spin_unlock_irqrestore(&port_lock,flags);
325 }
326
327 static void indirect_write16(int socket, unsigned short reg, unsigned short value)
328 {
329         unsigned long port;
330         unsigned char val;
331         unsigned long flags;
332         spin_lock_irqsave(&port_lock,flags);
333         reg = reg + socket * 0x40;
334         port = sockets[socket].io_base; 
335         
336         outb(reg,port);
337         val = value & 255;
338         outb(val,port+1);
339         
340         reg++;
341         
342         outb(reg,port);
343         val = value>>8;
344         outb(val,port+1);
345         spin_unlock_irqrestore(&port_lock,flags);
346 }
347
348 /* simple helper functions */
349 /* External clock time, in nanoseconds.  120 ns = 8.33 MHz */
350 static int cycle_time = 120;
351
352 static int to_cycles(int ns)
353 {
354         if (cycle_time!=0)
355                 return ns/cycle_time;
356         else
357                 return 0;
358 }
359     
360 static int to_ns(int cycles)
361 {
362         return cycle_time*cycles;
363 }
364
365
366 /* Interrupt handler functionality */
367
368 static void i82092aa_bh(void *dummy)
369 {
370         unsigned int events;
371         int i;
372                 
373         for (i=0; i < socket_count; i++) {
374                 events = xchg(&(sockets[i].pending_events),0);
375                 dprintk("events = %x \n",events);
376                 if (sockets[i].handler)
377                         sockets[i].handler(sockets[i].info, events);
378         }
379 }
380                                                                                                                                         
381
382 static struct tq_struct i82092aa_task = {
383         routine:        i82092aa_bh
384 };
385         
386
387 static void i82092aa_interrupt(int irq, void *dev, struct pt_regs *regs)
388 {
389         int i;
390         int loopcount = 0;
391         
392         unsigned int events, active=0;
393         
394 /*      enter("i82092aa_interrupt");*/
395         
396         while (1) {
397                 loopcount++;
398                 if (loopcount>20) {
399                         printk(KERN_ERR "i82092aa: infinite eventloop in interrupt \n");
400                         break;
401                 }
402                 
403                 active = 0;
404                 
405                 for (i=0;i<socket_count;i++) {
406                         int csc;
407                         if (sockets[i].card_state==0) /* Inactive socket, should not happen */
408                                 continue;
409                         
410                         csc = indirect_read(i,I365_CSC); /* card status change register */
411                         
412                         if ((csc==0) ||  /* no events on this socket */
413                            (sockets[i].handler==NULL)) /* no way to handle events */
414                                 continue;
415                         events = 0;
416                          
417                         if (csc & I365_CSC_DETECT) {
418                                 events |= SS_DETECT;
419                                 dprintk("Card detected in socket %i!\n",i);
420                          }
421                         
422                         if (indirect_read(i,I365_INTCTL) & I365_PC_IOCARD) { 
423                                 /* For IO/CARDS, bit 0 means "read the card" */
424                                 events |= (csc & I365_CSC_STSCHG) ? SS_STSCHG : 0; 
425                         } else {
426                                 /* Check for battery/ready events */
427                                 events |= (csc & I365_CSC_BVD1) ? SS_BATDEAD : 0;
428                                 events |= (csc & I365_CSC_BVD2) ? SS_BATWARN : 0;
429                                 events |= (csc & I365_CSC_READY) ? SS_READY : 0;
430                         }
431                         
432                         if (events) {
433                                 sockets[i].pending_events |= events;
434                                 schedule_task(&i82092aa_task);
435                         }
436                         active |= events;
437                 }
438                                 
439                 if (active==0) /* no more events to handle */
440                         break;                          
441                 
442         }
443         
444 /*      leave("i82092aa_interrupt");*/
445 }
446
447
448
449 /* socket functions */
450
451 static int card_present(int socketno)
452 {       
453         unsigned int val;
454         enter("card_present");
455         
456         if ((socketno<0) || (socketno > MAX_SOCKETS))
457                 return 0;
458         if (sockets[socketno].io_base == 0)
459                 return 0;
460
461                 
462         val = indirect_read(socketno, 1); /* Interface status register */
463         if ((val&12)==12) {
464                 leave("card_present 1");
465                 return 1;
466         }
467                 
468         leave("card_present 0");
469         return 0;
470 }
471
472 static void set_bridge_state(int sock)
473 {
474         enter("set_bridge_state");
475         indirect_write(sock, I365_GBLCTL,0x00);
476         indirect_write(sock, I365_GENCTL,0x00);
477         
478         indirect_setbit(sock, I365_INTCTL,0x08);
479         leave("set_bridge_state");
480 }
481
482
483
484
485
486       
487 static int i82092aa_init(unsigned int s)
488 {
489         int i;
490         pccard_io_map io = { 0, 0, 0, 0, 1 };
491         pccard_mem_map mem = { 0, 0, 0, 0, 0, 0 };
492         
493         enter("i82092aa_init");
494                         
495         i82092aa_set_socket(s, &dead_socket);
496         for (i = 0; i < 2; i++) {
497                 io.map = i;
498                 i82092aa_set_io_map(s, &io);
499         }
500         for (i = 0; i < 5; i++) {
501                 mem.map = i;
502                 i82092aa_set_mem_map(s, &mem);
503         }
504         
505         leave("i82092aa_init");
506         return 0;
507 }
508                                                                                                                                                                                                                                               
509 static int i82092aa_suspend(unsigned int sock)
510 {
511         int retval;
512         enter("i82092aa_suspend");
513         retval =  i82092aa_set_socket(sock, &dead_socket);
514         leave("i82092aa_suspend");
515         return retval;
516 }
517        
518 static int i82092aa_register_callback(unsigned int sock, void (*handler)(void *, unsigned int), void * info)
519 {
520         enter("i82092aa_register_callback");
521         sockets[sock].handler = handler;
522         sockets[sock].info = info;
523         if (handler == NULL) {   
524                 MOD_DEC_USE_COUNT;   
525         } else {
526                 MOD_INC_USE_COUNT;
527         }
528         leave("i82092aa_register_callback");
529         return 0;
530 } /* i82092aa_register_callback */
531                                         
532 static int i82092aa_inquire_socket(unsigned int sock, socket_cap_t *cap)
533 {
534         enter("i82092aa_inquire_socket");
535         *cap = sockets[sock].cap;
536         leave("i82092aa_inquire_socket");
537         return 0;
538 } /* i82092aa_inquire_socket */
539
540
541 static int i82092aa_get_status(unsigned int sock, u_int *value)
542 {
543         unsigned int status;
544         
545         enter("i82092aa_get_status");
546         
547         status = indirect_read(sock,I365_STATUS); /* Interface Status Register */
548         *value = 0;
549         
550         if ((status & I365_CS_DETECT) == I365_CS_DETECT) {
551                 *value |= SS_DETECT;
552         }
553                 
554         /* IO cards have a different meaning of bits 0,1 */
555         /* Also notice the inverse-logic on the bits */
556          if (indirect_read(sock, I365_INTCTL) & I365_PC_IOCARD) {
557                 /* IO card */
558                 if (!(status & I365_CS_STSCHG))
559                         *value |= SS_STSCHG;
560          } else { /* non I/O card */
561                 if (!(status & I365_CS_BVD1))
562                         *value |= SS_BATDEAD;
563                 if (!(status & I365_CS_BVD2))
564                         *value |= SS_BATWARN;
565                         
566          }
567          
568          if (status & I365_CS_WRPROT)
569                 (*value) |= SS_WRPROT;  /* card is write protected */
570          
571          if (status & I365_CS_READY)
572                 (*value) |= SS_READY;    /* card is not busy */
573                 
574          if (status & I365_CS_POWERON)
575                 (*value) |= SS_POWERON;  /* power is applied to the card */
576
577
578         leave("i82092aa_get_status");
579         return 0;
580 }
581
582
583 static int i82092aa_get_socket(unsigned int sock, socket_state_t *state) 
584 {
585         unsigned char reg,vcc,vpp;
586         
587         enter("i82092aa_get_socket");
588         state->flags    = 0;
589         state->Vcc      = 0;
590         state->Vpp      = 0;
591         state->io_irq   = 0;
592         state->csc_mask = 0;
593
594         /* First the power status of the socket */
595         reg = indirect_read(sock,I365_POWER); /* PCTRL - Power Control Register */
596
597         if (reg & I365_PWR_AUTO)
598                 state->flags |= SS_PWR_AUTO;  /* Automatic Power Switch */
599                 
600         if (reg & I365_PWR_OUT)
601                 state->flags |= SS_OUTPUT_ENA; /* Output signals are enabled */
602                 
603         vcc = reg & I365_VCC_MASK;    vpp = reg & I365_VPP1_MASK;
604         
605         if (reg & I365_VCC_5V) { /* Can still be 3.3V, in this case the Vcc value will be overwritten later */
606                 state->Vcc = 50;
607                 
608                 if (vpp == I365_VPP1_5V)
609                         state->Vpp = 50;
610                 if (vpp == I365_VPP1_12V)
611                         state->Vpp = 120;
612                         
613         }
614         
615         if ((reg & I365_VCC_3V)==I365_VCC_3V)
616                 state->Vcc = 33;
617         
618         
619         /* Now the IO card, RESET flags and IO interrupt */
620         
621         reg = indirect_read(sock, I365_INTCTL); /* IGENC, Interrupt and General Control */
622         
623         if ((reg & I365_PC_RESET)==0)
624                 state->flags |= SS_RESET;
625         if (reg & I365_PC_IOCARD) 
626                 state->flags |= SS_IOCARD; /* This is an IO card */
627         
628         /* Set the IRQ number */
629         if (sockets[sock].dev!=NULL)
630                 state->io_irq = sockets[sock].dev->irq;
631         
632         /* Card status change */
633         reg = indirect_read(sock, I365_CSCINT); /* CSCICR, Card Status Change Interrupt Configuration */
634         
635         if (reg & I365_CSC_DETECT) 
636                 state->csc_mask |= SS_DETECT; /* Card detect is enabled */
637         
638         if (state->flags & SS_IOCARD) {/* IO Cards behave different */
639                 if (reg & I365_CSC_STSCHG)
640                         state->csc_mask |= SS_STSCHG;
641         } else {
642                 if (reg & I365_CSC_BVD1) 
643                         state->csc_mask |= SS_BATDEAD;
644                 if (reg & I365_CSC_BVD2) 
645                         state->csc_mask |= SS_BATWARN;
646                 if (reg & I365_CSC_READY) 
647                         state->csc_mask |= SS_READY;
648         }
649                 
650         leave("i82092aa_get_socket");
651         return 0;
652 }
653
654 static int i82092aa_set_socket(unsigned int sock, socket_state_t *state) 
655 {
656         unsigned char reg;
657         
658         enter("i82092aa_set_socket");
659         
660         /* First, set the global controller options */
661         
662         set_bridge_state(sock);
663         
664         /* Values for the IGENC register */
665         
666         reg = 0;
667         if (!(state->flags & SS_RESET))         /* The reset bit has "inverse" logic */
668                 reg = reg | I365_PC_RESET;  
669         if (state->flags & SS_IOCARD) 
670                 reg = reg | I365_PC_IOCARD;
671                 
672         indirect_write(sock,I365_INTCTL,reg); /* IGENC, Interrupt and General Control Register */
673         
674         /* Power registers */
675         
676         reg = I365_PWR_NORESET; /* default: disable resetdrv on resume */
677         
678         if (state->flags & SS_PWR_AUTO) {
679                 dprintk("Auto power\n");
680                 reg |= I365_PWR_AUTO;   /* automatic power mngmnt */
681         }
682         if (state->flags & SS_OUTPUT_ENA) {
683                 dprintk("Power Enabled \n");
684                 reg |= I365_PWR_OUT;    /* enable power */
685         }
686         
687         switch (state->Vcc) {
688                 case 0: 
689                         break;
690                 case 50: 
691                         dprintk("setting voltage to Vcc to 5V on socket %i\n",sock);
692                         reg |= I365_VCC_5V;
693                         break;
694                 default:
695                         printk(KERN_WARNING "i82092aa: i82092aa_set_socket called with invalid VCC power value: %i ", state->Vcc);
696                         leave("i82092aa_set_socket");
697                         return -EINVAL;
698         }
699         
700         
701         switch (state->Vpp) {
702                 case 0: 
703                         dprintk("not setting Vpp on socket %i\n",sock);
704                         break;
705                 case 50: 
706                         dprintk("setting Vpp to 5.0 for socket %i\n",sock);
707                         reg |= I365_VPP1_5V | I365_VPP2_5V;
708                         break;
709                 case 120: 
710                         dprintk("setting Vpp to 12.0\n");
711                         reg |= I365_VPP1_12V | I365_VPP2_12V;
712                         break;
713                 default:
714                         printk(KERN_WARNING "i82092aa: i82092aa_set_socket called with invalid VPP power value: %i ", state->Vcc);
715                         leave("i82092aa_set_socket");
716                         return -EINVAL;
717         }
718         
719         if (reg != indirect_read(sock,I365_POWER)) /* only write if changed */
720                 indirect_write(sock,I365_POWER,reg);
721                 
722         /* Enable specific interrupt events */
723         
724         reg = 0x00;
725         if (state->csc_mask & SS_DETECT) {
726                 reg |= I365_CSC_DETECT;
727         }
728         if (state->flags & SS_IOCARD) {
729                 if (state->csc_mask & SS_STSCHG)
730                         reg |= I365_CSC_STSCHG;
731         } else {
732                 if (state->csc_mask & SS_BATDEAD) 
733                         reg |= I365_CSC_BVD1;
734                 if (state->csc_mask & SS_BATWARN) 
735                         reg |= I365_CSC_BVD2;
736                 if (state->csc_mask & SS_READY) 
737                         reg |= I365_CSC_READY; 
738                                         
739         }
740         
741         /* now write the value and clear the (probably bogus) pending stuff by doing a dummy read*/
742         
743         indirect_write(sock,I365_CSCINT,reg);
744         (void)indirect_read(sock,I365_CSC);
745
746         leave("i82092aa_set_socket");
747         return 0;
748 }
749
750 static int i82092aa_get_io_map(unsigned int sock, struct pccard_io_map *io)
751 {
752         unsigned char map, ioctl, addr;
753         
754         enter("i82092aa_get_io_map");
755         map = io->map;
756         if (map > 1) {
757                 leave("i82092aa_get_io_map with -EINVAL");
758                 return -EINVAL;
759         }
760         
761         /* FIXME: How does this fit in with the PCI resource (re)allocation */
762         io->start = indirect_read16(sock, I365_IO(map)+I365_W_START);
763         io->stop  = indirect_read16(sock, I365_IO(map)+I365_W_START);
764         
765         ioctl = indirect_read(sock,I365_IOCTL); /* IOCREG: I/O Control Register */
766         addr  = indirect_read(sock,I365_ADDRWIN); /* */
767         
768         io->speed = to_ns(ioctl & I365_IOCTL_WAIT(map)) ? 1 : 0; /* check this out later */
769         io->flags = 0;
770         
771         if (addr & I365_IOCTL_16BIT(map))
772                 io->flags |= MAP_AUTOSZ;
773                 
774         leave("i82092aa_get_io_map");
775         return 0;
776 }
777
778 static int i82092aa_set_io_map(unsigned sock, struct pccard_io_map *io)
779 {
780         unsigned char map, ioctl;
781         
782         enter("i82092aa_set_io_map");
783         
784         map = io->map;
785         
786         /* Check error conditions */    
787         if (map > 1) {
788                 leave("i82092aa_set_io_map with invalid map");
789                 return -EINVAL;
790         }
791         if ((io->start > 0xffff) || (io->stop > 0xffff) || (io->stop < io->start)){
792                 leave("i82092aa_set_io_map with invalid io");
793                 return -EINVAL;
794         }
795
796         /* Turn off the window before changing anything */ 
797         if (indirect_read(sock, I365_ADDRWIN) & I365_ENA_IO(map))
798                 indirect_resetbit(sock, I365_ADDRWIN, I365_ENA_IO(map));
799
800 /*      printk("set_io_map: Setting range to %x - %x \n",io->start,io->stop);  */
801         
802         /* write the new values */
803         indirect_write16(sock,I365_IO(map)+I365_W_START,io->start);             
804         indirect_write16(sock,I365_IO(map)+I365_W_STOP,io->stop);               
805                         
806         ioctl = indirect_read(sock,I365_IOCTL) & ~I365_IOCTL_MASK(map);
807         
808         if (io->flags & (MAP_16BIT|MAP_AUTOSZ))
809                 ioctl |= I365_IOCTL_16BIT(map);
810                 
811         indirect_write(sock,I365_IOCTL,ioctl);
812         
813         /* Turn the window back on if needed */
814         if (io->flags & MAP_ACTIVE)
815                 indirect_setbit(sock,I365_ADDRWIN,I365_ENA_IO(map));
816                         
817         leave("i82092aa_set_io_map");   
818         return 0;
819 }
820
821 static int i82092aa_get_mem_map(unsigned sock, struct pccard_mem_map *mem)
822 {
823         unsigned short base, i;
824         unsigned char map, addr;
825         
826         enter("i82092aa_get_mem_map");
827         
828         mem->flags = 0;
829         mem->speed = 0;
830         map = mem->map;
831         if (map > 4) {
832                 leave("i82092aa_get_mem_map: -EINVAL");
833                 return -EINVAL;
834         }
835         
836         addr = indirect_read(sock, I365_ADDRWIN);
837                 
838         if (addr & I365_ENA_MEM(map))
839                 mem->flags |= MAP_ACTIVE;               /* yes this mapping is active */
840         
841         base = I365_MEM(map); 
842         
843         /* Find the start address - this register also has mapping info */
844         
845         i = indirect_read16(sock,base+I365_W_START);
846         if (i & I365_MEM_16BIT)
847                 mem->flags |= MAP_16BIT;
848         if (i & I365_MEM_0WS)
849                 mem->flags |= MAP_0WS;
850         
851         mem->sys_start = ((unsigned long)(i & 0x0fff) << 12);
852         
853         /* Find the end address - this register also has speed info */
854         i = indirect_read16(sock,base+I365_W_STOP);
855         if (i & I365_MEM_WS0)
856                 mem->speed = 1;
857         if (i & I365_MEM_WS1)
858                 mem->speed += 2;
859         mem->speed = to_ns(mem->speed);
860         mem->sys_stop = ( (unsigned long)(i & 0x0fff) << 12) + 0x0fff;
861         
862         /* Find the card start address, also some more MAP attributes */
863         
864         i = indirect_read16(sock, base+I365_W_OFF);
865         if (i & I365_MEM_WRPROT)
866                 mem->flags |= MAP_WRPROT;
867         if (i & I365_MEM_REG)
868                 mem->flags |= MAP_ATTRIB;
869         mem->card_start = ( (unsigned long)(i & 0x3fff)<12) + mem->sys_start;
870         mem->card_start &=  0x3ffffff;
871         
872         dprintk("Card %i is from %lx to %lx \n",sock,mem->sys_start,mem->sys_stop);
873         
874         leave("i82092aa_get_mem_map");
875         return 0;
876         
877 }
878
879 static int i82092aa_set_mem_map(unsigned sock, struct pccard_mem_map *mem)
880 {
881         unsigned short base, i;
882         unsigned char map;
883
884         enter("i82092aa_set_mem_map");
885         
886         map = mem->map;
887         if (map > 4) {
888                 leave("i82092aa_set_mem_map: invalid map");
889                 return -EINVAL;
890         }
891         
892         /* Turn off the window before changing anything */
893         if (indirect_read(sock, I365_ADDRWIN) & I365_ENA_MEM(map))
894                       indirect_resetbit(sock, I365_ADDRWIN, I365_ENA_MEM(map));
895
896         
897         if (!(mem->flags & MAP_ACTIVE))
898                 return 0;
899
900         if ( (mem->card_start > 0x3ffffff) || (mem->sys_start > mem->sys_stop) ||
901              ((mem->sys_start >> 24) != membase) || ((mem->sys_stop >> 24) != membase) ||
902              (mem->speed > 1000) ) {
903                 leave("i82092aa_set_mem_map: invalid address / speed");
904                 printk(KERN_WARNING "invalid mem map for socket %i : %lx to %lx with a start of %x \n",sock,mem->sys_start, mem->sys_stop, mem->card_start);
905                 return -EINVAL;
906         }
907         
908                          
909                          
910 /*      printk("set_mem_map: Setting map %i range to %x - %x on socket %i, speed is %i, active = %i \n",map, mem->sys_start,mem->sys_stop,sock,mem->speed,mem->flags & MAP_ACTIVE);  */
911
912         /* write the start address */
913         base = I365_MEM(map);
914         i = (mem->sys_start >> 12) & 0x0fff;
915         if (mem->flags & MAP_16BIT) 
916                 i |= I365_MEM_16BIT;
917         if (mem->flags & MAP_0WS)
918                 i |= I365_MEM_0WS;      
919         indirect_write16(sock,base+I365_W_START,i);
920                                
921         /* write the stop address */
922         
923         i= (mem->sys_stop >> 12) & 0x0fff;
924         switch (to_cycles(mem->speed)) {
925                 case 0:
926                         break;
927                 case 1:
928                         i |= I365_MEM_WS0;
929                         break;
930                 case 2:
931                         i |= I365_MEM_WS1;
932                         break;
933                 default:
934                         i |= I365_MEM_WS1 | I365_MEM_WS0;
935                         break;
936         }
937         
938         indirect_write16(sock,base+I365_W_STOP,i);
939         
940         /* card start */
941         
942         i = (((mem->card_start - mem->sys_start) >> 12) - (membase << 12)) & 0x3fff;
943         if (mem->flags & MAP_WRPROT)
944                 i |= I365_MEM_WRPROT;
945         if (mem->flags & MAP_ATTRIB) {
946 /*              printk("requesting attribute memory for socket %i\n",sock);*/
947                 i |= I365_MEM_REG;
948         } else {
949 /*              printk("requesting normal memory for socket %i\n",sock);*/
950         }
951         indirect_write16(sock,base+I365_W_OFF,i);
952         indirect_write(sock, I365_CPAGE, membase);
953
954         /* Enable the window if necessary */
955         indirect_setbit(sock, I365_ADDRWIN, I365_ENA_MEM(map));
956                     
957         leave("i82092aa_set_mem_map");
958         return 0;
959 }
960
961 static void i82092aa_proc_setup(unsigned int sock, struct proc_dir_entry *base)
962 {
963         
964 }
965 /* Module stuff */
966
967 static int i82092aa_module_init(void)
968 {
969         enter("i82092aa_module_init");
970         pci_register_driver(&i82092aa_pci_drv);
971         leave("i82092aa_module_init");
972         return 0;
973 }
974
975 static void i82092aa_module_exit(void)
976 {
977         enter("i82092aa_module_exit");
978         pci_unregister_driver(&i82092aa_pci_drv);
979         unregister_ss_entry(&i82092aa_operations);
980         if (sockets[0].io_base>0)
981                          release_region(sockets[0].io_base, 2);
982         leave("i82092aa_module_exit");
983 }
984
985 module_init(i82092aa_module_init);
986 module_exit(i82092aa_module_exit);
987