xref: /linux/drivers/pcmcia/tcic.c (revision 4b2a108cd0d34880fe9d932258ca5b2ccebcd05e)
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     <dahinds@users.sourceforge.net>.  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/moduleparam.h>
36 #include <linux/init.h>
37 #include <linux/types.h>
38 #include <linux/fcntl.h>
39 #include <linux/string.h>
40 #include <linux/errno.h>
41 #include <linux/interrupt.h>
42 #include <linux/slab.h>
43 #include <linux/timer.h>
44 #include <linux/ioport.h>
45 #include <linux/delay.h>
46 #include <linux/workqueue.h>
47 #include <linux/platform_device.h>
48 #include <linux/bitops.h>
49 
50 #include <asm/io.h>
51 #include <asm/system.h>
52 
53 #include <pcmcia/cs_types.h>
54 #include <pcmcia/cs.h>
55 #include <pcmcia/ss.h>
56 #include "tcic.h"
57 
58 #ifdef CONFIG_PCMCIA_DEBUG
59 static int pc_debug;
60 
61 module_param(pc_debug, int, 0644);
62 static const char version[] =
63 "tcic.c 1.111 2000/02/15 04:13:12 (David Hinds)";
64 
65 #define debug(lvl, fmt, arg...) do {				\
66 	if (pc_debug > (lvl))					\
67 		printk(KERN_DEBUG "tcic: " fmt , ## arg);	\
68 } while (0)
69 #else
70 #define debug(lvl, fmt, arg...) do { } while (0)
71 #endif
72 
73 MODULE_AUTHOR("David Hinds <dahinds@users.sourceforge.net>");
74 MODULE_DESCRIPTION("Databook TCIC-2 PCMCIA socket driver");
75 MODULE_LICENSE("Dual MPL/GPL");
76 
77 /*====================================================================*/
78 
79 /* Parameters that can be set with 'insmod' */
80 
81 /* The base port address of the TCIC-2 chip */
82 static unsigned long tcic_base = TCIC_BASE;
83 
84 /* Specify a socket number to ignore */
85 static int ignore = -1;
86 
87 /* Probe for safe interrupts? */
88 static int do_scan = 1;
89 
90 /* Bit map of interrupts to choose from */
91 static u_int irq_mask = 0xffff;
92 static int irq_list[16];
93 static unsigned int irq_list_count;
94 
95 /* The card status change interrupt -- 0 means autoselect */
96 static int cs_irq;
97 
98 /* Poll status interval -- 0 means default to interrupt */
99 static int poll_interval;
100 
101 /* Delay for card status double-checking */
102 static int poll_quick = HZ/20;
103 
104 /* CCLK external clock time, in nanoseconds.  70 ns = 14.31818 MHz */
105 static int cycle_time = 70;
106 
107 module_param(tcic_base, ulong, 0444);
108 module_param(ignore, int, 0444);
109 module_param(do_scan, int, 0444);
110 module_param(irq_mask, int, 0444);
111 module_param_array(irq_list, int, &irq_list_count, 0444);
112 module_param(cs_irq, int, 0444);
113 module_param(poll_interval, int, 0444);
114 module_param(poll_quick, int, 0444);
115 module_param(cycle_time, int, 0444);
116 
117 /*====================================================================*/
118 
119 static irqreturn_t tcic_interrupt(int irq, void *dev);
120 static void tcic_timer(u_long data);
121 static struct pccard_operations tcic_operations;
122 
123 struct tcic_socket {
124     u_short	psock;
125     u_char	last_sstat;
126     u_char	id;
127     struct pcmcia_socket	socket;
128 };
129 
130 static struct timer_list poll_timer;
131 static int tcic_timer_pending;
132 
133 static int sockets;
134 static struct tcic_socket socket_table[2];
135 
136 /*====================================================================*/
137 
138 /* Trick when selecting interrupts: the TCIC sktirq pin is supposed
139    to map to irq 11, but is coded as 0 or 1 in the irq registers. */
140 #define TCIC_IRQ(x) ((x) ? (((x) == 11) ? 1 : (x)) : 15)
141 
142 #ifdef DEBUG_X
143 static u_char tcic_getb(u_char reg)
144 {
145     u_char val = inb(tcic_base+reg);
146     printk(KERN_DEBUG "tcic_getb(%#lx) = %#x\n", tcic_base+reg, val);
147     return val;
148 }
149 
150 static u_short tcic_getw(u_char reg)
151 {
152     u_short val = inw(tcic_base+reg);
153     printk(KERN_DEBUG "tcic_getw(%#lx) = %#x\n", tcic_base+reg, val);
154     return val;
155 }
156 
157 static void tcic_setb(u_char reg, u_char data)
158 {
159     printk(KERN_DEBUG "tcic_setb(%#lx, %#x)\n", tcic_base+reg, data);
160     outb(data, tcic_base+reg);
161 }
162 
163 static void tcic_setw(u_char reg, u_short data)
164 {
165     printk(KERN_DEBUG "tcic_setw(%#lx, %#x)\n", tcic_base+reg, data);
166     outw(data, tcic_base+reg);
167 }
168 #else
169 #define tcic_getb(reg) inb(tcic_base+reg)
170 #define tcic_getw(reg) inw(tcic_base+reg)
171 #define tcic_setb(reg, data) outb(data, tcic_base+reg)
172 #define tcic_setw(reg, data) outw(data, tcic_base+reg)
173 #endif
174 
175 static void tcic_setl(u_char reg, u_int data)
176 {
177 #ifdef DEBUG_X
178     printk(KERN_DEBUG "tcic_setl(%#x, %#lx)\n", tcic_base+reg, data);
179 #endif
180     outw(data & 0xffff, tcic_base+reg);
181     outw(data >> 16, tcic_base+reg+2);
182 }
183 
184 static void tcic_aux_setb(u_short reg, u_char data)
185 {
186     u_char mode = (tcic_getb(TCIC_MODE) & TCIC_MODE_PGMMASK) | reg;
187     tcic_setb(TCIC_MODE, mode);
188     tcic_setb(TCIC_AUX, data);
189 }
190 
191 static u_short tcic_aux_getw(u_short reg)
192 {
193     u_char mode = (tcic_getb(TCIC_MODE) & TCIC_MODE_PGMMASK) | reg;
194     tcic_setb(TCIC_MODE, mode);
195     return tcic_getw(TCIC_AUX);
196 }
197 
198 static void tcic_aux_setw(u_short reg, u_short data)
199 {
200     u_char mode = (tcic_getb(TCIC_MODE) & TCIC_MODE_PGMMASK) | reg;
201     tcic_setb(TCIC_MODE, mode);
202     tcic_setw(TCIC_AUX, data);
203 }
204 
205 /*====================================================================*/
206 
207 /* Time conversion functions */
208 
209 static int to_cycles(int ns)
210 {
211     if (ns < 14)
212 	return 0;
213     else
214 	return 2*(ns-14)/cycle_time;
215 }
216 
217 /*====================================================================*/
218 
219 static volatile u_int irq_hits;
220 
221 static irqreturn_t __init tcic_irq_count(int irq, void *dev)
222 {
223     irq_hits++;
224     return IRQ_HANDLED;
225 }
226 
227 static u_int __init try_irq(int irq)
228 {
229     u_short cfg;
230 
231     irq_hits = 0;
232     if (request_irq(irq, tcic_irq_count, 0, "irq scan", tcic_irq_count) != 0)
233 	return -1;
234     mdelay(10);
235     if (irq_hits) {
236 	free_irq(irq, tcic_irq_count);
237 	return -1;
238     }
239 
240     /* Generate one interrupt */
241     cfg = TCIC_SYSCFG_AUTOBUSY | 0x0a00;
242     tcic_aux_setw(TCIC_AUX_SYSCFG, cfg | TCIC_IRQ(irq));
243     tcic_setb(TCIC_IENA, TCIC_IENA_ERR | TCIC_IENA_CFG_HIGH);
244     tcic_setb(TCIC_ICSR, TCIC_ICSR_ERR | TCIC_ICSR_JAM);
245 
246     udelay(1000);
247     free_irq(irq, tcic_irq_count);
248 
249     /* Turn off interrupts */
250     tcic_setb(TCIC_IENA, TCIC_IENA_CFG_OFF);
251     while (tcic_getb(TCIC_ICSR))
252 	tcic_setb(TCIC_ICSR, TCIC_ICSR_JAM);
253     tcic_aux_setw(TCIC_AUX_SYSCFG, cfg);
254 
255     return (irq_hits != 1);
256 }
257 
258 static u_int __init irq_scan(u_int mask0)
259 {
260     u_int mask1;
261     int i;
262 
263 #ifdef __alpha__
264 #define PIC 0x4d0
265     /* Don't probe level-triggered interrupts -- reserved for PCI */
266     int level_mask = inb_p(PIC) | (inb_p(PIC+1) << 8);
267     if (level_mask)
268 	mask0 &= ~level_mask;
269 #endif
270 
271     mask1 = 0;
272     if (do_scan) {
273 	for (i = 0; i < 16; i++)
274 	    if ((mask0 & (1 << i)) && (try_irq(i) == 0))
275 		mask1 |= (1 << i);
276 	for (i = 0; i < 16; i++)
277 	    if ((mask1 & (1 << i)) && (try_irq(i) != 0)) {
278 		mask1 ^= (1 << i);
279 	    }
280     }
281 
282     if (mask1) {
283 	printk("scanned");
284     } else {
285 	/* Fallback: just find interrupts that aren't in use */
286 	for (i = 0; i < 16; i++)
287 	    if ((mask0 & (1 << i)) &&
288 		(request_irq(i, tcic_irq_count, 0, "x", tcic_irq_count) == 0)) {
289 		mask1 |= (1 << i);
290 		free_irq(i, tcic_irq_count);
291 	    }
292 	printk("default");
293     }
294 
295     printk(") = ");
296     for (i = 0; i < 16; i++)
297 	if (mask1 & (1<<i))
298 	    printk("%s%d", ((mask1 & ((1<<i)-1)) ? "," : ""), i);
299     printk(" ");
300 
301     return mask1;
302 }
303 
304 /*======================================================================
305 
306     See if a card is present, powered up, in IO mode, and already
307     bound to a (non-PCMCIA) Linux driver.
308 
309     We make an exception for cards that look like serial devices.
310 
311 ======================================================================*/
312 
313 static int __init is_active(int s)
314 {
315     u_short scf1, ioctl, base, num;
316     u_char pwr, sstat;
317     u_int addr;
318 
319     tcic_setl(TCIC_ADDR, (s << TCIC_ADDR_SS_SHFT)
320 	      | TCIC_ADDR_INDREG | TCIC_SCF1(s));
321     scf1 = tcic_getw(TCIC_DATA);
322     pwr = tcic_getb(TCIC_PWR);
323     sstat = tcic_getb(TCIC_SSTAT);
324     addr = TCIC_IWIN(s, 0);
325     tcic_setw(TCIC_ADDR, addr + TCIC_IBASE_X);
326     base = tcic_getw(TCIC_DATA);
327     tcic_setw(TCIC_ADDR, addr + TCIC_ICTL_X);
328     ioctl = tcic_getw(TCIC_DATA);
329 
330     if (ioctl & TCIC_ICTL_TINY)
331 	num = 1;
332     else {
333 	num = (base ^ (base-1));
334 	base = base & (base-1);
335     }
336 
337     if ((sstat & TCIC_SSTAT_CD) && (pwr & TCIC_PWR_VCC(s)) &&
338 	(scf1 & TCIC_SCF1_IOSTS) && (ioctl & TCIC_ICTL_ENA) &&
339 	((base & 0xfeef) != 0x02e8)) {
340 	struct resource *res = request_region(base, num, "tcic-2");
341 	if (!res) /* region is busy */
342 	    return 1;
343 	release_region(base, num);
344     }
345 
346     return 0;
347 }
348 
349 /*======================================================================
350 
351     This returns the revision code for the specified socket.
352 
353 ======================================================================*/
354 
355 static int __init get_tcic_id(void)
356 {
357     u_short id;
358 
359     tcic_aux_setw(TCIC_AUX_TEST, TCIC_TEST_DIAG);
360     id = tcic_aux_getw(TCIC_AUX_ILOCK);
361     id = (id & TCIC_ILOCKTEST_ID_MASK) >> TCIC_ILOCKTEST_ID_SH;
362     tcic_aux_setw(TCIC_AUX_TEST, 0);
363     return id;
364 }
365 
366 static int tcic_drv_pcmcia_suspend(struct platform_device *dev,
367 				     pm_message_t state)
368 {
369 	return pcmcia_socket_dev_suspend(&dev->dev, state);
370 }
371 
372 static int tcic_drv_pcmcia_resume(struct platform_device *dev)
373 {
374 	return pcmcia_socket_dev_resume(&dev->dev);
375 }
376 /*====================================================================*/
377 
378 static struct platform_driver tcic_driver = {
379 	.driver = {
380 		.name = "tcic-pcmcia",
381 		.owner		= THIS_MODULE,
382 	},
383 	.suspend 	= tcic_drv_pcmcia_suspend,
384 	.resume 	= tcic_drv_pcmcia_resume,
385 };
386 
387 static struct platform_device tcic_device = {
388 	.name = "tcic-pcmcia",
389 	.id = 0,
390 };
391 
392 
393 static int __init init_tcic(void)
394 {
395     int i, sock, ret = 0;
396     u_int mask, scan;
397 
398     if (platform_driver_register(&tcic_driver))
399 	return -1;
400 
401     printk(KERN_INFO "Databook TCIC-2 PCMCIA probe: ");
402     sock = 0;
403 
404     if (!request_region(tcic_base, 16, "tcic-2")) {
405 	printk("could not allocate ports,\n ");
406 	platform_driver_unregister(&tcic_driver);
407 	return -ENODEV;
408     }
409     else {
410 	tcic_setw(TCIC_ADDR, 0);
411 	if (tcic_getw(TCIC_ADDR) == 0) {
412 	    tcic_setw(TCIC_ADDR, 0xc3a5);
413 	    if (tcic_getw(TCIC_ADDR) == 0xc3a5) sock = 2;
414 	}
415 	if (sock == 0) {
416 	    /* See if resetting the controller does any good */
417 	    tcic_setb(TCIC_SCTRL, TCIC_SCTRL_RESET);
418 	    tcic_setb(TCIC_SCTRL, 0);
419 	    tcic_setw(TCIC_ADDR, 0);
420 	    if (tcic_getw(TCIC_ADDR) == 0) {
421 		tcic_setw(TCIC_ADDR, 0xc3a5);
422 		if (tcic_getw(TCIC_ADDR) == 0xc3a5) sock = 2;
423 	    }
424 	}
425     }
426     if (sock == 0) {
427 	printk("not found.\n");
428 	release_region(tcic_base, 16);
429 	platform_driver_unregister(&tcic_driver);
430 	return -ENODEV;
431     }
432 
433     sockets = 0;
434     for (i = 0; i < sock; i++) {
435 	if ((i == ignore) || is_active(i)) continue;
436 	socket_table[sockets].psock = i;
437 	socket_table[sockets].id = get_tcic_id();
438 
439 	socket_table[sockets].socket.owner = THIS_MODULE;
440 	/* only 16-bit cards, memory windows must be size-aligned */
441 	/* No PCI or CardBus support */
442 	socket_table[sockets].socket.features = SS_CAP_PCCARD | SS_CAP_MEM_ALIGN;
443 	/* irq 14, 11, 10, 7, 6, 5, 4, 3 */
444 	socket_table[sockets].socket.irq_mask = 0x4cf8;
445 	/* 4K minimum window size */
446 	socket_table[sockets].socket.map_size = 0x1000;
447 	sockets++;
448     }
449 
450     switch (socket_table[0].id) {
451     case TCIC_ID_DB86082:
452 	printk("DB86082"); break;
453     case TCIC_ID_DB86082A:
454 	printk("DB86082A"); break;
455     case TCIC_ID_DB86084:
456 	printk("DB86084"); break;
457     case TCIC_ID_DB86084A:
458 	printk("DB86084A"); break;
459     case TCIC_ID_DB86072:
460 	printk("DB86072"); break;
461     case TCIC_ID_DB86184:
462 	printk("DB86184"); break;
463     case TCIC_ID_DB86082B:
464 	printk("DB86082B"); break;
465     default:
466 	printk("Unknown ID 0x%02x", socket_table[0].id);
467     }
468 
469     /* Set up polling */
470     poll_timer.function = &tcic_timer;
471     poll_timer.data = 0;
472     init_timer(&poll_timer);
473 
474     /* Build interrupt mask */
475     printk(KERN_CONT ", %d sockets\n", sockets);
476     printk(KERN_INFO "  irq list (");
477     if (irq_list_count == 0)
478 	mask = irq_mask;
479     else
480 	for (i = mask = 0; i < irq_list_count; i++)
481 	    mask |= (1<<irq_list[i]);
482 
483     /* irq 14, 11, 10, 7, 6, 5, 4, 3 */
484     mask &= 0x4cf8;
485     /* Scan interrupts */
486     mask = irq_scan(mask);
487     for (i=0;i<sockets;i++)
488 	    socket_table[i].socket.irq_mask = mask;
489 
490     /* Check for only two interrupts available */
491     scan = (mask & (mask-1));
492     if (((scan & (scan-1)) == 0) && (poll_interval == 0))
493 	poll_interval = HZ;
494 
495     if (poll_interval == 0) {
496 	/* Avoid irq 12 unless it is explicitly requested */
497 	u_int cs_mask = mask & ((cs_irq) ? (1<<cs_irq) : ~(1<<12));
498 	for (i = 15; i > 0; i--)
499 	    if ((cs_mask & (1 << i)) &&
500 		(request_irq(i, tcic_interrupt, 0, "tcic",
501 			     tcic_interrupt) == 0))
502 		break;
503 	cs_irq = i;
504 	if (cs_irq == 0) poll_interval = HZ;
505     }
506 
507     if (socket_table[0].socket.irq_mask & (1 << 11))
508 	printk("sktirq is irq 11, ");
509     if (cs_irq != 0)
510 	printk("status change on irq %d\n", cs_irq);
511     else
512 	printk("polled status, interval = %d ms\n",
513 	       poll_interval * 1000 / HZ);
514 
515     for (i = 0; i < sockets; i++) {
516 	tcic_setw(TCIC_ADDR+2, socket_table[i].psock << TCIC_SS_SHFT);
517 	socket_table[i].last_sstat = tcic_getb(TCIC_SSTAT);
518     }
519 
520     /* jump start interrupt handler, if needed */
521     tcic_interrupt(0, NULL);
522 
523     platform_device_register(&tcic_device);
524 
525     for (i = 0; i < sockets; i++) {
526 	    socket_table[i].socket.ops = &tcic_operations;
527 	    socket_table[i].socket.resource_ops = &pccard_nonstatic_ops;
528 	    socket_table[i].socket.dev.parent = &tcic_device.dev;
529 	    ret = pcmcia_register_socket(&socket_table[i].socket);
530 	    if (ret && i)
531 		    pcmcia_unregister_socket(&socket_table[0].socket);
532     }
533 
534     return ret;
535 
536     return 0;
537 
538 } /* init_tcic */
539 
540 /*====================================================================*/
541 
542 static void __exit exit_tcic(void)
543 {
544     int i;
545 
546     del_timer_sync(&poll_timer);
547     if (cs_irq != 0) {
548 	tcic_aux_setw(TCIC_AUX_SYSCFG, TCIC_SYSCFG_AUTOBUSY|0x0a00);
549 	free_irq(cs_irq, tcic_interrupt);
550     }
551     release_region(tcic_base, 16);
552 
553     for (i = 0; i < sockets; i++) {
554 	    pcmcia_unregister_socket(&socket_table[i].socket);
555     }
556 
557     platform_device_unregister(&tcic_device);
558     platform_driver_unregister(&tcic_driver);
559 } /* exit_tcic */
560 
561 /*====================================================================*/
562 
563 static irqreturn_t tcic_interrupt(int irq, void *dev)
564 {
565     int i, quick = 0;
566     u_char latch, sstat;
567     u_short psock;
568     u_int events;
569     static volatile int active = 0;
570 
571     if (active) {
572 	printk(KERN_NOTICE "tcic: reentered interrupt handler!\n");
573 	return IRQ_NONE;
574     } else
575 	active = 1;
576 
577     debug(2, "tcic_interrupt()\n");
578 
579     for (i = 0; i < sockets; i++) {
580 	psock = socket_table[i].psock;
581 	tcic_setl(TCIC_ADDR, (psock << TCIC_ADDR_SS_SHFT)
582 		  | TCIC_ADDR_INDREG | TCIC_SCF1(psock));
583 	sstat = tcic_getb(TCIC_SSTAT);
584 	latch = sstat ^ socket_table[psock].last_sstat;
585 	socket_table[i].last_sstat = sstat;
586 	if (tcic_getb(TCIC_ICSR) & TCIC_ICSR_CDCHG) {
587 	    tcic_setb(TCIC_ICSR, TCIC_ICSR_CLEAR);
588 	    quick = 1;
589 	}
590 	if (latch == 0)
591 	    continue;
592 	events = (latch & TCIC_SSTAT_CD) ? SS_DETECT : 0;
593 	events |= (latch & TCIC_SSTAT_WP) ? SS_WRPROT : 0;
594 	if (tcic_getw(TCIC_DATA) & TCIC_SCF1_IOSTS) {
595 	    events |= (latch & TCIC_SSTAT_LBAT1) ? SS_STSCHG : 0;
596 	} else {
597 	    events |= (latch & TCIC_SSTAT_RDY) ? SS_READY : 0;
598 	    events |= (latch & TCIC_SSTAT_LBAT1) ? SS_BATDEAD : 0;
599 	    events |= (latch & TCIC_SSTAT_LBAT2) ? SS_BATWARN : 0;
600 	}
601 	if (events) {
602 		pcmcia_parse_events(&socket_table[i].socket, events);
603 	}
604     }
605 
606     /* Schedule next poll, if needed */
607     if (((cs_irq == 0) || quick) && (!tcic_timer_pending)) {
608 	poll_timer.expires = jiffies + (quick ? poll_quick : poll_interval);
609 	add_timer(&poll_timer);
610 	tcic_timer_pending = 1;
611     }
612     active = 0;
613 
614     debug(2, "interrupt done\n");
615     return IRQ_HANDLED;
616 } /* tcic_interrupt */
617 
618 static void tcic_timer(u_long data)
619 {
620     debug(2, "tcic_timer()\n");
621     tcic_timer_pending = 0;
622     tcic_interrupt(0, NULL);
623 } /* tcic_timer */
624 
625 /*====================================================================*/
626 
627 static int tcic_get_status(struct pcmcia_socket *sock, u_int *value)
628 {
629     u_short psock = container_of(sock, struct tcic_socket, socket)->psock;
630     u_char reg;
631 
632     tcic_setl(TCIC_ADDR, (psock << TCIC_ADDR_SS_SHFT)
633 	      | TCIC_ADDR_INDREG | TCIC_SCF1(psock));
634     reg = tcic_getb(TCIC_SSTAT);
635     *value  = (reg & TCIC_SSTAT_CD) ? SS_DETECT : 0;
636     *value |= (reg & TCIC_SSTAT_WP) ? SS_WRPROT : 0;
637     if (tcic_getw(TCIC_DATA) & TCIC_SCF1_IOSTS) {
638 	*value |= (reg & TCIC_SSTAT_LBAT1) ? SS_STSCHG : 0;
639     } else {
640 	*value |= (reg & TCIC_SSTAT_RDY) ? SS_READY : 0;
641 	*value |= (reg & TCIC_SSTAT_LBAT1) ? SS_BATDEAD : 0;
642 	*value |= (reg & TCIC_SSTAT_LBAT2) ? SS_BATWARN : 0;
643     }
644     reg = tcic_getb(TCIC_PWR);
645     if (reg & (TCIC_PWR_VCC(psock)|TCIC_PWR_VPP(psock)))
646 	*value |= SS_POWERON;
647     debug(1, "GetStatus(%d) = %#2.2x\n", psock, *value);
648     return 0;
649 } /* tcic_get_status */
650 
651 /*====================================================================*/
652 
653 static int tcic_set_socket(struct pcmcia_socket *sock, socket_state_t *state)
654 {
655     u_short psock = container_of(sock, struct tcic_socket, socket)->psock;
656     u_char reg;
657     u_short scf1, scf2;
658 
659     debug(1, "SetSocket(%d, flags %#3.3x, Vcc %d, Vpp %d, "
660 	  "io_irq %d, csc_mask %#2.2x)\n", psock, state->flags,
661 	  state->Vcc, state->Vpp, state->io_irq, state->csc_mask);
662     tcic_setw(TCIC_ADDR+2, (psock << TCIC_SS_SHFT) | TCIC_ADR2_INDREG);
663 
664     reg = tcic_getb(TCIC_PWR);
665     reg &= ~(TCIC_PWR_VCC(psock) | TCIC_PWR_VPP(psock));
666 
667     if (state->Vcc == 50) {
668 	switch (state->Vpp) {
669 	case 0:   reg |= TCIC_PWR_VCC(psock) | TCIC_PWR_VPP(psock); break;
670 	case 50:  reg |= TCIC_PWR_VCC(psock); break;
671 	case 120: reg |= TCIC_PWR_VPP(psock); break;
672 	default:  return -EINVAL;
673 	}
674     } else if (state->Vcc != 0)
675 	return -EINVAL;
676 
677     if (reg != tcic_getb(TCIC_PWR))
678 	tcic_setb(TCIC_PWR, reg);
679 
680     reg = TCIC_ILOCK_HOLD_CCLK | TCIC_ILOCK_CWAIT;
681     if (state->flags & SS_OUTPUT_ENA) {
682 	tcic_setb(TCIC_SCTRL, TCIC_SCTRL_ENA);
683 	reg |= TCIC_ILOCK_CRESENA;
684     } else
685 	tcic_setb(TCIC_SCTRL, 0);
686     if (state->flags & SS_RESET)
687 	reg |= TCIC_ILOCK_CRESET;
688     tcic_aux_setb(TCIC_AUX_ILOCK, reg);
689 
690     tcic_setw(TCIC_ADDR, TCIC_SCF1(psock));
691     scf1 = TCIC_SCF1_FINPACK;
692     scf1 |= TCIC_IRQ(state->io_irq);
693     if (state->flags & SS_IOCARD) {
694 	scf1 |= TCIC_SCF1_IOSTS;
695 	if (state->flags & SS_SPKR_ENA)
696 	    scf1 |= TCIC_SCF1_SPKR;
697 	if (state->flags & SS_DMA_MODE)
698 	    scf1 |= TCIC_SCF1_DREQ2 << TCIC_SCF1_DMA_SHIFT;
699     }
700     tcic_setw(TCIC_DATA, scf1);
701 
702     /* Some general setup stuff, and configure status interrupt */
703     reg = TCIC_WAIT_ASYNC | TCIC_WAIT_SENSE | to_cycles(250);
704     tcic_aux_setb(TCIC_AUX_WCTL, reg);
705     tcic_aux_setw(TCIC_AUX_SYSCFG, TCIC_SYSCFG_AUTOBUSY|0x0a00|
706 		  TCIC_IRQ(cs_irq));
707 
708     /* Card status change interrupt mask */
709     tcic_setw(TCIC_ADDR, TCIC_SCF2(psock));
710     scf2 = TCIC_SCF2_MALL;
711     if (state->csc_mask & SS_DETECT) scf2 &= ~TCIC_SCF2_MCD;
712     if (state->flags & SS_IOCARD) {
713 	if (state->csc_mask & SS_STSCHG) reg &= ~TCIC_SCF2_MLBAT1;
714     } else {
715 	if (state->csc_mask & SS_BATDEAD) reg &= ~TCIC_SCF2_MLBAT1;
716 	if (state->csc_mask & SS_BATWARN) reg &= ~TCIC_SCF2_MLBAT2;
717 	if (state->csc_mask & SS_READY) reg &= ~TCIC_SCF2_MRDY;
718     }
719     tcic_setw(TCIC_DATA, scf2);
720     /* For the ISA bus, the irq should be active-high totem-pole */
721     tcic_setb(TCIC_IENA, TCIC_IENA_CDCHG | TCIC_IENA_CFG_HIGH);
722 
723     return 0;
724 } /* tcic_set_socket */
725 
726 /*====================================================================*/
727 
728 static int tcic_set_io_map(struct pcmcia_socket *sock, struct pccard_io_map *io)
729 {
730     u_short psock = container_of(sock, struct tcic_socket, socket)->psock;
731     u_int addr;
732     u_short base, len, ioctl;
733 
734     debug(1, "SetIOMap(%d, %d, %#2.2x, %d ns, "
735 	  "%#x-%#x)\n", psock, io->map, io->flags,
736 	  io->speed, io->start, io->stop);
737     if ((io->map > 1) || (io->start > 0xffff) || (io->stop > 0xffff) ||
738 	(io->stop < io->start)) return -EINVAL;
739     tcic_setw(TCIC_ADDR+2, TCIC_ADR2_INDREG | (psock << TCIC_SS_SHFT));
740     addr = TCIC_IWIN(psock, io->map);
741 
742     base = io->start; len = io->stop - io->start;
743     /* Check to see that len+1 is power of two, etc */
744     if ((len & (len+1)) || (base & len)) return -EINVAL;
745     base |= (len+1)>>1;
746     tcic_setw(TCIC_ADDR, addr + TCIC_IBASE_X);
747     tcic_setw(TCIC_DATA, base);
748 
749     ioctl  = (psock << TCIC_ICTL_SS_SHFT);
750     ioctl |= (len == 0) ? TCIC_ICTL_TINY : 0;
751     ioctl |= (io->flags & MAP_ACTIVE) ? TCIC_ICTL_ENA : 0;
752     ioctl |= to_cycles(io->speed) & TCIC_ICTL_WSCNT_MASK;
753     if (!(io->flags & MAP_AUTOSZ)) {
754 	ioctl |= TCIC_ICTL_QUIET;
755 	ioctl |= (io->flags & MAP_16BIT) ? TCIC_ICTL_BW_16 : TCIC_ICTL_BW_8;
756     }
757     tcic_setw(TCIC_ADDR, addr + TCIC_ICTL_X);
758     tcic_setw(TCIC_DATA, ioctl);
759 
760     return 0;
761 } /* tcic_set_io_map */
762 
763 /*====================================================================*/
764 
765 static int tcic_set_mem_map(struct pcmcia_socket *sock, struct pccard_mem_map *mem)
766 {
767     u_short psock = container_of(sock, struct tcic_socket, socket)->psock;
768     u_short addr, ctl;
769     u_long base, len, mmap;
770 
771     debug(1, "SetMemMap(%d, %d, %#2.2x, %d ns, "
772 	  "%#llx-%#llx, %#x)\n", psock, mem->map, mem->flags,
773 	  mem->speed, (unsigned long long)mem->res->start,
774 	  (unsigned long long)mem->res->end, mem->card_start);
775     if ((mem->map > 3) || (mem->card_start > 0x3ffffff) ||
776 	(mem->res->start > 0xffffff) || (mem->res->end > 0xffffff) ||
777 	(mem->res->start > mem->res->end) || (mem->speed > 1000))
778 	return -EINVAL;
779     tcic_setw(TCIC_ADDR+2, TCIC_ADR2_INDREG | (psock << TCIC_SS_SHFT));
780     addr = TCIC_MWIN(psock, mem->map);
781 
782     base = mem->res->start; len = mem->res->end - mem->res->start;
783     if ((len & (len+1)) || (base & len)) return -EINVAL;
784     if (len == 0x0fff)
785 	base = (base >> TCIC_MBASE_HA_SHFT) | TCIC_MBASE_4K_BIT;
786     else
787 	base = (base | (len+1)>>1) >> TCIC_MBASE_HA_SHFT;
788     tcic_setw(TCIC_ADDR, addr + TCIC_MBASE_X);
789     tcic_setw(TCIC_DATA, base);
790 
791     mmap = mem->card_start - mem->res->start;
792     mmap = (mmap >> TCIC_MMAP_CA_SHFT) & TCIC_MMAP_CA_MASK;
793     if (mem->flags & MAP_ATTRIB) mmap |= TCIC_MMAP_REG;
794     tcic_setw(TCIC_ADDR, addr + TCIC_MMAP_X);
795     tcic_setw(TCIC_DATA, mmap);
796 
797     ctl  = TCIC_MCTL_QUIET | (psock << TCIC_MCTL_SS_SHFT);
798     ctl |= to_cycles(mem->speed) & TCIC_MCTL_WSCNT_MASK;
799     ctl |= (mem->flags & MAP_16BIT) ? 0 : TCIC_MCTL_B8;
800     ctl |= (mem->flags & MAP_WRPROT) ? TCIC_MCTL_WP : 0;
801     ctl |= (mem->flags & MAP_ACTIVE) ? TCIC_MCTL_ENA : 0;
802     tcic_setw(TCIC_ADDR, addr + TCIC_MCTL_X);
803     tcic_setw(TCIC_DATA, ctl);
804 
805     return 0;
806 } /* tcic_set_mem_map */
807 
808 /*====================================================================*/
809 
810 static int tcic_init(struct pcmcia_socket *s)
811 {
812 	int i;
813 	struct resource res = { .start = 0, .end = 0x1000 };
814 	pccard_io_map io = { 0, 0, 0, 0, 1 };
815 	pccard_mem_map mem = { .res = &res, };
816 
817 	for (i = 0; i < 2; i++) {
818 		io.map = i;
819 		tcic_set_io_map(s, &io);
820 	}
821 	for (i = 0; i < 5; i++) {
822 		mem.map = i;
823 		tcic_set_mem_map(s, &mem);
824 	}
825 	return 0;
826 }
827 
828 static struct pccard_operations tcic_operations = {
829 	.init		   = tcic_init,
830 	.get_status	   = tcic_get_status,
831 	.set_socket	   = tcic_set_socket,
832 	.set_io_map	   = tcic_set_io_map,
833 	.set_mem_map	   = tcic_set_mem_map,
834 };
835 
836 /*====================================================================*/
837 
838 module_init(init_tcic);
839 module_exit(exit_tcic);
840