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