linux/drivers/pcmcia/tcic.c
<<
>>
Prefs
   1/*======================================================================
   2
   3    Device driver for Databook TCIC-2 PCMCIA controller
   4
   5    tcic.c 1.111 2000/02/15 04:13:12
   6
   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/
  11
  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.
  16
  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.
  20
  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.
  31    
  32======================================================================*/
  33
  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>
  49
  50#include <asm/io.h>
  51#include <asm/system.h>
  52
  53#include <pcmcia/cs_types.h>
  54#include <pcmcia/cs.h>
  55#include <pcmcia/ss.h>
  56#include "tcic.h"
  57
  58#ifdef CONFIG_PCMCIA_DEBUG
  59static int pc_debug;
  60
  61module_param(pc_debug, int, 0644);
  62static const char version[] =
  63"tcic.c 1.111 2000/02/15 04:13:12 (David Hinds)";
  64
  65#define debug(lvl, fmt, arg...) do {                            \
  66        if (pc_debug > (lvl))                                   \
  67                printk(KERN_DEBUG "tcic: " fmt , ## arg);       \
  68} while (0)
  69#else
  70#define debug(lvl, fmt, arg...) do { } while (0)
  71#endif
  72
  73MODULE_AUTHOR("David Hinds <dahinds@users.sourceforge.net>");
  74MODULE_DESCRIPTION("Databook TCIC-2 PCMCIA socket driver");
  75MODULE_LICENSE("Dual MPL/GPL");
  76
  77/*====================================================================*/
  78
  79/* Parameters that can be set with 'insmod' */
  80
  81/* The base port address of the TCIC-2 chip */
  82static unsigned long tcic_base = TCIC_BASE;
  83
  84/* Specify a socket number to ignore */
  85static int ignore = -1;
  86
  87/* Probe for safe interrupts? */
  88static int do_scan = 1;
  89
  90/* Bit map of interrupts to choose from */
  91static u_int irq_mask = 0xffff;
  92static int irq_list[16];
  93static unsigned int irq_list_count;
  94
  95/* The card status change interrupt -- 0 means autoselect */
  96static int cs_irq;
  97
  98/* Poll status interval -- 0 means default to interrupt */
  99static int poll_interval;
 100
 101/* Delay for card status double-checking */
 102static int poll_quick = HZ/20;
 103
 104/* CCLK external clock time, in nanoseconds.  70 ns = 14.31818 MHz */
 105static int cycle_time = 70;
 106
 107module_param(tcic_base, ulong, 0444);
 108module_param(ignore, int, 0444);
 109module_param(do_scan, int, 0444);
 110module_param(irq_mask, int, 0444);
 111module_param_array(irq_list, int, &irq_list_count, 0444);
 112module_param(cs_irq, int, 0444);
 113module_param(poll_interval, int, 0444);
 114module_param(poll_quick, int, 0444);
 115module_param(cycle_time, int, 0444);
 116
 117/*====================================================================*/
 118
 119static irqreturn_t tcic_interrupt(int irq, void *dev);
 120static void tcic_timer(u_long data);
 121static struct pccard_operations tcic_operations;
 122
 123struct tcic_socket {
 124    u_short     psock;
 125    u_char      last_sstat;
 126    u_char      id;
 127    struct pcmcia_socket        socket;
 128};
 129
 130static struct timer_list poll_timer;
 131static int tcic_timer_pending;
 132
 133static int sockets;
 134static struct tcic_socket socket_table[2];
 135
 136/*====================================================================*/
 137
 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)
 141
 142#ifdef DEBUG_X
 143static u_char tcic_getb(u_char reg)
 144{
 145    u_char val = inb(tcic_base+reg);
 146    printk(KERN_DEBUG "tcic_getb(%#lx) = %#x\n", tcic_base+reg, val);
 147    return val;
 148}
 149
 150static u_short tcic_getw(u_char reg)
 151{
 152    u_short val = inw(tcic_base+reg);
 153    printk(KERN_DEBUG "tcic_getw(%#lx) = %#x\n", tcic_base+reg, val);
 154    return val;
 155}
 156
 157static void tcic_setb(u_char reg, u_char data)
 158{
 159    printk(KERN_DEBUG "tcic_setb(%#lx, %#x)\n", tcic_base+reg, data);
 160    outb(data, tcic_base+reg);
 161}
 162
 163static void tcic_setw(u_char reg, u_short data)
 164{
 165    printk(KERN_DEBUG "tcic_setw(%#lx, %#x)\n", tcic_base+reg, data);
 166    outw(data, tcic_base+reg);
 167}
 168#else
 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)
 173#endif
 174
 175static void tcic_setl(u_char reg, u_int data)
 176{
 177#ifdef DEBUG_X
 178    printk(KERN_DEBUG "tcic_setl(%#x, %#lx)\n", tcic_base+reg, data);
 179#endif
 180    outw(data & 0xffff, tcic_base+reg);
 181    outw(data >> 16, tcic_base+reg+2);
 182}
 183
 184static void tcic_aux_setb(u_short reg, u_char data)
 185{
 186    u_char mode = (tcic_getb(TCIC_MODE) & TCIC_MODE_PGMMASK) | reg;
 187    tcic_setb(TCIC_MODE, mode);
 188    tcic_setb(TCIC_AUX, data);
 189}
 190
 191static u_short tcic_aux_getw(u_short reg)
 192{
 193    u_char mode = (tcic_getb(TCIC_MODE) & TCIC_MODE_PGMMASK) | reg;
 194    tcic_setb(TCIC_MODE, mode);
 195    return tcic_getw(TCIC_AUX);
 196}
 197
 198static void tcic_aux_setw(u_short reg, u_short data)
 199{
 200    u_char mode = (tcic_getb(TCIC_MODE) & TCIC_MODE_PGMMASK) | reg;
 201    tcic_setb(TCIC_MODE, mode);
 202    tcic_setw(TCIC_AUX, data);
 203}
 204
 205/*====================================================================*/
 206
 207/* Time conversion functions */
 208
 209static int to_cycles(int ns)
 210{
 211    if (ns < 14)
 212        return 0;
 213    else
 214        return 2*(ns-14)/cycle_time;
 215}
 216
 217/*====================================================================*/
 218
 219static volatile u_int irq_hits;
 220
 221static irqreturn_t __init tcic_irq_count(int irq, void *dev)
 222{
 223    irq_hits++;
 224    return IRQ_HANDLED;
 225}
 226
 227static u_int __init try_irq(int irq)
 228{
 229    u_short cfg;
 230
 231    irq_hits = 0;
 232    if (request_irq(irq, tcic_irq_count, 0, "irq scan", tcic_irq_count) != 0)
 233        return -1;
 234    mdelay(10);
 235    if (irq_hits) {
 236        free_irq(irq, tcic_irq_count);
 237        return -1;
 238    }
 239
 240    /* Generate one interrupt */
 241    cfg = TCIC_SYSCFG_AUTOBUSY | 0x0a00;
 242    tcic_aux_setw(TCIC_AUX_SYSCFG, cfg | TCIC_IRQ(irq));
 243    tcic_setb(TCIC_IENA, TCIC_IENA_ERR | TCIC_IENA_CFG_HIGH);
 244    tcic_setb(TCIC_ICSR, TCIC_ICSR_ERR | TCIC_ICSR_JAM);
 245
 246    udelay(1000);
 247    free_irq(irq, tcic_irq_count);
 248
 249    /* Turn off interrupts */
 250    tcic_setb(TCIC_IENA, TCIC_IENA_CFG_OFF);
 251    while (tcic_getb(TCIC_ICSR))
 252        tcic_setb(TCIC_ICSR, TCIC_ICSR_JAM);
 253    tcic_aux_setw(TCIC_AUX_SYSCFG, cfg);
 254    
 255    return (irq_hits != 1);
 256}
 257
 258static u_int __init irq_scan(u_int mask0)
 259{
 260    u_int mask1;
 261    int i;
 262
 263#ifdef __alpha__
 264#define PIC 0x4d0
 265    /* Don't probe level-triggered interrupts -- reserved for PCI */
 266    int level_mask = inb_p(PIC) | (inb_p(PIC+1) << 8);
 267    if (level_mask)
 268        mask0 &= ~level_mask;
 269#endif
 270
 271    mask1 = 0;
 272    if (do_scan) {
 273        for (i = 0; i < 16; i++)
 274            if ((mask0 & (1 << i)) && (try_irq(i) == 0))
 275                mask1 |= (1 << i);
 276        for (i = 0; i < 16; i++)
 277            if ((mask1 & (1 << i)) && (try_irq(i) != 0)) {
 278                mask1 ^= (1 << i);
 279            }
 280    }
 281    
 282    if (mask1) {
 283        printk("scanned");
 284    } else {
 285        /* Fallback: just find interrupts that aren't in use */
 286        for (i = 0; i < 16; i++)
 287            if ((mask0 & (1 << i)) &&
 288                (request_irq(i, tcic_irq_count, 0, "x", tcic_irq_count) == 0)) {
 289                mask1 |= (1 << i);
 290                free_irq(i, tcic_irq_count);
 291            }
 292        printk("default");
 293    }
 294    
 295    printk(") = ");
 296    for (i = 0; i < 16; i++)
 297        if (mask1 & (1<<i))
 298            printk("%s%d", ((mask1 & ((1<<i)-1)) ? "," : ""), i);
 299    printk(" ");
 300    
 301    return mask1;
 302}
 303
 304/*======================================================================
 305
 306    See if a card is present, powered up, in IO mode, and already
 307    bound to a (non-PCMCIA) Linux driver.
 308
 309    We make an exception for cards that look like serial devices.
 310    
 311======================================================================*/
 312
 313static int __init is_active(int s)
 314{
 315    u_short scf1, ioctl, base, num;
 316    u_char pwr, sstat;
 317    u_int addr;
 318    
 319    tcic_setl(TCIC_ADDR, (s << TCIC_ADDR_SS_SHFT)
 320              | TCIC_ADDR_INDREG | TCIC_SCF1(s));
 321    scf1 = tcic_getw(TCIC_DATA);
 322    pwr = tcic_getb(TCIC_PWR);
 323    sstat = tcic_getb(TCIC_SSTAT);
 324    addr = TCIC_IWIN(s, 0);
 325    tcic_setw(TCIC_ADDR, addr + TCIC_IBASE_X);
 326    base = tcic_getw(TCIC_DATA);
 327    tcic_setw(TCIC_ADDR, addr + TCIC_ICTL_X);
 328    ioctl = tcic_getw(TCIC_DATA);
 329
 330    if (ioctl & TCIC_ICTL_TINY)
 331        num = 1;
 332    else {
 333        num = (base ^ (base-1));
 334        base = base & (base-1);
 335    }
 336
 337    if ((sstat & TCIC_SSTAT_CD) && (pwr & TCIC_PWR_VCC(s)) &&
 338        (scf1 & TCIC_SCF1_IOSTS) && (ioctl & TCIC_ICTL_ENA) &&
 339        ((base & 0xfeef) != 0x02e8)) {
 340        struct resource *res = request_region(base, num, "tcic-2");
 341        if (!res) /* region is busy */
 342            return 1;
 343        release_region(base, num);
 344    }
 345
 346    return 0;
 347}
 348
 349/*======================================================================
 350
 351    This returns the revision code for the specified socket.
 352    
 353======================================================================*/
 354
 355static int __init get_tcic_id(void)
 356{
 357    u_short id;
 358    
 359    tcic_aux_setw(TCIC_AUX_TEST, TCIC_TEST_DIAG);
 360    id = tcic_aux_getw(TCIC_AUX_ILOCK);
 361    id = (id & TCIC_ILOCKTEST_ID_MASK) >> TCIC_ILOCKTEST_ID_SH;
 362    tcic_aux_setw(TCIC_AUX_TEST, 0);
 363    return id;
 364}
 365
 366static int tcic_drv_pcmcia_suspend(struct platform_device *dev,
 367                                     pm_message_t state)
 368{
 369        return pcmcia_socket_dev_suspend(&dev->dev);
 370}
 371
 372static int tcic_drv_pcmcia_resume(struct platform_device *dev)
 373{
 374        return pcmcia_socket_dev_resume(&dev->dev);
 375}
 376/*====================================================================*/
 377
 378static struct platform_driver tcic_driver = {
 379        .driver = {
 380                .name = "tcic-pcmcia",
 381                .owner          = THIS_MODULE,
 382        },
 383        .suspend        = tcic_drv_pcmcia_suspend,
 384        .resume         = tcic_drv_pcmcia_resume,
 385};
 386
 387static struct platform_device tcic_device = {
 388        .name = "tcic-pcmcia",
 389        .id = 0,
 390};
 391
 392
 393static int __init init_tcic(void)
 394{
 395    int i, sock, ret = 0;
 396    u_int mask, scan;
 397
 398    if (platform_driver_register(&tcic_driver))
 399        return -1;
 400    
 401    printk(KERN_INFO "Databook TCIC-2 PCMCIA probe: ");
 402    sock = 0;
 403
 404    if (!request_region(tcic_base, 16, "tcic-2")) {
 405        printk("could not allocate ports,\n ");
 406        platform_driver_unregister(&tcic_driver);
 407        return -ENODEV;
 408    }
 409    else {
 410        tcic_setw(TCIC_ADDR, 0);
 411        if (tcic_getw(TCIC_ADDR) == 0) {
 412            tcic_setw(TCIC_ADDR, 0xc3a5);
 413            if (tcic_getw(TCIC_ADDR) == 0xc3a5) sock = 2;
 414        }
 415        if (sock == 0) {
 416            /* See if resetting the controller does any good */
 417            tcic_setb(TCIC_SCTRL, TCIC_SCTRL_RESET);
 418            tcic_setb(TCIC_SCTRL, 0);
 419            tcic_setw(TCIC_ADDR, 0);
 420            if (tcic_getw(TCIC_ADDR) == 0) {
 421                tcic_setw(TCIC_ADDR, 0xc3a5);
 422                if (tcic_getw(TCIC_ADDR) == 0xc3a5) sock = 2;
 423            }
 424        }
 425    }
 426    if (sock == 0) {
 427        printk("not found.\n");
 428        release_region(tcic_base, 16);
 429        platform_driver_unregister(&tcic_driver);
 430        return -ENODEV;
 431    }
 432
 433    sockets = 0;
 434    for (i = 0; i < sock; i++) {
 435        if ((i == ignore) || is_active(i)) continue;
 436        socket_table[sockets].psock = i;
 437        socket_table[sockets].id = get_tcic_id();
 438
 439        socket_table[sockets].socket.owner = THIS_MODULE;
 440        /* only 16-bit cards, memory windows must be size-aligned */
 441        /* No PCI or CardBus support */
 442        socket_table[sockets].socket.features = SS_CAP_PCCARD | SS_CAP_MEM_ALIGN;
 443        /* irq 14, 11, 10, 7, 6, 5, 4, 3 */
 444        socket_table[sockets].socket.irq_mask = 0x4cf8;
 445        /* 4K minimum window size */
 446        socket_table[sockets].socket.map_size = 0x1000;         
 447        sockets++;
 448    }
 449
 450    switch (socket_table[0].id) {
 451    case TCIC_ID_DB86082:
 452        printk("DB86082"); break;
 453    case TCIC_ID_DB86082A:
 454        printk("DB86082A"); break;
 455    case TCIC_ID_DB86084:
 456        printk("DB86084"); break;
 457    case TCIC_ID_DB86084A:
 458        printk("DB86084A"); break;
 459    case TCIC_ID_DB86072:
 460        printk("DB86072"); break;
 461    case TCIC_ID_DB86184:
 462        printk("DB86184"); break;
 463    case TCIC_ID_DB86082B:
 464        printk("DB86082B"); break;
 465    default:
 466        printk("Unknown ID 0x%02x", socket_table[0].id);
 467    }
 468    
 469    /* Set up polling */
 470    poll_timer.function = &tcic_timer;
 471    poll_timer.data = 0;
 472    init_timer(&poll_timer);
 473
 474    /* Build interrupt mask */
 475    printk(KERN_CONT ", %d sockets\n", sockets);
 476    printk(KERN_INFO "  irq list (");
 477    if (irq_list_count == 0)
 478        mask = irq_mask;
 479    else
 480        for (i = mask = 0; i < irq_list_count; i++)
 481            mask |= (1<<irq_list[i]);
 482
 483    /* irq 14, 11, 10, 7, 6, 5, 4, 3 */
 484    mask &= 0x4cf8;
 485    /* Scan interrupts */
 486    mask = irq_scan(mask);
 487    for (i=0;i<sockets;i++)
 488            socket_table[i].socket.irq_mask = mask;
 489    
 490    /* Check for only two interrupts available */
 491    scan = (mask & (mask-1));
 492    if (((scan & (scan-1)) == 0) && (poll_interval == 0))
 493        poll_interval = HZ;
 494    
 495    if (poll_interval == 0) {
 496        /* Avoid irq 12 unless it is explicitly requested */
 497        u_int cs_mask = mask & ((cs_irq) ? (1<<cs_irq) : ~(1<<12));
 498        for (i = 15; i > 0; i--)
 499            if ((cs_mask & (1 << i)) &&
 500                (request_irq(i, tcic_interrupt, 0, "tcic",
 501                             tcic_interrupt) == 0))
 502                break;
 503        cs_irq = i;
 504        if (cs_irq == 0) poll_interval = HZ;
 505    }
 506    
 507    if (socket_table[0].socket.irq_mask & (1 << 11))
 508        printk("sktirq is irq 11, ");
 509    if (cs_irq != 0)
 510        printk("status change on irq %d\n", cs_irq);
 511    else
 512        printk("polled status, interval = %d ms\n",
 513               poll_interval * 1000 / HZ);
 514    
 515    for (i = 0; i < sockets; i++) {
 516        tcic_setw(TCIC_ADDR+2, socket_table[i].psock << TCIC_SS_SHFT);
 517        socket_table[i].last_sstat = tcic_getb(TCIC_SSTAT);
 518    }
 519    
 520    /* jump start interrupt handler, if needed */
 521    tcic_interrupt(0, NULL);
 522
 523    platform_device_register(&tcic_device);
 524
 525    for (i = 0; i < sockets; i++) {
 526            socket_table[i].socket.ops = &tcic_operations;
 527            socket_table[i].socket.resource_ops = &pccard_nonstatic_ops;
 528            socket_table[i].socket.dev.parent = &tcic_device.dev;
 529            ret = pcmcia_register_socket(&socket_table[i].socket);
 530            if (ret && i)
 531                    pcmcia_unregister_socket(&socket_table[0].socket);
 532    }
 533    
 534    return ret;
 535
 536    return 0;
 537    
 538} /* init_tcic */
 539
 540/*====================================================================*/
 541
 542static void __exit exit_tcic(void)
 543{
 544    int i;
 545
 546    del_timer_sync(&poll_timer);
 547    if (cs_irq != 0) {
 548        tcic_aux_setw(TCIC_AUX_SYSCFG, TCIC_SYSCFG_AUTOBUSY|0x0a00);
 549        free_irq(cs_irq, tcic_interrupt);
 550    }
 551    release_region(tcic_base, 16);
 552
 553    for (i = 0; i < sockets; i++) {
 554            pcmcia_unregister_socket(&socket_table[i].socket);      
 555    }
 556
 557    platform_device_unregister(&tcic_device);
 558    platform_driver_unregister(&tcic_driver);
 559} /* exit_tcic */
 560
 561/*====================================================================*/
 562
 563static irqreturn_t tcic_interrupt(int irq, void *dev)
 564{
 565    int i, quick = 0;
 566    u_char latch, sstat;
 567    u_short psock;
 568    u_int events;
 569    static volatile int active = 0;
 570
 571    if (active) {
 572        printk(KERN_NOTICE "tcic: reentered interrupt handler!\n");
 573        return IRQ_NONE;
 574    } else
 575        active = 1;
 576
 577    debug(2, "tcic_interrupt()\n");
 578    
 579    for (i = 0; i < sockets; i++) {
 580        psock = socket_table[i].psock;
 581        tcic_setl(TCIC_ADDR, (psock << TCIC_ADDR_SS_SHFT)
 582                  | TCIC_ADDR_INDREG | TCIC_SCF1(psock));
 583        sstat = tcic_getb(TCIC_SSTAT);
 584        latch = sstat ^ socket_table[psock].last_sstat;
 585        socket_table[i].last_sstat = sstat;
 586        if (tcic_getb(TCIC_ICSR) & TCIC_ICSR_CDCHG) {
 587            tcic_setb(TCIC_ICSR, TCIC_ICSR_CLEAR);
 588            quick = 1;
 589        }
 590        if (latch == 0)
 591            continue;
 592        events = (latch & TCIC_SSTAT_CD) ? SS_DETECT : 0;
 593        events |= (latch & TCIC_SSTAT_WP) ? SS_WRPROT : 0;
 594        if (tcic_getw(TCIC_DATA) & TCIC_SCF1_IOSTS) {
 595            events |= (latch & TCIC_SSTAT_LBAT1) ? SS_STSCHG : 0;
 596        } else {
 597            events |= (latch & TCIC_SSTAT_RDY) ? SS_READY : 0;
 598            events |= (latch & TCIC_SSTAT_LBAT1) ? SS_BATDEAD : 0;
 599            events |= (latch & TCIC_SSTAT_LBAT2) ? SS_BATWARN : 0;
 600        }
 601        if (events) {
 602                pcmcia_parse_events(&socket_table[i].socket, events);
 603        }
 604    }
 605
 606    /* Schedule next poll, if needed */
 607    if (((cs_irq == 0) || quick) && (!tcic_timer_pending)) {
 608        poll_timer.expires = jiffies + (quick ? poll_quick : poll_interval);
 609        add_timer(&poll_timer);
 610        tcic_timer_pending = 1;
 611    }
 612    active = 0;
 613    
 614    debug(2, "interrupt done\n");
 615    return IRQ_HANDLED;
 616} /* tcic_interrupt */
 617
 618static void tcic_timer(u_long data)
 619{
 620    debug(2, "tcic_timer()\n");
 621    tcic_timer_pending = 0;
 622    tcic_interrupt(0, NULL);
 623} /* tcic_timer */
 624
 625/*====================================================================*/
 626
 627static int tcic_get_status(struct pcmcia_socket *sock, u_int *value)
 628{
 629    u_short psock = container_of(sock, struct tcic_socket, socket)->psock;
 630    u_char reg;
 631
 632    tcic_setl(TCIC_ADDR, (psock << TCIC_ADDR_SS_SHFT)
 633              | TCIC_ADDR_INDREG | TCIC_SCF1(psock));
 634    reg = tcic_getb(TCIC_SSTAT);
 635    *value  = (reg & TCIC_SSTAT_CD) ? SS_DETECT : 0;
 636    *value |= (reg & TCIC_SSTAT_WP) ? SS_WRPROT : 0;
 637    if (tcic_getw(TCIC_DATA) & TCIC_SCF1_IOSTS) {
 638        *value |= (reg & TCIC_SSTAT_LBAT1) ? SS_STSCHG : 0;
 639    } else {
 640        *value |= (reg & TCIC_SSTAT_RDY) ? SS_READY : 0;
 641        *value |= (reg & TCIC_SSTAT_LBAT1) ? SS_BATDEAD : 0;
 642        *value |= (reg & TCIC_SSTAT_LBAT2) ? SS_BATWARN : 0;
 643    }
 644    reg = tcic_getb(TCIC_PWR);
 645    if (reg & (TCIC_PWR_VCC(psock)|TCIC_PWR_VPP(psock)))
 646        *value |= SS_POWERON;
 647    debug(1, "GetStatus(%d) = %#2.2x\n", psock, *value);
 648    return 0;
 649} /* tcic_get_status */
 650
 651/*====================================================================*/
 652
 653static int tcic_set_socket(struct pcmcia_socket *sock, socket_state_t *state)
 654{
 655    u_short psock = container_of(sock, struct tcic_socket, socket)->psock;
 656    u_char reg;
 657    u_short scf1, scf2;
 658
 659    debug(1, "SetSocket(%d, flags %#3.3x, Vcc %d, Vpp %d, "
 660          "io_irq %d, csc_mask %#2.2x)\n", psock, state->flags,
 661          state->Vcc, state->Vpp, state->io_irq, state->csc_mask);
 662    tcic_setw(TCIC_ADDR+2, (psock << TCIC_SS_SHFT) | TCIC_ADR2_INDREG);
 663
 664    reg = tcic_getb(TCIC_PWR);
 665    reg &= ~(TCIC_PWR_VCC(psock) | TCIC_PWR_VPP(psock));
 666
 667    if (state->Vcc == 50) {
 668        switch (state->Vpp) {
 669        case 0:   reg |= TCIC_PWR_VCC(psock) | TCIC_PWR_VPP(psock); break;
 670        case 50:  reg |= TCIC_PWR_VCC(psock); break;
 671        case 120: reg |= TCIC_PWR_VPP(psock); break;
 672        default:  return -EINVAL;
 673        }
 674    } else if (state->Vcc != 0)
 675        return -EINVAL;
 676
 677    if (reg != tcic_getb(TCIC_PWR))
 678        tcic_setb(TCIC_PWR, reg);
 679
 680    reg = TCIC_ILOCK_HOLD_CCLK | TCIC_ILOCK_CWAIT;
 681    if (state->flags & SS_OUTPUT_ENA) {
 682        tcic_setb(TCIC_SCTRL, TCIC_SCTRL_ENA);
 683        reg |= TCIC_ILOCK_CRESENA;
 684    } else
 685        tcic_setb(TCIC_SCTRL, 0);
 686    if (state->flags & SS_RESET)
 687        reg |= TCIC_ILOCK_CRESET;
 688    tcic_aux_setb(TCIC_AUX_ILOCK, reg);
 689    
 690    tcic_setw(TCIC_ADDR, TCIC_SCF1(psock));
 691    scf1 = TCIC_SCF1_FINPACK;
 692    scf1 |= TCIC_IRQ(state->io_irq);
 693    if (state->flags & SS_IOCARD) {
 694        scf1 |= TCIC_SCF1_IOSTS;
 695        if (state->flags & SS_SPKR_ENA)
 696            scf1 |= TCIC_SCF1_SPKR;
 697        if (state->flags & SS_DMA_MODE)
 698            scf1 |= TCIC_SCF1_DREQ2 << TCIC_SCF1_DMA_SHIFT;
 699    }
 700    tcic_setw(TCIC_DATA, scf1);
 701
 702    /* Some general setup stuff, and configure status interrupt */
 703    reg = TCIC_WAIT_ASYNC | TCIC_WAIT_SENSE | to_cycles(250);
 704    tcic_aux_setb(TCIC_AUX_WCTL, reg);
 705    tcic_aux_setw(TCIC_AUX_SYSCFG, TCIC_SYSCFG_AUTOBUSY|0x0a00|
 706                  TCIC_IRQ(cs_irq));
 707    
 708    /* Card status change interrupt mask */
 709    tcic_setw(TCIC_ADDR, TCIC_SCF2(psock));
 710    scf2 = TCIC_SCF2_MALL;
 711    if (state->csc_mask & SS_DETECT) scf2 &= ~TCIC_SCF2_MCD;
 712    if (state->flags & SS_IOCARD) {
 713        if (state->csc_mask & SS_STSCHG) reg &= ~TCIC_SCF2_MLBAT1;
 714    } else {
 715        if (state->csc_mask & SS_BATDEAD) reg &= ~TCIC_SCF2_MLBAT1;
 716        if (state->csc_mask & SS_BATWARN) reg &= ~TCIC_SCF2_MLBAT2;
 717        if (state->csc_mask & SS_READY) reg &= ~TCIC_SCF2_MRDY;
 718    }
 719    tcic_setw(TCIC_DATA, scf2);
 720    /* For the ISA bus, the irq should be active-high totem-pole */
 721    tcic_setb(TCIC_IENA, TCIC_IENA_CDCHG | TCIC_IENA_CFG_HIGH);
 722
 723    return 0;
 724} /* tcic_set_socket */
 725  
 726/*====================================================================*/
 727
 728static int tcic_set_io_map(struct pcmcia_socket *sock, struct pccard_io_map *io)
 729{
 730    u_short psock = container_of(sock, struct tcic_socket, socket)->psock;
 731    u_int addr;
 732    u_short base, len, ioctl;
 733    
 734    debug(1, "SetIOMap(%d, %d, %#2.2x, %d ns, "
 735          "%#llx-%#llx)\n", psock, io->map, io->flags, io->speed,
 736          (unsigned long long)io->start, (unsigned long long)io->stop);
 737    if ((io->map > 1) || (io->start > 0xffff) || (io->stop > 0xffff) ||
 738        (io->stop < io->start)) return -EINVAL;
 739    tcic_setw(TCIC_ADDR+2, TCIC_ADR2_INDREG | (psock << TCIC_SS_SHFT));
 740    addr = TCIC_IWIN(psock, io->map);
 741
 742    base = io->start; len = io->stop - io->start;
 743    /* Check to see that len+1 is power of two, etc */
 744    if ((len & (len+1)) || (base & len)) return -EINVAL;
 745    base |= (len+1)>>1;
 746    tcic_setw(TCIC_ADDR, addr + TCIC_IBASE_X);
 747    tcic_setw(TCIC_DATA, base);
 748    
 749    ioctl  = (psock << TCIC_ICTL_SS_SHFT);
 750    ioctl |= (len == 0) ? TCIC_ICTL_TINY : 0;
 751    ioctl |= (io->flags & MAP_ACTIVE) ? TCIC_ICTL_ENA : 0;
 752    ioctl |= to_cycles(io->speed) & TCIC_ICTL_WSCNT_MASK;
 753    if (!(io->flags & MAP_AUTOSZ)) {
 754        ioctl |= TCIC_ICTL_QUIET;
 755        ioctl |= (io->flags & MAP_16BIT) ? TCIC_ICTL_BW_16 : TCIC_ICTL_BW_8;
 756    }
 757    tcic_setw(TCIC_ADDR, addr + TCIC_ICTL_X);
 758    tcic_setw(TCIC_DATA, ioctl);
 759    
 760    return 0;
 761} /* tcic_set_io_map */
 762
 763/*====================================================================*/
 764
 765static int tcic_set_mem_map(struct pcmcia_socket *sock, struct pccard_mem_map *mem)
 766{
 767    u_short psock = container_of(sock, struct tcic_socket, socket)->psock;
 768    u_short addr, ctl;
 769    u_long base, len, mmap;
 770
 771    debug(1, "SetMemMap(%d, %d, %#2.2x, %d ns, "
 772          "%#llx-%#llx, %#x)\n", psock, mem->map, mem->flags,
 773          mem->speed, (unsigned long long)mem->res->start,
 774          (unsigned long long)mem->res->end, mem->card_start);
 775    if ((mem->map > 3) || (mem->card_start > 0x3ffffff) ||
 776        (mem->res->start > 0xffffff) || (mem->res->end > 0xffffff) ||
 777        (mem->res->start > mem->res->end) || (mem->speed > 1000))
 778        return -EINVAL;
 779    tcic_setw(TCIC_ADDR+2, TCIC_ADR2_INDREG | (psock << TCIC_SS_SHFT));
 780    addr = TCIC_MWIN(psock, mem->map);
 781
 782    base = mem->res->start; len = mem->res->end - mem->res->start;
 783    if ((len & (len+1)) || (base & len)) return -EINVAL;
 784    if (len == 0x0fff)
 785        base = (base >> TCIC_MBASE_HA_SHFT) | TCIC_MBASE_4K_BIT;
 786    else
 787        base = (base | (len+1)>>1) >> TCIC_MBASE_HA_SHFT;
 788    tcic_setw(TCIC_ADDR, addr + TCIC_MBASE_X);
 789    tcic_setw(TCIC_DATA, base);
 790    
 791    mmap = mem->card_start - mem->res->start;
 792    mmap = (mmap >> TCIC_MMAP_CA_SHFT) & TCIC_MMAP_CA_MASK;
 793    if (mem->flags & MAP_ATTRIB) mmap |= TCIC_MMAP_REG;
 794    tcic_setw(TCIC_ADDR, addr + TCIC_MMAP_X);
 795    tcic_setw(TCIC_DATA, mmap);
 796
 797    ctl  = TCIC_MCTL_QUIET | (psock << TCIC_MCTL_SS_SHFT);
 798    ctl |= to_cycles(mem->speed) & TCIC_MCTL_WSCNT_MASK;
 799    ctl |= (mem->flags & MAP_16BIT) ? 0 : TCIC_MCTL_B8;
 800    ctl |= (mem->flags & MAP_WRPROT) ? TCIC_MCTL_WP : 0;
 801    ctl |= (mem->flags & MAP_ACTIVE) ? TCIC_MCTL_ENA : 0;
 802    tcic_setw(TCIC_ADDR, addr + TCIC_MCTL_X);
 803    tcic_setw(TCIC_DATA, ctl);
 804    
 805    return 0;
 806} /* tcic_set_mem_map */
 807
 808/*====================================================================*/
 809
 810static int tcic_init(struct pcmcia_socket *s)
 811{
 812        int i;
 813        struct resource res = { .start = 0, .end = 0x1000 };
 814        pccard_io_map io = { 0, 0, 0, 0, 1 };
 815        pccard_mem_map mem = { .res = &res, };
 816
 817        for (i = 0; i < 2; i++) {
 818                io.map = i;
 819                tcic_set_io_map(s, &io);
 820        }
 821        for (i = 0; i < 5; i++) {
 822                mem.map = i;
 823                tcic_set_mem_map(s, &mem);
 824        }
 825        return 0;
 826}
 827
 828static struct pccard_operations tcic_operations = {
 829        .init              = tcic_init,
 830        .get_status        = tcic_get_status,
 831        .set_socket        = tcic_set_socket,
 832        .set_io_map        = tcic_set_io_map,
 833        .set_mem_map       = tcic_set_mem_map,
 834};
 835
 836/*====================================================================*/
 837
 838module_init(init_tcic);
 839module_exit(exit_tcic);
 840