File: /usr/src/linux/drivers/pcmcia/tcic.c

1     /*======================================================================
2     
3         Device driver for Databook TCIC-2 PCMCIA controller
4     
5         tcic.c 1.111 2000/02/15 04:13:12
6     
7         The contents of this file are subject to the Mozilla Public
8         License Version 1.1 (the "License"); you may not use this file
9         except in compliance with the License. You may obtain a copy of
10         the License at http://www.mozilla.org/MPL/
11     
12         Software distributed under the License is distributed on an "AS
13         IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
14         implied. See the License for the specific language governing
15         rights and limitations under the License.
16     
17         The initial developer of the original code is David A. Hinds
18         <dhinds@pcmcia.sourceforge.org>.  Portions created by David A. Hinds
19         are Copyright (C) 1999 David A. Hinds.  All Rights Reserved.
20     
21         Alternatively, the contents of this file may be used under the
22         terms of the GNU General Public License version 2 (the "GPL"), in which
23         case the provisions of the GPL are applicable instead of the
24         above.  If you wish to allow the use of your version of this file
25         only under the terms of the GPL and not to allow others to use
26         your version of this file under the MPL, indicate your decision
27         by deleting the provisions above and replace them with the notice
28         and other provisions required by the GPL.  If you do not delete
29         the provisions above, a recipient may use your version of this
30         file under either the MPL or the GPL.
31         
32     ======================================================================*/
33     
34     #include <linux/module.h>
35     #include <linux/init.h>
36     #include <linux/types.h>
37     #include <linux/fcntl.h>
38     #include <linux/string.h>
39     
40     #include <asm/io.h>
41     #include <asm/bitops.h>
42     #include <asm/segment.h>
43     #include <asm/system.h>
44     
45     #include <linux/kernel.h>
46     #include <linux/errno.h>
47     #include <linux/sched.h>
48     #include <linux/slab.h>
49     #include <linux/timer.h>
50     #include <linux/ioport.h>
51     #include <linux/delay.h>
52     #include <linux/proc_fs.h>
53     
54     #include <pcmcia/version.h>
55     #include <pcmcia/cs_types.h>
56     #include <pcmcia/cs.h>
57     #include <pcmcia/ss.h>
58     #include "tcic.h"
59     
60     #ifdef PCMCIA_DEBUG
61     static int pc_debug = PCMCIA_DEBUG;
62     MODULE_PARM(pc_debug, "i");
63     static const char *version =
64     "tcic.c 1.111 2000/02/15 04:13:12 (David Hinds)";
65     #define DEBUG(n, args...) if (pc_debug>(n)) printk(KERN_DEBUG args)
66     #else
67     #define DEBUG(n, args...)
68     #endif
69     
70     MODULE_AUTHOR("David Hinds <dhinds@pcmcia.sourceforge.org>");
71     MODULE_DESCRIPTION("Databook TCIC-2 PCMCIA socket driver");
72     
73     /*====================================================================*/
74     
75     /* Parameters that can be set with 'insmod' */
76     
77     /* The base port address of the TCIC-2 chip */
78     static int tcic_base = TCIC_BASE;
79     
80     /* Specify a socket number to ignore */
81     static int ignore = -1;
82     
83     /* Probe for safe interrupts? */
84     static int do_scan = 1;
85     
86     /* Bit map of interrupts to choose from */
87     static u_int irq_mask = 0xffff;
88     static int irq_list[16] = { -1 };
89     
90     /* The card status change interrupt -- 0 means autoselect */
91     static int cs_irq = 0;
92     
93     /* Poll status interval -- 0 means default to interrupt */
94     static int poll_interval = 0;
95     
96     /* Delay for card status double-checking */
97     static int poll_quick = HZ/20;
98     
99     /* CCLK external clock time, in nanoseconds.  70 ns = 14.31818 MHz */
100     static int cycle_time = 70;
101     
102     MODULE_PARM(tcic_base, "i");
103     MODULE_PARM(ignore, "i");
104     MODULE_PARM(do_scan, "i");
105     MODULE_PARM(irq_mask, "i");
106     MODULE_PARM(irq_list, "1-16i");
107     MODULE_PARM(cs_irq, "i");
108     MODULE_PARM(poll_interval, "i");
109     MODULE_PARM(poll_quick, "i");
110     MODULE_PARM(cycle_time, "i");
111     
112     /*====================================================================*/
113     
114     static void tcic_interrupt(int irq, void *dev, struct pt_regs *regs);
115     static void tcic_timer(u_long data);
116     static struct pccard_operations tcic_operations;
117     
118     typedef struct socket_info_t {
119         u_short	psock;
120         void	(*handler)(void *info, u_int events);
121         void	*info;
122         u_char	last_sstat;
123         u_char	id;
124     } socket_info_t;
125     
126     static struct timer_list poll_timer;
127     static int tcic_timer_pending = 0;
128     
129     static int sockets;
130     static socket_info_t socket_table[2];
131     
132     static socket_cap_t tcic_cap = {
133         /* only 16-bit cards, memory windows must be size-aligned */
134         SS_CAP_PCCARD | SS_CAP_MEM_ALIGN,
135         0x4cf8,		/* irq 14, 11, 10, 7, 6, 5, 4, 3 */
136         0x1000,		/* 4K minimum window size */
137         0, 0		/* No PCI or CardBus support */
138     };
139     
140     /*====================================================================*/
141     
142     /* Trick when selecting interrupts: the TCIC sktirq pin is supposed
143        to map to irq 11, but is coded as 0 or 1 in the irq registers. */
144     #define TCIC_IRQ(x) ((x) ? (((x) == 11) ? 1 : (x)) : 15)
145     
146     #ifdef PCMCIA_DEBUG_X
147     static u_char tcic_getb(u_char reg)
148     {
149         u_char val = inb(tcic_base+reg);
150         printk(KERN_DEBUG "tcic_getb(%#x) = %#x\n", tcic_base+reg, val);
151         return val;
152     }
153     
154     static u_short tcic_getw(u_char reg)
155     {
156         u_short val = inw(tcic_base+reg);
157         printk(KERN_DEBUG "tcic_getw(%#x) = %#x\n", tcic_base+reg, val);
158         return val;
159     }
160     
161     static void tcic_setb(u_char reg, u_char data)
162     {
163         printk(KERN_DEBUG "tcic_setb(%#x, %#x)\n", tcic_base+reg, data);
164         outb(data, tcic_base+reg);
165     }
166     
167     static void tcic_setw(u_char reg, u_short data)
168     {
169         printk(KERN_DEBUG "tcic_setw(%#x, %#x)\n", tcic_base+reg, data);
170         outw(data, tcic_base+reg);
171     }
172     #else
173     #define tcic_getb(reg) inb(tcic_base+reg)
174     #define tcic_getw(reg) inw(tcic_base+reg)
175     #define tcic_setb(reg, data) outb(data, tcic_base+reg)
176     #define tcic_setw(reg, data) outw(data, tcic_base+reg)
177     #endif
178     
179     static void tcic_setl(u_char reg, u_int data)
180     {
181     #ifdef PCMCIA_DEBUG_X
182         printk(KERN_DEBUG "tcic_setl(%#x, %#lx)\n", tcic_base+reg, data);
183     #endif
184         outw(data & 0xffff, tcic_base+reg);
185         outw(data >> 16, tcic_base+reg+2);
186     }
187     
188     static u_char tcic_aux_getb(u_short reg)
189     {
190         u_char mode = (tcic_getb(TCIC_MODE) & TCIC_MODE_PGMMASK) | reg;
191         tcic_setb(TCIC_MODE, mode);
192         return tcic_getb(TCIC_AUX);
193     }
194     
195     static void tcic_aux_setb(u_short reg, u_char data)
196     {
197         u_char mode = (tcic_getb(TCIC_MODE) & TCIC_MODE_PGMMASK) | reg;
198         tcic_setb(TCIC_MODE, mode);
199         tcic_setb(TCIC_AUX, data);
200     }
201     
202     static u_short tcic_aux_getw(u_short reg)
203     {
204         u_char mode = (tcic_getb(TCIC_MODE) & TCIC_MODE_PGMMASK) | reg;
205         tcic_setb(TCIC_MODE, mode);
206         return tcic_getw(TCIC_AUX);
207     }
208     
209     static void tcic_aux_setw(u_short reg, u_short data)
210     {
211         u_char mode = (tcic_getb(TCIC_MODE) & TCIC_MODE_PGMMASK) | reg;
212         tcic_setb(TCIC_MODE, mode);
213         tcic_setw(TCIC_AUX, data);
214     }
215     
216     /*====================================================================*/
217     
218     /* Time conversion functions */
219     
220     static int to_cycles(int ns)
221     {
222         if (ns < 14)
223     	return 0;
224         else
225     	return 2*(ns-14)/cycle_time;
226     }
227     
228     static int to_ns(int cycles)
229     {
230         return (cycles*cycle_time)/2 + 14;
231     }
232     
233     /*====================================================================*/
234     
235     static volatile u_int irq_hits;
236     
237     static void __init irq_count(int irq, void *dev, struct pt_regs *regs)
238     {
239         irq_hits++;
240     }
241     
242     static u_int __init try_irq(int irq)
243     {
244         u_short cfg;
245     
246         irq_hits = 0;
247         if (request_irq(irq, irq_count, 0, "irq scan", irq_count) != 0)
248     	return -1;
249         mdelay(10);
250         if (irq_hits) {
251     	free_irq(irq, irq_count);
252     	return -1;
253         }
254     
255         /* Generate one interrupt */
256         cfg = TCIC_SYSCFG_AUTOBUSY | 0x0a00;
257         tcic_aux_setw(TCIC_AUX_SYSCFG, cfg | TCIC_IRQ(irq));
258         tcic_setb(TCIC_IENA, TCIC_IENA_ERR | TCIC_IENA_CFG_HIGH);
259         tcic_setb(TCIC_ICSR, TCIC_ICSR_ERR | TCIC_ICSR_JAM);
260     
261         udelay(1000);
262         free_irq(irq, irq_count);
263     
264         /* Turn off interrupts */
265         tcic_setb(TCIC_IENA, TCIC_IENA_CFG_OFF);
266         while (tcic_getb(TCIC_ICSR))
267     	tcic_setb(TCIC_ICSR, TCIC_ICSR_JAM);
268         tcic_aux_setw(TCIC_AUX_SYSCFG, cfg);
269         
270         return (irq_hits != 1);
271     }
272     
273     static u_int __init irq_scan(u_int mask0)
274     {
275         u_int mask1;
276         int i;
277     
278     #ifdef __alpha__
279     #define PIC 0x4d0
280         /* Don't probe level-triggered interrupts -- reserved for PCI */
281         int level_mask = inb_p(PIC) | (inb_p(PIC+1) << 8);
282         if (level_mask)
283     	mask0 &= ~level_mask;
284     #endif
285     
286         mask1 = 0;
287         if (do_scan) {
288     	for (i = 0; i < 16; i++)
289     	    if ((mask0 & (1 << i)) && (try_irq(i) == 0))
290     		mask1 |= (1 << i);
291     	for (i = 0; i < 16; i++)
292     	    if ((mask1 & (1 << i)) && (try_irq(i) != 0)) {
293     		mask1 ^= (1 << i);
294     	    }
295         }
296         
297         if (mask1) {
298     	printk("scanned");
299         } else {
300     	/* Fallback: just find interrupts that aren't in use */
301     	for (i = 0; i < 16; i++)
302     	    if ((mask0 & (1 << i)) &&
303     		(request_irq(i, irq_count, 0, "x", irq_count) == 0)) {
304     		mask1 |= (1 << i);
305     		free_irq(i, irq_count);
306     	    }
307     	printk("default");
308         }
309         
310         printk(") = ");
311         for (i = 0; i < 16; i++)
312     	if (mask1 & (1<<i))
313     	    printk("%s%d", ((mask1 & ((1<<i)-1)) ? "," : ""), i);
314         printk(" ");
315         
316         return mask1;
317     }
318     
319     /*======================================================================
320     
321         See if a card is present, powered up, in IO mode, and already
322         bound to a (non-PCMCIA) Linux driver.
323     
324         We make an exception for cards that look like serial devices.
325         
326     ======================================================================*/
327     
328     static int __init is_active(int s)
329     {
330         u_short scf1, ioctl, base, num;
331         u_char pwr, sstat;
332         u_int addr;
333         
334         tcic_setl(TCIC_ADDR, (s << TCIC_ADDR_SS_SHFT)
335     	      | TCIC_ADDR_INDREG | TCIC_SCF1(s));
336         scf1 = tcic_getw(TCIC_DATA);
337         pwr = tcic_getb(TCIC_PWR);
338         sstat = tcic_getb(TCIC_SSTAT);
339         addr = TCIC_IWIN(s, 0);
340         tcic_setw(TCIC_ADDR, addr + TCIC_IBASE_X);
341         base = tcic_getw(TCIC_DATA);
342         tcic_setw(TCIC_ADDR, addr + TCIC_ICTL_X);
343         ioctl = tcic_getw(TCIC_DATA);
344     
345         if (ioctl & TCIC_ICTL_TINY)
346     	num = 1;
347         else {
348     	num = (base ^ (base-1));
349     	base = base & (base-1);
350         }
351     
352         if ((sstat & TCIC_SSTAT_CD) && (pwr & TCIC_PWR_VCC(s)) &&
353     	(scf1 & TCIC_SCF1_IOSTS) && (ioctl & TCIC_ICTL_ENA) &&
354     	(check_region(base, num) != 0) && ((base & 0xfeef) != 0x02e8))
355     	return 1;
356         else
357     	return 0;
358     }
359     
360     /*======================================================================
361     
362         This returns the revision code for the specified socket.
363         
364     ======================================================================*/
365     
366     static int __init get_tcic_id(void)
367     {
368         u_short id;
369         
370         tcic_aux_setw(TCIC_AUX_TEST, TCIC_TEST_DIAG);
371         id = tcic_aux_getw(TCIC_AUX_ILOCK);
372         id = (id & TCIC_ILOCKTEST_ID_MASK) >> TCIC_ILOCKTEST_ID_SH;
373         tcic_aux_setw(TCIC_AUX_TEST, 0);
374         return id;
375     }
376     
377     /*====================================================================*/
378     
379     static int __init init_tcic(void)
380     {
381         int i, sock;
382         u_int mask, scan;
383         servinfo_t serv;
384     
385         DEBUG(0, "%s\n", version);
386         pcmcia_get_card_services_info(&serv);
387         if (serv.Revision != CS_RELEASE_CODE) {
388     	printk(KERN_NOTICE "tcic: Card Services release "
389     	       "does not match!\n");
390     	return -1;
391         }
392         
393         printk(KERN_INFO "Databook TCIC-2 PCMCIA probe: ");
394         sock = 0;
395     
396         if (check_region(tcic_base, 16) == 0) {
397     	tcic_setw(TCIC_ADDR, 0);
398     	if (tcic_getw(TCIC_ADDR) == 0) {
399     	    tcic_setw(TCIC_ADDR, 0xc3a5);
400     	    if (tcic_getw(TCIC_ADDR) == 0xc3a5) sock = 2;
401     	}
402     	if (sock == 0) {
403     	    /* See if resetting the controller does any good */
404     	    tcic_setb(TCIC_SCTRL, TCIC_SCTRL_RESET);
405     	    tcic_setb(TCIC_SCTRL, 0);
406     	    tcic_setw(TCIC_ADDR, 0);
407     	    if (tcic_getw(TCIC_ADDR) == 0) {
408     		tcic_setw(TCIC_ADDR, 0xc3a5);
409     		if (tcic_getw(TCIC_ADDR) == 0xc3a5) sock = 2;
410     	    }
411     	}
412         } else
413     	printk("could not allocate ports, ");
414     
415         if (sock == 0) {
416     	printk("not found.\n");
417     	return -ENODEV;
418         }
419     
420         request_region(tcic_base, 16, "tcic-2");
421     
422         sockets = 0;
423         for (i = 0; i < sock; i++) {
424     	if ((i == ignore) || is_active(i)) continue;
425     	socket_table[sockets].psock = i;
426     	socket_table[sockets].handler = NULL;
427     	socket_table[sockets].info = NULL;
428     	socket_table[sockets].id = get_tcic_id();
429     	sockets++;
430         }
431     
432         switch (socket_table[0].id) {
433         case TCIC_ID_DB86082:
434     	printk("DB86082"); break;
435         case TCIC_ID_DB86082A:
436     	printk("DB86082A"); break;
437         case TCIC_ID_DB86084:
438     	printk("DB86084"); break;
439         case TCIC_ID_DB86084A:
440     	printk("DB86084A"); break;
441         case TCIC_ID_DB86072:
442     	printk("DB86072"); break;
443         case TCIC_ID_DB86184:
444     	printk("DB86184"); break;
445         case TCIC_ID_DB86082B:
446     	printk("DB86082B"); break;
447         default:
448     	printk("Unknown ID 0x%02x", socket_table[0].id);
449         }
450         
451         /* Set up polling */
452         poll_timer.function = &tcic_timer;
453         poll_timer.data = 0;
454         init_timer(&poll_timer);
455     
456         /* Build interrupt mask */
457         printk(", %d sockets\n" KERN_INFO "  irq list (", sockets);
458         if (irq_list[0] == -1)
459     	mask = irq_mask;
460         else
461     	for (i = mask = 0; i < 16; i++)
462     	    mask |= (1<<irq_list[i]);
463         mask &= tcic_cap.irq_mask;
464     
465         /* Scan interrupts */
466         mask = irq_scan(mask);
467         tcic_cap.irq_mask = mask;
468         
469         /* Check for only two interrupts available */
470         scan = (mask & (mask-1));
471         if (((scan & (scan-1)) == 0) && (poll_interval == 0))
472     	poll_interval = HZ;
473         
474         if (poll_interval == 0) {
475     	/* Avoid irq 12 unless it is explicitly requested */
476     	u_int cs_mask = mask & ((cs_irq) ? (1<<cs_irq) : ~(1<<12));
477     	for (i = 15; i > 0; i--)
478     	    if ((cs_mask & (1 << i)) &&
479     		(request_irq(i, tcic_interrupt, 0, "tcic",
480     			     tcic_interrupt) == 0))
481     		break;
482     	cs_irq = i;
483     	if (cs_irq == 0) poll_interval = HZ;
484         }
485         
486         if (tcic_cap.irq_mask & (1 << 11))
487     	printk("sktirq is irq 11, ");
488         if (cs_irq != 0)
489     	printk("status change on irq %d\n", cs_irq);
490         else
491     	printk("polled status, interval = %d ms\n",
492     	       poll_interval * 1000 / HZ);
493         
494         for (i = 0; i < sockets; i++) {
495     	tcic_setw(TCIC_ADDR+2, socket_table[i].psock << TCIC_SS_SHFT);
496     	socket_table[i].last_sstat = tcic_getb(TCIC_SSTAT);
497         }
498         
499         /* jump start interrupt handler, if needed */
500         tcic_interrupt(0, NULL, NULL);
501     
502         if (register_ss_entry(sockets, &tcic_operations) != 0) {
503     	printk(KERN_NOTICE "tcic: register_ss_entry() failed\n");
504     	release_region(tcic_base, 16);
505     	if (cs_irq != 0)
506     	    free_irq(cs_irq, tcic_interrupt);
507     	return -ENODEV;
508         }
509     
510         return 0;
511         
512     } /* init_tcic */
513     
514     /*====================================================================*/
515     
516     static void __exit exit_tcic(void)
517     {
518         u_long flags;
519         unregister_ss_entry(&tcic_operations);
520         save_flags(flags);
521         cli();
522         if (cs_irq != 0) {
523     	tcic_aux_setw(TCIC_AUX_SYSCFG, TCIC_SYSCFG_AUTOBUSY|0x0a00);
524     	free_irq(cs_irq, tcic_interrupt);
525         }
526         if (tcic_timer_pending)
527     	del_timer(&poll_timer);
528         restore_flags(flags);
529         release_region(tcic_base, 16);
530     } /* exit_tcic */
531     
532     /*====================================================================*/
533     
534     static u_int pending_events[2];
535     static spinlock_t pending_event_lock = SPIN_LOCK_UNLOCKED;
536     
537     static void tcic_bh(void *dummy)
538     {
539     	u_int events;
540     	int i;
541     
542     	for (i=0; i < sockets; i++) {
543     		spin_lock_irq(&pending_event_lock);
544     		events = pending_events[i];
545     		pending_events[i] = 0;
546     		spin_unlock_irq(&pending_event_lock);
547     		if (socket_table[i].handler)
548     			socket_table[i].handler(socket_table[i].info, events);
549     	}
550     }
551     
552     static struct tq_struct tcic_task = {
553     	routine:	tcic_bh
554     };
555     
556     static void tcic_interrupt(int irq, void *dev, struct pt_regs *regs)
557     {
558         int i, quick = 0;
559         u_char latch, sstat;
560         u_short psock;
561         u_int events;
562         static volatile int active = 0;
563     
564         if (active) {
565     	printk(KERN_NOTICE "tcic: reentered interrupt handler!\n");
566     	return;
567         } else
568     	active = 1;
569     
570         DEBUG(2, "tcic: tcic_interrupt()\n");
571         
572         for (i = 0; i < sockets; i++) {
573     	psock = socket_table[i].psock;
574     	tcic_setl(TCIC_ADDR, (psock << TCIC_ADDR_SS_SHFT)
575     		  | TCIC_ADDR_INDREG | TCIC_SCF1(psock));
576     	sstat = tcic_getb(TCIC_SSTAT);
577     	latch = sstat ^ socket_table[psock].last_sstat;
578     	socket_table[i].last_sstat = sstat;
579     	if (tcic_getb(TCIC_ICSR) & TCIC_ICSR_CDCHG) {
580     	    tcic_setb(TCIC_ICSR, TCIC_ICSR_CLEAR);
581     	    quick = 1;
582     	}
583     	if ((latch == 0) || (socket_table[psock].handler == NULL))
584     	    continue;
585     	events = (latch & TCIC_SSTAT_CD) ? SS_DETECT : 0;
586     	events |= (latch & TCIC_SSTAT_WP) ? SS_WRPROT : 0;
587     	if (tcic_getw(TCIC_DATA) & TCIC_SCF1_IOSTS) {
588     	    events |= (latch & TCIC_SSTAT_LBAT1) ? SS_STSCHG : 0;
589     	} else {
590     	    events |= (latch & TCIC_SSTAT_RDY) ? SS_READY : 0;
591     	    events |= (latch & TCIC_SSTAT_LBAT1) ? SS_BATDEAD : 0;
592     	    events |= (latch & TCIC_SSTAT_LBAT2) ? SS_BATWARN : 0;
593     	}
594     	if (events) {
595     		spin_lock(&pending_event_lock);
596     		pending_events[i] |= events;
597     		spin_unlock(&pending_event_lock);
598     		schedule_task(&tcic_task);
599     	}
600         }
601     
602         /* Schedule next poll, if needed */
603         if (((cs_irq == 0) || quick) && (!tcic_timer_pending)) {
604     	poll_timer.expires = jiffies + (quick ? poll_quick : poll_interval);
605     	add_timer(&poll_timer);
606     	tcic_timer_pending = 1;
607         }
608         active = 0;
609         
610         DEBUG(2, "tcic: interrupt done\n");
611         
612     } /* tcic_interrupt */
613     
614     static void tcic_timer(u_long data)
615     {
616         DEBUG(2, "tcic: tcic_timer()\n");
617         tcic_timer_pending = 0;
618         tcic_interrupt(0, NULL, NULL);
619     } /* tcic_timer */
620     
621     /*====================================================================*/
622     
623     static int tcic_register_callback(unsigned int lsock, void (*handler)(void *, unsigned int), void * info)
624     {
625         socket_table[lsock].handler = handler;
626         socket_table[lsock].info = info;
627         if (handler == NULL) {
628     	MOD_DEC_USE_COUNT;
629         } else {
630     	MOD_INC_USE_COUNT;
631         }
632         return 0;
633     } /* tcic_register_callback */
634     
635     /*====================================================================*/
636     
637     static int tcic_get_status(unsigned int lsock, u_int *value)
638     {
639         u_short psock = socket_table[lsock].psock;
640         u_char reg;
641     
642         tcic_setl(TCIC_ADDR, (psock << TCIC_ADDR_SS_SHFT)
643     	      | TCIC_ADDR_INDREG | TCIC_SCF1(psock));
644         reg = tcic_getb(TCIC_SSTAT);
645         *value  = (reg & TCIC_SSTAT_CD) ? SS_DETECT : 0;
646         *value |= (reg & TCIC_SSTAT_WP) ? SS_WRPROT : 0;
647         if (tcic_getw(TCIC_DATA) & TCIC_SCF1_IOSTS) {
648     	*value |= (reg & TCIC_SSTAT_LBAT1) ? SS_STSCHG : 0;
649         } else {
650     	*value |= (reg & TCIC_SSTAT_RDY) ? SS_READY : 0;
651     	*value |= (reg & TCIC_SSTAT_LBAT1) ? SS_BATDEAD : 0;
652     	*value |= (reg & TCIC_SSTAT_LBAT2) ? SS_BATWARN : 0;
653         }
654         reg = tcic_getb(TCIC_PWR);
655         if (reg & (TCIC_PWR_VCC(psock)|TCIC_PWR_VPP(psock)))
656     	*value |= SS_POWERON;
657         DEBUG(1, "tcic: GetStatus(%d) = %#2.2x\n", lsock, *value);
658         return 0;
659     } /* tcic_get_status */
660       
661     /*====================================================================*/
662     
663     static int tcic_inquire_socket(unsigned int lsock, socket_cap_t *cap)
664     {
665         *cap = tcic_cap;
666         return 0;
667     } /* tcic_inquire_socket */
668     
669     /*====================================================================*/
670     
671     static int tcic_get_socket(unsigned int lsock, socket_state_t *state)
672     {
673         u_short psock = socket_table[lsock].psock;
674         u_char reg;
675         u_short scf1, scf2;
676         
677         tcic_setl(TCIC_ADDR, (psock << TCIC_ADDR_SS_SHFT)
678     	      | TCIC_ADDR_INDREG | TCIC_SCF1(psock));
679         scf1 = tcic_getw(TCIC_DATA);
680         state->flags = (scf1 & TCIC_SCF1_IOSTS) ? SS_IOCARD : 0;
681         state->flags |= (scf1 & TCIC_SCF1_DMA_MASK) ? SS_DMA_MODE : 0;
682         state->flags |= (scf1 & TCIC_SCF1_SPKR) ? SS_SPKR_ENA : 0;
683         if (tcic_getb(TCIC_SCTRL) & TCIC_SCTRL_ENA)
684     	state->flags |= SS_OUTPUT_ENA;
685         state->io_irq = scf1 & TCIC_SCF1_IRQ_MASK;
686         if (state->io_irq == 1) state->io_irq = 11;
687     
688         reg = tcic_getb(TCIC_PWR);
689         state->Vcc = state->Vpp = 0;
690         if (reg & TCIC_PWR_VCC(psock)) {
691     	if (reg & TCIC_PWR_VPP(psock))
692     	    state->Vcc = 50;
693     	else
694     	    state->Vcc = state->Vpp = 50;
695         } else {
696     	if (reg & TCIC_PWR_VPP(psock)) {
697     	    state->Vcc = 50;
698     	    state->Vpp = 120;
699     	}
700         }
701         reg = tcic_aux_getb(TCIC_AUX_ILOCK);
702         state->flags |= (reg & TCIC_ILOCK_CRESET) ? SS_RESET : 0;
703     
704         /* Card status change interrupt mask */
705         tcic_setw(TCIC_ADDR, TCIC_SCF2(psock));
706         scf2 = tcic_getw(TCIC_DATA);
707         state->csc_mask = (scf2 & TCIC_SCF2_MCD) ? 0 : SS_DETECT;
708         if (state->flags & SS_IOCARD) {
709     	state->csc_mask |= (scf2 & TCIC_SCF2_MLBAT1) ? 0 : SS_STSCHG;
710         } else {
711     	state->csc_mask |= (scf2 & TCIC_SCF2_MLBAT1) ? 0 : SS_BATDEAD;
712     	state->csc_mask |= (scf2 & TCIC_SCF2_MLBAT2) ? 0 : SS_BATWARN;
713     	state->csc_mask |= (scf2 & TCIC_SCF2_MRDY) ? 0 : SS_READY;
714         }
715     
716         DEBUG(1, "tcic: GetSocket(%d) = flags %#3.3x, Vcc %d, Vpp %d, "
717     	  "io_irq %d, csc_mask %#2.2x\n", lsock, state->flags,
718     	  state->Vcc, state->Vpp, state->io_irq, state->csc_mask);
719         return 0;
720     } /* tcic_get_socket */
721     
722     /*====================================================================*/
723     
724     static int tcic_set_socket(unsigned int lsock, socket_state_t *state)
725     {
726         u_short psock = socket_table[lsock].psock;
727         u_char reg;
728         u_short scf1, scf2;
729     
730         DEBUG(1, "tcic: SetSocket(%d, flags %#3.3x, Vcc %d, Vpp %d, "
731     	  "io_irq %d, csc_mask %#2.2x)\n", lsock, state->flags,
732     	  state->Vcc, state->Vpp, state->io_irq, state->csc_mask);
733         tcic_setw(TCIC_ADDR+2, (psock << TCIC_SS_SHFT) | TCIC_ADR2_INDREG);
734     
735         reg = tcic_getb(TCIC_PWR);
736         reg &= ~(TCIC_PWR_VCC(psock) | TCIC_PWR_VPP(psock));
737     
738         if (state->Vcc == 50) {
739     	switch (state->Vpp) {
740     	case 0:   reg |= TCIC_PWR_VCC(psock) | TCIC_PWR_VPP(psock); break;
741     	case 50:  reg |= TCIC_PWR_VCC(psock); break;
742     	case 120: reg |= TCIC_PWR_VPP(psock); break;
743     	default:  return -EINVAL;
744     	}
745         } else if (state->Vcc != 0)
746     	return -EINVAL;
747     
748         if (reg != tcic_getb(TCIC_PWR))
749     	tcic_setb(TCIC_PWR, reg);
750     
751         reg = TCIC_ILOCK_HOLD_CCLK | TCIC_ILOCK_CWAIT;
752         if (state->flags & SS_OUTPUT_ENA) {
753     	tcic_setb(TCIC_SCTRL, TCIC_SCTRL_ENA);
754     	reg |= TCIC_ILOCK_CRESENA;
755         } else
756     	tcic_setb(TCIC_SCTRL, 0);
757         if (state->flags & SS_RESET)
758     	reg |= TCIC_ILOCK_CRESET;
759         tcic_aux_setb(TCIC_AUX_ILOCK, reg);
760         
761         tcic_setw(TCIC_ADDR, TCIC_SCF1(psock));
762         scf1 = TCIC_SCF1_FINPACK;
763         scf1 |= TCIC_IRQ(state->io_irq);
764         if (state->flags & SS_IOCARD) {
765     	scf1 |= TCIC_SCF1_IOSTS;
766     	if (state->flags & SS_SPKR_ENA)
767     	    scf1 |= TCIC_SCF1_SPKR;
768     	if (state->flags & SS_DMA_MODE)
769     	    scf1 |= TCIC_SCF1_DREQ2 << TCIC_SCF1_DMA_SHIFT;
770         }
771         tcic_setw(TCIC_DATA, scf1);
772     
773         /* Some general setup stuff, and configure status interrupt */
774         reg = TCIC_WAIT_ASYNC | TCIC_WAIT_SENSE | to_cycles(250);
775         tcic_aux_setb(TCIC_AUX_WCTL, reg);
776         tcic_aux_setw(TCIC_AUX_SYSCFG, TCIC_SYSCFG_AUTOBUSY|0x0a00|
777     		  TCIC_IRQ(cs_irq));
778         
779         /* Card status change interrupt mask */
780         tcic_setw(TCIC_ADDR, TCIC_SCF2(psock));
781         scf2 = TCIC_SCF2_MALL;
782         if (state->csc_mask & SS_DETECT) scf2 &= ~TCIC_SCF2_MCD;
783         if (state->flags & SS_IOCARD) {
784     	if (state->csc_mask & SS_STSCHG) reg &= ~TCIC_SCF2_MLBAT1;
785         } else {
786     	if (state->csc_mask & SS_BATDEAD) reg &= ~TCIC_SCF2_MLBAT1;
787     	if (state->csc_mask & SS_BATWARN) reg &= ~TCIC_SCF2_MLBAT2;
788     	if (state->csc_mask & SS_READY) reg &= ~TCIC_SCF2_MRDY;
789         }
790         tcic_setw(TCIC_DATA, scf2);
791         /* For the ISA bus, the irq should be active-high totem-pole */
792         tcic_setb(TCIC_IENA, TCIC_IENA_CDCHG | TCIC_IENA_CFG_HIGH);
793     
794         return 0;
795     } /* tcic_set_socket */
796       
797     /*====================================================================*/
798     
799     static int tcic_get_io_map(unsigned int lsock, struct pccard_io_map *io)
800     {
801         u_short psock = socket_table[lsock].psock;
802         u_short base, ioctl;
803         u_int addr;
804         
805         if (io->map > 1) return -EINVAL;
806         tcic_setw(TCIC_ADDR+2, TCIC_ADR2_INDREG | (psock << TCIC_SS_SHFT));
807         addr = TCIC_IWIN(psock, io->map);
808         tcic_setw(TCIC_ADDR, addr + TCIC_IBASE_X);
809         base = tcic_getw(TCIC_DATA);
810         tcic_setw(TCIC_ADDR, addr + TCIC_ICTL_X);
811         ioctl = tcic_getw(TCIC_DATA);
812     
813         if (ioctl & TCIC_ICTL_TINY)
814     	io->start = io->stop = base;
815         else {
816     	io->start = base & (base-1);
817     	io->stop = io->start + (base ^ (base-1));
818         }
819         io->speed = to_ns(ioctl & TCIC_ICTL_WSCNT_MASK);
820         io->flags  = (ioctl & TCIC_ICTL_ENA) ? MAP_ACTIVE : 0;
821         switch (ioctl & TCIC_ICTL_BW_MASK) {
822         case TCIC_ICTL_BW_DYN:
823     	io->flags |= MAP_AUTOSZ; break;
824         case TCIC_ICTL_BW_16:
825     	io->flags |= MAP_16BIT; break;
826         default:
827     	break;
828         }
829         DEBUG(1, "tcic: GetIOMap(%d, %d) = %#2.2x, %d ns, "
830     	  "%#4.4x-%#4.4x\n", lsock, io->map, io->flags,
831     	  io->speed, io->start, io->stop);
832         return 0;
833     } /* tcic_get_io_map */
834     
835     /*====================================================================*/
836     
837     static int tcic_set_io_map(unsigned int lsock, struct pccard_io_map *io)
838     {
839         u_short psock = socket_table[lsock].psock;
840         u_int addr;
841         u_short base, len, ioctl;
842         
843         DEBUG(1, "tcic: SetIOMap(%d, %d, %#2.2x, %d ns, "
844     	  "%#4.4x-%#4.4x)\n", lsock, io->map, io->flags,
845     	  io->speed, io->start, io->stop);
846         if ((io->map > 1) || (io->start > 0xffff) || (io->stop > 0xffff) ||
847     	(io->stop < io->start)) return -EINVAL;
848         tcic_setw(TCIC_ADDR+2, TCIC_ADR2_INDREG | (psock << TCIC_SS_SHFT));
849         addr = TCIC_IWIN(psock, io->map);
850     
851         base = io->start; len = io->stop - io->start;
852         /* Check to see that len+1 is power of two, etc */
853         if ((len & (len+1)) || (base & len)) return -EINVAL;
854         base |= (len+1)>>1;
855         tcic_setw(TCIC_ADDR, addr + TCIC_IBASE_X);
856         tcic_setw(TCIC_DATA, base);
857         
858         ioctl  = (psock << TCIC_ICTL_SS_SHFT);
859         ioctl |= (len == 0) ? TCIC_ICTL_TINY : 0;
860         ioctl |= (io->flags & MAP_ACTIVE) ? TCIC_ICTL_ENA : 0;
861         ioctl |= to_cycles(io->speed) & TCIC_ICTL_WSCNT_MASK;
862         if (!(io->flags & MAP_AUTOSZ)) {
863     	ioctl |= TCIC_ICTL_QUIET;
864     	ioctl |= (io->flags & MAP_16BIT) ? TCIC_ICTL_BW_16 : TCIC_ICTL_BW_8;
865         }
866         tcic_setw(TCIC_ADDR, addr + TCIC_ICTL_X);
867         tcic_setw(TCIC_DATA, ioctl);
868         
869         return 0;
870     } /* tcic_set_io_map */
871     
872     /*====================================================================*/
873     
874     static int tcic_get_mem_map(unsigned int lsock, struct pccard_mem_map *mem)
875     {
876         u_short psock = socket_table[lsock].psock;
877         u_short addr, ctl;
878         u_long base, mmap;
879         
880         if (mem->map > 3) return -EINVAL;
881         tcic_setw(TCIC_ADDR+2, TCIC_ADR2_INDREG | (psock << TCIC_SS_SHFT));
882         addr = TCIC_MWIN(psock, mem->map);
883         
884         tcic_setw(TCIC_ADDR, addr + TCIC_MBASE_X);
885         base = tcic_getw(TCIC_DATA);
886         if (base & TCIC_MBASE_4K_BIT) {
887     	mem->sys_start = base & TCIC_MBASE_HA_MASK;
888     	mem->sys_stop = mem->sys_start;
889         } else {
890     	base &= TCIC_MBASE_HA_MASK;
891     	mem->sys_start = (base & (base-1));
892     	mem->sys_stop = mem->sys_start + (base ^ (base-1));
893         }
894         mem->sys_start = mem->sys_start << TCIC_MBASE_HA_SHFT;
895         mem->sys_stop = (mem->sys_stop << TCIC_MBASE_HA_SHFT) + 0x0fff;
896         
897         tcic_setw(TCIC_ADDR, addr + TCIC_MMAP_X);
898         mmap = tcic_getw(TCIC_DATA);
899         mem->flags = (mmap & TCIC_MMAP_REG) ? MAP_ATTRIB : 0;
900         mmap &= TCIC_MMAP_CA_MASK;
901         mem->card_start = mem->sys_start + (mmap << TCIC_MMAP_CA_SHFT);
902         mem->card_start &= 0x3ffffff;
903         
904         tcic_setw(TCIC_ADDR, addr + TCIC_MCTL_X);
905         ctl = tcic_getw(TCIC_DATA);
906         mem->flags |= (ctl & TCIC_MCTL_ENA) ? MAP_ACTIVE : 0;
907         mem->flags |= (ctl & TCIC_MCTL_B8) ? 0 : MAP_16BIT;
908         mem->flags |= (ctl & TCIC_MCTL_WP) ? MAP_WRPROT : 0;
909         mem->speed = to_ns(ctl & TCIC_MCTL_WSCNT_MASK);
910         
911         DEBUG(1, "tcic: GetMemMap(%d, %d) = %#2.2x, %d ns, "
912     	  "%#5.5lx-%#5.5lx, %#5.5x\n", lsock, mem->map, mem->flags,
913     	  mem->speed, mem->sys_start, mem->sys_stop, mem->card_start);
914         return 0;
915     } /* tcic_get_mem_map */
916     
917     /*====================================================================*/
918       
919     static int tcic_set_mem_map(unsigned int lsock, struct pccard_mem_map *mem)
920     {
921         u_short psock = socket_table[lsock].psock;
922         u_short addr, ctl;
923         u_long base, len, mmap;
924     
925         DEBUG(1, "tcic: SetMemMap(%d, %d, %#2.2x, %d ns, "
926     	  "%#5.5lx-%#5.5lx, %#5.5x)\n", lsock, mem->map, mem->flags,
927     	  mem->speed, mem->sys_start, mem->sys_stop, mem->card_start);
928         if ((mem->map > 3) || (mem->card_start > 0x3ffffff) ||
929     	(mem->sys_start > 0xffffff) || (mem->sys_stop > 0xffffff) ||
930     	(mem->sys_start > mem->sys_stop) || (mem->speed > 1000))
931     	return -EINVAL;
932         tcic_setw(TCIC_ADDR+2, TCIC_ADR2_INDREG | (psock << TCIC_SS_SHFT));
933         addr = TCIC_MWIN(psock, mem->map);
934     
935         base = mem->sys_start; len = mem->sys_stop - mem->sys_start;
936         if ((len & (len+1)) || (base & len)) return -EINVAL;
937         if (len == 0x0fff)
938     	base = (base >> TCIC_MBASE_HA_SHFT) | TCIC_MBASE_4K_BIT;
939         else
940     	base = (base | (len+1)>>1) >> TCIC_MBASE_HA_SHFT;
941         tcic_setw(TCIC_ADDR, addr + TCIC_MBASE_X);
942         tcic_setw(TCIC_DATA, base);
943         
944         mmap = mem->card_start - mem->sys_start;
945         mmap = (mmap >> TCIC_MMAP_CA_SHFT) & TCIC_MMAP_CA_MASK;
946         if (mem->flags & MAP_ATTRIB) mmap |= TCIC_MMAP_REG;
947         tcic_setw(TCIC_ADDR, addr + TCIC_MMAP_X);
948         tcic_setw(TCIC_DATA, mmap);
949     
950         ctl  = TCIC_MCTL_QUIET | (psock << TCIC_MCTL_SS_SHFT);
951         ctl |= to_cycles(mem->speed) & TCIC_MCTL_WSCNT_MASK;
952         ctl |= (mem->flags & MAP_16BIT) ? 0 : TCIC_MCTL_B8;
953         ctl |= (mem->flags & MAP_WRPROT) ? TCIC_MCTL_WP : 0;
954         ctl |= (mem->flags & MAP_ACTIVE) ? TCIC_MCTL_ENA : 0;
955         tcic_setw(TCIC_ADDR, addr + TCIC_MCTL_X);
956         tcic_setw(TCIC_DATA, ctl);
957         
958         return 0;
959     } /* tcic_set_mem_map */
960     
961     /*====================================================================*/
962     
963     static void tcic_proc_setup(unsigned int sock, struct proc_dir_entry *base)
964     {
965     }
966     
967     static int tcic_init(unsigned int s)
968     {
969     	int i;
970     	pccard_io_map io = { 0, 0, 0, 0, 1 };
971     	pccard_mem_map mem = { 0, 0, 0, 0, 0, 0 };
972     
973     	mem.sys_stop = 0x1000;
974     	tcic_set_socket(s, &dead_socket);
975     	for (i = 0; i < 2; i++) {
976     		io.map = i;
977     		tcic_set_io_map(s, &io);
978     	}
979     	for (i = 0; i < 5; i++) {
980     		mem.map = i;
981     		tcic_set_mem_map(s, &mem);
982     	}
983     	return 0;
984     }
985     
986     static int tcic_suspend(unsigned int sock)
987     {
988     	return tcic_set_socket(sock, &dead_socket);
989     }
990     
991     static struct pccard_operations tcic_operations = {
992     	tcic_init,
993     	tcic_suspend,
994     	tcic_register_callback,
995     	tcic_inquire_socket,
996     	tcic_get_status,
997     	tcic_get_socket,
998     	tcic_set_socket,
999     	tcic_get_io_map,
1000     	tcic_set_io_map,
1001     	tcic_get_mem_map,
1002     	tcic_set_mem_map,
1003     	tcic_proc_setup
1004     };
1005     
1006     /*====================================================================*/
1007     
1008     module_init(init_tcic);
1009     module_exit(exit_tcic);
1010