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