xref: /openbmc/linux/drivers/pcmcia/tcic.c (revision b04b4f78)
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(", %d sockets\n" KERN_INFO "  irq list (", sockets);
476     if (irq_list_count == 0)
477 	mask = irq_mask;
478     else
479 	for (i = mask = 0; i < irq_list_count; i++)
480 	    mask |= (1<<irq_list[i]);
481 
482     /* irq 14, 11, 10, 7, 6, 5, 4, 3 */
483     mask &= 0x4cf8;
484     /* Scan interrupts */
485     mask = irq_scan(mask);
486     for (i=0;i<sockets;i++)
487 	    socket_table[i].socket.irq_mask = mask;
488 
489     /* Check for only two interrupts available */
490     scan = (mask & (mask-1));
491     if (((scan & (scan-1)) == 0) && (poll_interval == 0))
492 	poll_interval = HZ;
493 
494     if (poll_interval == 0) {
495 	/* Avoid irq 12 unless it is explicitly requested */
496 	u_int cs_mask = mask & ((cs_irq) ? (1<<cs_irq) : ~(1<<12));
497 	for (i = 15; i > 0; i--)
498 	    if ((cs_mask & (1 << i)) &&
499 		(request_irq(i, tcic_interrupt, 0, "tcic",
500 			     tcic_interrupt) == 0))
501 		break;
502 	cs_irq = i;
503 	if (cs_irq == 0) poll_interval = HZ;
504     }
505 
506     if (socket_table[0].socket.irq_mask & (1 << 11))
507 	printk("sktirq is irq 11, ");
508     if (cs_irq != 0)
509 	printk("status change on irq %d\n", cs_irq);
510     else
511 	printk("polled status, interval = %d ms\n",
512 	       poll_interval * 1000 / HZ);
513 
514     for (i = 0; i < sockets; i++) {
515 	tcic_setw(TCIC_ADDR+2, socket_table[i].psock << TCIC_SS_SHFT);
516 	socket_table[i].last_sstat = tcic_getb(TCIC_SSTAT);
517     }
518 
519     /* jump start interrupt handler, if needed */
520     tcic_interrupt(0, NULL);
521 
522     platform_device_register(&tcic_device);
523 
524     for (i = 0; i < sockets; i++) {
525 	    socket_table[i].socket.ops = &tcic_operations;
526 	    socket_table[i].socket.resource_ops = &pccard_nonstatic_ops;
527 	    socket_table[i].socket.dev.parent = &tcic_device.dev;
528 	    ret = pcmcia_register_socket(&socket_table[i].socket);
529 	    if (ret && i)
530 		    pcmcia_unregister_socket(&socket_table[0].socket);
531     }
532 
533     return ret;
534 
535     return 0;
536 
537 } /* init_tcic */
538 
539 /*====================================================================*/
540 
541 static void __exit exit_tcic(void)
542 {
543     int i;
544 
545     del_timer_sync(&poll_timer);
546     if (cs_irq != 0) {
547 	tcic_aux_setw(TCIC_AUX_SYSCFG, TCIC_SYSCFG_AUTOBUSY|0x0a00);
548 	free_irq(cs_irq, tcic_interrupt);
549     }
550     release_region(tcic_base, 16);
551 
552     for (i = 0; i < sockets; i++) {
553 	    pcmcia_unregister_socket(&socket_table[i].socket);
554     }
555 
556     platform_device_unregister(&tcic_device);
557     platform_driver_unregister(&tcic_driver);
558 } /* exit_tcic */
559 
560 /*====================================================================*/
561 
562 static irqreturn_t tcic_interrupt(int irq, void *dev)
563 {
564     int i, quick = 0;
565     u_char latch, sstat;
566     u_short psock;
567     u_int events;
568     static volatile int active = 0;
569 
570     if (active) {
571 	printk(KERN_NOTICE "tcic: reentered interrupt handler!\n");
572 	return IRQ_NONE;
573     } else
574 	active = 1;
575 
576     debug(2, "tcic_interrupt()\n");
577 
578     for (i = 0; i < sockets; i++) {
579 	psock = socket_table[i].psock;
580 	tcic_setl(TCIC_ADDR, (psock << TCIC_ADDR_SS_SHFT)
581 		  | TCIC_ADDR_INDREG | TCIC_SCF1(psock));
582 	sstat = tcic_getb(TCIC_SSTAT);
583 	latch = sstat ^ socket_table[psock].last_sstat;
584 	socket_table[i].last_sstat = sstat;
585 	if (tcic_getb(TCIC_ICSR) & TCIC_ICSR_CDCHG) {
586 	    tcic_setb(TCIC_ICSR, TCIC_ICSR_CLEAR);
587 	    quick = 1;
588 	}
589 	if (latch == 0)
590 	    continue;
591 	events = (latch & TCIC_SSTAT_CD) ? SS_DETECT : 0;
592 	events |= (latch & TCIC_SSTAT_WP) ? SS_WRPROT : 0;
593 	if (tcic_getw(TCIC_DATA) & TCIC_SCF1_IOSTS) {
594 	    events |= (latch & TCIC_SSTAT_LBAT1) ? SS_STSCHG : 0;
595 	} else {
596 	    events |= (latch & TCIC_SSTAT_RDY) ? SS_READY : 0;
597 	    events |= (latch & TCIC_SSTAT_LBAT1) ? SS_BATDEAD : 0;
598 	    events |= (latch & TCIC_SSTAT_LBAT2) ? SS_BATWARN : 0;
599 	}
600 	if (events) {
601 		pcmcia_parse_events(&socket_table[i].socket, events);
602 	}
603     }
604 
605     /* Schedule next poll, if needed */
606     if (((cs_irq == 0) || quick) && (!tcic_timer_pending)) {
607 	poll_timer.expires = jiffies + (quick ? poll_quick : poll_interval);
608 	add_timer(&poll_timer);
609 	tcic_timer_pending = 1;
610     }
611     active = 0;
612 
613     debug(2, "interrupt done\n");
614     return IRQ_HANDLED;
615 } /* tcic_interrupt */
616 
617 static void tcic_timer(u_long data)
618 {
619     debug(2, "tcic_timer()\n");
620     tcic_timer_pending = 0;
621     tcic_interrupt(0, NULL);
622 } /* tcic_timer */
623 
624 /*====================================================================*/
625 
626 static int tcic_get_status(struct pcmcia_socket *sock, u_int *value)
627 {
628     u_short psock = container_of(sock, struct tcic_socket, socket)->psock;
629     u_char reg;
630 
631     tcic_setl(TCIC_ADDR, (psock << TCIC_ADDR_SS_SHFT)
632 	      | TCIC_ADDR_INDREG | TCIC_SCF1(psock));
633     reg = tcic_getb(TCIC_SSTAT);
634     *value  = (reg & TCIC_SSTAT_CD) ? SS_DETECT : 0;
635     *value |= (reg & TCIC_SSTAT_WP) ? SS_WRPROT : 0;
636     if (tcic_getw(TCIC_DATA) & TCIC_SCF1_IOSTS) {
637 	*value |= (reg & TCIC_SSTAT_LBAT1) ? SS_STSCHG : 0;
638     } else {
639 	*value |= (reg & TCIC_SSTAT_RDY) ? SS_READY : 0;
640 	*value |= (reg & TCIC_SSTAT_LBAT1) ? SS_BATDEAD : 0;
641 	*value |= (reg & TCIC_SSTAT_LBAT2) ? SS_BATWARN : 0;
642     }
643     reg = tcic_getb(TCIC_PWR);
644     if (reg & (TCIC_PWR_VCC(psock)|TCIC_PWR_VPP(psock)))
645 	*value |= SS_POWERON;
646     debug(1, "GetStatus(%d) = %#2.2x\n", psock, *value);
647     return 0;
648 } /* tcic_get_status */
649 
650 /*====================================================================*/
651 
652 static int tcic_set_socket(struct pcmcia_socket *sock, socket_state_t *state)
653 {
654     u_short psock = container_of(sock, struct tcic_socket, socket)->psock;
655     u_char reg;
656     u_short scf1, scf2;
657 
658     debug(1, "SetSocket(%d, flags %#3.3x, Vcc %d, Vpp %d, "
659 	  "io_irq %d, csc_mask %#2.2x)\n", psock, state->flags,
660 	  state->Vcc, state->Vpp, state->io_irq, state->csc_mask);
661     tcic_setw(TCIC_ADDR+2, (psock << TCIC_SS_SHFT) | TCIC_ADR2_INDREG);
662 
663     reg = tcic_getb(TCIC_PWR);
664     reg &= ~(TCIC_PWR_VCC(psock) | TCIC_PWR_VPP(psock));
665 
666     if (state->Vcc == 50) {
667 	switch (state->Vpp) {
668 	case 0:   reg |= TCIC_PWR_VCC(psock) | TCIC_PWR_VPP(psock); break;
669 	case 50:  reg |= TCIC_PWR_VCC(psock); break;
670 	case 120: reg |= TCIC_PWR_VPP(psock); break;
671 	default:  return -EINVAL;
672 	}
673     } else if (state->Vcc != 0)
674 	return -EINVAL;
675 
676     if (reg != tcic_getb(TCIC_PWR))
677 	tcic_setb(TCIC_PWR, reg);
678 
679     reg = TCIC_ILOCK_HOLD_CCLK | TCIC_ILOCK_CWAIT;
680     if (state->flags & SS_OUTPUT_ENA) {
681 	tcic_setb(TCIC_SCTRL, TCIC_SCTRL_ENA);
682 	reg |= TCIC_ILOCK_CRESENA;
683     } else
684 	tcic_setb(TCIC_SCTRL, 0);
685     if (state->flags & SS_RESET)
686 	reg |= TCIC_ILOCK_CRESET;
687     tcic_aux_setb(TCIC_AUX_ILOCK, reg);
688 
689     tcic_setw(TCIC_ADDR, TCIC_SCF1(psock));
690     scf1 = TCIC_SCF1_FINPACK;
691     scf1 |= TCIC_IRQ(state->io_irq);
692     if (state->flags & SS_IOCARD) {
693 	scf1 |= TCIC_SCF1_IOSTS;
694 	if (state->flags & SS_SPKR_ENA)
695 	    scf1 |= TCIC_SCF1_SPKR;
696 	if (state->flags & SS_DMA_MODE)
697 	    scf1 |= TCIC_SCF1_DREQ2 << TCIC_SCF1_DMA_SHIFT;
698     }
699     tcic_setw(TCIC_DATA, scf1);
700 
701     /* Some general setup stuff, and configure status interrupt */
702     reg = TCIC_WAIT_ASYNC | TCIC_WAIT_SENSE | to_cycles(250);
703     tcic_aux_setb(TCIC_AUX_WCTL, reg);
704     tcic_aux_setw(TCIC_AUX_SYSCFG, TCIC_SYSCFG_AUTOBUSY|0x0a00|
705 		  TCIC_IRQ(cs_irq));
706 
707     /* Card status change interrupt mask */
708     tcic_setw(TCIC_ADDR, TCIC_SCF2(psock));
709     scf2 = TCIC_SCF2_MALL;
710     if (state->csc_mask & SS_DETECT) scf2 &= ~TCIC_SCF2_MCD;
711     if (state->flags & SS_IOCARD) {
712 	if (state->csc_mask & SS_STSCHG) reg &= ~TCIC_SCF2_MLBAT1;
713     } else {
714 	if (state->csc_mask & SS_BATDEAD) reg &= ~TCIC_SCF2_MLBAT1;
715 	if (state->csc_mask & SS_BATWARN) reg &= ~TCIC_SCF2_MLBAT2;
716 	if (state->csc_mask & SS_READY) reg &= ~TCIC_SCF2_MRDY;
717     }
718     tcic_setw(TCIC_DATA, scf2);
719     /* For the ISA bus, the irq should be active-high totem-pole */
720     tcic_setb(TCIC_IENA, TCIC_IENA_CDCHG | TCIC_IENA_CFG_HIGH);
721 
722     return 0;
723 } /* tcic_set_socket */
724 
725 /*====================================================================*/
726 
727 static int tcic_set_io_map(struct pcmcia_socket *sock, struct pccard_io_map *io)
728 {
729     u_short psock = container_of(sock, struct tcic_socket, socket)->psock;
730     u_int addr;
731     u_short base, len, ioctl;
732 
733     debug(1, "SetIOMap(%d, %d, %#2.2x, %d ns, "
734 	  "%#x-%#x)\n", psock, io->map, io->flags,
735 	  io->speed, io->start, io->stop);
736     if ((io->map > 1) || (io->start > 0xffff) || (io->stop > 0xffff) ||
737 	(io->stop < io->start)) return -EINVAL;
738     tcic_setw(TCIC_ADDR+2, TCIC_ADR2_INDREG | (psock << TCIC_SS_SHFT));
739     addr = TCIC_IWIN(psock, io->map);
740 
741     base = io->start; len = io->stop - io->start;
742     /* Check to see that len+1 is power of two, etc */
743     if ((len & (len+1)) || (base & len)) return -EINVAL;
744     base |= (len+1)>>1;
745     tcic_setw(TCIC_ADDR, addr + TCIC_IBASE_X);
746     tcic_setw(TCIC_DATA, base);
747 
748     ioctl  = (psock << TCIC_ICTL_SS_SHFT);
749     ioctl |= (len == 0) ? TCIC_ICTL_TINY : 0;
750     ioctl |= (io->flags & MAP_ACTIVE) ? TCIC_ICTL_ENA : 0;
751     ioctl |= to_cycles(io->speed) & TCIC_ICTL_WSCNT_MASK;
752     if (!(io->flags & MAP_AUTOSZ)) {
753 	ioctl |= TCIC_ICTL_QUIET;
754 	ioctl |= (io->flags & MAP_16BIT) ? TCIC_ICTL_BW_16 : TCIC_ICTL_BW_8;
755     }
756     tcic_setw(TCIC_ADDR, addr + TCIC_ICTL_X);
757     tcic_setw(TCIC_DATA, ioctl);
758 
759     return 0;
760 } /* tcic_set_io_map */
761 
762 /*====================================================================*/
763 
764 static int tcic_set_mem_map(struct pcmcia_socket *sock, struct pccard_mem_map *mem)
765 {
766     u_short psock = container_of(sock, struct tcic_socket, socket)->psock;
767     u_short addr, ctl;
768     u_long base, len, mmap;
769 
770     debug(1, "SetMemMap(%d, %d, %#2.2x, %d ns, "
771 	  "%#llx-%#llx, %#x)\n", psock, mem->map, mem->flags,
772 	  mem->speed, (unsigned long long)mem->res->start,
773 	  (unsigned long long)mem->res->end, mem->card_start);
774     if ((mem->map > 3) || (mem->card_start > 0x3ffffff) ||
775 	(mem->res->start > 0xffffff) || (mem->res->end > 0xffffff) ||
776 	(mem->res->start > mem->res->end) || (mem->speed > 1000))
777 	return -EINVAL;
778     tcic_setw(TCIC_ADDR+2, TCIC_ADR2_INDREG | (psock << TCIC_SS_SHFT));
779     addr = TCIC_MWIN(psock, mem->map);
780 
781     base = mem->res->start; len = mem->res->end - mem->res->start;
782     if ((len & (len+1)) || (base & len)) return -EINVAL;
783     if (len == 0x0fff)
784 	base = (base >> TCIC_MBASE_HA_SHFT) | TCIC_MBASE_4K_BIT;
785     else
786 	base = (base | (len+1)>>1) >> TCIC_MBASE_HA_SHFT;
787     tcic_setw(TCIC_ADDR, addr + TCIC_MBASE_X);
788     tcic_setw(TCIC_DATA, base);
789 
790     mmap = mem->card_start - mem->res->start;
791     mmap = (mmap >> TCIC_MMAP_CA_SHFT) & TCIC_MMAP_CA_MASK;
792     if (mem->flags & MAP_ATTRIB) mmap |= TCIC_MMAP_REG;
793     tcic_setw(TCIC_ADDR, addr + TCIC_MMAP_X);
794     tcic_setw(TCIC_DATA, mmap);
795 
796     ctl  = TCIC_MCTL_QUIET | (psock << TCIC_MCTL_SS_SHFT);
797     ctl |= to_cycles(mem->speed) & TCIC_MCTL_WSCNT_MASK;
798     ctl |= (mem->flags & MAP_16BIT) ? 0 : TCIC_MCTL_B8;
799     ctl |= (mem->flags & MAP_WRPROT) ? TCIC_MCTL_WP : 0;
800     ctl |= (mem->flags & MAP_ACTIVE) ? TCIC_MCTL_ENA : 0;
801     tcic_setw(TCIC_ADDR, addr + TCIC_MCTL_X);
802     tcic_setw(TCIC_DATA, ctl);
803 
804     return 0;
805 } /* tcic_set_mem_map */
806 
807 /*====================================================================*/
808 
809 static int tcic_init(struct pcmcia_socket *s)
810 {
811 	int i;
812 	struct resource res = { .start = 0, .end = 0x1000 };
813 	pccard_io_map io = { 0, 0, 0, 0, 1 };
814 	pccard_mem_map mem = { .res = &res, };
815 
816 	for (i = 0; i < 2; i++) {
817 		io.map = i;
818 		tcic_set_io_map(s, &io);
819 	}
820 	for (i = 0; i < 5; i++) {
821 		mem.map = i;
822 		tcic_set_mem_map(s, &mem);
823 	}
824 	return 0;
825 }
826 
827 static struct pccard_operations tcic_operations = {
828 	.init		   = tcic_init,
829 	.get_status	   = tcic_get_status,
830 	.set_socket	   = tcic_set_socket,
831 	.set_io_map	   = tcic_set_io_map,
832 	.set_mem_map	   = tcic_set_mem_map,
833 };
834 
835 /*====================================================================*/
836 
837 module_init(init_tcic);
838 module_exit(exit_tcic);
839