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