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