patches attached :-)

-- 
Nicholas Henke
Undergraduate - Engineerring 2002
--
Senior Architect and Developer
Liniac Project - University of Pennsylvania
http://clubmask.sourceforge.net
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
There's nothing like good food, good beer, and a bad girl.
--- i82365.c    Wed Jan 16 20:36:29 2002
+++ /home/henken/armbuild/2.4.7/linux/drivers/pcmcia/i82365.c   Sun Nov 25 13:15:13 
+2001
@@ -73,15 +73,23 @@
 #define I365_MASK              (1 << 6)
 #define SOCKIRQ2REG(sock,irq)  ((sock) ? 3 : 4)
 #define REG2SOCKIRQ(sock,reg)  (6)
+#elif defined (CONFIG_SA1100_OMNIMETER)
+#define SOCKIRQ2REG(sock,irq)  (sock ? 3 : 3)
+#define REG2SOCKIRQ(sock,reg)  (PIN_cardInt1)
 #else
 #define SOCKIRQ2REG(sock,irq)  (irq)
 #define REG2SOCKIRQ(sock,reg)  (reg)
 #endif
 
+#define PCMCIA_DEBUG 100
+
+
+
 #ifdef PCMCIA_DEBUG
 static int pc_debug = PCMCIA_DEBUG;
 MODULE_PARM(pc_debug, "i");
-#define DEBUG(n, args...) if (pc_debug>(n)) printk(KERN_DEBUG args)
+/* #define DEBUG(n, args...) if (pc_debug>(n)) printk(KERN_DEBUG args) */
+#define DEBUG(n, args...) if (pc_debug>(n)) printk(KERN_INFO args)
 static const char *version =
 "i82365.c 1.265 1999/11/10 18:36:21 (David Hinds)";
 #else
@@ -114,6 +122,9 @@
 /* The card status change interrupt -- 0 means autoselect */
 static int cs_irq = 0;
 #endif
+#ifdef __arm__
+static int cs_irq = 0;
+#endif
 
 /* Probe for safe interrupts? */
 static int do_scan = 1;
@@ -221,13 +232,13 @@
                  PCI_COMMAND_MASTER|PCI_COMMAND_WAIT)
 
 /* These definitions must match the pcic table! */
-#ifdef CONFIG_ISA
+/* #ifdef CONFIG_ISA */
 typedef enum pcic_id {
     IS_I82365A, IS_I82365B, IS_I82365DF,
     IS_IBM, IS_RF5Cx96, IS_VLSI, IS_VG468, IS_VG469,
     IS_PD6710, IS_PD672X, IS_VT83C469,
 } pcic_id;
-#endif
+/* #endif */
 
 /* Flags for classifying groups of controllers */
 #define IS_VADEM       0x0001
@@ -249,7 +260,7 @@
 } pcic_t;
 
 static pcic_t pcic[] = {
-#ifdef CONFIG_ISA
+/* #ifdef CONFIG_ISA */
     { "Intel i82365sl A step", 0 },
     { "Intel i82365sl B step", 0 },
     { "Intel i82365sl DF", IS_DF_PWR },
@@ -261,7 +272,7 @@
     { "Cirrus PD6710", IS_CIRRUS },
     { "Cirrus PD672x", IS_CIRRUS },
     { "VIA VT83C469", IS_CIRRUS|IS_VIA },
-#endif
+/* #endif */
 };
 
 #define PCIC_COUNT     (sizeof(pcic)/sizeof(pcic_t))
@@ -738,8 +749,14 @@
 
 /*====================================================================*/
 
-static void __init add_socket(u_short port, int psock, int type)
+static void __init add_socket(ioaddr_t port, int psock, int type)
 {
+#ifdef __arm__
+    port = (u_int)__ioremap(port, 0x8000, 0);
+    DEBUG (1, "socket mapped to virt=%x\n", port);
+    if (!port)
+       printk ("add_socket: Cannot ioremap\n");
+#endif
     socket[sockets].ioaddr = port;
     socket[sockets].psock = psock;
     socket[sockets].type = type;
@@ -749,6 +766,11 @@
     sockets++;
 }
 
+#ifdef __arm__
+static void pcic_interrupt(int irq, void *dev,
+                                   struct pt_regs *regs);
+#endif
+
 static void __init add_pcic(int ns, int type)
 {
     u_int mask = 0, i, base;
@@ -803,22 +825,64 @@
        }
     }
 #endif
