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