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>
48 #include <linux/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>
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); \
71 #define debug(lvl, fmt, arg...) do { } while (0)
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 */
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;
128 struct pcmcia_socket socket;
131 static struct timer_list poll_timer;
132 static int tcic_timer_pending;
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)
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);
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);
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);
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)
176 static void tcic_setl(u_char reg, u_int data)
179 printk(KERN_DEBUG "tcic_setl(%#x, %#lx)\n", tcic_base+reg, data);
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)
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)
235 static u_int __init try_irq(int irq)
240 if (request_irq(irq, tcic_irq_count, 0, "irq scan", tcic_irq_count) != 0)
244 free_irq(irq, tcic_irq_count);
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);
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)
273 /* Don't probe level-triggered interrupts -- reserved for PCI */
274 int level_mask = inb_p(PIC) | (inb_p(PIC+1) << 8);
276 mask0 &= ~level_mask;
281 for (i = 0; i < 16; i++)
282 if ((mask0 & (1 << i)) && (try_irq(i) == 0))
284 for (i = 0; i < 16; i++)
285 if ((mask1 & (1 << i)) && (try_irq(i) != 0)) {
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)) {
298 free_irq(i, tcic_irq_count);
304 for (i = 0; i < 16; i++)
306 printk("%s%d", ((mask1 & ((1<<i)-1)) ? "," : ""), i);
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;
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)
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))
353 /*======================================================================
355 This returns the revision code for the specified socket.
357 ======================================================================*/
359 static int __init get_tcic_id(void)
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);
370 /*====================================================================*/
372 static int tcic_drv_suspend(struct device *dev, u32 state, u32 level)
375 if (level == SUSPEND_SAVE_STATE)
376 ret = pcmcia_socket_dev_suspend(dev, state);
380 static int tcic_drv_resume(struct device *dev, u32 level)
383 if (level == RESUME_RESTORE_STATE)
384 ret = pcmcia_socket_dev_resume(dev);
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",
401 static int __init init_tcic(void)
403 int i, sock, ret = 0;
406 if (driver_register(&tcic_driver))
409 printk(KERN_INFO "Databook TCIC-2 PCMCIA probe: ");
412 if (!request_region(tcic_base, 16, "tcic-2")) {
413 printk("could not allocate ports,\n ");
414 driver_unregister(&tcic_driver);
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;
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;
435 printk("not found.\n");
436 release_region(tcic_base, 16);
437 driver_unregister(&tcic_driver);
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;
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;
474 printk("Unknown ID 0x%02x", socket_table[0].id);
478 poll_timer.function = &tcic_timer;
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)
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 */
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))
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))
511 if (cs_irq == 0) poll_interval = HZ;
514 if (socket_table[0].socket.irq_mask & (1 << 11))
515 printk("sktirq is irq 11, ");
517 printk("status change on irq %d\n", cs_irq);
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.resource_ops = &pccard_nonstatic_ops;
535 socket_table[i].socket.dev.dev = &tcic_device.dev;
536 ret = pcmcia_register_socket(&socket_table[i].socket);
538 pcmcia_unregister_socket(&socket_table[0].socket);
547 /*====================================================================*/
549 static void __exit exit_tcic(void)
553 del_timer_sync(&poll_timer);
555 tcic_aux_setw(TCIC_AUX_SYSCFG, TCIC_SYSCFG_AUTOBUSY|0x0a00);
556 free_irq(cs_irq, tcic_interrupt);
558 release_region(tcic_base, 16);
560 for (i = 0; i < sockets; i++) {
561 pcmcia_unregister_socket(&socket_table[i].socket);
564 platform_device_unregister(&tcic_device);
565 driver_unregister(&tcic_driver);
568 /*====================================================================*/
570 static irqreturn_t tcic_interrupt(int irq, void *dev, struct pt_regs *regs)
576 static volatile int active = 0;
579 printk(KERN_NOTICE "tcic: reentered interrupt handler!\n");
584 debug(2, "tcic_interrupt()\n");
586 for (i = 0; i < sockets; i++) {
587 psock = socket_table[i].psock;
588 tcic_setl(TCIC_ADDR, (psock << TCIC_ADDR_SS_SHFT)
589 | TCIC_ADDR_INDREG | TCIC_SCF1(psock));
590 sstat = tcic_getb(TCIC_SSTAT);
591 latch = sstat ^ socket_table[psock].last_sstat;
592 socket_table[i].last_sstat = sstat;
593 if (tcic_getb(TCIC_ICSR) & TCIC_ICSR_CDCHG) {
594 tcic_setb(TCIC_ICSR, TCIC_ICSR_CLEAR);
599 events = (latch & TCIC_SSTAT_CD) ? SS_DETECT : 0;
600 events |= (latch & TCIC_SSTAT_WP) ? SS_WRPROT : 0;
601 if (tcic_getw(TCIC_DATA) & TCIC_SCF1_IOSTS) {
602 events |= (latch & TCIC_SSTAT_LBAT1) ? SS_STSCHG : 0;
604 events |= (latch & TCIC_SSTAT_RDY) ? SS_READY : 0;
605 events |= (latch & TCIC_SSTAT_LBAT1) ? SS_BATDEAD : 0;
606 events |= (latch & TCIC_SSTAT_LBAT2) ? SS_BATWARN : 0;
609 pcmcia_parse_events(&socket_table[i].socket, events);
613 /* Schedule next poll, if needed */
614 if (((cs_irq == 0) || quick) && (!tcic_timer_pending)) {
615 poll_timer.expires = jiffies + (quick ? poll_quick : poll_interval);
616 add_timer(&poll_timer);
617 tcic_timer_pending = 1;
621 debug(2, "interrupt done\n");
623 } /* tcic_interrupt */
625 static void tcic_timer(u_long data)
627 debug(2, "tcic_timer()\n");
628 tcic_timer_pending = 0;
629 tcic_interrupt(0, NULL, NULL);
632 /*====================================================================*/
634 static int tcic_get_status(struct pcmcia_socket *sock, u_int *value)
636 u_short psock = container_of(sock, struct tcic_socket, socket)->psock;
639 tcic_setl(TCIC_ADDR, (psock << TCIC_ADDR_SS_SHFT)
640 | TCIC_ADDR_INDREG | TCIC_SCF1(psock));
641 reg = tcic_getb(TCIC_SSTAT);
642 *value = (reg & TCIC_SSTAT_CD) ? SS_DETECT : 0;
643 *value |= (reg & TCIC_SSTAT_WP) ? SS_WRPROT : 0;
644 if (tcic_getw(TCIC_DATA) & TCIC_SCF1_IOSTS) {
645 *value |= (reg & TCIC_SSTAT_LBAT1) ? SS_STSCHG : 0;
647 *value |= (reg & TCIC_SSTAT_RDY) ? SS_READY : 0;
648 *value |= (reg & TCIC_SSTAT_LBAT1) ? SS_BATDEAD : 0;
649 *value |= (reg & TCIC_SSTAT_LBAT2) ? SS_BATWARN : 0;
651 reg = tcic_getb(TCIC_PWR);
652 if (reg & (TCIC_PWR_VCC(psock)|TCIC_PWR_VPP(psock)))
653 *value |= SS_POWERON;
654 debug(1, "GetStatus(%d) = %#2.2x\n", psock, *value);
656 } /* tcic_get_status */
658 /*====================================================================*/
660 static int tcic_get_socket(struct pcmcia_socket *sock, socket_state_t *state)
662 u_short psock = container_of(sock, struct tcic_socket, socket)->psock;
666 tcic_setl(TCIC_ADDR, (psock << TCIC_ADDR_SS_SHFT)
667 | TCIC_ADDR_INDREG | TCIC_SCF1(psock));
668 scf1 = tcic_getw(TCIC_DATA);
669 state->flags = (scf1 & TCIC_SCF1_IOSTS) ? SS_IOCARD : 0;
670 state->flags |= (scf1 & TCIC_SCF1_DMA_MASK) ? SS_DMA_MODE : 0;
671 state->flags |= (scf1 & TCIC_SCF1_SPKR) ? SS_SPKR_ENA : 0;
672 if (tcic_getb(TCIC_SCTRL) & TCIC_SCTRL_ENA)
673 state->flags |= SS_OUTPUT_ENA;
674 state->io_irq = scf1 & TCIC_SCF1_IRQ_MASK;
675 if (state->io_irq == 1) state->io_irq = 11;
677 reg = tcic_getb(TCIC_PWR);
678 state->Vcc = state->Vpp = 0;
679 if (reg & TCIC_PWR_VCC(psock)) {
680 if (reg & TCIC_PWR_VPP(psock))
683 state->Vcc = state->Vpp = 50;
685 if (reg & TCIC_PWR_VPP(psock)) {
690 reg = tcic_aux_getb(TCIC_AUX_ILOCK);
691 state->flags |= (reg & TCIC_ILOCK_CRESET) ? SS_RESET : 0;
693 /* Card status change interrupt mask */
694 tcic_setw(TCIC_ADDR, TCIC_SCF2(psock));
695 scf2 = tcic_getw(TCIC_DATA);
696 state->csc_mask = (scf2 & TCIC_SCF2_MCD) ? 0 : SS_DETECT;
697 if (state->flags & SS_IOCARD) {
698 state->csc_mask |= (scf2 & TCIC_SCF2_MLBAT1) ? 0 : SS_STSCHG;
700 state->csc_mask |= (scf2 & TCIC_SCF2_MLBAT1) ? 0 : SS_BATDEAD;
701 state->csc_mask |= (scf2 & TCIC_SCF2_MLBAT2) ? 0 : SS_BATWARN;
702 state->csc_mask |= (scf2 & TCIC_SCF2_MRDY) ? 0 : SS_READY;
705 debug(1, "GetSocket(%d) = flags %#3.3x, Vcc %d, Vpp %d, "
706 "io_irq %d, csc_mask %#2.2x\n", psock, state->flags,
707 state->Vcc, state->Vpp, state->io_irq, state->csc_mask);
709 } /* tcic_get_socket */
711 /*====================================================================*/
713 static int tcic_set_socket(struct pcmcia_socket *sock, socket_state_t *state)
715 u_short psock = container_of(sock, struct tcic_socket, socket)->psock;
719 debug(1, "SetSocket(%d, flags %#3.3x, Vcc %d, Vpp %d, "
720 "io_irq %d, csc_mask %#2.2x)\n", psock, state->flags,
721 state->Vcc, state->Vpp, state->io_irq, state->csc_mask);
722 tcic_setw(TCIC_ADDR+2, (psock << TCIC_SS_SHFT) | TCIC_ADR2_INDREG);
724 reg = tcic_getb(TCIC_PWR);
725 reg &= ~(TCIC_PWR_VCC(psock) | TCIC_PWR_VPP(psock));
727 if (state->Vcc == 50) {
728 switch (state->Vpp) {
729 case 0: reg |= TCIC_PWR_VCC(psock) | TCIC_PWR_VPP(psock); break;
730 case 50: reg |= TCIC_PWR_VCC(psock); break;
731 case 120: reg |= TCIC_PWR_VPP(psock); break;
732 default: return -EINVAL;
734 } else if (state->Vcc != 0)
737 if (reg != tcic_getb(TCIC_PWR))
738 tcic_setb(TCIC_PWR, reg);
740 reg = TCIC_ILOCK_HOLD_CCLK | TCIC_ILOCK_CWAIT;
741 if (state->flags & SS_OUTPUT_ENA) {
742 tcic_setb(TCIC_SCTRL, TCIC_SCTRL_ENA);
743 reg |= TCIC_ILOCK_CRESENA;
745 tcic_setb(TCIC_SCTRL, 0);
746 if (state->flags & SS_RESET)
747 reg |= TCIC_ILOCK_CRESET;
748 tcic_aux_setb(TCIC_AUX_ILOCK, reg);
750 tcic_setw(TCIC_ADDR, TCIC_SCF1(psock));
751 scf1 = TCIC_SCF1_FINPACK;
752 scf1 |= TCIC_IRQ(state->io_irq);
753 if (state->flags & SS_IOCARD) {
754 scf1 |= TCIC_SCF1_IOSTS;
755 if (state->flags & SS_SPKR_ENA)
756 scf1 |= TCIC_SCF1_SPKR;
757 if (state->flags & SS_DMA_MODE)
758 scf1 |= TCIC_SCF1_DREQ2 << TCIC_SCF1_DMA_SHIFT;
760 tcic_setw(TCIC_DATA, scf1);
762 /* Some general setup stuff, and configure status interrupt */
763 reg = TCIC_WAIT_ASYNC | TCIC_WAIT_SENSE | to_cycles(250);
764 tcic_aux_setb(TCIC_AUX_WCTL, reg);
765 tcic_aux_setw(TCIC_AUX_SYSCFG, TCIC_SYSCFG_AUTOBUSY|0x0a00|
768 /* Card status change interrupt mask */
769 tcic_setw(TCIC_ADDR, TCIC_SCF2(psock));
770 scf2 = TCIC_SCF2_MALL;
771 if (state->csc_mask & SS_DETECT) scf2 &= ~TCIC_SCF2_MCD;
772 if (state->flags & SS_IOCARD) {
773 if (state->csc_mask & SS_STSCHG) reg &= ~TCIC_SCF2_MLBAT1;
775 if (state->csc_mask & SS_BATDEAD) reg &= ~TCIC_SCF2_MLBAT1;
776 if (state->csc_mask & SS_BATWARN) reg &= ~TCIC_SCF2_MLBAT2;
777 if (state->csc_mask & SS_READY) reg &= ~TCIC_SCF2_MRDY;
779 tcic_setw(TCIC_DATA, scf2);
780 /* For the ISA bus, the irq should be active-high totem-pole */
781 tcic_setb(TCIC_IENA, TCIC_IENA_CDCHG | TCIC_IENA_CFG_HIGH);
784 } /* tcic_set_socket */
786 /*====================================================================*/
788 static int tcic_set_io_map(struct pcmcia_socket *sock, struct pccard_io_map *io)
790 u_short psock = container_of(sock, struct tcic_socket, socket)->psock;
792 u_short base, len, ioctl;
794 debug(1, "SetIOMap(%d, %d, %#2.2x, %d ns, "
795 "%#4.4x-%#4.4x)\n", psock, io->map, io->flags,
796 io->speed, io->start, io->stop);
797 if ((io->map > 1) || (io->start > 0xffff) || (io->stop > 0xffff) ||
798 (io->stop < io->start)) return -EINVAL;
799 tcic_setw(TCIC_ADDR+2, TCIC_ADR2_INDREG | (psock << TCIC_SS_SHFT));
800 addr = TCIC_IWIN(psock, io->map);
802 base = io->start; len = io->stop - io->start;
803 /* Check to see that len+1 is power of two, etc */
804 if ((len & (len+1)) || (base & len)) return -EINVAL;
806 tcic_setw(TCIC_ADDR, addr + TCIC_IBASE_X);
807 tcic_setw(TCIC_DATA, base);
809 ioctl = (psock << TCIC_ICTL_SS_SHFT);
810 ioctl |= (len == 0) ? TCIC_ICTL_TINY : 0;
811 ioctl |= (io->flags & MAP_ACTIVE) ? TCIC_ICTL_ENA : 0;
812 ioctl |= to_cycles(io->speed) & TCIC_ICTL_WSCNT_MASK;
813 if (!(io->flags & MAP_AUTOSZ)) {
814 ioctl |= TCIC_ICTL_QUIET;
815 ioctl |= (io->flags & MAP_16BIT) ? TCIC_ICTL_BW_16 : TCIC_ICTL_BW_8;
817 tcic_setw(TCIC_ADDR, addr + TCIC_ICTL_X);
818 tcic_setw(TCIC_DATA, ioctl);
821 } /* tcic_set_io_map */
823 /*====================================================================*/
825 static int tcic_set_mem_map(struct pcmcia_socket *sock, struct pccard_mem_map *mem)
827 u_short psock = container_of(sock, struct tcic_socket, socket)->psock;
829 u_long base, len, mmap;
831 debug(1, "SetMemMap(%d, %d, %#2.2x, %d ns, "
832 "%#5.5lx-%#5.5lx, %#5.5x)\n", psock, mem->map, mem->flags,
833 mem->speed, mem->res->start, mem->res->end, mem->card_start);
834 if ((mem->map > 3) || (mem->card_start > 0x3ffffff) ||
835 (mem->res->start > 0xffffff) || (mem->res->end > 0xffffff) ||
836 (mem->res->start > mem->res->end) || (mem->speed > 1000))
838 tcic_setw(TCIC_ADDR+2, TCIC_ADR2_INDREG | (psock << TCIC_SS_SHFT));
839 addr = TCIC_MWIN(psock, mem->map);
841 base = mem->res->start; len = mem->res->end - mem->res->start;
842 if ((len & (len+1)) || (base & len)) return -EINVAL;
844 base = (base >> TCIC_MBASE_HA_SHFT) | TCIC_MBASE_4K_BIT;
846 base = (base | (len+1)>>1) >> TCIC_MBASE_HA_SHFT;
847 tcic_setw(TCIC_ADDR, addr + TCIC_MBASE_X);
848 tcic_setw(TCIC_DATA, base);
850 mmap = mem->card_start - mem->res->start;
851 mmap = (mmap >> TCIC_MMAP_CA_SHFT) & TCIC_MMAP_CA_MASK;
852 if (mem->flags & MAP_ATTRIB) mmap |= TCIC_MMAP_REG;
853 tcic_setw(TCIC_ADDR, addr + TCIC_MMAP_X);
854 tcic_setw(TCIC_DATA, mmap);
856 ctl = TCIC_MCTL_QUIET | (psock << TCIC_MCTL_SS_SHFT);
857 ctl |= to_cycles(mem->speed) & TCIC_MCTL_WSCNT_MASK;
858 ctl |= (mem->flags & MAP_16BIT) ? 0 : TCIC_MCTL_B8;
859 ctl |= (mem->flags & MAP_WRPROT) ? TCIC_MCTL_WP : 0;
860 ctl |= (mem->flags & MAP_ACTIVE) ? TCIC_MCTL_ENA : 0;
861 tcic_setw(TCIC_ADDR, addr + TCIC_MCTL_X);
862 tcic_setw(TCIC_DATA, ctl);
865 } /* tcic_set_mem_map */
867 /*====================================================================*/
869 static int tcic_init(struct pcmcia_socket *s)
872 struct resource res = { .start = 0, .end = 0x1000 };
873 pccard_io_map io = { 0, 0, 0, 0, 1 };
874 pccard_mem_map mem = { .res = &res, };
876 for (i = 0; i < 2; i++) {
878 tcic_set_io_map(s, &io);
880 for (i = 0; i < 5; i++) {
882 tcic_set_mem_map(s, &mem);
887 static int tcic_suspend(struct pcmcia_socket *sock)
889 return tcic_set_socket(sock, &dead_socket);
892 static struct pccard_operations tcic_operations = {
894 .suspend = tcic_suspend,
895 .get_status = tcic_get_status,
896 .get_socket = tcic_get_socket,
897 .set_socket = tcic_set_socket,
898 .set_io_map = tcic_set_io_map,
899 .set_mem_map = tcic_set_mem_map,
902 /*====================================================================*/
904 module_init(init_tcic);
905 module_exit(exit_tcic);