MOXA linux-2.6.x / linux-2.6.9-uc0 from sdlinux-moxaart.tgz
[linux-2.6.9-moxart.git] / drivers / pcmcia / tcic.c
blobd986d13f288bb1b3df2d3e87ef1ffb69867c30f7
1 /*======================================================================
3 Device driver for Databook TCIC-2 PCMCIA controller
5 tcic.c 1.111 2000/02/15 04:13:12
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/
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.
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.
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.
32 ======================================================================*/
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/device.h>
49 #include <asm/io.h>
50 #include <asm/bitops.h>
51 #include <asm/system.h>
53 #include <pcmcia/version.h>
54 #include <pcmcia/cs_types.h>
55 #include <pcmcia/cs.h>
56 #include <pcmcia/ss.h>
57 #include "tcic.h"
59 #ifdef DEBUG
60 static int pc_debug;
62 module_param(pc_debug, int, 0644);
63 static const char version[] =
64 "tcic.c 1.111 2000/02/15 04:13:12 (David Hinds)";
66 #define debug(lvl, fmt, arg...) do { \
67 if (pc_debug > (lvl)) \
68 printk(KERN_DEBUG "tcic: " fmt , ## arg); \
69 } while (0)
70 #else
71 #define debug(lvl, fmt, arg...) do { } while (0)
72 #endif
74 MODULE_AUTHOR("David Hinds <dahinds@users.sourceforge.net>");
75 MODULE_DESCRIPTION("Databook TCIC-2 PCMCIA socket driver");
76 MODULE_LICENSE("Dual MPL/GPL");
78 /*====================================================================*/
80 /* Parameters that can be set with 'insmod' */
82 /* The base port address of the TCIC-2 chip */
83 static int tcic_base = TCIC_BASE;
85 /* Specify a socket number to ignore */
86 static int ignore = -1;
88 /* Probe for safe interrupts? */
89 static int do_scan = 1;
91 /* Bit map of interrupts to choose from */
92 static u_int irq_mask = 0xffff;
93 static int irq_list[16];
94 static int irq_list_count;
96 /* The card status change interrupt -- 0 means autoselect */
97 static int cs_irq;
99 /* Poll status interval -- 0 means default to interrupt */
100 static int poll_interval;
102 /* Delay for card status double-checking */
103 static int poll_quick = HZ/20;
105 /* CCLK external clock time, in nanoseconds. 70 ns = 14.31818 MHz */
106 static int cycle_time = 70;
108 module_param(tcic_base, int, 0444);
109 module_param(ignore, int, 0444);
110 module_param(do_scan, int, 0444);
111 module_param(irq_mask, int, 0444);
112 module_param_array(irq_list, int, irq_list_count, 0444);
113 module_param(cs_irq, int, 0444);
114 module_param(poll_interval, int, 0444);
115 module_param(poll_quick, int, 0444);
116 module_param(cycle_time, int, 0444);
118 /*====================================================================*/
120 static irqreturn_t tcic_interrupt(int irq, void *dev, struct pt_regs *regs);
121 static void tcic_timer(u_long data);
122 static struct pccard_operations tcic_operations;
124 struct tcic_socket {
125 u_short psock;
126 u_char last_sstat;
127 u_char id;
128 struct pcmcia_socket socket;
131 static struct timer_list poll_timer;
132 static int tcic_timer_pending;
134 static int sockets;
135 static struct tcic_socket socket_table[2];
137 /*====================================================================*/
139 /* Trick when selecting interrupts: the TCIC sktirq pin is supposed
140 to map to irq 11, but is coded as 0 or 1 in the irq registers. */
141 #define TCIC_IRQ(x) ((x) ? (((x) == 11) ? 1 : (x)) : 15)
143 #ifdef DEBUG_X
144 static u_char tcic_getb(u_char reg)
146 u_char val = inb(tcic_base+reg);
147 printk(KERN_DEBUG "tcic_getb(%#x) = %#x\n", tcic_base+reg, val);
148 return val;
151 static u_short tcic_getw(u_char reg)
153 u_short val = inw(tcic_base+reg);
154 printk(KERN_DEBUG "tcic_getw(%#x) = %#x\n", tcic_base+reg, val);
155 return val;
158 static void tcic_setb(u_char reg, u_char data)
160 printk(KERN_DEBUG "tcic_setb(%#x, %#x)\n", tcic_base+reg, data);
161 outb(data, tcic_base+reg);
164 static void tcic_setw(u_char reg, u_short data)
166 printk(KERN_DEBUG "tcic_setw(%#x, %#x)\n", tcic_base+reg, data);
167 outw(data, tcic_base+reg);
169 #else
170 #define tcic_getb(reg) inb(tcic_base+reg)
171 #define tcic_getw(reg) inw(tcic_base+reg)
172 #define tcic_setb(reg, data) outb(data, tcic_base+reg)
173 #define tcic_setw(reg, data) outw(data, tcic_base+reg)
174 #endif
176 static void tcic_setl(u_char reg, u_int data)
178 #ifdef DEBUG_X
179 printk(KERN_DEBUG "tcic_setl(%#x, %#lx)\n", tcic_base+reg, data);
180 #endif
181 outw(data & 0xffff, tcic_base+reg);
182 outw(data >> 16, tcic_base+reg+2);
185 static u_char tcic_aux_getb(u_short reg)
187 u_char mode = (tcic_getb(TCIC_MODE) & TCIC_MODE_PGMMASK) | reg;
188 tcic_setb(TCIC_MODE, mode);
189 return tcic_getb(TCIC_AUX);
192 static void tcic_aux_setb(u_short reg, u_char data)
194 u_char mode = (tcic_getb(TCIC_MODE) & TCIC_MODE_PGMMASK) | reg;
195 tcic_setb(TCIC_MODE, mode);
196 tcic_setb(TCIC_AUX, data);
199 static u_short tcic_aux_getw(u_short reg)
201 u_char mode = (tcic_getb(TCIC_MODE) & TCIC_MODE_PGMMASK) | reg;
202 tcic_setb(TCIC_MODE, mode);
203 return tcic_getw(TCIC_AUX);
206 static void tcic_aux_setw(u_short reg, u_short data)
208 u_char mode = (tcic_getb(TCIC_MODE) & TCIC_MODE_PGMMASK) | reg;
209 tcic_setb(TCIC_MODE, mode);
210 tcic_setw(TCIC_AUX, data);
213 /*====================================================================*/
215 /* Time conversion functions */
217 static int to_cycles(int ns)
219 if (ns < 14)
220 return 0;
221 else
222 return 2*(ns-14)/cycle_time;
225 /*====================================================================*/
227 static volatile u_int irq_hits;
229 static irqreturn_t __init tcic_irq_count(int irq, void *dev, struct pt_regs *regs)
231 irq_hits++;
232 return IRQ_HANDLED;
235 static u_int __init try_irq(int irq)
237 u_short cfg;
239 irq_hits = 0;
240 if (request_irq(irq, tcic_irq_count, 0, "irq scan", tcic_irq_count) != 0)
241 return -1;
242 mdelay(10);
243 if (irq_hits) {
244 free_irq(irq, tcic_irq_count);
245 return -1;
248 /* Generate one interrupt */
249 cfg = TCIC_SYSCFG_AUTOBUSY | 0x0a00;
250 tcic_aux_setw(TCIC_AUX_SYSCFG, cfg | TCIC_IRQ(irq));
251 tcic_setb(TCIC_IENA, TCIC_IENA_ERR | TCIC_IENA_CFG_HIGH);
252 tcic_setb(TCIC_ICSR, TCIC_ICSR_ERR | TCIC_ICSR_JAM);
254 udelay(1000);
255 free_irq(irq, tcic_irq_count);
257 /* Turn off interrupts */
258 tcic_setb(TCIC_IENA, TCIC_IENA_CFG_OFF);
259 while (tcic_getb(TCIC_ICSR))
260 tcic_setb(TCIC_ICSR, TCIC_ICSR_JAM);
261 tcic_aux_setw(TCIC_AUX_SYSCFG, cfg);
263 return (irq_hits != 1);
266 static u_int __init irq_scan(u_int mask0)
268 u_int mask1;
269 int i;
271 #ifdef __alpha__
272 #define PIC 0x4d0
273 /* Don't probe level-triggered interrupts -- reserved for PCI */
274 int level_mask = inb_p(PIC) | (inb_p(PIC+1) << 8);
275 if (level_mask)
276 mask0 &= ~level_mask;
277 #endif
279 mask1 = 0;
280 if (do_scan) {
281 for (i = 0; i < 16; i++)
282 if ((mask0 & (1 << i)) && (try_irq(i) == 0))
283 mask1 |= (1 << i);
284 for (i = 0; i < 16; i++)
285 if ((mask1 & (1 << i)) && (try_irq(i) != 0)) {
286 mask1 ^= (1 << i);
290 if (mask1) {
291 printk("scanned");
292 } else {
293 /* Fallback: just find interrupts that aren't in use */
294 for (i = 0; i < 16; i++)
295 if ((mask0 & (1 << i)) &&
296 (request_irq(i, tcic_irq_count, 0, "x", tcic_irq_count) == 0)) {
297 mask1 |= (1 << i);
298 free_irq(i, tcic_irq_count);
300 printk("default");
303 printk(") = ");
304 for (i = 0; i < 16; i++)
305 if (mask1 & (1<<i))
306 printk("%s%d", ((mask1 & ((1<<i)-1)) ? "," : ""), i);
307 printk(" ");
309 return mask1;
312 /*======================================================================
314 See if a card is present, powered up, in IO mode, and already
315 bound to a (non-PCMCIA) Linux driver.
317 We make an exception for cards that look like serial devices.
319 ======================================================================*/
321 static int __init is_active(int s)
323 u_short scf1, ioctl, base, num;
324 u_char pwr, sstat;
325 u_int addr;
327 tcic_setl(TCIC_ADDR, (s << TCIC_ADDR_SS_SHFT)
328 | TCIC_ADDR_INDREG | TCIC_SCF1(s));
329 scf1 = tcic_getw(TCIC_DATA);
330 pwr = tcic_getb(TCIC_PWR);
331 sstat = tcic_getb(TCIC_SSTAT);
332 addr = TCIC_IWIN(s, 0);
333 tcic_setw(TCIC_ADDR, addr + TCIC_IBASE_X);
334 base = tcic_getw(TCIC_DATA);
335 tcic_setw(TCIC_ADDR, addr + TCIC_ICTL_X);
336 ioctl = tcic_getw(TCIC_DATA);
338 if (ioctl & TCIC_ICTL_TINY)
339 num = 1;
340 else {
341 num = (base ^ (base-1));
342 base = base & (base-1);
345 if ((sstat & TCIC_SSTAT_CD) && (pwr & TCIC_PWR_VCC(s)) &&
346 (scf1 & TCIC_SCF1_IOSTS) && (ioctl & TCIC_ICTL_ENA) &&
347 (check_region(base, num) != 0) && ((base & 0xfeef) != 0x02e8))
348 return 1;
349 else
350 return 0;
353 /*======================================================================
355 This returns the revision code for the specified socket.
357 ======================================================================*/
359 static int __init get_tcic_id(void)
361 u_short id;
363 tcic_aux_setw(TCIC_AUX_TEST, TCIC_TEST_DIAG);
364 id = tcic_aux_getw(TCIC_AUX_ILOCK);
365 id = (id & TCIC_ILOCKTEST_ID_MASK) >> TCIC_ILOCKTEST_ID_SH;
366 tcic_aux_setw(TCIC_AUX_TEST, 0);
367 return id;
370 /*====================================================================*/
372 static int tcic_drv_suspend(struct device *dev, u32 state, u32 level)
374 int ret = 0;
375 if (level == SUSPEND_SAVE_STATE)
376 ret = pcmcia_socket_dev_suspend(dev, state);
377 return ret;
380 static int tcic_drv_resume(struct device *dev, u32 level)
382 int ret = 0;
383 if (level == RESUME_RESTORE_STATE)
384 ret = pcmcia_socket_dev_resume(dev);
385 return ret;
388 static struct device_driver tcic_driver = {
389 .name = "tcic-pcmcia",
390 .bus = &platform_bus_type,
391 .suspend = tcic_drv_suspend,
392 .resume = tcic_drv_resume,
395 static struct platform_device tcic_device = {
396 .name = "tcic-pcmcia",
397 .id = 0,
401 static int __init init_tcic(void)
403 int i, sock, ret = 0;
404 u_int mask, scan;
406 if (driver_register(&tcic_driver))
407 return -1;
409 printk(KERN_INFO "Databook TCIC-2 PCMCIA probe: ");
410 sock = 0;
412 if (!request_region(tcic_base, 16, "tcic-2")) {
413 printk("could not allocate ports,\n ");
414 driver_unregister(&tcic_driver);
415 return -ENODEV;
417 else {
418 tcic_setw(TCIC_ADDR, 0);
419 if (tcic_getw(TCIC_ADDR) == 0) {
420 tcic_setw(TCIC_ADDR, 0xc3a5);
421 if (tcic_getw(TCIC_ADDR) == 0xc3a5) sock = 2;
423 if (sock == 0) {
424 /* See if resetting the controller does any good */
425 tcic_setb(TCIC_SCTRL, TCIC_SCTRL_RESET);
426 tcic_setb(TCIC_SCTRL, 0);
427 tcic_setw(TCIC_ADDR, 0);
428 if (tcic_getw(TCIC_ADDR) == 0) {
429 tcic_setw(TCIC_ADDR, 0xc3a5);
430 if (tcic_getw(TCIC_ADDR) == 0xc3a5) sock = 2;
434 if (sock == 0) {
435 printk("not found.\n");
436 release_region(tcic_base, 16);
437 driver_unregister(&tcic_driver);
438 return -ENODEV;
441 sockets = 0;
442 for (i = 0; i < sock; i++) {
443 if ((i == ignore) || is_active(i)) continue;
444 socket_table[sockets].psock = i;
445 socket_table[sockets].id = get_tcic_id();
447 socket_table[sockets].socket.owner = THIS_MODULE;
448 /* only 16-bit cards, memory windows must be size-aligned */
449 /* No PCI or CardBus support */
450 socket_table[sockets].socket.features = SS_CAP_PCCARD | SS_CAP_MEM_ALIGN;
451 /* irq 14, 11, 10, 7, 6, 5, 4, 3 */
452 socket_table[sockets].socket.irq_mask = 0x4cf8;
453 /* 4K minimum window size */
454 socket_table[sockets].socket.map_size = 0x1000;
455 sockets++;
458 switch (socket_table[0].id) {
459 case TCIC_ID_DB86082:
460 printk("DB86082"); break;
461 case TCIC_ID_DB86082A:
462 printk("DB86082A"); break;
463 case TCIC_ID_DB86084:
464 printk("DB86084"); break;
465 case TCIC_ID_DB86084A:
466 printk("DB86084A"); break;
467 case TCIC_ID_DB86072:
468 printk("DB86072"); break;
469 case TCIC_ID_DB86184:
470 printk("DB86184"); break;
471 case TCIC_ID_DB86082B:
472 printk("DB86082B"); break;
473 default:
474 printk("Unknown ID 0x%02x", socket_table[0].id);
477 /* Set up polling */
478 poll_timer.function = &tcic_timer;
479 poll_timer.data = 0;
480 init_timer(&poll_timer);
482 /* Build interrupt mask */
483 printk(", %d sockets\n" KERN_INFO " irq list (", sockets);
484 if (irq_list_count == 0)
485 mask = irq_mask;
486 else
487 for (i = mask = 0; i < irq_list_count; i++)
488 mask |= (1<<irq_list[i]);
490 /* irq 14, 11, 10, 7, 6, 5, 4, 3 */
491 mask &= 0x4cf8;
492 /* Scan interrupts */
493 mask = irq_scan(mask);
494 for (i=0;i<sockets;i++)
495 socket_table[i].socket.irq_mask = mask;
497 /* Check for only two interrupts available */
498 scan = (mask & (mask-1));
499 if (((scan & (scan-1)) == 0) && (poll_interval == 0))
500 poll_interval = HZ;
502 if (poll_interval == 0) {
503 /* Avoid irq 12 unless it is explicitly requested */
504 u_int cs_mask = mask & ((cs_irq) ? (1<<cs_irq) : ~(1<<12));
505 for (i = 15; i > 0; i--)
506 if ((cs_mask & (1 << i)) &&
507 (request_irq(i, tcic_interrupt, 0, "tcic",
508 tcic_interrupt) == 0))
509 break;
510 cs_irq = i;
511 if (cs_irq == 0) poll_interval = HZ;
514 if (socket_table[0].socket.irq_mask & (1 << 11))
515 printk("sktirq is irq 11, ");
516 if (cs_irq != 0)
517 printk("status change on irq %d\n", cs_irq);
518 else
519 printk("polled status, interval = %d ms\n",
520 poll_interval * 1000 / HZ);
522 for (i = 0; i < sockets; i++) {
523 tcic_setw(TCIC_ADDR+2, socket_table[i].psock << TCIC_SS_SHFT);
524 socket_table[i].last_sstat = tcic_getb(TCIC_SSTAT);
527 /* jump start interrupt handler, if needed */
528 tcic_interrupt(0, NULL, NULL);
530 platform_device_register(&tcic_device);
532 for (i = 0; i < sockets; i++) {
533 socket_table[i].socket.ops = &tcic_operations;
534 socket_table[i].socket.dev.dev = &tcic_device.dev;
535 ret = pcmcia_register_socket(&socket_table[i].socket);
536 if (ret && i)
537 pcmcia_unregister_socket(&socket_table[0].socket);
540 return ret;
542 return 0;
544 } /* init_tcic */
546 /*====================================================================*/
548 static void __exit exit_tcic(void)
550 int i;
552 del_timer_sync(&poll_timer);
553 if (cs_irq != 0) {
554 tcic_aux_setw(TCIC_AUX_SYSCFG, TCIC_SYSCFG_AUTOBUSY|0x0a00);
555 free_irq(cs_irq, tcic_interrupt);
557 release_region(tcic_base, 16);
559 for (i = 0; i < sockets; i++) {
560 pcmcia_unregister_socket(&socket_table[i].socket);
563 platform_device_unregister(&tcic_device);
564 driver_unregister(&tcic_driver);
565 } /* exit_tcic */
567 /*====================================================================*/
569 static irqreturn_t tcic_interrupt(int irq, void *dev, struct pt_regs *regs)
571 int i, quick = 0;
572 u_char latch, sstat;
573 u_short psock;
574 u_int events;
575 static volatile int active = 0;
577 if (active) {
578 printk(KERN_NOTICE "tcic: reentered interrupt handler!\n");
579 return IRQ_NONE;
580 } else
581 active = 1;
583 debug(2, "tcic_interrupt()\n");
585 for (i = 0; i < sockets; i++) {
586 psock = socket_table[i].psock;
587 tcic_setl(TCIC_ADDR, (psock << TCIC_ADDR_SS_SHFT)
588 | TCIC_ADDR_INDREG | TCIC_SCF1(psock));
589 sstat = tcic_getb(TCIC_SSTAT);
590 latch = sstat ^ socket_table[psock].last_sstat;
591 socket_table[i].last_sstat = sstat;
592 if (tcic_getb(TCIC_ICSR) & TCIC_ICSR_CDCHG) {
593 tcic_setb(TCIC_ICSR, TCIC_ICSR_CLEAR);
594 quick = 1;
596 if (latch == 0)
597 continue;
598 events = (latch & TCIC_SSTAT_CD) ? SS_DETECT : 0;
599 events |= (latch & TCIC_SSTAT_WP) ? SS_WRPROT : 0;
600 if (tcic_getw(TCIC_DATA) & TCIC_SCF1_IOSTS) {
601 events |= (latch & TCIC_SSTAT_LBAT1) ? SS_STSCHG : 0;
602 } else {
603 events |= (latch & TCIC_SSTAT_RDY) ? SS_READY : 0;
604 events |= (latch & TCIC_SSTAT_LBAT1) ? SS_BATDEAD : 0;
605 events |= (latch & TCIC_SSTAT_LBAT2) ? SS_BATWARN : 0;
607 if (events) {
608 pcmcia_parse_events(&socket_table[i].socket, events);
612 /* Schedule next poll, if needed */
613 if (((cs_irq == 0) || quick) && (!tcic_timer_pending)) {
614 poll_timer.expires = jiffies + (quick ? poll_quick : poll_interval);
615 add_timer(&poll_timer);
616 tcic_timer_pending = 1;
618 active = 0;
620 debug(2, "interrupt done\n");
621 return IRQ_HANDLED;
622 } /* tcic_interrupt */
624 static void tcic_timer(u_long data)
626 debug(2, "tcic_timer()\n");
627 tcic_timer_pending = 0;
628 tcic_interrupt(0, NULL, NULL);
629 } /* tcic_timer */
631 /*====================================================================*/
633 static int tcic_get_status(struct pcmcia_socket *sock, u_int *value)
635 u_short psock = container_of(sock, struct tcic_socket, socket)->psock;
636 u_char reg;
638 tcic_setl(TCIC_ADDR, (psock << TCIC_ADDR_SS_SHFT)
639 | TCIC_ADDR_INDREG | TCIC_SCF1(psock));
640 reg = tcic_getb(TCIC_SSTAT);
641 *value = (reg & TCIC_SSTAT_CD) ? SS_DETECT : 0;
642 *value |= (reg & TCIC_SSTAT_WP) ? SS_WRPROT : 0;
643 if (tcic_getw(TCIC_DATA) & TCIC_SCF1_IOSTS) {
644 *value |= (reg & TCIC_SSTAT_LBAT1) ? SS_STSCHG : 0;
645 } else {
646 *value |= (reg & TCIC_SSTAT_RDY) ? SS_READY : 0;
647 *value |= (reg & TCIC_SSTAT_LBAT1) ? SS_BATDEAD : 0;
648 *value |= (reg & TCIC_SSTAT_LBAT2) ? SS_BATWARN : 0;
650 reg = tcic_getb(TCIC_PWR);
651 if (reg & (TCIC_PWR_VCC(psock)|TCIC_PWR_VPP(psock)))
652 *value |= SS_POWERON;
653 debug(1, "GetStatus(%d) = %#2.2x\n", psock, *value);
654 return 0;
655 } /* tcic_get_status */
657 /*====================================================================*/
659 static int tcic_get_socket(struct pcmcia_socket *sock, socket_state_t *state)
661 u_short psock = container_of(sock, struct tcic_socket, socket)->psock;
662 u_char reg;
663 u_short scf1, scf2;
665 tcic_setl(TCIC_ADDR, (psock << TCIC_ADDR_SS_SHFT)
666 | TCIC_ADDR_INDREG | TCIC_SCF1(psock));
667 scf1 = tcic_getw(TCIC_DATA);
668 state->flags = (scf1 & TCIC_SCF1_IOSTS) ? SS_IOCARD : 0;
669 state->flags |= (scf1 & TCIC_SCF1_DMA_MASK) ? SS_DMA_MODE : 0;
670 state->flags |= (scf1 & TCIC_SCF1_SPKR) ? SS_SPKR_ENA : 0;
671 if (tcic_getb(TCIC_SCTRL) & TCIC_SCTRL_ENA)
672 state->flags |= SS_OUTPUT_ENA;
673 state->io_irq = scf1 & TCIC_SCF1_IRQ_MASK;
674 if (state->io_irq == 1) state->io_irq = 11;
676 reg = tcic_getb(TCIC_PWR);
677 state->Vcc = state->Vpp = 0;
678 if (reg & TCIC_PWR_VCC(psock)) {
679 if (reg & TCIC_PWR_VPP(psock))
680 state->Vcc = 50;
681 else
682 state->Vcc = state->Vpp = 50;
683 } else {
684 if (reg & TCIC_PWR_VPP(psock)) {
685 state->Vcc = 50;
686 state->Vpp = 120;
689 reg = tcic_aux_getb(TCIC_AUX_ILOCK);
690 state->flags |= (reg & TCIC_ILOCK_CRESET) ? SS_RESET : 0;
692 /* Card status change interrupt mask */
693 tcic_setw(TCIC_ADDR, TCIC_SCF2(psock));
694 scf2 = tcic_getw(TCIC_DATA);
695 state->csc_mask = (scf2 & TCIC_SCF2_MCD) ? 0 : SS_DETECT;
696 if (state->flags & SS_IOCARD) {
697 state->csc_mask |= (scf2 & TCIC_SCF2_MLBAT1) ? 0 : SS_STSCHG;
698 } else {
699 state->csc_mask |= (scf2 & TCIC_SCF2_MLBAT1) ? 0 : SS_BATDEAD;
700 state->csc_mask |= (scf2 & TCIC_SCF2_MLBAT2) ? 0 : SS_BATWARN;
701 state->csc_mask |= (scf2 & TCIC_SCF2_MRDY) ? 0 : SS_READY;
704 debug(1, "GetSocket(%d) = flags %#3.3x, Vcc %d, Vpp %d, "
705 "io_irq %d, csc_mask %#2.2x\n", psock, state->flags,
706 state->Vcc, state->Vpp, state->io_irq, state->csc_mask);
707 return 0;
708 } /* tcic_get_socket */
710 /*====================================================================*/
712 static int tcic_set_socket(struct pcmcia_socket *sock, socket_state_t *state)
714 u_short psock = container_of(sock, struct tcic_socket, socket)->psock;
715 u_char reg;
716 u_short scf1, scf2;
718 debug(1, "SetSocket(%d, flags %#3.3x, Vcc %d, Vpp %d, "
719 "io_irq %d, csc_mask %#2.2x)\n", psock, state->flags,
720 state->Vcc, state->Vpp, state->io_irq, state->csc_mask);
721 tcic_setw(TCIC_ADDR+2, (psock << TCIC_SS_SHFT) | TCIC_ADR2_INDREG);
723 reg = tcic_getb(TCIC_PWR);
724 reg &= ~(TCIC_PWR_VCC(psock) | TCIC_PWR_VPP(psock));
726 if (state->Vcc == 50) {
727 switch (state->Vpp) {
728 case 0: reg |= TCIC_PWR_VCC(psock) | TCIC_PWR_VPP(psock); break;
729 case 50: reg |= TCIC_PWR_VCC(psock); break;
730 case 120: reg |= TCIC_PWR_VPP(psock); break;
731 default: return -EINVAL;
733 } else if (state->Vcc != 0)
734 return -EINVAL;
736 if (reg != tcic_getb(TCIC_PWR))
737 tcic_setb(TCIC_PWR, reg);
739 reg = TCIC_ILOCK_HOLD_CCLK | TCIC_ILOCK_CWAIT;
740 if (state->flags & SS_OUTPUT_ENA) {
741 tcic_setb(TCIC_SCTRL, TCIC_SCTRL_ENA);
742 reg |= TCIC_ILOCK_CRESENA;
743 } else
744 tcic_setb(TCIC_SCTRL, 0);
745 if (state->flags & SS_RESET)
746 reg |= TCIC_ILOCK_CRESET;
747 tcic_aux_setb(TCIC_AUX_ILOCK, reg);
749 tcic_setw(TCIC_ADDR, TCIC_SCF1(psock));
750 scf1 = TCIC_SCF1_FINPACK;
751 scf1 |= TCIC_IRQ(state->io_irq);
752 if (state->flags & SS_IOCARD) {
753 scf1 |= TCIC_SCF1_IOSTS;
754 if (state->flags & SS_SPKR_ENA)
755 scf1 |= TCIC_SCF1_SPKR;
756 if (state->flags & SS_DMA_MODE)
757 scf1 |= TCIC_SCF1_DREQ2 << TCIC_SCF1_DMA_SHIFT;
759 tcic_setw(TCIC_DATA, scf1);
761 /* Some general setup stuff, and configure status interrupt */
762 reg = TCIC_WAIT_ASYNC | TCIC_WAIT_SENSE | to_cycles(250);
763 tcic_aux_setb(TCIC_AUX_WCTL, reg);
764 tcic_aux_setw(TCIC_AUX_SYSCFG, TCIC_SYSCFG_AUTOBUSY|0x0a00|
765 TCIC_IRQ(cs_irq));
767 /* Card status change interrupt mask */
768 tcic_setw(TCIC_ADDR, TCIC_SCF2(psock));
769 scf2 = TCIC_SCF2_MALL;
770 if (state->csc_mask & SS_DETECT) scf2 &= ~TCIC_SCF2_MCD;
771 if (state->flags & SS_IOCARD) {
772 if (state->csc_mask & SS_STSCHG) reg &= ~TCIC_SCF2_MLBAT1;
773 } else {
774 if (state->csc_mask & SS_BATDEAD) reg &= ~TCIC_SCF2_MLBAT1;
775 if (state->csc_mask & SS_BATWARN) reg &= ~TCIC_SCF2_MLBAT2;
776 if (state->csc_mask & SS_READY) reg &= ~TCIC_SCF2_MRDY;
778 tcic_setw(TCIC_DATA, scf2);
779 /* For the ISA bus, the irq should be active-high totem-pole */
780 tcic_setb(TCIC_IENA, TCIC_IENA_CDCHG | TCIC_IENA_CFG_HIGH);
782 return 0;
783 } /* tcic_set_socket */
785 /*====================================================================*/
787 static int tcic_set_io_map(struct pcmcia_socket *sock, struct pccard_io_map *io)
789 u_short psock = container_of(sock, struct tcic_socket, socket)->psock;
790 u_int addr;
791 u_short base, len, ioctl;
793 debug(1, "SetIOMap(%d, %d, %#2.2x, %d ns, "
794 "%#4.4x-%#4.4x)\n", psock, io->map, io->flags,
795 io->speed, io->start, io->stop);
796 if ((io->map > 1) || (io->start > 0xffff) || (io->stop > 0xffff) ||
797 (io->stop < io->start)) return -EINVAL;
798 tcic_setw(TCIC_ADDR+2, TCIC_ADR2_INDREG | (psock << TCIC_SS_SHFT));
799 addr = TCIC_IWIN(psock, io->map);
801 base = io->start; len = io->stop - io->start;
802 /* Check to see that len+1 is power of two, etc */
803 if ((len & (len+1)) || (base & len)) return -EINVAL;
804 base |= (len+1)>>1;
805 tcic_setw(TCIC_ADDR, addr + TCIC_IBASE_X);
806 tcic_setw(TCIC_DATA, base);
808 ioctl = (psock << TCIC_ICTL_SS_SHFT);
809 ioctl |= (len == 0) ? TCIC_ICTL_TINY : 0;
810 ioctl |= (io->flags & MAP_ACTIVE) ? TCIC_ICTL_ENA : 0;
811 ioctl |= to_cycles(io->speed) & TCIC_ICTL_WSCNT_MASK;
812 if (!(io->flags & MAP_AUTOSZ)) {
813 ioctl |= TCIC_ICTL_QUIET;
814 ioctl |= (io->flags & MAP_16BIT) ? TCIC_ICTL_BW_16 : TCIC_ICTL_BW_8;
816 tcic_setw(TCIC_ADDR, addr + TCIC_ICTL_X);
817 tcic_setw(TCIC_DATA, ioctl);
819 return 0;
820 } /* tcic_set_io_map */
822 /*====================================================================*/
824 static int tcic_set_mem_map(struct pcmcia_socket *sock, struct pccard_mem_map *mem)
826 u_short psock = container_of(sock, struct tcic_socket, socket)->psock;
827 u_short addr, ctl;
828 u_long base, len, mmap;
830 debug(1, "SetMemMap(%d, %d, %#2.2x, %d ns, "
831 "%#5.5lx-%#5.5lx, %#5.5x)\n", psock, mem->map, mem->flags,
832 mem->speed, mem->res->start, mem->res->end, mem->card_start);
833 if ((mem->map > 3) || (mem->card_start > 0x3ffffff) ||
834 (mem->res->start > 0xffffff) || (mem->res->end > 0xffffff) ||
835 (mem->res->start > mem->res->end) || (mem->speed > 1000))
836 return -EINVAL;
837 tcic_setw(TCIC_ADDR+2, TCIC_ADR2_INDREG | (psock << TCIC_SS_SHFT));
838 addr = TCIC_MWIN(psock, mem->map);
840 base = mem->res->start; len = mem->res->end - mem->res->start;
841 if ((len & (len+1)) || (base & len)) return -EINVAL;
842 if (len == 0x0fff)
843 base = (base >> TCIC_MBASE_HA_SHFT) | TCIC_MBASE_4K_BIT;
844 else
845 base = (base | (len+1)>>1) >> TCIC_MBASE_HA_SHFT;
846 tcic_setw(TCIC_ADDR, addr + TCIC_MBASE_X);
847 tcic_setw(TCIC_DATA, base);
849 mmap = mem->card_start - mem->res->start;
850 mmap = (mmap >> TCIC_MMAP_CA_SHFT) & TCIC_MMAP_CA_MASK;
851 if (mem->flags & MAP_ATTRIB) mmap |= TCIC_MMAP_REG;
852 tcic_setw(TCIC_ADDR, addr + TCIC_MMAP_X);
853 tcic_setw(TCIC_DATA, mmap);
855 ctl = TCIC_MCTL_QUIET | (psock << TCIC_MCTL_SS_SHFT);
856 ctl |= to_cycles(mem->speed) & TCIC_MCTL_WSCNT_MASK;
857 ctl |= (mem->flags & MAP_16BIT) ? 0 : TCIC_MCTL_B8;
858 ctl |= (mem->flags & MAP_WRPROT) ? TCIC_MCTL_WP : 0;
859 ctl |= (mem->flags & MAP_ACTIVE) ? TCIC_MCTL_ENA : 0;
860 tcic_setw(TCIC_ADDR, addr + TCIC_MCTL_X);
861 tcic_setw(TCIC_DATA, ctl);
863 return 0;
864 } /* tcic_set_mem_map */
866 /*====================================================================*/
868 static int tcic_init(struct pcmcia_socket *s)
870 int i;
871 struct resource res = { .start = 0, .end = 0x1000 };
872 pccard_io_map io = { 0, 0, 0, 0, 1 };
873 pccard_mem_map mem = { .res = &res, };
875 for (i = 0; i < 2; i++) {
876 io.map = i;
877 tcic_set_io_map(s, &io);
879 for (i = 0; i < 5; i++) {
880 mem.map = i;
881 tcic_set_mem_map(s, &mem);
883 return 0;
886 static int tcic_suspend(struct pcmcia_socket *sock)
888 return tcic_set_socket(sock, &dead_socket);
891 static struct pccard_operations tcic_operations = {
892 .init = tcic_init,
893 .suspend = tcic_suspend,
894 .get_status = tcic_get_status,
895 .get_socket = tcic_get_socket,
896 .set_socket = tcic_set_socket,
897 .set_io_map = tcic_set_io_map,
898 .set_mem_map = tcic_set_mem_map,
901 /*====================================================================*/
903 module_init(init_tcic);
904 module_exit(exit_tcic);