0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034 #include <linux/module.h>
0035 #include <linux/moduleparam.h>
0036 #include <linux/init.h>
0037 #include <linux/types.h>
0038 #include <linux/fcntl.h>
0039 #include <linux/string.h>
0040 #include <linux/errno.h>
0041 #include <linux/interrupt.h>
0042 #include <linux/timer.h>
0043 #include <linux/ioport.h>
0044 #include <linux/delay.h>
0045 #include <linux/workqueue.h>
0046 #include <linux/platform_device.h>
0047 #include <linux/bitops.h>
0048
0049 #include <asm/io.h>
0050
0051 #include <pcmcia/ss.h>
0052 #include "tcic.h"
0053
0054 MODULE_AUTHOR("David Hinds <dahinds@users.sourceforge.net>");
0055 MODULE_DESCRIPTION("Databook TCIC-2 PCMCIA socket driver");
0056 MODULE_LICENSE("Dual MPL/GPL");
0057
0058
0059
0060
0061
0062
0063 static unsigned long tcic_base = TCIC_BASE;
0064
0065
0066 static int ignore = -1;
0067
0068
0069 static int do_scan = 1;
0070
0071
0072 static u_int irq_mask = 0xffff;
0073 static int irq_list[16];
0074 static unsigned int irq_list_count;
0075
0076
0077 static int cs_irq;
0078
0079
0080 static int poll_interval;
0081
0082
0083 static int poll_quick = HZ/20;
0084
0085
0086 static int cycle_time = 70;
0087
0088 module_param_hw(tcic_base, ulong, ioport, 0444);
0089 module_param(ignore, int, 0444);
0090 module_param(do_scan, int, 0444);
0091 module_param_hw(irq_mask, int, other, 0444);
0092 module_param_hw_array(irq_list, int, irq, &irq_list_count, 0444);
0093 module_param_hw(cs_irq, int, irq, 0444);
0094 module_param(poll_interval, int, 0444);
0095 module_param(poll_quick, int, 0444);
0096 module_param(cycle_time, int, 0444);
0097
0098
0099
0100 static irqreturn_t tcic_interrupt(int irq, void *dev);
0101 static void tcic_timer(struct timer_list *unused);
0102 static struct pccard_operations tcic_operations;
0103
0104 struct tcic_socket {
0105 u_short psock;
0106 u_char last_sstat;
0107 u_char id;
0108 struct pcmcia_socket socket;
0109 };
0110
0111 static struct timer_list poll_timer;
0112 static int tcic_timer_pending;
0113
0114 static int sockets;
0115 static struct tcic_socket socket_table[2];
0116
0117
0118
0119
0120
0121 #define TCIC_IRQ(x) ((x) ? (((x) == 11) ? 1 : (x)) : 15)
0122
0123 #ifdef DEBUG_X
0124 static u_char tcic_getb(u_char reg)
0125 {
0126 u_char val = inb(tcic_base+reg);
0127 printk(KERN_DEBUG "tcic_getb(%#lx) = %#x\n", tcic_base+reg, val);
0128 return val;
0129 }
0130
0131 static u_short tcic_getw(u_char reg)
0132 {
0133 u_short val = inw(tcic_base+reg);
0134 printk(KERN_DEBUG "tcic_getw(%#lx) = %#x\n", tcic_base+reg, val);
0135 return val;
0136 }
0137
0138 static void tcic_setb(u_char reg, u_char data)
0139 {
0140 printk(KERN_DEBUG "tcic_setb(%#lx, %#x)\n", tcic_base+reg, data);
0141 outb(data, tcic_base+reg);
0142 }
0143
0144 static void tcic_setw(u_char reg, u_short data)
0145 {
0146 printk(KERN_DEBUG "tcic_setw(%#lx, %#x)\n", tcic_base+reg, data);
0147 outw(data, tcic_base+reg);
0148 }
0149 #else
0150 #define tcic_getb(reg) inb(tcic_base+reg)
0151 #define tcic_getw(reg) inw(tcic_base+reg)
0152 #define tcic_setb(reg, data) outb(data, tcic_base+reg)
0153 #define tcic_setw(reg, data) outw(data, tcic_base+reg)
0154 #endif
0155
0156 static void tcic_setl(u_char reg, u_int data)
0157 {
0158 #ifdef DEBUG_X
0159 printk(KERN_DEBUG "tcic_setl(%#x, %#lx)\n", tcic_base+reg, data);
0160 #endif
0161 outw(data & 0xffff, tcic_base+reg);
0162 outw(data >> 16, tcic_base+reg+2);
0163 }
0164
0165 static void tcic_aux_setb(u_short reg, u_char data)
0166 {
0167 u_char mode = (tcic_getb(TCIC_MODE) & TCIC_MODE_PGMMASK) | reg;
0168 tcic_setb(TCIC_MODE, mode);
0169 tcic_setb(TCIC_AUX, data);
0170 }
0171
0172 static u_short tcic_aux_getw(u_short reg)
0173 {
0174 u_char mode = (tcic_getb(TCIC_MODE) & TCIC_MODE_PGMMASK) | reg;
0175 tcic_setb(TCIC_MODE, mode);
0176 return tcic_getw(TCIC_AUX);
0177 }
0178
0179 static void tcic_aux_setw(u_short reg, u_short data)
0180 {
0181 u_char mode = (tcic_getb(TCIC_MODE) & TCIC_MODE_PGMMASK) | reg;
0182 tcic_setb(TCIC_MODE, mode);
0183 tcic_setw(TCIC_AUX, data);
0184 }
0185
0186
0187
0188
0189
0190 static int to_cycles(int ns)
0191 {
0192 if (ns < 14)
0193 return 0;
0194 else
0195 return 2*(ns-14)/cycle_time;
0196 }
0197
0198
0199
0200 static volatile u_int irq_hits;
0201
0202 static irqreturn_t __init tcic_irq_count(int irq, void *dev)
0203 {
0204 irq_hits++;
0205 return IRQ_HANDLED;
0206 }
0207
0208 static u_int __init try_irq(int irq)
0209 {
0210 u_short cfg;
0211
0212 irq_hits = 0;
0213 if (request_irq(irq, tcic_irq_count, 0, "irq scan", tcic_irq_count) != 0)
0214 return -1;
0215 mdelay(10);
0216 if (irq_hits) {
0217 free_irq(irq, tcic_irq_count);
0218 return -1;
0219 }
0220
0221
0222 cfg = TCIC_SYSCFG_AUTOBUSY | 0x0a00;
0223 tcic_aux_setw(TCIC_AUX_SYSCFG, cfg | TCIC_IRQ(irq));
0224 tcic_setb(TCIC_IENA, TCIC_IENA_ERR | TCIC_IENA_CFG_HIGH);
0225 tcic_setb(TCIC_ICSR, TCIC_ICSR_ERR | TCIC_ICSR_JAM);
0226
0227 udelay(1000);
0228 free_irq(irq, tcic_irq_count);
0229
0230
0231 tcic_setb(TCIC_IENA, TCIC_IENA_CFG_OFF);
0232 while (tcic_getb(TCIC_ICSR))
0233 tcic_setb(TCIC_ICSR, TCIC_ICSR_JAM);
0234 tcic_aux_setw(TCIC_AUX_SYSCFG, cfg);
0235
0236 return (irq_hits != 1);
0237 }
0238
0239 static u_int __init irq_scan(u_int mask0)
0240 {
0241 u_int mask1;
0242 int i;
0243
0244 #ifdef __alpha__
0245 #define PIC 0x4d0
0246
0247 int level_mask = inb_p(PIC) | (inb_p(PIC+1) << 8);
0248 if (level_mask)
0249 mask0 &= ~level_mask;
0250 #endif
0251
0252 mask1 = 0;
0253 if (do_scan) {
0254 for (i = 0; i < 16; i++)
0255 if ((mask0 & (1 << i)) && (try_irq(i) == 0))
0256 mask1 |= (1 << i);
0257 for (i = 0; i < 16; i++)
0258 if ((mask1 & (1 << i)) && (try_irq(i) != 0)) {
0259 mask1 ^= (1 << i);
0260 }
0261 }
0262
0263 if (mask1) {
0264 printk("scanned");
0265 } else {
0266
0267 for (i = 0; i < 16; i++)
0268 if ((mask0 & (1 << i)) &&
0269 (request_irq(i, tcic_irq_count, 0, "x", tcic_irq_count) == 0)) {
0270 mask1 |= (1 << i);
0271 free_irq(i, tcic_irq_count);
0272 }
0273 printk("default");
0274 }
0275
0276 printk(") = ");
0277 for (i = 0; i < 16; i++)
0278 if (mask1 & (1<<i))
0279 printk("%s%d", ((mask1 & ((1<<i)-1)) ? "," : ""), i);
0280 printk(" ");
0281
0282 return mask1;
0283 }
0284
0285
0286
0287
0288
0289
0290
0291
0292
0293
0294 static int __init is_active(int s)
0295 {
0296 u_short scf1, ioctl, base, num;
0297 u_char pwr, sstat;
0298 u_int addr;
0299
0300 tcic_setl(TCIC_ADDR, (s << TCIC_ADDR_SS_SHFT)
0301 | TCIC_ADDR_INDREG | TCIC_SCF1(s));
0302 scf1 = tcic_getw(TCIC_DATA);
0303 pwr = tcic_getb(TCIC_PWR);
0304 sstat = tcic_getb(TCIC_SSTAT);
0305 addr = TCIC_IWIN(s, 0);
0306 tcic_setw(TCIC_ADDR, addr + TCIC_IBASE_X);
0307 base = tcic_getw(TCIC_DATA);
0308 tcic_setw(TCIC_ADDR, addr + TCIC_ICTL_X);
0309 ioctl = tcic_getw(TCIC_DATA);
0310
0311 if (ioctl & TCIC_ICTL_TINY)
0312 num = 1;
0313 else {
0314 num = (base ^ (base-1));
0315 base = base & (base-1);
0316 }
0317
0318 if ((sstat & TCIC_SSTAT_CD) && (pwr & TCIC_PWR_VCC(s)) &&
0319 (scf1 & TCIC_SCF1_IOSTS) && (ioctl & TCIC_ICTL_ENA) &&
0320 ((base & 0xfeef) != 0x02e8)) {
0321 struct resource *res = request_region(base, num, "tcic-2");
0322 if (!res)
0323 return 1;
0324 release_region(base, num);
0325 }
0326
0327 return 0;
0328 }
0329
0330
0331
0332
0333
0334
0335
0336 static int __init get_tcic_id(void)
0337 {
0338 u_short id;
0339
0340 tcic_aux_setw(TCIC_AUX_TEST, TCIC_TEST_DIAG);
0341 id = tcic_aux_getw(TCIC_AUX_ILOCK);
0342 id = (id & TCIC_ILOCKTEST_ID_MASK) >> TCIC_ILOCKTEST_ID_SH;
0343 tcic_aux_setw(TCIC_AUX_TEST, 0);
0344 return id;
0345 }
0346
0347
0348
0349 static struct platform_driver tcic_driver = {
0350 .driver = {
0351 .name = "tcic-pcmcia",
0352 },
0353 };
0354
0355 static struct platform_device tcic_device = {
0356 .name = "tcic-pcmcia",
0357 .id = 0,
0358 };
0359
0360
0361 static int __init init_tcic(void)
0362 {
0363 int i, sock, ret = 0;
0364 u_int mask, scan;
0365
0366 if (platform_driver_register(&tcic_driver))
0367 return -1;
0368
0369 printk(KERN_INFO "Databook TCIC-2 PCMCIA probe: ");
0370 sock = 0;
0371
0372 if (!request_region(tcic_base, 16, "tcic-2")) {
0373 printk("could not allocate ports,\n ");
0374 platform_driver_unregister(&tcic_driver);
0375 return -ENODEV;
0376 }
0377 else {
0378 tcic_setw(TCIC_ADDR, 0);
0379 if (tcic_getw(TCIC_ADDR) == 0) {
0380 tcic_setw(TCIC_ADDR, 0xc3a5);
0381 if (tcic_getw(TCIC_ADDR) == 0xc3a5) sock = 2;
0382 }
0383 if (sock == 0) {
0384
0385 tcic_setb(TCIC_SCTRL, TCIC_SCTRL_RESET);
0386 tcic_setb(TCIC_SCTRL, 0);
0387 tcic_setw(TCIC_ADDR, 0);
0388 if (tcic_getw(TCIC_ADDR) == 0) {
0389 tcic_setw(TCIC_ADDR, 0xc3a5);
0390 if (tcic_getw(TCIC_ADDR) == 0xc3a5) sock = 2;
0391 }
0392 }
0393 }
0394 if (sock == 0) {
0395 printk("not found.\n");
0396 release_region(tcic_base, 16);
0397 platform_driver_unregister(&tcic_driver);
0398 return -ENODEV;
0399 }
0400
0401 sockets = 0;
0402 for (i = 0; i < sock; i++) {
0403 if ((i == ignore) || is_active(i)) continue;
0404 socket_table[sockets].psock = i;
0405 socket_table[sockets].id = get_tcic_id();
0406
0407 socket_table[sockets].socket.owner = THIS_MODULE;
0408
0409
0410 socket_table[sockets].socket.features = SS_CAP_PCCARD | SS_CAP_MEM_ALIGN;
0411
0412 socket_table[sockets].socket.irq_mask = 0x4cf8;
0413
0414 socket_table[sockets].socket.map_size = 0x1000;
0415 sockets++;
0416 }
0417
0418 switch (socket_table[0].id) {
0419 case TCIC_ID_DB86082:
0420 printk("DB86082"); break;
0421 case TCIC_ID_DB86082A:
0422 printk("DB86082A"); break;
0423 case TCIC_ID_DB86084:
0424 printk("DB86084"); break;
0425 case TCIC_ID_DB86084A:
0426 printk("DB86084A"); break;
0427 case TCIC_ID_DB86072:
0428 printk("DB86072"); break;
0429 case TCIC_ID_DB86184:
0430 printk("DB86184"); break;
0431 case TCIC_ID_DB86082B:
0432 printk("DB86082B"); break;
0433 default:
0434 printk("Unknown ID 0x%02x", socket_table[0].id);
0435 }
0436
0437
0438 timer_setup(&poll_timer, &tcic_timer, 0);
0439
0440
0441 printk(KERN_CONT ", %d sockets\n", sockets);
0442 printk(KERN_INFO " irq list (");
0443 if (irq_list_count == 0)
0444 mask = irq_mask;
0445 else
0446 for (i = mask = 0; i < irq_list_count; i++)
0447 mask |= (1<<irq_list[i]);
0448
0449
0450 mask &= 0x4cf8;
0451
0452 mask = irq_scan(mask);
0453 for (i=0;i<sockets;i++)
0454 socket_table[i].socket.irq_mask = mask;
0455
0456
0457 scan = (mask & (mask-1));
0458 if (((scan & (scan-1)) == 0) && (poll_interval == 0))
0459 poll_interval = HZ;
0460
0461 if (poll_interval == 0) {
0462
0463 u_int cs_mask = mask & ((cs_irq) ? (1<<cs_irq) : ~(1<<12));
0464 for (i = 15; i > 0; i--)
0465 if ((cs_mask & (1 << i)) &&
0466 (request_irq(i, tcic_interrupt, 0, "tcic",
0467 tcic_interrupt) == 0))
0468 break;
0469 cs_irq = i;
0470 if (cs_irq == 0) poll_interval = HZ;
0471 }
0472
0473 if (socket_table[0].socket.irq_mask & (1 << 11))
0474 printk("sktirq is irq 11, ");
0475 if (cs_irq != 0)
0476 printk("status change on irq %d\n", cs_irq);
0477 else
0478 printk("polled status, interval = %d ms\n",
0479 poll_interval * 1000 / HZ);
0480
0481 for (i = 0; i < sockets; i++) {
0482 tcic_setw(TCIC_ADDR+2, socket_table[i].psock << TCIC_SS_SHFT);
0483 socket_table[i].last_sstat = tcic_getb(TCIC_SSTAT);
0484 }
0485
0486
0487 tcic_interrupt(0, NULL);
0488
0489 platform_device_register(&tcic_device);
0490
0491 for (i = 0; i < sockets; i++) {
0492 socket_table[i].socket.ops = &tcic_operations;
0493 socket_table[i].socket.resource_ops = &pccard_nonstatic_ops;
0494 socket_table[i].socket.dev.parent = &tcic_device.dev;
0495 ret = pcmcia_register_socket(&socket_table[i].socket);
0496 if (ret && i)
0497 pcmcia_unregister_socket(&socket_table[0].socket);
0498 }
0499
0500 return ret;
0501
0502 return 0;
0503
0504 }
0505
0506
0507
0508 static void __exit exit_tcic(void)
0509 {
0510 int i;
0511
0512 del_timer_sync(&poll_timer);
0513 if (cs_irq != 0) {
0514 tcic_aux_setw(TCIC_AUX_SYSCFG, TCIC_SYSCFG_AUTOBUSY|0x0a00);
0515 free_irq(cs_irq, tcic_interrupt);
0516 }
0517 release_region(tcic_base, 16);
0518
0519 for (i = 0; i < sockets; i++) {
0520 pcmcia_unregister_socket(&socket_table[i].socket);
0521 }
0522
0523 platform_device_unregister(&tcic_device);
0524 platform_driver_unregister(&tcic_driver);
0525 }
0526
0527
0528
0529 static irqreturn_t tcic_interrupt(int irq, void *dev)
0530 {
0531 int i, quick = 0;
0532 u_char latch, sstat;
0533 u_short psock;
0534 u_int events;
0535 static volatile int active = 0;
0536
0537 if (active) {
0538 printk(KERN_NOTICE "tcic: reentered interrupt handler!\n");
0539 return IRQ_NONE;
0540 } else
0541 active = 1;
0542
0543 pr_debug("tcic_interrupt()\n");
0544
0545 for (i = 0; i < sockets; i++) {
0546 psock = socket_table[i].psock;
0547 tcic_setl(TCIC_ADDR, (psock << TCIC_ADDR_SS_SHFT)
0548 | TCIC_ADDR_INDREG | TCIC_SCF1(psock));
0549 sstat = tcic_getb(TCIC_SSTAT);
0550 latch = sstat ^ socket_table[psock].last_sstat;
0551 socket_table[i].last_sstat = sstat;
0552 if (tcic_getb(TCIC_ICSR) & TCIC_ICSR_CDCHG) {
0553 tcic_setb(TCIC_ICSR, TCIC_ICSR_CLEAR);
0554 quick = 1;
0555 }
0556 if (latch == 0)
0557 continue;
0558 events = (latch & TCIC_SSTAT_CD) ? SS_DETECT : 0;
0559 events |= (latch & TCIC_SSTAT_WP) ? SS_WRPROT : 0;
0560 if (tcic_getw(TCIC_DATA) & TCIC_SCF1_IOSTS) {
0561 events |= (latch & TCIC_SSTAT_LBAT1) ? SS_STSCHG : 0;
0562 } else {
0563 events |= (latch & TCIC_SSTAT_RDY) ? SS_READY : 0;
0564 events |= (latch & TCIC_SSTAT_LBAT1) ? SS_BATDEAD : 0;
0565 events |= (latch & TCIC_SSTAT_LBAT2) ? SS_BATWARN : 0;
0566 }
0567 if (events) {
0568 pcmcia_parse_events(&socket_table[i].socket, events);
0569 }
0570 }
0571
0572
0573 if (((cs_irq == 0) || quick) && (!tcic_timer_pending)) {
0574 poll_timer.expires = jiffies + (quick ? poll_quick : poll_interval);
0575 add_timer(&poll_timer);
0576 tcic_timer_pending = 1;
0577 }
0578 active = 0;
0579
0580 pr_debug("interrupt done\n");
0581 return IRQ_HANDLED;
0582 }
0583
0584 static void tcic_timer(struct timer_list *unused)
0585 {
0586 pr_debug("tcic_timer()\n");
0587 tcic_timer_pending = 0;
0588 tcic_interrupt(0, NULL);
0589 }
0590
0591
0592
0593 static int tcic_get_status(struct pcmcia_socket *sock, u_int *value)
0594 {
0595 u_short psock = container_of(sock, struct tcic_socket, socket)->psock;
0596 u_char reg;
0597
0598 tcic_setl(TCIC_ADDR, (psock << TCIC_ADDR_SS_SHFT)
0599 | TCIC_ADDR_INDREG | TCIC_SCF1(psock));
0600 reg = tcic_getb(TCIC_SSTAT);
0601 *value = (reg & TCIC_SSTAT_CD) ? SS_DETECT : 0;
0602 *value |= (reg & TCIC_SSTAT_WP) ? SS_WRPROT : 0;
0603 if (tcic_getw(TCIC_DATA) & TCIC_SCF1_IOSTS) {
0604 *value |= (reg & TCIC_SSTAT_LBAT1) ? SS_STSCHG : 0;
0605 } else {
0606 *value |= (reg & TCIC_SSTAT_RDY) ? SS_READY : 0;
0607 *value |= (reg & TCIC_SSTAT_LBAT1) ? SS_BATDEAD : 0;
0608 *value |= (reg & TCIC_SSTAT_LBAT2) ? SS_BATWARN : 0;
0609 }
0610 reg = tcic_getb(TCIC_PWR);
0611 if (reg & (TCIC_PWR_VCC(psock)|TCIC_PWR_VPP(psock)))
0612 *value |= SS_POWERON;
0613 dev_dbg(&sock->dev, "GetStatus(%d) = %#2.2x\n", psock, *value);
0614 return 0;
0615 }
0616
0617
0618
0619 static int tcic_set_socket(struct pcmcia_socket *sock, socket_state_t *state)
0620 {
0621 u_short psock = container_of(sock, struct tcic_socket, socket)->psock;
0622 u_char reg;
0623 u_short scf1, scf2;
0624
0625 dev_dbg(&sock->dev, "SetSocket(%d, flags %#3.3x, Vcc %d, Vpp %d, "
0626 "io_irq %d, csc_mask %#2.2x)\n", psock, state->flags,
0627 state->Vcc, state->Vpp, state->io_irq, state->csc_mask);
0628 tcic_setw(TCIC_ADDR+2, (psock << TCIC_SS_SHFT) | TCIC_ADR2_INDREG);
0629
0630 reg = tcic_getb(TCIC_PWR);
0631 reg &= ~(TCIC_PWR_VCC(psock) | TCIC_PWR_VPP(psock));
0632
0633 if (state->Vcc == 50) {
0634 switch (state->Vpp) {
0635 case 0: reg |= TCIC_PWR_VCC(psock) | TCIC_PWR_VPP(psock); break;
0636 case 50: reg |= TCIC_PWR_VCC(psock); break;
0637 case 120: reg |= TCIC_PWR_VPP(psock); break;
0638 default: return -EINVAL;
0639 }
0640 } else if (state->Vcc != 0)
0641 return -EINVAL;
0642
0643 if (reg != tcic_getb(TCIC_PWR))
0644 tcic_setb(TCIC_PWR, reg);
0645
0646 reg = TCIC_ILOCK_HOLD_CCLK | TCIC_ILOCK_CWAIT;
0647 if (state->flags & SS_OUTPUT_ENA) {
0648 tcic_setb(TCIC_SCTRL, TCIC_SCTRL_ENA);
0649 reg |= TCIC_ILOCK_CRESENA;
0650 } else
0651 tcic_setb(TCIC_SCTRL, 0);
0652 if (state->flags & SS_RESET)
0653 reg |= TCIC_ILOCK_CRESET;
0654 tcic_aux_setb(TCIC_AUX_ILOCK, reg);
0655
0656 tcic_setw(TCIC_ADDR, TCIC_SCF1(psock));
0657 scf1 = TCIC_SCF1_FINPACK;
0658 scf1 |= TCIC_IRQ(state->io_irq);
0659 if (state->flags & SS_IOCARD) {
0660 scf1 |= TCIC_SCF1_IOSTS;
0661 if (state->flags & SS_SPKR_ENA)
0662 scf1 |= TCIC_SCF1_SPKR;
0663 if (state->flags & SS_DMA_MODE)
0664 scf1 |= TCIC_SCF1_DREQ2 << TCIC_SCF1_DMA_SHIFT;
0665 }
0666 tcic_setw(TCIC_DATA, scf1);
0667
0668
0669 reg = TCIC_WAIT_ASYNC | TCIC_WAIT_SENSE | to_cycles(250);
0670 tcic_aux_setb(TCIC_AUX_WCTL, reg);
0671 tcic_aux_setw(TCIC_AUX_SYSCFG, TCIC_SYSCFG_AUTOBUSY|0x0a00|
0672 TCIC_IRQ(cs_irq));
0673
0674
0675 tcic_setw(TCIC_ADDR, TCIC_SCF2(psock));
0676 scf2 = TCIC_SCF2_MALL;
0677 if (state->csc_mask & SS_DETECT) scf2 &= ~TCIC_SCF2_MCD;
0678 if (state->flags & SS_IOCARD) {
0679 if (state->csc_mask & SS_STSCHG) reg &= ~TCIC_SCF2_MLBAT1;
0680 } else {
0681 if (state->csc_mask & SS_BATDEAD) reg &= ~TCIC_SCF2_MLBAT1;
0682 if (state->csc_mask & SS_BATWARN) reg &= ~TCIC_SCF2_MLBAT2;
0683 if (state->csc_mask & SS_READY) reg &= ~TCIC_SCF2_MRDY;
0684 }
0685 tcic_setw(TCIC_DATA, scf2);
0686
0687 tcic_setb(TCIC_IENA, TCIC_IENA_CDCHG | TCIC_IENA_CFG_HIGH);
0688
0689 return 0;
0690 }
0691
0692
0693
0694 static int tcic_set_io_map(struct pcmcia_socket *sock, struct pccard_io_map *io)
0695 {
0696 u_short psock = container_of(sock, struct tcic_socket, socket)->psock;
0697 u_int addr;
0698 u_short base, len, ioctl;
0699
0700 dev_dbg(&sock->dev, "SetIOMap(%d, %d, %#2.2x, %d ns, "
0701 "%#llx-%#llx)\n", psock, io->map, io->flags, io->speed,
0702 (unsigned long long)io->start, (unsigned long long)io->stop);
0703 if ((io->map > 1) || (io->start > 0xffff) || (io->stop > 0xffff) ||
0704 (io->stop < io->start)) return -EINVAL;
0705 tcic_setw(TCIC_ADDR+2, TCIC_ADR2_INDREG | (psock << TCIC_SS_SHFT));
0706 addr = TCIC_IWIN(psock, io->map);
0707
0708 base = io->start; len = io->stop - io->start;
0709
0710 if ((len & (len+1)) || (base & len)) return -EINVAL;
0711 base |= (len+1)>>1;
0712 tcic_setw(TCIC_ADDR, addr + TCIC_IBASE_X);
0713 tcic_setw(TCIC_DATA, base);
0714
0715 ioctl = (psock << TCIC_ICTL_SS_SHFT);
0716 ioctl |= (len == 0) ? TCIC_ICTL_TINY : 0;
0717 ioctl |= (io->flags & MAP_ACTIVE) ? TCIC_ICTL_ENA : 0;
0718 ioctl |= to_cycles(io->speed) & TCIC_ICTL_WSCNT_MASK;
0719 if (!(io->flags & MAP_AUTOSZ)) {
0720 ioctl |= TCIC_ICTL_QUIET;
0721 ioctl |= (io->flags & MAP_16BIT) ? TCIC_ICTL_BW_16 : TCIC_ICTL_BW_8;
0722 }
0723 tcic_setw(TCIC_ADDR, addr + TCIC_ICTL_X);
0724 tcic_setw(TCIC_DATA, ioctl);
0725
0726 return 0;
0727 }
0728
0729
0730
0731 static int tcic_set_mem_map(struct pcmcia_socket *sock, struct pccard_mem_map *mem)
0732 {
0733 u_short psock = container_of(sock, struct tcic_socket, socket)->psock;
0734 u_short addr, ctl;
0735 u_long base, len, mmap;
0736
0737 dev_dbg(&sock->dev, "SetMemMap(%d, %d, %#2.2x, %d ns, "
0738 "%#llx-%#llx, %#x)\n", psock, mem->map, mem->flags,
0739 mem->speed, (unsigned long long)mem->res->start,
0740 (unsigned long long)mem->res->end, mem->card_start);
0741 if ((mem->map > 3) || (mem->card_start > 0x3ffffff) ||
0742 (mem->res->start > 0xffffff) || (mem->res->end > 0xffffff) ||
0743 (mem->res->start > mem->res->end) || (mem->speed > 1000))
0744 return -EINVAL;
0745 tcic_setw(TCIC_ADDR+2, TCIC_ADR2_INDREG | (psock << TCIC_SS_SHFT));
0746 addr = TCIC_MWIN(psock, mem->map);
0747
0748 base = mem->res->start; len = mem->res->end - mem->res->start;
0749 if ((len & (len+1)) || (base & len)) return -EINVAL;
0750 if (len == 0x0fff)
0751 base = (base >> TCIC_MBASE_HA_SHFT) | TCIC_MBASE_4K_BIT;
0752 else
0753 base = (base | (len+1)>>1) >> TCIC_MBASE_HA_SHFT;
0754 tcic_setw(TCIC_ADDR, addr + TCIC_MBASE_X);
0755 tcic_setw(TCIC_DATA, base);
0756
0757 mmap = mem->card_start - mem->res->start;
0758 mmap = (mmap >> TCIC_MMAP_CA_SHFT) & TCIC_MMAP_CA_MASK;
0759 if (mem->flags & MAP_ATTRIB) mmap |= TCIC_MMAP_REG;
0760 tcic_setw(TCIC_ADDR, addr + TCIC_MMAP_X);
0761 tcic_setw(TCIC_DATA, mmap);
0762
0763 ctl = TCIC_MCTL_QUIET | (psock << TCIC_MCTL_SS_SHFT);
0764 ctl |= to_cycles(mem->speed) & TCIC_MCTL_WSCNT_MASK;
0765 ctl |= (mem->flags & MAP_16BIT) ? 0 : TCIC_MCTL_B8;
0766 ctl |= (mem->flags & MAP_WRPROT) ? TCIC_MCTL_WP : 0;
0767 ctl |= (mem->flags & MAP_ACTIVE) ? TCIC_MCTL_ENA : 0;
0768 tcic_setw(TCIC_ADDR, addr + TCIC_MCTL_X);
0769 tcic_setw(TCIC_DATA, ctl);
0770
0771 return 0;
0772 }
0773
0774
0775
0776 static int tcic_init(struct pcmcia_socket *s)
0777 {
0778 int i;
0779 struct resource res = { .start = 0, .end = 0x1000 };
0780 pccard_io_map io = { 0, 0, 0, 0, 1 };
0781 pccard_mem_map mem = { .res = &res, };
0782
0783 for (i = 0; i < 2; i++) {
0784 io.map = i;
0785 tcic_set_io_map(s, &io);
0786 }
0787 for (i = 0; i < 5; i++) {
0788 mem.map = i;
0789 tcic_set_mem_map(s, &mem);
0790 }
0791 return 0;
0792 }
0793
0794 static struct pccard_operations tcic_operations = {
0795 .init = tcic_init,
0796 .get_status = tcic_get_status,
0797 .set_socket = tcic_set_socket,
0798 .set_io_map = tcic_set_io_map,
0799 .set_mem_map = tcic_set_mem_map,
0800 };
0801
0802
0803
0804 module_init(init_tcic);
0805 module_exit(exit_tcic);