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