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/platform_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>
58 MODULE_AUTHOR("David Hinds <dahinds@users.sourceforge.net>");
59 MODULE_DESCRIPTION("Databook TCIC-2 PCMCIA socket driver");
60 MODULE_LICENSE("Dual MPL/GPL");
62 /*====================================================================*/
64 /* Parameters that can be set with 'insmod' */
66 /* The base port address of the TCIC-2 chip */
67 static unsigned long tcic_base = TCIC_BASE;
69 /* Specify a socket number to ignore */
70 static int ignore = -1;
72 /* Probe for safe interrupts? */
73 static int do_scan = 1;
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;
80 /* The card status change interrupt -- 0 means autoselect */
83 /* Poll status interval -- 0 means default to interrupt */
84 static int poll_interval;
86 /* Delay for card status double-checking */
87 static int poll_quick = HZ/20;
89 /* CCLK external clock time, in nanoseconds. 70 ns = 14.31818 MHz */
90 static int cycle_time = 70;
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);
102 /*====================================================================*/
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;
112 struct pcmcia_socket socket;
115 static struct timer_list poll_timer;
116 static int tcic_timer_pending;
119 static struct tcic_socket socket_table[2];
121 /*====================================================================*/
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)
128 static u_char tcic_getb(u_char reg)
130 u_char val = inb(tcic_base+reg);
131 printk(KERN_DEBUG "tcic_getb(%#lx) = %#x\n", tcic_base+reg, val);
135 static u_short tcic_getw(u_char reg)
137 u_short val = inw(tcic_base+reg);
138 printk(KERN_DEBUG "tcic_getw(%#lx) = %#x\n", tcic_base+reg, val);
142 static void tcic_setb(u_char reg, u_char data)
144 printk(KERN_DEBUG "tcic_setb(%#lx, %#x)\n", tcic_base+reg, data);
145 outb(data, tcic_base+reg);
148 static void tcic_setw(u_char reg, u_short data)
150 printk(KERN_DEBUG "tcic_setw(%#lx, %#x)\n", tcic_base+reg, data);
151 outw(data, tcic_base+reg);
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)
160 static void tcic_setl(u_char reg, u_int data)
163 printk(KERN_DEBUG "tcic_setl(%#x, %#lx)\n", tcic_base+reg, data);
165 outw(data & 0xffff, tcic_base+reg);
166 outw(data >> 16, tcic_base+reg+2);
169 static void tcic_aux_setb(u_short reg, u_char data)
171 u_char mode = (tcic_getb(TCIC_MODE) & TCIC_MODE_PGMMASK) | reg;
172 tcic_setb(TCIC_MODE, mode);
173 tcic_setb(TCIC_AUX, data);
176 static u_short tcic_aux_getw(u_short reg)
178 u_char mode = (tcic_getb(TCIC_MODE) & TCIC_MODE_PGMMASK) | reg;
179 tcic_setb(TCIC_MODE, mode);
180 return tcic_getw(TCIC_AUX);
183 static void tcic_aux_setw(u_short reg, u_short data)
185 u_char mode = (tcic_getb(TCIC_MODE) & TCIC_MODE_PGMMASK) | reg;
186 tcic_setb(TCIC_MODE, mode);
187 tcic_setw(TCIC_AUX, data);
190 /*====================================================================*/
192 /* Time conversion functions */
194 static int to_cycles(int ns)
199 return 2*(ns-14)/cycle_time;
202 /*====================================================================*/
204 static volatile u_int irq_hits;
206 static irqreturn_t __init tcic_irq_count(int irq, void *dev)
212 static u_int __init try_irq(int irq)
217 if (request_irq(irq, tcic_irq_count, 0, "irq scan", tcic_irq_count) != 0)
221 free_irq(irq, tcic_irq_count);
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);
232 free_irq(irq, tcic_irq_count);
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);
240 return (irq_hits != 1);
243 static u_int __init irq_scan(u_int mask0)
250 /* Don't probe level-triggered interrupts -- reserved for PCI */
251 int level_mask = inb_p(PIC) | (inb_p(PIC+1) << 8);
253 mask0 &= ~level_mask;
258 for (i = 0; i < 16; i++)
259 if ((mask0 & (1 << i)) && (try_irq(i) == 0))
261 for (i = 0; i < 16; i++)
262 if ((mask1 & (1 << i)) && (try_irq(i) != 0)) {
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)) {
275 free_irq(i, tcic_irq_count);
281 for (i = 0; i < 16; i++)
283 printk("%s%d", ((mask1 & ((1<<i)-1)) ? "," : ""), i);
289 /*======================================================================
291 See if a card is present, powered up, in IO mode, and already
292 bound to a (non-PCMCIA) Linux driver.
294 We make an exception for cards that look like serial devices.
296 ======================================================================*/
298 static int __init is_active(int s)
300 u_short scf1, ioctl, base, num;
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);
315 if (ioctl & TCIC_ICTL_TINY)
318 num = (base ^ (base-1));
319 base = base & (base-1);
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 */
328 release_region(base, num);
334 /*======================================================================
336 This returns the revision code for the specified socket.
338 ======================================================================*/
340 static int __init get_tcic_id(void)
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);
351 /*====================================================================*/
353 static struct platform_driver tcic_driver = {
355 .name = "tcic-pcmcia",
356 .owner = THIS_MODULE,
360 static struct platform_device tcic_device = {
361 .name = "tcic-pcmcia",
366 static int __init init_tcic(void)
368 int i, sock, ret = 0;
371 if (platform_driver_register(&tcic_driver))
374 printk(KERN_INFO "Databook TCIC-2 PCMCIA probe: ");
377 if (!request_region(tcic_base, 16, "tcic-2")) {
378 printk("could not allocate ports,\n ");
379 platform_driver_unregister(&tcic_driver);
383 tcic_setw(TCIC_ADDR, 0);
384 if (tcic_getw(TCIC_ADDR) == 0) {
385 tcic_setw(TCIC_ADDR, 0xc3a5);
386 if (tcic_getw(TCIC_ADDR) == 0xc3a5) sock = 2;
389 /* See if resetting the controller does any good */
390 tcic_setb(TCIC_SCTRL, TCIC_SCTRL_RESET);
391 tcic_setb(TCIC_SCTRL, 0);
392 tcic_setw(TCIC_ADDR, 0);
393 if (tcic_getw(TCIC_ADDR) == 0) {
394 tcic_setw(TCIC_ADDR, 0xc3a5);
395 if (tcic_getw(TCIC_ADDR) == 0xc3a5) sock = 2;
400 printk("not found.\n");
401 release_region(tcic_base, 16);
402 platform_driver_unregister(&tcic_driver);
407 for (i = 0; i < sock; i++) {
408 if ((i == ignore) || is_active(i)) continue;
409 socket_table[sockets].psock = i;
410 socket_table[sockets].id = get_tcic_id();
412 socket_table[sockets].socket.owner = THIS_MODULE;
413 /* only 16-bit cards, memory windows must be size-aligned */
414 /* No PCI or CardBus support */
415 socket_table[sockets].socket.features = SS_CAP_PCCARD | SS_CAP_MEM_ALIGN;
416 /* irq 14, 11, 10, 7, 6, 5, 4, 3 */
417 socket_table[sockets].socket.irq_mask = 0x4cf8;
418 /* 4K minimum window size */
419 socket_table[sockets].socket.map_size = 0x1000;
423 switch (socket_table[0].id) {
424 case TCIC_ID_DB86082:
425 printk("DB86082"); break;
426 case TCIC_ID_DB86082A:
427 printk("DB86082A"); break;
428 case TCIC_ID_DB86084:
429 printk("DB86084"); break;
430 case TCIC_ID_DB86084A:
431 printk("DB86084A"); break;
432 case TCIC_ID_DB86072:
433 printk("DB86072"); break;
434 case TCIC_ID_DB86184:
435 printk("DB86184"); break;
436 case TCIC_ID_DB86082B:
437 printk("DB86082B"); break;
439 printk("Unknown ID 0x%02x", socket_table[0].id);
443 poll_timer.function = &tcic_timer;
445 init_timer(&poll_timer);
447 /* Build interrupt mask */
448 printk(KERN_CONT ", %d sockets\n", sockets);
449 printk(KERN_INFO " irq list (");
450 if (irq_list_count == 0)
453 for (i = mask = 0; i < irq_list_count; i++)
454 mask |= (1<<irq_list[i]);
456 /* irq 14, 11, 10, 7, 6, 5, 4, 3 */
458 /* Scan interrupts */
459 mask = irq_scan(mask);
460 for (i=0;i<sockets;i++)
461 socket_table[i].socket.irq_mask = mask;
463 /* Check for only two interrupts available */
464 scan = (mask & (mask-1));
465 if (((scan & (scan-1)) == 0) && (poll_interval == 0))
468 if (poll_interval == 0) {
469 /* Avoid irq 12 unless it is explicitly requested */
470 u_int cs_mask = mask & ((cs_irq) ? (1<<cs_irq) : ~(1<<12));
471 for (i = 15; i > 0; i--)
472 if ((cs_mask & (1 << i)) &&
473 (request_irq(i, tcic_interrupt, 0, "tcic",
474 tcic_interrupt) == 0))
477 if (cs_irq == 0) poll_interval = HZ;
480 if (socket_table[0].socket.irq_mask & (1 << 11))
481 printk("sktirq is irq 11, ");
483 printk("status change on irq %d\n", cs_irq);
485 printk("polled status, interval = %d ms\n",
486 poll_interval * 1000 / HZ);
488 for (i = 0; i < sockets; i++) {
489 tcic_setw(TCIC_ADDR+2, socket_table[i].psock << TCIC_SS_SHFT);
490 socket_table[i].last_sstat = tcic_getb(TCIC_SSTAT);
493 /* jump start interrupt handler, if needed */
494 tcic_interrupt(0, NULL);
496 platform_device_register(&tcic_device);
498 for (i = 0; i < sockets; i++) {
499 socket_table[i].socket.ops = &tcic_operations;
500 socket_table[i].socket.resource_ops = &pccard_nonstatic_ops;
501 socket_table[i].socket.dev.parent = &tcic_device.dev;
502 ret = pcmcia_register_socket(&socket_table[i].socket);
504 pcmcia_unregister_socket(&socket_table[0].socket);
513 /*====================================================================*/
515 static void __exit exit_tcic(void)
519 del_timer_sync(&poll_timer);
521 tcic_aux_setw(TCIC_AUX_SYSCFG, TCIC_SYSCFG_AUTOBUSY|0x0a00);
522 free_irq(cs_irq, tcic_interrupt);
524 release_region(tcic_base, 16);
526 for (i = 0; i < sockets; i++) {
527 pcmcia_unregister_socket(&socket_table[i].socket);
530 platform_device_unregister(&tcic_device);
531 platform_driver_unregister(&tcic_driver);
534 /*====================================================================*/
536 static irqreturn_t tcic_interrupt(int irq, void *dev)
542 static volatile int active = 0;
545 printk(KERN_NOTICE "tcic: reentered interrupt handler!\n");
550 pr_debug("tcic_interrupt()\n");
552 for (i = 0; i < sockets; i++) {
553 psock = socket_table[i].psock;
554 tcic_setl(TCIC_ADDR, (psock << TCIC_ADDR_SS_SHFT)
555 | TCIC_ADDR_INDREG | TCIC_SCF1(psock));
556 sstat = tcic_getb(TCIC_SSTAT);
557 latch = sstat ^ socket_table[psock].last_sstat;
558 socket_table[i].last_sstat = sstat;
559 if (tcic_getb(TCIC_ICSR) & TCIC_ICSR_CDCHG) {
560 tcic_setb(TCIC_ICSR, TCIC_ICSR_CLEAR);
565 events = (latch & TCIC_SSTAT_CD) ? SS_DETECT : 0;
566 events |= (latch & TCIC_SSTAT_WP) ? SS_WRPROT : 0;
567 if (tcic_getw(TCIC_DATA) & TCIC_SCF1_IOSTS) {
568 events |= (latch & TCIC_SSTAT_LBAT1) ? SS_STSCHG : 0;
570 events |= (latch & TCIC_SSTAT_RDY) ? SS_READY : 0;
571 events |= (latch & TCIC_SSTAT_LBAT1) ? SS_BATDEAD : 0;
572 events |= (latch & TCIC_SSTAT_LBAT2) ? SS_BATWARN : 0;
575 pcmcia_parse_events(&socket_table[i].socket, events);
579 /* Schedule next poll, if needed */
580 if (((cs_irq == 0) || quick) && (!tcic_timer_pending)) {
581 poll_timer.expires = jiffies + (quick ? poll_quick : poll_interval);
582 add_timer(&poll_timer);
583 tcic_timer_pending = 1;
587 pr_debug("interrupt done\n");
589 } /* tcic_interrupt */
591 static void tcic_timer(u_long data)
593 pr_debug("tcic_timer()\n");
594 tcic_timer_pending = 0;
595 tcic_interrupt(0, NULL);
598 /*====================================================================*/
600 static int tcic_get_status(struct pcmcia_socket *sock, u_int *value)
602 u_short psock = container_of(sock, struct tcic_socket, socket)->psock;
605 tcic_setl(TCIC_ADDR, (psock << TCIC_ADDR_SS_SHFT)
606 | TCIC_ADDR_INDREG | TCIC_SCF1(psock));
607 reg = tcic_getb(TCIC_SSTAT);
608 *value = (reg & TCIC_SSTAT_CD) ? SS_DETECT : 0;
609 *value |= (reg & TCIC_SSTAT_WP) ? SS_WRPROT : 0;
610 if (tcic_getw(TCIC_DATA) & TCIC_SCF1_IOSTS) {
611 *value |= (reg & TCIC_SSTAT_LBAT1) ? SS_STSCHG : 0;
613 *value |= (reg & TCIC_SSTAT_RDY) ? SS_READY : 0;
614 *value |= (reg & TCIC_SSTAT_LBAT1) ? SS_BATDEAD : 0;
615 *value |= (reg & TCIC_SSTAT_LBAT2) ? SS_BATWARN : 0;
617 reg = tcic_getb(TCIC_PWR);
618 if (reg & (TCIC_PWR_VCC(psock)|TCIC_PWR_VPP(psock)))
619 *value |= SS_POWERON;
620 dev_dbg(&sock->dev, "GetStatus(%d) = %#2.2x\n", psock, *value);
622 } /* tcic_get_status */
624 /*====================================================================*/
626 static int tcic_set_socket(struct pcmcia_socket *sock, socket_state_t *state)
628 u_short psock = container_of(sock, struct tcic_socket, socket)->psock;
632 dev_dbg(&sock->dev, "SetSocket(%d, flags %#3.3x, Vcc %d, Vpp %d, "
633 "io_irq %d, csc_mask %#2.2x)\n", psock, state->flags,
634 state->Vcc, state->Vpp, state->io_irq, state->csc_mask);
635 tcic_setw(TCIC_ADDR+2, (psock << TCIC_SS_SHFT) | TCIC_ADR2_INDREG);
637 reg = tcic_getb(TCIC_PWR);
638 reg &= ~(TCIC_PWR_VCC(psock) | TCIC_PWR_VPP(psock));
640 if (state->Vcc == 50) {
641 switch (state->Vpp) {
642 case 0: reg |= TCIC_PWR_VCC(psock) | TCIC_PWR_VPP(psock); break;
643 case 50: reg |= TCIC_PWR_VCC(psock); break;
644 case 120: reg |= TCIC_PWR_VPP(psock); break;
645 default: return -EINVAL;
647 } else if (state->Vcc != 0)
650 if (reg != tcic_getb(TCIC_PWR))
651 tcic_setb(TCIC_PWR, reg);
653 reg = TCIC_ILOCK_HOLD_CCLK | TCIC_ILOCK_CWAIT;
654 if (state->flags & SS_OUTPUT_ENA) {
655 tcic_setb(TCIC_SCTRL, TCIC_SCTRL_ENA);
656 reg |= TCIC_ILOCK_CRESENA;
658 tcic_setb(TCIC_SCTRL, 0);
659 if (state->flags & SS_RESET)
660 reg |= TCIC_ILOCK_CRESET;
661 tcic_aux_setb(TCIC_AUX_ILOCK, reg);
663 tcic_setw(TCIC_ADDR, TCIC_SCF1(psock));
664 scf1 = TCIC_SCF1_FINPACK;
665 scf1 |= TCIC_IRQ(state->io_irq);
666 if (state->flags & SS_IOCARD) {
667 scf1 |= TCIC_SCF1_IOSTS;
668 if (state->flags & SS_SPKR_ENA)
669 scf1 |= TCIC_SCF1_SPKR;
670 if (state->flags & SS_DMA_MODE)
671 scf1 |= TCIC_SCF1_DREQ2 << TCIC_SCF1_DMA_SHIFT;
673 tcic_setw(TCIC_DATA, scf1);
675 /* Some general setup stuff, and configure status interrupt */
676 reg = TCIC_WAIT_ASYNC | TCIC_WAIT_SENSE | to_cycles(250);
677 tcic_aux_setb(TCIC_AUX_WCTL, reg);
678 tcic_aux_setw(TCIC_AUX_SYSCFG, TCIC_SYSCFG_AUTOBUSY|0x0a00|
681 /* Card status change interrupt mask */
682 tcic_setw(TCIC_ADDR, TCIC_SCF2(psock));
683 scf2 = TCIC_SCF2_MALL;
684 if (state->csc_mask & SS_DETECT) scf2 &= ~TCIC_SCF2_MCD;
685 if (state->flags & SS_IOCARD) {
686 if (state->csc_mask & SS_STSCHG) reg &= ~TCIC_SCF2_MLBAT1;
688 if (state->csc_mask & SS_BATDEAD) reg &= ~TCIC_SCF2_MLBAT1;
689 if (state->csc_mask & SS_BATWARN) reg &= ~TCIC_SCF2_MLBAT2;
690 if (state->csc_mask & SS_READY) reg &= ~TCIC_SCF2_MRDY;
692 tcic_setw(TCIC_DATA, scf2);
693 /* For the ISA bus, the irq should be active-high totem-pole */
694 tcic_setb(TCIC_IENA, TCIC_IENA_CDCHG | TCIC_IENA_CFG_HIGH);
697 } /* tcic_set_socket */
699 /*====================================================================*/
701 static int tcic_set_io_map(struct pcmcia_socket *sock, struct pccard_io_map *io)
703 u_short psock = container_of(sock, struct tcic_socket, socket)->psock;
705 u_short base, len, ioctl;
707 dev_dbg(&sock->dev, "SetIOMap(%d, %d, %#2.2x, %d ns, "
708 "%#llx-%#llx)\n", psock, io->map, io->flags, io->speed,
709 (unsigned long long)io->start, (unsigned long long)io->stop);
710 if ((io->map > 1) || (io->start > 0xffff) || (io->stop > 0xffff) ||
711 (io->stop < io->start)) return -EINVAL;
712 tcic_setw(TCIC_ADDR+2, TCIC_ADR2_INDREG | (psock << TCIC_SS_SHFT));
713 addr = TCIC_IWIN(psock, io->map);
715 base = io->start; len = io->stop - io->start;
716 /* Check to see that len+1 is power of two, etc */
717 if ((len & (len+1)) || (base & len)) return -EINVAL;
719 tcic_setw(TCIC_ADDR, addr + TCIC_IBASE_X);
720 tcic_setw(TCIC_DATA, base);
722 ioctl = (psock << TCIC_ICTL_SS_SHFT);
723 ioctl |= (len == 0) ? TCIC_ICTL_TINY : 0;
724 ioctl |= (io->flags & MAP_ACTIVE) ? TCIC_ICTL_ENA : 0;
725 ioctl |= to_cycles(io->speed) & TCIC_ICTL_WSCNT_MASK;
726 if (!(io->flags & MAP_AUTOSZ)) {
727 ioctl |= TCIC_ICTL_QUIET;
728 ioctl |= (io->flags & MAP_16BIT) ? TCIC_ICTL_BW_16 : TCIC_ICTL_BW_8;
730 tcic_setw(TCIC_ADDR, addr + TCIC_ICTL_X);
731 tcic_setw(TCIC_DATA, ioctl);
734 } /* tcic_set_io_map */
736 /*====================================================================*/
738 static int tcic_set_mem_map(struct pcmcia_socket *sock, struct pccard_mem_map *mem)
740 u_short psock = container_of(sock, struct tcic_socket, socket)->psock;
742 u_long base, len, mmap;
744 dev_dbg(&sock->dev, "SetMemMap(%d, %d, %#2.2x, %d ns, "
745 "%#llx-%#llx, %#x)\n", psock, mem->map, mem->flags,
746 mem->speed, (unsigned long long)mem->res->start,
747 (unsigned long long)mem->res->end, mem->card_start);
748 if ((mem->map > 3) || (mem->card_start > 0x3ffffff) ||
749 (mem->res->start > 0xffffff) || (mem->res->end > 0xffffff) ||
750 (mem->res->start > mem->res->end) || (mem->speed > 1000))
752 tcic_setw(TCIC_ADDR+2, TCIC_ADR2_INDREG | (psock << TCIC_SS_SHFT));
753 addr = TCIC_MWIN(psock, mem->map);
755 base = mem->res->start; len = mem->res->end - mem->res->start;
756 if ((len & (len+1)) || (base & len)) return -EINVAL;
758 base = (base >> TCIC_MBASE_HA_SHFT) | TCIC_MBASE_4K_BIT;
760 base = (base | (len+1)>>1) >> TCIC_MBASE_HA_SHFT;
761 tcic_setw(TCIC_ADDR, addr + TCIC_MBASE_X);
762 tcic_setw(TCIC_DATA, base);
764 mmap = mem->card_start - mem->res->start;
765 mmap = (mmap >> TCIC_MMAP_CA_SHFT) & TCIC_MMAP_CA_MASK;
766 if (mem->flags & MAP_ATTRIB) mmap |= TCIC_MMAP_REG;
767 tcic_setw(TCIC_ADDR, addr + TCIC_MMAP_X);
768 tcic_setw(TCIC_DATA, mmap);
770 ctl = TCIC_MCTL_QUIET | (psock << TCIC_MCTL_SS_SHFT);
771 ctl |= to_cycles(mem->speed) & TCIC_MCTL_WSCNT_MASK;
772 ctl |= (mem->flags & MAP_16BIT) ? 0 : TCIC_MCTL_B8;
773 ctl |= (mem->flags & MAP_WRPROT) ? TCIC_MCTL_WP : 0;
774 ctl |= (mem->flags & MAP_ACTIVE) ? TCIC_MCTL_ENA : 0;
775 tcic_setw(TCIC_ADDR, addr + TCIC_MCTL_X);
776 tcic_setw(TCIC_DATA, ctl);
779 } /* tcic_set_mem_map */
781 /*====================================================================*/
783 static int tcic_init(struct pcmcia_socket *s)
786 struct resource res = { .start = 0, .end = 0x1000 };
787 pccard_io_map io = { 0, 0, 0, 0, 1 };
788 pccard_mem_map mem = { .res = &res, };
790 for (i = 0; i < 2; i++) {
792 tcic_set_io_map(s, &io);
794 for (i = 0; i < 5; i++) {
796 tcic_set_mem_map(s, &mem);
801 static struct pccard_operations tcic_operations = {
803 .get_status = tcic_get_status,
804 .set_socket = tcic_set_socket,
805 .set_io_map = tcic_set_io_map,
806 .set_mem_map = tcic_set_mem_map,
809 /*====================================================================*/
811 module_init(init_tcic);
812 module_exit(exit_tcic);