-    
+
+#ifdef CONFIG_SA1100_OMNIMETER
+    use_pci = 0;
+#endif
     if (!use_pci && !isa_irq) {
        if (poll_interval == 0)
            poll_interval = HZ;
        printk(" polling interval = %d ms\n",
               poll_interval * 1000 / HZ);
-       
+
     }
-    
+
+#ifdef CONFIG_SA1100_OMNIMETER
+    if (use_pci)
+       printk(" status change on irqs");
+#endif
+
     /* Update socket interrupt information, capabilities */
     for (i = 0; i < ns; i++) {
+
        t[i].cap.features |= SS_CAP_PCCARD;
-       t[i].cap.map_size = 0x1000;
+#ifdef __arm__
+        t[i].cap.features |= SS_CAP_PAGE_REGS | SS_CAP_STATIC_MAP;
+        t[i].cap.io_offset = i ? 0xf6008000 : 0xf6000000;
+        t[i].cap.irq_mask = 0;
+
+#ifdef CONFIG_SA1100_OMNIMETER
+        {
+        cs_irq = PIN_cardInt1;
+        if (use_pci)
+           {
+           t[i].cap.pci_irq = cs_irq;
+           printk(" %d", cs_irq);
+           GPDR &= ~(1 << cs_irq);  /* make it an input */
+           set_GPIO_IRQ_edge(1 << cs_irq, GPIO_RISING_EDGE);
+           if (request_irq(cs_irq, pcic_interrupt, SA_INTERRUPT, "i82365",
+                  &t[i]) < 0)
+               printk( KERN_ERR "%s: Request for IRQ %u failed\n", __FUNCTION__,
+                   cs_irq );
+           }
+        else
+           {
+           t[i].cap.pci_irq = cs_irq;
+           set_GPIO_IRQ_edge(1 << cs_irq, GPIO_RISING_EDGE);
+           GPDR &= ~(1 << cs_irq);  /* make it an input */
+           }
+        }
+#endif
+#else
        t[i].cap.irq_mask = mask;
        t[i].cs_irq = isa_irq;
+#endif
+       t[i].cap.map_size = 0x1000;
     }
+#ifdef CONFIG_SA1100_OMNIMETER
+    if (use_pci)
+       printk("\n");
+#endif
 
 } /* add_pcic */
 
@@ -917,8 +980,8 @@
 #ifdef CONFIG_ISA
     u_long flags = 0;
 #endif
