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/cs_types.h>
54 #include <pcmcia/cs.h>
55 #include <pcmcia/ss.h>
61 module_param(pc_debug, int, 0644);
62 static const char version[] =
63 "tcic.c 1.111 2000/02/15 04:13:12 (David Hinds)";
65 #define debug(lvl, fmt, arg...) do { \
66 if (pc_debug > (lvl)) \
67 printk(KERN_DEBUG "tcic: " fmt , ## arg); \
70 #define debug(lvl, fmt, arg...) do { } while (0)
73 MODULE_AUTHOR("David Hinds <dahinds@users.sourceforge.net>");
74 MODULE_DESCRIPTION("Databook TCIC-2 PCMCIA socket driver");
75 MODULE_LICENSE("Dual MPL/GPL");
77 /*====================================================================*/
79 /* Parameters that can be set with 'insmod' */
81 /* The base port address of the TCIC-2 chip */
82 static unsigned long tcic_base = TCIC_BASE;
84 /* Specify a socket number to ignore */
85 static int ignore = -1;
87 /* Probe for safe interrupts? */
88 static int do_scan = 1;
90 /* Bit map of interrupts to choose from */
91 static u_int irq_mask = 0xffff;
92 static int irq_list[16];
93 static int irq_list_count;
95 /* The card status change interrupt -- 0 means autoselect */
98 /* Poll status interval -- 0 means default to interrupt */
99 static int poll_interval;
101 /* Delay for card status double-checking */
102 static int poll_quick = HZ/20;
104 /* CCLK external clock time, in nanoseconds. 70 ns = 14.31818 MHz */
105 static int cycle_time = 70;
107 module_param(tcic_base, ulong, 0444);
108 module_param(ignore, int, 0444);
109 module_param(do_scan, int, 0444);
110 module_param(irq_mask, int, 0444);
111 module_param_array(irq_list, int, &irq_list_count, 0444);
112 module_param(cs_irq, int, 0444);
113 module_param(poll_interval, int, 0444);
114 module_param(poll_quick, int, 0444);
115 module_param(cycle_time, int, 0444);
117 /*====================================================================*/
119 static irqreturn_t tcic_interrupt(int irq, void *dev, struct pt_regs *regs);
120 static void tcic_timer(u_long data);
121 static struct pccard_operations tcic_operations;
127 struct pcmcia_socket socket;
130 static struct timer_list poll_timer;
131 static int tcic_timer_pending;
134 static struct tcic_socket socket_table[2];
136 /*====================================================================*/
138 /* Trick when selecting interrupts: the TCIC sktirq pin is supposed
139 to map to irq 11, but is coded as 0 or 1 in the irq registers. */
140 #define TCIC_IRQ(x) ((x) ? (((x) == 11) ? 1 : (x)) : 15)
143 static u_char tcic_getb(u_char reg)
145 u_char val = inb(tcic_base+reg);
146 printk(KERN_DEBUG "tcic_getb(%#lx) = %#x\n", tcic_base+reg, val);
150 static u_short tcic_getw(u_char reg)
152 u_short val = inw(tcic_base+reg);
153 printk(KERN_DEBUG "tcic_getw(%#lx) = %#x\n", tcic_base+reg, val);
157 static void tcic_setb(u_char reg, u_char data)
159 printk(KERN_DEBUG "tcic_setb(%#lx, %#x)\n", tcic_base+reg, data);
160 outb(data, tcic_base+reg);
163 static void tcic_setw(u_char reg, u_short data)
165 printk(KERN_DEBUG "tcic_setw(%#lx, %#x)\n", tcic_base+reg, data);
166 outw(data, tcic_base+reg);
169 #define tcic_getb(reg) inb(tcic_base+reg)
170 #define tcic_getw(reg) inw(tcic_base+reg)
171 #define tcic_setb(reg, data) outb(data, tcic_base+reg)
172 #define tcic_setw(reg, data) outw(data, tcic_base+reg)
175 static void tcic_setl(u_char reg, u_int data)
178 printk(KERN_DEBUG "tcic_setl(%#x, %#lx)\n", tcic_base+reg, data);
180 outw(data & 0xffff, tcic_base+reg);
181 outw(data >> 16, tcic_base+reg+2);
184 static u_char tcic_aux_getb(u_short reg)
186 u_char mode = (tcic_getb(TCIC_MODE) & TCIC_MODE_PGMMASK) | reg;
187 tcic_setb(TCIC_MODE, mode);
188 return tcic_getb(TCIC_AUX);
191 static void tcic_aux_setb(u_short reg, u_char data)
193 u_char mode = (tcic_getb(TCIC_MODE) & TCIC_MODE_PGMMASK) | reg;
194 tcic_setb(TCIC_MODE, mode);
195 tcic_setb(TCIC_AUX, data);
198 static u_short tcic_aux_getw(u_short reg)
200 u_char mode = (tcic_getb(TCIC_MODE) & TCIC_MODE_PGMMASK) | reg;
201 tcic_setb(TCIC_MODE, mode);
202 return tcic_getw(TCIC_AUX);
205 static void tcic_aux_setw(u_short reg, u_short data)
207 u_char mode = (tcic_getb(TCIC_MODE) & TCIC_MODE_PGMMASK) | reg;
208 tcic_setb(TCIC_MODE, mode);
209 tcic_setw(TCIC_AUX, data);
212 /*====================================================================*/
214 /* Time conversion functions */
216 static int to_cycles(int ns)
221 return 2*(ns-14)/cycle_time;
224 /*====================================================================*/
226 static volatile u_int irq_hits;
228 static irqreturn_t __init tcic_irq_count(int irq, void *dev, struct pt_regs *regs)
234 static u_int __init try_irq(int irq)
239 if (request_irq(irq, tcic_irq_count, 0, "irq scan", tcic_irq_count) != 0)
243 free_irq(irq, tcic_irq_count);
247 /* Generate one interrupt */
248 cfg = TCIC_SYSCFG_AUTOBUSY | 0x0a00;
249 tcic_aux_setw(TCIC_AUX_SYSCFG, cfg | TCIC_IRQ(irq));
250 tcic_setb(TCIC_IENA, TCIC_IENA_ERR | TCIC_IENA_CFG_HIGH);
251 tcic_setb(TCIC_ICSR, TCIC_ICSR_ERR | TCIC_ICSR_JAM);
254 free_irq(irq, tcic_irq_count);
256 /* Turn off interrupts */
257 tcic_setb(TCIC_IENA, TCIC_IENA_CFG_OFF);
258 while (tcic_getb(TCIC_ICSR))
259 tcic_setb(TCIC_ICSR, TCIC_ICSR_JAM);
260 tcic_aux_setw(TCIC_AUX_SYSCFG, cfg);
262 return (irq_hits != 1);
265 static u_int __init irq_scan(u_int mask0)
272 /* Don't probe level-triggered interrupts -- reserved for PCI */
273 int level_mask = inb_p(PIC) | (inb_p(PIC+1) << 8);
275 mask0 &= ~level_mask;
280 for (i = 0; i < 16; i++)
281 if ((mask0 & (1 << i)) && (try_irq(i) == 0))
283 for (i = 0; i < 16; i++)
284 if ((mask1 & (1 << i)) && (try_irq(i) != 0)) {
292 /* Fallback: just find interrupts that aren't in use */
293 for (i = 0; i < 16; i++)
294 if ((mask0 & (1 << i)) &&
295 (request_irq(i, tcic_irq_count, 0, "x", tcic_irq_count) == 0)) {
297 free_irq(i, tcic_irq_count);
303 for (i = 0; i < 16; i++)
305 printk("%s%d", ((mask1 & ((1<<i)-1)) ? "," : ""), i);
311 /*======================================================================
313 See if a card is present, powered up, in IO mode, and already
314 bound to a (non-PCMCIA) Linux driver.
316 We make an exception for cards that look like serial devices.
318 ======================================================================*/
320 static int __init is_active(int s)
322 u_short scf1, ioctl, base, num;
326 tcic_setl(TCIC_ADDR, (s << TCIC_ADDR_SS_SHFT)
327 | TCIC_ADDR_INDREG | TCIC_SCF1(s));
328 scf1 = tcic_getw(TCIC_DATA);
329 pwr = tcic_getb(TCIC_PWR);
330 sstat = tcic_getb(TCIC_SSTAT);
331 addr = TCIC_IWIN(s, 0);
332 tcic_setw(TCIC_ADDR, addr + TCIC_IBASE_X);
333 base = tcic_getw(TCIC_DATA);
334 tcic_setw(TCIC_ADDR, addr + TCIC_ICTL_X);
335 ioctl = tcic_getw(TCIC_DATA);
337 if (ioctl & TCIC_ICTL_TINY)
340 num = (base ^ (base-1));
341 base = base & (base-1);
344 if ((sstat & TCIC_SSTAT_CD) && (pwr & TCIC_PWR_VCC(s)) &&
345 (scf1 & TCIC_SCF1_IOSTS) && (ioctl & TCIC_ICTL_ENA) &&
346 ((base & 0xfeef) != 0x02e8)) {
347 struct resource *res = request_region(base, num, "tcic-2");
348 if (!res) /* region is busy */
350 release_region(base, num);
356 /*======================================================================
358 This returns the revision code for the specified socket.
360 ======================================================================*/
362 static int __init get_tcic_id(void)
366 tcic_aux_setw(TCIC_AUX_TEST, TCIC_TEST_DIAG);
367 id = tcic_aux_getw(TCIC_AUX_ILOCK);
368 id = (id & TCIC_ILOCKTEST_ID_MASK) >> TCIC_ILOCKTEST_ID_SH;
369 tcic_aux_setw(TCIC_AUX_TEST, 0);
373 /*====================================================================*/
375 static int tcic_drv_suspend(struct device *dev, pm_message_t state, u32 level)
378 if (level == SUSPEND_SAVE_STATE)
379 ret = pcmcia_socket_dev_suspend(dev, state);
383 static int tcic_drv_resume(struct device *dev, u32 level)
386 if (level == RESUME_RESTORE_STATE)
387 ret = pcmcia_socket_dev_resume(dev);
391 static struct device_driver tcic_driver = {
392 .name = "tcic-pcmcia",
393 .bus = &platform_bus_type,
394 .suspend = tcic_drv_suspend,
395 .resume = tcic_drv_resume,
398 static struct platform_device tcic_device = {
399 .name = "tcic-pcmcia",
404 static int __init init_tcic(void)
406 int i, sock, ret = 0;
409 if (driver_register(&tcic_driver))
412 printk(KERN_INFO "Databook TCIC-2 PCMCIA probe: ");
415 if (!request_region(tcic_base, 16, "tcic-2")) {
416 printk("could not allocate ports,\n ");
417 driver_unregister(&tcic_driver);
421 tcic_setw(TCIC_ADDR, 0);
422 if (tcic_getw(TCIC_ADDR) == 0) {
423 tcic_setw(TCIC_ADDR, 0xc3a5);
424 if (tcic_getw(TCIC_ADDR) == 0xc3a5) sock = 2;
427 /* See if resetting the controller does any good */
428 tcic_setb(TCIC_SCTRL, TCIC_SCTRL_RESET);
429 tcic_setb(TCIC_SCTRL, 0);
430 tcic_setw(TCIC_ADDR, 0);
431 if (tcic_getw(TCIC_ADDR) == 0) {
432 tcic_setw(TCIC_ADDR, 0xc3a5);
433 if (tcic_getw(TCIC_ADDR) == 0xc3a5) sock = 2;
438 printk("not found.\n");
439 release_region(tcic_base, 16);
440 driver_unregister(&tcic_driver);
445 for (i = 0; i < sock; i++) {
446 if ((i == ignore) || is_active(i)) continue;
447 socket_table[sockets].psock = i;
448 socket_table[sockets].id = get_tcic_id();
450 socket_table[sockets].socket.owner = THIS_MODULE;
451 /* only 16-bit cards, memory windows must be size-aligned */
452 /* No PCI or CardBus support */
453 socket_table[sockets].socket.features = SS_CAP_PCCARD | SS_CAP_MEM_ALIGN;
454 /* irq 14, 11, 10, 7, 6, 5, 4, 3 */
455 socket_table[sockets].socket.irq_mask = 0x4cf8;
456 /* 4K minimum window size */
457 socket_table[sockets].socket.map_size = 0x1000;
461 switch (socket_table[0].id) {
462 case TCIC_ID_DB86082:
463 printk("DB86082"); break;
464 case TCIC_ID_DB86082A:
465 printk("DB86082A"); break;
466 case TCIC_ID_DB86084:
467 printk("DB86084"); break;
468 case TCIC_ID_DB86084A:
469 printk("DB86084A"); break;
470 case TCIC_ID_DB86072:
471 printk("DB86072"); break;
472 case TCIC_ID_DB86184:
473 printk("DB86184"); break;
474 case TCIC_ID_DB86082B:
475 printk("DB86082B"); break;
477 printk("Unknown ID 0x%02x", socket_table[0].id);
481 poll_timer.function = &tcic_timer;
483 init_timer(&poll_timer);
485 /* Build interrupt mask */
486 printk(", %d sockets\n" KERN_INFO " irq list (", sockets);
487 if (irq_list_count == 0)
490 for (i = mask = 0; i < irq_list_count; i++)
491 mask |= (1<<irq_list[i]);
493 /* irq 14, 11, 10, 7, 6, 5, 4, 3 */
495 /* Scan interrupts */
496 mask = irq_scan(mask);
497 for (i=0;i<sockets;i++)
498 socket_table[i].socket.irq_mask = mask;
500 /* Check for only two interrupts available */
501 scan = (mask & (mask-1));
502 if (((scan & (scan-1)) == 0) && (poll_interval == 0))
505 if (poll_interval == 0) {
506 /* Avoid irq 12 unless it is explicitly requested */
507 u_int cs_mask = mask & ((cs_irq) ? (1<<cs_irq) : ~(1<<12));
508 for (i = 15; i > 0; i--)
509 if ((cs_mask & (1 << i)) &&
510 (request_irq(i, tcic_interrupt, 0, "tcic",
511 tcic_interrupt) == 0))
514 if (cs_irq == 0) poll_interval = HZ;
517 if (socket_table[0].socket.irq_mask & (1 << 11))
518 printk("sktirq is irq 11, ");
520 printk("status change on irq %d\n", cs_irq);
522 printk("polled status, interval = %d ms\n",
523 poll_interval * 1000 / HZ);
525 for (i = 0; i < sockets; i++) {
526 tcic_setw(TCIC_ADDR+2, socket_table[i].psock << TCIC_SS_SHFT);
527 socket_table[i].last_sstat = tcic_getb(TCIC_SSTAT);
530 /* jump start interrupt handler, if needed */
531 tcic_interrupt(0, NULL, NULL);
533 platform_device_register(&tcic_device);
535 for (i = 0; i < sockets; i++) {
536 socket_table[i].socket.ops = &tcic_operations;
537 socket_table[i].socket.resource_ops = &pccard_nonstatic_ops;
538 socket_table[i].socket.dev.dev = &tcic_device.dev;
539 ret = pcmcia_register_socket(&socket_table[i].socket);
541 pcmcia_unregister_socket(&socket_table[0].socket);
550 /*====================================================================*/
552 static void __exit exit_tcic(void)
556 del_timer_sync(&poll_timer);
558 tcic_aux_setw(TCIC_AUX_SYSCFG, TCIC_SYSCFG_AUTOBUSY|0x0a00);
559 free_irq(cs_irq, tcic_interrupt);
561 release_region(tcic_base, 16);
563 for (i = 0; i < sockets; i++) {
564 pcmcia_unregister_socket(&socket_table[i].socket);
567 platform_device_unregister(&tcic_device);
568 driver_unregister(&tcic_driver);
571 /*====================================================================*/
573 static irqreturn_t tcic_interrupt(int irq, void *dev, struct pt_regs *regs)
579 static volatile int active = 0;
582 printk(KERN_NOTICE "tcic: reentered interrupt handler!\n");
587 debug(2, "tcic_interrupt()\n");
589 for (i = 0; i < sockets; i++) {
590 psock = socket_table[i].psock;
591 tcic_setl(TCIC_ADDR, (psock << TCIC_ADDR_SS_SHFT)
592 | TCIC_ADDR_INDREG | TCIC_SCF1(psock));
593 sstat = tcic_getb(TCIC_SSTAT);
594 latch = sstat ^ socket_table[psock].last_sstat;
595 socket_table[i].last_sstat = sstat;
596 if (tcic_getb(TCIC_ICSR) & TCIC_ICSR_CDCHG) {
597 tcic_setb(TCIC_ICSR, TCIC_ICSR_CLEAR);
602 events = (latch & TCIC_SSTAT_CD) ? SS_DETECT : 0;
603 events |= (latch & TCIC_SSTAT_WP) ? SS_WRPROT : 0;
604 if (tcic_getw(TCIC_DATA) & TCIC_SCF1_IOSTS) {
605 events |= (latch & TCIC_SSTAT_LBAT1) ? SS_STSCHG : 0;
607 events |= (latch & TCIC_SSTAT_RDY) ? SS_READY : 0;
608 events |= (latch & TCIC_SSTAT_LBAT1) ? SS_BATDEAD : 0;
609 events |= (latch & TCIC_SSTAT_LBAT2) ? SS_BATWARN : 0;
612 pcmcia_parse_events(&socket_table[i].socket, events);
616 /* Schedule next poll, if needed */
617 if (((cs_irq == 0) || quick) && (!tcic_timer_pending)) {
618 poll_timer.expires = jiffies + (quick ? poll_quick : poll_interval);
619 add_timer(&poll_timer);
620 tcic_timer_pending = 1;
624 debug(2, "interrupt done\n");
626 } /* tcic_interrupt */
628 static void tcic_timer(u_long data)
630 debug(2, "tcic_timer()\n");
631 tcic_timer_pending = 0;
632 tcic_interrupt(0, NULL, NULL);
635 /*====================================================================*/
637 static int tcic_get_status(struct pcmcia_socket *sock, u_int *value)
639 u_short psock = container_of(sock, struct tcic_socket, socket)->psock;
642 tcic_setl(TCIC_ADDR, (psock << TCIC_ADDR_SS_SHFT)
643 | TCIC_ADDR_INDREG | TCIC_SCF1(psock));
644 reg = tcic_getb(TCIC_SSTAT);
645 *value = (reg & TCIC_SSTAT_CD) ? SS_DETECT : 0;
646 *value |= (reg & TCIC_SSTAT_WP) ? SS_WRPROT : 0;
647 if (tcic_getw(TCIC_DATA) & TCIC_SCF1_IOSTS) {
648 *value |= (reg & TCIC_SSTAT_LBAT1) ? SS_STSCHG : 0;
650 *value |= (reg & TCIC_SSTAT_RDY) ? SS_READY : 0;
651 *value |= (reg & TCIC_SSTAT_LBAT1) ? SS_BATDEAD : 0;
652 *value |= (reg & TCIC_SSTAT_LBAT2) ? SS_BATWARN : 0;
654 reg = tcic_getb(TCIC_PWR);
655 if (reg & (TCIC_PWR_VCC(psock)|TCIC_PWR_VPP(psock)))
656 *value |= SS_POWERON;
657 debug(1, "GetStatus(%d) = %#2.2x\n", psock, *value);
659 } /* tcic_get_status */
661 /*====================================================================*/
663 static int tcic_get_socket(struct pcmcia_socket *sock, socket_state_t *state)
665 u_short psock = container_of(sock, struct tcic_socket, socket)->psock;
669 tcic_setl(TCIC_ADDR, (psock << TCIC_ADDR_SS_SHFT)
670 | TCIC_ADDR_INDREG | TCIC_SCF1(psock));
671 scf1 = tcic_getw(TCIC_DATA);
672 state->flags = (scf1 & TCIC_SCF1_IOSTS) ? SS_IOCARD : 0;
673 state->flags |= (scf1 & TCIC_SCF1_DMA_MASK) ? SS_DMA_MODE : 0;
674 state->flags |= (scf1 & TCIC_SCF1_SPKR) ? SS_SPKR_ENA : 0;
675 if (tcic_getb(TCIC_SCTRL) & TCIC_SCTRL_ENA)
676 state->flags |= SS_OUTPUT_ENA;
677 state->io_irq = scf1 & TCIC_SCF1_IRQ_MASK;
678 if (state->io_irq == 1) state->io_irq = 11;
680 reg = tcic_getb(TCIC_PWR);
681 state->Vcc = state->Vpp = 0;
682 if (reg & TCIC_PWR_VCC(psock)) {
683 if (reg & TCIC_PWR_VPP(psock))
686 state->Vcc = state->Vpp = 50;
688 if (reg & TCIC_PWR_VPP(psock)) {
693 reg = tcic_aux_getb(TCIC_AUX_ILOCK);
694 state->flags |= (reg & TCIC_ILOCK_CRESET) ? SS_RESET : 0;
696 /* Card status change interrupt mask */
697 tcic_setw(TCIC_ADDR, TCIC_SCF2(psock));
698 scf2 = tcic_getw(TCIC_DATA);
699 state->csc_mask = (scf2 & TCIC_SCF2_MCD) ? 0 : SS_DETECT;
700 if (state->flags & SS_IOCARD) {
701 state->csc_mask |= (scf2 & TCIC_SCF2_MLBAT1) ? 0 : SS_STSCHG;
703 state->csc_mask |= (scf2 & TCIC_SCF2_MLBAT1) ? 0 : SS_BATDEAD;
704 state->csc_mask |= (scf2 & TCIC_SCF2_MLBAT2) ? 0 : SS_BATWARN;
705 state->csc_mask |= (scf2 & TCIC_SCF2_MRDY) ? 0 : SS_READY;
708 debug(1, "GetSocket(%d) = flags %#3.3x, Vcc %d, Vpp %d, "
709 "io_irq %d, csc_mask %#2.2x\n", psock, state->flags,
710 state->Vcc, state->Vpp, state->io_irq, state->csc_mask);
712 } /* tcic_get_socket */
714 /*====================================================================*/
716 static int tcic_set_socket(struct pcmcia_socket *sock, socket_state_t *state)
718 u_short psock = container_of(sock, struct tcic_socket, socket)->psock;
722 debug(1, "SetSocket(%d, flags %#3.3x, Vcc %d, Vpp %d, "
723 "io_irq %d, csc_mask %#2.2x)\n", psock, state->flags,
724 state->Vcc, state->Vpp, state->io_irq, state->csc_mask);
725 tcic_setw(TCIC_ADDR+2, (psock << TCIC_SS_SHFT) | TCIC_ADR2_INDREG);
727 reg = tcic_getb(TCIC_PWR);
728 reg &= ~(TCIC_PWR_VCC(psock) | TCIC_PWR_VPP(psock));
730 if (state->Vcc == 50) {
731 switch (state->Vpp) {
732 case 0: reg |= TCIC_PWR_VCC(psock) | TCIC_PWR_VPP(psock); break;
733 case 50: reg |= TCIC_PWR_VCC(psock); break;
734 case 120: reg |= TCIC_PWR_VPP(psock); break;
735 default: return -EINVAL;
737 } else if (state->Vcc != 0)
740 if (reg != tcic_getb(TCIC_PWR))
741 tcic_setb(TCIC_PWR, reg);
743 reg = TCIC_ILOCK_HOLD_CCLK | TCIC_ILOCK_CWAIT;
744 if (state->flags & SS_OUTPUT_ENA) {
745 tcic_setb(TCIC_SCTRL, TCIC_SCTRL_ENA);
746 reg |= TCIC_ILOCK_CRESENA;
748 tcic_setb(TCIC_SCTRL, 0);
749 if (state->flags & SS_RESET)
750 reg |= TCIC_ILOCK_CRESET;
751 tcic_aux_setb(TCIC_AUX_ILOCK, reg);
753 tcic_setw(TCIC_ADDR, TCIC_SCF1(psock));
754 scf1 = TCIC_SCF1_FINPACK;
755 scf1 |= TCIC_IRQ(state->io_irq);
756 if (state->flags & SS_IOCARD) {
757 scf1 |= TCIC_SCF1_IOSTS;
758 if (state->flags & SS_SPKR_ENA)
759 scf1 |= TCIC_SCF1_SPKR;
760 if (state->flags & SS_DMA_MODE)
761 scf1 |= TCIC_SCF1_DREQ2 << TCIC_SCF1_DMA_SHIFT;
763 tcic_setw(TCIC_DATA, scf1);
765 /* Some general setup stuff, and configure status interrupt */
766 reg = TCIC_WAIT_ASYNC | TCIC_WAIT_SENSE | to_cycles(250);
767 tcic_aux_setb(TCIC_AUX_WCTL, reg);
768 tcic_aux_setw(TCIC_AUX_SYSCFG, TCIC_SYSCFG_AUTOBUSY|0x0a00|
771 /* Card status change interrupt mask */
772 tcic_setw(TCIC_ADDR, TCIC_SCF2(psock));
773 scf2 = TCIC_SCF2_MALL;
774 if (state->csc_mask & SS_DETECT) scf2 &= ~TCIC_SCF2_MCD;
775 if (state->flags & SS_IOCARD) {
776 if (state->csc_mask & SS_STSCHG) reg &= ~TCIC_SCF2_MLBAT1;
778 if (state->csc_mask & SS_BATDEAD) reg &= ~TCIC_SCF2_MLBAT1;
779 if (state->csc_mask & SS_BATWARN) reg &= ~TCIC_SCF2_MLBAT2;
780 if (state->csc_mask & SS_READY) reg &= ~TCIC_SCF2_MRDY;
782 tcic_setw(TCIC_DATA, scf2);
783 /* For the ISA bus, the irq should be active-high totem-pole */
784 tcic_setb(TCIC_IENA, TCIC_IENA_CDCHG | TCIC_IENA_CFG_HIGH);
787 } /* tcic_set_socket */
789 /*====================================================================*/
791 static int tcic_set_io_map(struct pcmcia_socket *sock, struct pccard_io_map *io)
793 u_short psock = container_of(sock, struct tcic_socket, socket)->psock;
795 u_short base, len, ioctl;
797 debug(1, "SetIOMap(%d, %d, %#2.2x, %d ns, "
798 "%#lx-%#lx)\n", psock, io->map, io->flags,
799 io->speed, io->start, io->stop);
800 if ((io->map > 1) || (io->start > 0xffff) || (io->stop > 0xffff) ||
801 (io->stop < io->start)) return -EINVAL;
802 tcic_setw(TCIC_ADDR+2, TCIC_ADR2_INDREG | (psock << TCIC_SS_SHFT));
803 addr = TCIC_IWIN(psock, io->map);
805 base = io->start; len = io->stop - io->start;
806 /* Check to see that len+1 is power of two, etc */
807 if ((len & (len+1)) || (base & len)) return -EINVAL;
809 tcic_setw(TCIC_ADDR, addr + TCIC_IBASE_X);
810 tcic_setw(TCIC_DATA, base);
812 ioctl = (psock << TCIC_ICTL_SS_SHFT);
813 ioctl |= (len == 0) ? TCIC_ICTL_TINY : 0;
814 ioctl |= (io->flags & MAP_ACTIVE) ? TCIC_ICTL_ENA : 0;
815 ioctl |= to_cycles(io->speed) & TCIC_ICTL_WSCNT_MASK;
816 if (!(io->flags & MAP_AUTOSZ)) {
817 ioctl |= TCIC_ICTL_QUIET;
818 ioctl |= (io->flags & MAP_16BIT) ? TCIC_ICTL_BW_16 : TCIC_ICTL_BW_8;
820 tcic_setw(TCIC_ADDR, addr + TCIC_ICTL_X);
821 tcic_setw(TCIC_DATA, ioctl);
824 } /* tcic_set_io_map */
826 /*====================================================================*/
828 static int tcic_set_mem_map(struct pcmcia_socket *sock, struct pccard_mem_map *mem)
830 u_short psock = container_of(sock, struct tcic_socket, socket)->psock;
832 u_long base, len, mmap;
834 debug(1, "SetMemMap(%d, %d, %#2.2x, %d ns, "
835 "%#lx-%#lx, %#x)\n", psock, mem->map, mem->flags,
836 mem->speed, mem->res->start, mem->res->end, mem->card_start);
837 if ((mem->map > 3) || (mem->card_start > 0x3ffffff) ||
838 (mem->res->start > 0xffffff) || (mem->res->end > 0xffffff) ||
839 (mem->res->start > mem->res->end) || (mem->speed > 1000))
841 tcic_setw(TCIC_ADDR+2, TCIC_ADR2_INDREG | (psock << TCIC_SS_SHFT));
842 addr = TCIC_MWIN(psock, mem->map);
844 base = mem->res->start; len = mem->res->end - mem->res->start;
845 if ((len & (len+1)) || (base & len)) return -EINVAL;
847 base = (base >> TCIC_MBASE_HA_SHFT) | TCIC_MBASE_4K_BIT;
849 base = (base | (len+1)>>1) >> TCIC_MBASE_HA_SHFT;
850 tcic_setw(TCIC_ADDR, addr + TCIC_MBASE_X);
851 tcic_setw(TCIC_DATA, base);
853 mmap = mem->card_start - mem->res->start;
854 mmap = (mmap >> TCIC_MMAP_CA_SHFT) & TCIC_MMAP_CA_MASK;
855 if (mem->flags & MAP_ATTRIB) mmap |= TCIC_MMAP_REG;
856 tcic_setw(TCIC_ADDR, addr + TCIC_MMAP_X);
857 tcic_setw(TCIC_DATA, mmap);
859 ctl = TCIC_MCTL_QUIET | (psock << TCIC_MCTL_SS_SHFT);
860 ctl |= to_cycles(mem->speed) & TCIC_MCTL_WSCNT_MASK;
861 ctl |= (mem->flags & MAP_16BIT) ? 0 : TCIC_MCTL_B8;
862 ctl |= (mem->flags & MAP_WRPROT) ? TCIC_MCTL_WP : 0;
863 ctl |= (mem->flags & MAP_ACTIVE) ? TCIC_MCTL_ENA : 0;
864 tcic_setw(TCIC_ADDR, addr + TCIC_MCTL_X);
865 tcic_setw(TCIC_DATA, ctl);
868 } /* tcic_set_mem_map */
870 /*====================================================================*/
872 static int tcic_init(struct pcmcia_socket *s)
875 struct resource res = { .start = 0, .end = 0x1000 };
876 pccard_io_map io = { 0, 0, 0, 0, 1 };
877 pccard_mem_map mem = { .res = &res, };
879 for (i = 0; i < 2; i++) {
881 tcic_set_io_map(s, &io);
883 for (i = 0; i < 5; i++) {
885 tcic_set_mem_map(s, &mem);
890 static struct pccard_operations tcic_operations = {
892 .get_status = tcic_get_status,
893 .get_socket = tcic_get_socket,
894 .set_socket = tcic_set_socket,
895 .set_io_map = tcic_set_io_map,
896 .set_mem_map = tcic_set_mem_map,
899 /*====================================================================*/
901 module_init(init_tcic);
902 module_exit(exit_tcic);