-    
-    DEBUG(4, "i82365: pcic_interrupt(%d)\n", irq);
+
+/*     DEBUG(4, "i82365: pcic_interrupt(%d)\n", irq); */
 
     for (j = 0; j < 20; j++) {
        active = 0;
@@ -928,28 +991,31 @@
                continue;
            ISA_LOCK(i, flags);
            csc = i365_get(i, I365_CSC);
+/*         printk("status=%x\n", csc); */
            if ((csc == 0) || (!socket[i].handler) ||
                (i365_get(i, I365_IDENT) & 0x70)) {
                ISA_UNLOCK(i, flags);
                continue;
            }
            events = (csc & I365_CSC_DETECT) ? SS_DETECT : 0;
-           
-           
+
            /* Several sockets will send multiple "new card detected"
-              events in rapid succession. However, the rest of the pcmcia expects 
+              events in rapid succession. However, the rest of the pcmcia expects
               only one such event. We just ignore these events by having a
                timeout */
 
            if (events) {
-               if ((jiffies - last_detect_jiffies)<(HZ/20)) 
+               if ((jiffies - last_detect_jiffies)<(HZ/20))
                        events = 0;
                last_detect_jiffies = jiffies;
-               
+
            }
-       
+
            if (i365_get(i, I365_INTCTL) & I365_PC_IOCARD)
+               {
                events |= (csc & I365_CSC_STSCHG) ? SS_STSCHG : 0;
+               DEBUG(1, "io card\n");
+               }
            else {
                events |= (csc & I365_CSC_BVD1) ? SS_BATDEAD : 0;
                events |= (csc & I365_CSC_BVD2) ? SS_BATWARN : 0;
@@ -971,7 +1037,7 @@
     if (j == 20)
        printk(KERN_NOTICE "i82365: infinite loop in interrupt handler\n");
 
-    DEBUG(4, "i82365: interrupt done\n");
+/*     DEBUG(4, "i82365: interrupt done\n"); */
 } /* pcic_interrupt */
 
 static void pcic_interrupt_wrapper(u_long data)
@@ -1118,21 +1184,26 @@
 {
     socket_info_t *t = &socket[sock];
     u_char reg;
-    
+
     DEBUG(1, "i82365: SetSocket(%d, flags %#3.3x, Vcc %d, Vpp %d, "
          "io_irq %d, csc_mask %#2.2x)\n", sock, state->flags,
          state->Vcc, state->Vpp, state->io_irq, state->csc_mask);
-    
+
     /* First set global controller options */
     set_bridge_state(sock);
-    
+
     /* IO card, RESET flag, IO interrupt */
     reg = t->intr;
-    if (state->io_irq != t->cap.pci_irq) reg |= SOCKIRQ2REG(sock, state->io_irq);
+#ifndef CONFIG_SA1100_OMNIMETER  /* uses polling */
+    if (state->io_irq != t->cap.pci_irq)
+#endif
+       reg |= SOCKIRQ2REG(sock, state->io_irq);
     reg |= (state->flags & SS_RESET) ? 0 : I365_PC_RESET;
     reg |= (state->flags & SS_IOCARD) ? I365_PC_IOCARD : 0;
+    DEBUG(1, "i82365: setting intctl to %x\n", reg);
+/*     printk ("i82365: setting intctl to %x, flags =%x\n", reg); */
     i365_set(sock, I365_INTCTL, reg);
-    
+
     reg = I365_PWR_NORESET;
     if (state->flags & SS_PWR_AUTO) reg |= I365_PWR_AUTO;
     if (state->flags & SS_OUTPUT_ENA) reg |= I365_PWR_OUT;
@@ -1205,9 +1276,14 @@
        i365_bflip(sock, PD67_MISC_CTL_1, PD67_MC1_SPKR_ENA,
                   state->flags & SS_SPKR_ENA);
     }
-    
+
     /* Card status change interrupt mask */
+#ifdef CONFIG_SA1100_OMNIMETER
+    reg = 4;
+    reg |= I365_CSC_STSCHG | I365_CSC_BVD2 | I365_CSC_READY;
+#else
     reg = SOCKIRQ2REG(sock, t->cs_irq) << 4;
+#endif
     if (state->csc_mask & SS_DETECT) reg |= I365_CSC_DETECT;
     if (state->flags & SS_IOCARD) {
        if (state->csc_mask & SS_STSCHG) reg |= I365_CSC_STSCHG;
@@ -1216,9 +1292,16 @@
        if (state->csc_mask & SS_BATWARN) reg |= I365_CSC_BVD2;
        if (state->csc_mask & SS_READY) reg |= I365_CSC_READY;
     }
+    DEBUG(1, "i82365: setting cscint to %x\n", reg);
+/*     printk ("i82365: setting cscint to %x\n", reg); */
     i365_set(sock, I365_CSCINT, reg);
+#ifdef CONFIG_SA1100_OMNIMETER
+    i365_set(sock, I365_GENCTL, 0x0c);
+    i365_set(sock, I365_GENCTL, 0x0c);
+/*     printk ("i82365: setting genctl to %x\n", 0xc); */
+#endif
     i365_get(sock, I365_CSC);
-    
+
     return 0;
 } /* i365_set_socket */
 
@@ -1262,6 +1345,9 @@
        i365_bclr(sock, I365_ADDRWIN, I365_ENA_IO(map));
     i365_set_pair(sock, I365_IO(map)+I365_W_START, io->start);
     i365_set_pair(sock, I365_IO(map)+I365_W_STOP, io->stop);
+#ifdef CONFIG_SA1100_OMNIMETER
+    i365_set_pair(sock, I365_IO(map)+I365_W_OFF, sock ? 0x8000 : 0);
+#endif
     ioctl = i365_get(sock, I365_IOCTL) & ~I365_IOCTL_MASK(map);
     if (io->speed) ioctl |= I365_IOCTL_WAIT(map);
     if (io->flags & MAP_0WS) ioctl |= I365_IOCTL_0WS(map);
@@ -1311,12 +1397,15 @@
 } /* i365_get_mem_map */
 
 /*====================================================================*/
-  
+
 static int i365_set_mem_map(u_short sock, struct pccard_mem_map *mem)
 {
-    u_short base, i;
+    u_int base, i;
     u_char map;
-    
+#ifdef __arm__
+    unsigned int start;
+#endif
+
     DEBUG(1, "i82365: SetMemMap(%d, %d, %#2.2x, %d ns, %#5.5lx-%#5.5"
          "lx, %#5.5x)\n", sock, mem->map, mem->flags, mem->speed,
          mem->sys_start, mem->sys_stop, mem->card_start);
@@ -1324,22 +1413,65 @@
     map = mem->map;
     if ((map > 4) || (mem->card_start > 0x3ffffff) ||
        (mem->sys_start > mem->sys_stop) || (mem->speed > 1000))
+       {
+       DEBUG(1, "i82365: eEINVAL\n");
        return -EINVAL;
+       }
+#ifndef CONFIG_SA1100_OMNIMETER
     if (!(socket[sock].flags & IS_PCI) &&
        ((mem->sys_start > 0xffffff) || (mem->sys_stop > 0xffffff)))
+       {
+       DEBUG(1, "i82365: eEINVAL\n");
        return -EINVAL;
-       
+       }
+#endif
+#ifdef CONFIG_SA1100_OMNIMETER
+    start = mem->sys_start;
+
+    if(mem->sys_stop == 0)
+      mem->sys_stop = 0x10000 - 1;
+
+    mem->sys_start = mem->flags & MAP_ATTRIB
+       ? 0x38000000
+       : 0x3c010000;
+    if (sock)
+       mem->sys_start += 0x00400000;
+
+    mem->sys_stop = mem->sys_start + (mem->sys_stop - start);
+
+/* socket0   socket1  */
+/* 00800000  00c00000 */
+/* 00bfffff  00ffffff */
+/* 03800000  03400000 */
+#endif
+
     /* Turn off the window before changing anything */
     if (i365_get(sock, I365_ADDRWIN) & I365_ENA_MEM(map))
        i365_bclr(sock, I365_ADDRWIN, I365_ENA_MEM(map));
-    
+
+    /* set map 'map' start address bits 23:12 */
     base = I365_MEM(map);
-    i = (mem->sys_start >> 12) & 0x0fff;
+#ifdef CONFIG_SA1100_OMNIMETER
+    i = mem->sys_start + 0x800000;
+#else
+    i = mem->sys_start;
+#endif
+    DEBUG(1, "start=%x, ", i);
+    i = (i >> 12) & 0x0fff;
+/*     i = 0xc00000 >> 12; */
     if (mem->flags & MAP_16BIT) i |= I365_MEM_16BIT;
     if (mem->flags & MAP_0WS) i |= I365_MEM_0WS;
     i365_set_pair(sock, base+I365_W_START, i);
-    
-    i = (mem->sys_stop >> 12) & 0x0fff;
+
+    /* set map 'map' end address bits 23:12 */
+#ifdef CONFIG_SA1100_OMNIMETER
+    i = mem->sys_stop + 0x800000;
+#else
+    i = mem->sys_stop;
+#endif
+    DEBUG(1, "stop=%x, ", i);
+    i = (i >> 12) & 0x0fff;
+/*     i = 0xfff000 >> 12; */
     switch (to_cycles(mem->speed)) {
     case 0:    break;
     case 1:    i |= I365_MEM_WS0; break;
@@ -1347,15 +1479,34 @@
     default:   i |= I365_MEM_WS1 | I365_MEM_WS0; break;
     }
     i365_set_pair(sock, base+I365_W_STOP, i);
-    
-    i = ((mem->card_start - mem->sys_start) >> 12) & 0x3fff;
+
+    /* set map 'map' offset address bits 25:12 */
+#ifdef CONFIG_SA1100_OMNIMETER
+/*     i = mem->card_start - mem->sys_start - 0x80000; */
+    i = mem->card_start - mem->sys_start;
+    if (sock)
+       i += 0x800000;
+#else
+    i = mem->card_start - mem->sys_start;
+#endif
+    DEBUG(1, "offset=%x\n", i);
+/*     i = 0x03400000; */
+    i = (i >> 12) & 0x3fff;
     if (mem->flags & MAP_WRPROT) i |= I365_MEM_WRPROT;
     if (mem->flags & MAP_ATTRIB) i |= I365_MEM_REG;
     i365_set_pair(sock, base+I365_W_OFF, i);
-    
+
+    i = i365_get_pair(sock, base+I365_W_OFF);
+
     /* Turn on the window if necessary */
     if (mem->flags & MAP_ACTIVE)
        i365_bset(sock, I365_ADDRWIN, I365_ENA_MEM(map));
+
+/*     i365_get_mem_map(sock, mem); */
+/*     for (i = 0; i <= 0x3f; i ++) */
+/*        DEBUG(1, "   %02x: %x\n", i, i365_get (sock, i)); */
+/*     DEBUG(1,"\n"); */
+
     return 0;
 } /* i365_set_mem_map */
 
@@ -1528,6 +1679,25 @@
                mem.map = i;
                pcic_set_mem_map(s, &mem);
        }
+#ifdef CONFIG_SA1100_OMNIMETER
+        {
+        struct pccard_mem_map mem;
+        struct pccard_io_map io;
+
+        mem.sys_start = mem.card_start = 0;
+        mem.map = 4;
+        mem.flags = MAP_ACTIVE | MAP_16BIT;
+        mem.speed = 300;
+        i365_set_mem_map(s, &mem);
+
+        io.map = 0;
+        io.flags = MAP_AUTOSZ;
+        io.speed = 0;
+        io.start = s ? 0x8000 : 0;
+        io.stop = s ? 0x83df : 0x3df;
+        i365_set_io_map (s, &io);
+        }
+#endif
        return 0;
 }
 
@@ -1569,6 +1740,11 @@
 #ifdef CONFIG_ISA
     isa_probe();
 #endif
+#ifdef CONFIG_SA1100_OMNIMETER
+    add_socket (PCCardIndexRegister, 0, IS_PD672X);
+    add_socket (PCCardIndexRegister, 1, IS_PD672X);
+    add_pcic (2, IS_PD672X);
+#endif
 
     if (sockets == 0) {
        printk("not found.\n");
--- cs.c        Wed Jan 16 20:36:29 2002
+++ /home/henken/armbuild/2.4.7/linux/drivers/pcmcia/cs.c       Sun Nov 25 13:15:25 
+2001
@@ -1718,6 +1718,9 @@
        if (c->state & CONFIG_IRQ_REQ)
            if (!(c->irq.Attributes & IRQ_FORCED_PULSE))
                c->Option |= COR_LEVEL_REQ;
+#ifdef CONFIG_SA1100_OMNIMETER
+       c->Option &= ~COR_FUNC_ENA;  /* force to use memory map, not io space */
+#endif
        write_cis_mem(s, 1, (base + CISREG_COR)>>1, 1, &c->Option);
        mdelay(40);
     }
@@ -1895,18 +1898,26 @@
     if (ret != 0) return ret;
 
     if (req->Attributes & IRQ_HANDLE_PRESENT) {
-       if (bus_request_irq(s->cap.bus, irq, req->Handler,
-                           ((req->Attributes & IRQ_TYPE_DYNAMIC_SHARING) || 
-                            (s->functions > 1) ||
-                            (irq == s->cap.pci_irq)) ? SA_SHIRQ : 0,
-                           handle->dev_info, req->Instance))
+        int result;
+        int type = ((req->Attributes & IRQ_TYPE_DYNAMIC_SHARING)
+#ifndef CONFIG_SA1100_OMNIMETER
+                    || (irq == s->cap.pci_irq)
+#endif
+                    || (s->functions > 1))
+                    ? SA_SHIRQ : 0;
+
+       result = bus_request_irq(s->cap.bus, irq, req->Handler, type,
+                           handle->dev_info, req->Instance);
+       printk ("pcmcis_request_irq: %d, %d, %d. result=%d\n", irq,
+              req->Attributes & IRQ_HANDLE_PRESENT, type, result);
+       if (result)
            return CS_IN_USE;
     }
 
     c->irq.Attributes = req->Attributes;
     s->irq.AssignedIRQ = req->AssignedIRQ = irq;
     s->irq.Config++;
-    
+
     c->state |= CONFIG_IRQ_REQ;
     handle->state |= CLIENT_IRQ_REQ;
     return CS_SUCCESS;


Reply via email to