linux-old/drivers/pcmcia/m8xx_pcmcia.c
<<
>>
Prefs
   1/* 
   2 * m8xx_pcmcia.c - Linux PCMCIA socket driver for the mpc8xx series.
   3 *
   4 * (C) 1999-2000 Magnus Damm <damm@bitsmart.com>
   5 * (C) 2001-2002 Montavista Software, Inc.
   6 *     <mlocke@mvista.com>
   7 *
   8 * "The ExCA standard specifies that socket controllers should provide 
   9 * two IO and five memory windows per socket, which can be independently 
  10 * configured and positioned in the host address space and mapped to 
  11 * arbitrary segments of card address space. " - David A Hinds. 1999
  12 *
  13 * This controller does _not_ meet the ExCA standard.
  14 * 
  15 * m8xx pcmcia controller brief info:
  16 * + 8 windows (attrib, mem, i/o)
  17 * + up to two slots (SLOT_A and SLOT_B)
  18 * + inputpins, outputpins, event and mask registers.
  19 * - no offset register. sigh.
  20 *
  21 * Because of the lacking offset register we must map the whole card.
  22 * We assign each memory window PCMCIA_MEM_WIN_SIZE address space.
  23 * Make sure there is (PCMCIA_MEM_WIN_SIZE * PCMCIA_MEM_WIN_NO 
  24 * * PCMCIA_SOCKETS_NO) bytes at PCMCIA_MEM_WIN_BASE.
  25 * The i/o windows are dynamically allocated at PCMCIA_IO_WIN_BASE.
  26 * They are maximum 64KByte each...
  27 */
  28
  29#include <linux/module.h>
  30#include <linux/init.h>
  31#include <linux/types.h>
  32#include <linux/fcntl.h>
  33#include <linux/string.h>
  34
  35#include <asm/io.h>
  36#include <asm/bitops.h>
  37#include <asm/segment.h>
  38#include <asm/system.h>
  39
  40#include <linux/kernel.h>
  41#include <linux/errno.h>
  42#include <linux/sched.h>
  43#include <linux/slab.h>
  44#include <linux/timer.h>
  45#include <linux/ioport.h>
  46#include <linux/delay.h>
  47
  48#include <asm/mpc8xx.h>
  49#include <asm/8xx_immap.h>
  50#include <asm/irq.h>
  51
  52#include <pcmcia/version.h>
  53#include <pcmcia/cs_types.h>
  54#include <pcmcia/cs.h>
  55#include <pcmcia/ss.h>
  56
  57#ifdef PCMCIA_DEBUG
  58static int pc_debug = PCMCIA_DEBUG;
  59MODULE_PARM(pc_debug, "i");
  60#define DEBUG(n, args...) printk(KERN_DEBUG "m8xx_pcmcia: " args);
  61#else
  62#define DEBUG(n, args...)
  63#endif
  64
  65#define PCMCIA_INFO(args...) printk(KERN_INFO "m8xx_pcmcia: "args)
  66#define PCMCIA_ERROR(args...) printk(KERN_ERR "m8xx_pcmcia: "args)
  67
  68static const char *version = "Version 0.05, 14-Apr-2002";
  69MODULE_LICENSE("Dual MPL/GPL");
  70
  71/* The RPX series use SLOT_B */
  72
  73#if defined(CONFIG_RPXCLASSIC) || defined(CONFIG_RPXLITE)
  74#define CONFIG_PCMCIA_SLOT_B
  75#endif
  76
  77/* The MBX board use SLOT_A */
  78
  79#ifdef CONFIG_MBX
  80#define CONFIG_PCMCIA_SLOT_A
  81#endif
  82
  83/* The FADS860T board use SLOT_A */
  84
  85#ifdef CONFIG_FADS
  86#define CONFIG_PCMCIA_SLOT_A
  87#endif
  88
  89/* ------------------------------------------------------------------------- */
  90
  91#define PCMCIA_MEM_WIN_BASE 0xe0000000 /* base address for memory window 0   */
  92#define PCMCIA_MEM_WIN_SIZE 0x04000000 /* each memory window is 64 MByte     */
  93#define PCMCIA_IO_WIN_BASE  _IO_BASE   /* base address for io window 0       */
  94
  95#define PCMCIA_SCHLVL PCMCIA_INTERRUPT /* Status Change Interrupt Level      */
  96
  97/* ------------------------------------------------------------------------- */
  98
  99#define PCMCIA_SOCKETS_NO 1
 100
 101#define PCMCIA_MEM_WIN_NO 5
 102#define PCMCIA_IO_WIN_NO  2
 103
 104/* define _slot_ to be able to optimize macros */
 105
 106#ifdef CONFIG_PCMCIA_SLOT_A
 107#define _slot_ 0
 108#define PCMCIA_SLOT_MSG "SLOT_A"
 109#else
 110#define _slot_ 1
 111#define PCMCIA_SLOT_MSG "SLOT_B"
 112#endif
 113
 114#define M8XX_BUSFREQ ((((bd_t *)&(__res))->bi_busfreq))
 115
 116static int pcmcia_schlvl = PCMCIA_SCHLVL;
 117
 118/* ------------------------------------------------------------------------- */
 119
 120#define PCMCIA_SOCKET_KEY_5V 1
 121#define PCMCIA_SOCKET_KEY_LV 2
 122
 123
 124/* look up table for pgcrx registers */
 125
 126static u_int *m8xx_pgcrx[2] = {
 127        &((immap_t *)IMAP_ADDR)->im_pcmcia.pcmc_pgcra,
 128        &((immap_t *)IMAP_ADDR)->im_pcmcia.pcmc_pgcrb
 129}; 
 130
 131/*
 132 * This structure is used to address each window in the PCMCIA controller. 
 133 * 
 134 * Keep in mind that we assume that pcmcia_win_t[n+1] is mapped directly
 135 * after pcmcia_win_t[n]... 
 136 */
 137
 138typedef struct {             
 139        uint    br;           
 140        uint    or;
 141} pcmcia_win_t;
 142
 143/* 
 144 * For some reason the hardware guys decided to make both slots share
 145 * some registers.
 146 *
 147 * Could someone invent object oriented hardware ?
 148 *
 149 * The macros are used to get the right bit from the registers.
 150 * SLOT_A : slot = 0
 151 * SLOT_B : slot = 1
 152 */
 153
 154#define M8XX_PCMCIA_VS1(slot)      (0x80000000 >> (slot << 4))
 155#define M8XX_PCMCIA_VS2(slot)      (0x40000000 >> (slot << 4))
 156#define M8XX_PCMCIA_VS_MASK(slot)  (0xc0000000 >> (slot << 4))
 157#define M8XX_PCMCIA_VS_SHIFT(slot) (30 - (slot << 4))
 158
 159#define M8XX_PCMCIA_WP(slot)       (0x20000000 >> (slot << 4))
 160#define M8XX_PCMCIA_CD2(slot)      (0x10000000 >> (slot << 4))
 161#define M8XX_PCMCIA_CD1(slot)      (0x08000000 >> (slot << 4))
 162#define M8XX_PCMCIA_BVD2(slot)     (0x04000000 >> (slot << 4))
 163#define M8XX_PCMCIA_BVD1(slot)     (0x02000000 >> (slot << 4))
 164#define M8XX_PCMCIA_RDY(slot)      (0x01000000 >> (slot << 4))
 165#define M8XX_PCMCIA_RDY_L(slot)    (0x00800000 >> (slot << 4))
 166#define M8XX_PCMCIA_RDY_H(slot)    (0x00400000 >> (slot << 4))
 167#define M8XX_PCMCIA_RDY_R(slot)    (0x00200000 >> (slot << 4))
 168#define M8XX_PCMCIA_RDY_F(slot)    (0x00100000 >> (slot << 4))
 169#define M8XX_PCMCIA_MASK(slot)     (0xFFFF0000 >> (slot << 4))
 170
 171#define M8XX_PGCRX(slot)  (*m8xx_pgcrx[slot])
 172
 173#define M8XX_PGCRX_CXOE    0x00000080
 174#define M8XX_PGCRX_CXRESET 0x00000040
 175
 176/* we keep one lookup table per socket to check flags */ 
 177
 178#define PCMCIA_EVENTS_MAX 5  /* 4 max at a time + termination */
 179
 180typedef struct  {
 181        u_int regbit;
 182        u_int eventbit;
 183} event_table_t;
 184
 185typedef struct socket_info_t {
 186    void        (*handler)(void *info, u_int events);
 187    void        *info;
 188
 189    u_int  slot;
 190
 191    socket_state_t state;
 192    struct pccard_mem_map mem_win[PCMCIA_MEM_WIN_NO];
 193    struct pccard_io_map  io_win[PCMCIA_IO_WIN_NO];
 194    event_table_t events[PCMCIA_EVENTS_MAX]; 
 195} socket_info_t;
 196
 197static socket_info_t socket[PCMCIA_SOCKETS_NO];
 198
 199static socket_cap_t capabilities = {
 200    SS_CAP_PCCARD | SS_CAP_MEM_ALIGN | SS_CAP_STATIC_MAP, /* features - 
 201                                                             only 16-bit cards, 
 202                                                             memory windows must be
 203                                                             size-aligned */
 204    0x000,              /* irq_mask - SIU_LEVEL 7 -> 0          */
 205    0x1000,             /* map_size - 4K minimum window size    */
 206    0,                  /* io_offset -                  */
 207    9,                  /* pci_irq */
 208    0           /* No PCI or CardBus support */
 209};
 210
 211/* 
 212 * Search this table to see if the windowsize is
 213 * supported...
 214 */
 215
 216#define M8XX_SIZES_NO 32
 217
 218static const u_int m8xx_size_to_gray[M8XX_SIZES_NO] = 
 219{ 0x00000001, 0x00000002, 0x00000008, 0x00000004,
 220  0x00000080, 0x00000040, 0x00000010, 0x00000020,
 221  0x00008000, 0x00004000, 0x00001000, 0x00002000,
 222  0x00000100, 0x00000200, 0x00000800, 0x00000400,
 223
 224  0x0fffffff, 0xffffffff, 0xffffffff, 0xffffffff,
 225  0x01000000, 0x02000000, 0xffffffff, 0x04000000,
 226  0x00010000, 0x00020000, 0x00080000, 0x00040000,
 227  0x00800000, 0x00400000, 0x00100000, 0x00200000 };
 228
 229
 230/* ------------------------------------------------------------------------- */
 231
 232static void m8xx_interrupt(int irq, void *dev, struct pt_regs *regs);
 233
 234#define PCMCIA_BMT_LIMIT (15*4)  /* Bus Monitor Timeout value */
 235
 236/* ------------------------------------------------------------------------- */
 237/* board specific stuff:                                                     */
 238/* voltage_set(), hardware_enable() and hardware_disable()                   */
 239/* ------------------------------------------------------------------------- */
 240/* RPX Boards from Embedded Planet                                           */
 241
 242#if defined(CONFIG_RPXCLASSIC) || defined(CONFIG_RPXLITE)
 243
 244/* The RPX boards seems to have it's bus monitor timeout set to 6*8 clocks.
 245 * SYPCR is write once only, therefore must the slowest memory be faster 
 246 * than the bus monitor or we will get a machine check due to the bus timeout.
 247 */
 248
 249#define PCMCIA_BOARD_MSG "RPX CLASSIC or RPX LITE"
 250
 251#undef PCMCIA_BMT_LIMIT
 252#define PCMCIA_BMT_LIMIT (6*8) 
 253
 254static int voltage_set(int slot, int vcc, int vpp)
 255{
 256        u_int reg = 0;
 257
 258        switch(vcc) {
 259        case 0: break;
 260        case 33: reg |= BCSR1_PCVCTL4; break;
 261        case 50: reg |= BCSR1_PCVCTL5; break;
 262        default: return 1;
 263        }
 264
 265        switch(vpp) {
 266        case 0: break;
 267        case 33: 
 268        case 50:
 269                if(vcc == vpp)
 270                        reg |= BCSR1_PCVCTL6;
 271                else
 272                        return 1;
 273                break;
 274        case 120: 
 275                reg |= BCSR1_PCVCTL7;
 276        default: return 1;
 277        }
 278
 279        if(!((vcc == 50) || (vcc == 0)))
 280           return 1;
 281
 282        /* first, turn off all power */
 283
 284        *((uint *)RPX_CSR_ADDR) &= ~(BCSR1_PCVCTL4 | BCSR1_PCVCTL5
 285                                     | BCSR1_PCVCTL6 | BCSR1_PCVCTL7);
 286
 287        /* enable new powersettings */
 288
 289        *((uint *)RPX_CSR_ADDR) |= reg;
 290
 291        return 0;
 292}
 293
 294#define socket_get(_slot_) PCMCIA_SOCKET_KEY_5V
 295#define hardware_enable(_slot_)  /* No hardware to enable */
 296#define hardware_disable(_slot_) /* No hardware to disable */
 297
 298#endif /* CONFIG_RPXCLASSIC */
 299
 300/* ------------------------------------------------------------------------- */
 301/* FADS Boards from Motorola                                               */
 302
 303#if defined(CONFIG_FADS)
 304
 305#define PCMCIA_BOARD_MSG "FADS"
 306
 307static int voltage_set(int slot, int vcc, int vpp)
 308{
 309        uint reg = 0;
 310
 311        switch(vcc) {
 312                case 0: break;
 313                case 33: reg |= BCSR1_PCCVCC0; break;
 314                case 50: reg |= BCSR1_PCCVCC1; break;
 315                default: return 1;
 316        }
 317
 318        switch(vpp) {
 319                case 0: break;
 320                case 33:
 321                case 50:
 322                        if(vcc == vpp)
 323                                reg |= BCSR1_PCCVPP1;
 324                        else
 325                                return 1;
 326                        break;
 327                case 120:
 328                        if ((vcc == 33) || (vcc == 50))
 329                                reg |= BCSR1_PCCVPP0;
 330                        else
 331                                return 1;
 332                default: return 1;
 333        }
 334
 335        /* first, turn off all power */
 336        *((uint *)BCSR1) &= ~(BCSR1_PCCVCC_MASK | BCSR1_PCCVPP_MASK);
 337
 338        /* enable new powersettings */
 339        *((uint *)BCSR1) |= reg;
 340
 341        return 0;
 342}
 343
 344#define socket_get(_slot_) PCMCIA_SOCKET_KEY_5V
 345
 346static void hardware_enable(int slot)
 347{
 348        *((uint *)BCSR1) &= ~BCSR1_PCCEN;
 349}
 350
 351static void hardware_disable(int slot)
 352{
 353        *((uint *)BCSR1) |=  BCSR1_PCCEN;
 354}
 355
 356#endif
 357
 358/* ------------------------------------------------------------------------- */
 359/* Motorola MBX860                                                           */
 360
 361#if defined(CONFIG_MBX)
 362
 363#define PCMCIA_BOARD_MSG "MBX"
 364
 365static int voltage_set(int slot, int vcc, int vpp)
 366{
 367        unsigned char reg = 0;
 368
 369        switch(vcc) {
 370                case 0: break;
 371                case 33: reg |= CSR2_VCC_33; break;
 372                case 50: reg |= CSR2_VCC_50; break;
 373                default: return 1;
 374        }
 375
 376        switch(vpp) {
 377                case 0: break;
 378                case 33:
 379                case 50:
 380                        if(vcc == vpp)
 381                                reg |= CSR2_VPP_VCC;
 382                        else
 383                                return 1;
 384                        break;
 385                case 120:
 386                        if ((vcc == 33) || (vcc == 50))
 387                                reg |= CSR2_VPP_12;
 388                        else
 389                                return 1;
 390                default: return 1;
 391        }
 392
 393        /* first, turn off all power */
 394        *((unsigned char *)MBX_CSR2_ADDR) &= ~(CSR2_VCC_MASK | CSR2_VPP_MASK);
 395
 396        /* enable new powersettings */
 397        *((unsigned char *)MBX_CSR2_ADDR) |= reg;
 398
 399        return 0;
 400}
 401
 402#define socket_get(_slot_) PCMCIA_SOCKET_KEY_5V
 403#define hardware_enable(_slot_)  /* No hardware to enable */
 404#define hardware_disable(_slot_) /* No hardware to disable */
 405
 406#endif /* CONFIG_MBX */
 407
 408/* ------------------------------------------------------------------------- */
 409
 410static void m8xx_shutdown(void)
 411{
 412        u_int m;
 413        pcmcia_win_t *w;
 414
 415        
 416        w = (void *) &((immap_t *)IMAP_ADDR)->im_pcmcia.pcmc_pbr0;
 417
 418
 419                ((immap_t *)IMAP_ADDR)->im_pcmcia.pcmc_pscr = 
 420                        M8XX_PCMCIA_MASK(_slot_); 
 421                ((immap_t *)IMAP_ADDR)->im_pcmcia.pcmc_per 
 422                        &= ~M8XX_PCMCIA_MASK(_slot_);
 423 
 424                /* turn off interrupt and disable CxOE */
 425
 426                M8XX_PGCRX(_slot_) = M8XX_PGCRX_CXOE;
 427
 428                /* turn off memory windows */
 429
 430                for(m = 0; m < PCMCIA_MEM_WIN_NO; m++) {
 431                        w->or = 0;  /* set to not valid */
 432                        w++;
 433                }
 434
 435                /* turn off voltage */
 436
 437                voltage_set(_slot_, 0, 0);
 438
 439                /* disable external hardware */
 440        
 441                hardware_disable(_slot_);
 442
 443        free_irq(pcmcia_schlvl, NULL);
 444
 445}
 446
 447/* ------------------------------------------------------------------------- */
 448
 449/* ------------------------------------------------------------------------- */
 450
 451static u_int pending_events[PCMCIA_SOCKETS_NO];
 452static spinlock_t pending_event_lock = SPIN_LOCK_UNLOCKED;
 453
 454static void m8xx_pcmcia_bh(void *dummy)
 455{
 456        u_int events;
 457        int i;
 458
 459        for (i=0; i < PCMCIA_SOCKETS_NO; i++) {
 460                spin_lock_irq(&pending_event_lock);
 461                events = pending_events[i];
 462                pending_events[i] = 0;
 463                spin_unlock_irq(&pending_event_lock);
 464                /*
 465                SS_DETECT events need a small delay here. The reason for this is that
 466                the "is there a card" electronics need time to see the card after the
 467                "we have a card coming in" electronics have seen it.
 468                */
 469                if (events & SS_DETECT)
 470                        mdelay(4);
 471                if (socket[i].handler)
 472                        socket[i].handler(socket[i].info, events);
 473        }
 474}
 475
 476static struct tq_struct m8xx_pcmcia_task = {
 477        routine:        m8xx_pcmcia_bh
 478};
 479
 480
 481static void m8xx_interrupt(int irq, void *dev, struct pt_regs *regs)
 482{
 483        socket_info_t *s;
 484        event_table_t *e;
 485        u_int events, pscr, pipr;
 486
 487        DEBUG(3,"Interrupt!\n");
 488
 489        /* get interrupt sources */
 490
 491        pscr = ((immap_t *)IMAP_ADDR)->im_pcmcia.pcmc_pscr;
 492        pipr = ((immap_t *)IMAP_ADDR)->im_pcmcia.pcmc_pipr;
 493
 494        s = &socket[0];
 495
 496            if(s->handler) {
 497
 498                    e = &s->events[0]; 
 499                    events = 0;
 500
 501                    while(e->regbit) {
 502                            if(pscr & e->regbit)
 503                                    events |= e->eventbit;
 504                    
 505                            e++;
 506                    }
 507
 508                    /* 
 509                     * report only if both card detect signals are the same 
 510                     * not too nice done, 
 511                     * we depend on that CD2 is the bit to the left of CD1...
 512                     */
 513
 514                    if(events & SS_DETECT)
 515                            if(((pipr & M8XX_PCMCIA_CD2(_slot_)) >> 1)
 516                                    ^ (pipr & M8XX_PCMCIA_CD1(_slot_)))
 517                                    events &= ~SS_DETECT;
 518
 519#ifdef PCMCIA_GLITCHY_CD
 520                    
 521                    /*
 522                     * I've experienced CD problems with my ADS board.
 523                     * We make an extra check to see if there was a
 524                     * real change of Card detection.
 525                     */
 526
 527                    if((events & SS_DETECT) && 
 528                       ((pipr &
 529                         (M8XX_PCMCIA_CD2(_slot_) | M8XX_PCMCIA_CD1(_slot_)))
 530                        == 0) && (s->state.Vcc | s->state.Vpp)) {
 531                          events &= ~SS_DETECT;
 532                          printk( "CD glitch workaround - CD = 0x%08x!\n",
 533                                (pipr & (M8XX_PCMCIA_CD2(_slot_) 
 534                                         | M8XX_PCMCIA_CD1(_slot_))));
 535                    }
 536#endif
 537
 538                    /* call the handler */
 539
 540                    DEBUG(3,"slot %u: events = 0x%02x, pscr = 0x%08x, "
 541                          "pipr = 0x%08x\n", 
 542                          _slot_, events, pscr, pipr);
 543
 544                    if(events) {
 545                            spin_lock(&pending_event_lock);
 546                            pending_events[0] |= events;
 547                            spin_unlock(&pending_event_lock);
 548                            schedule_task(&m8xx_pcmcia_task);
 549                    }
 550
 551            }
 552
 553
 554    /* clear the interrupt sources */
 555
 556    ((immap_t *)IMAP_ADDR)->im_pcmcia.pcmc_pscr = pscr;
 557    
 558    DEBUG(3,"Interrupt done.\n");
 559    
 560}
 561
 562/* ------------------------------------------------------------------------- */
 563
 564static u_int m8xx_get_graycode(u_int size)
 565{
 566        u_int k;
 567
 568        for(k = 0; k < M8XX_SIZES_NO; k++)
 569                if(m8xx_size_to_gray[k] == size)
 570                        break;
 571
 572        if((k == M8XX_SIZES_NO) || (m8xx_size_to_gray[k] == -1))
 573                k = -1;
 574
 575        return k;
 576}
 577
 578/* ------------------------------------------------------------------------- */
 579
 580static u_int m8xx_get_speed(u_int ns, u_int is_io)
 581{
 582        u_int reg, clocks, psst, psl, psht;
 583
 584        if(!ns) {
 585
 586                /*
 587                 * We get called with IO maps setup to 0ns
 588                 * if not specified by the user.
 589                 * They should be 255ns.
 590                 */
 591
 592                if(is_io)
 593                        ns = 255;
 594                else 
 595                        ns = 100;  /* fast memory if 0 */
 596        }
 597
 598        /* 
 599         * In PSST, PSL, PSHT fields we tell the controller
 600         * timing parameters in CLKOUT clock cycles.
 601         * CLKOUT is the same as GCLK2_50.
 602         */
 603
 604/* how we want to adjust the timing - in percent */
 605
 606#define ADJ 180 /* 80 % longer accesstime - to be sure */
 607
 608
 609        clocks = ((M8XX_BUSFREQ / 1000) * ns) / 1000;
 610        clocks = (clocks * ADJ) / (100*1000);
 611        if(clocks >= PCMCIA_BMT_LIMIT) {
 612                printk( "Max access time limit reached\n");
 613                clocks = PCMCIA_BMT_LIMIT-1;
 614        }
 615
 616        psst = clocks / 7;          /* setup time */
 617        psht = clocks / 7;          /* hold time */
 618        psl  = (clocks * 5) / 7;    /* strobe length */
 619
 620        psst += clocks - (psst + psht + psl);
 621
 622        reg =  psst << 12;
 623        reg |= psl  << 7; 
 624        reg |= psht << 16;
 625
 626        return reg;
 627}
 628
 629/* ------------------------------------------------------------------------- */
 630        
 631static int m8xx_register_callback(unsigned int sock, void (*handler)(void *, unsigned int), void * info)
 632{
 633        socket[sock].handler = handler;
 634        socket[sock].info = info;
 635        if (handler == NULL) {
 636                MOD_DEC_USE_COUNT;
 637        } 
 638        else {
 639                MOD_INC_USE_COUNT;
 640        }
 641        return 0;
 642}
 643
 644/* ------------------------------------------------------------------------- */
 645
 646static int m8xx_get_status(unsigned int lsock, u_int *value)
 647{
 648        socket_info_t *s = &socket[lsock];
 649        u_int pipr, reg;
 650
 651
 652        pipr = ((immap_t *)IMAP_ADDR)->im_pcmcia.pcmc_pipr;
 653
 654        *value  = ((pipr & (M8XX_PCMCIA_CD1(_slot_) 
 655                            | M8XX_PCMCIA_CD2(_slot_))) == 0) ? SS_DETECT : 0;
 656        *value |= (pipr & M8XX_PCMCIA_WP(_slot_)) ? SS_WRPROT : 0;
 657
 658        if (s->state.flags & SS_IOCARD)
 659                *value |= (pipr & M8XX_PCMCIA_BVD1(_slot_)) ? SS_STSCHG : 0;
 660        else {
 661                *value |= (pipr & M8XX_PCMCIA_RDY(_slot_)) ? SS_READY : 0;
 662                *value |= (pipr & M8XX_PCMCIA_BVD1(_slot_)) ? SS_BATDEAD : 0;
 663                *value |= (pipr & M8XX_PCMCIA_BVD2(_slot_)) ? SS_BATWARN : 0;
 664        }
 665        
 666        if (s->state.Vcc | s->state.Vpp)
 667                *value |= SS_POWERON;
 668        
 669        /*
 670         * Voltage detection:
 671         * This driver only supports 16-Bit pc-cards.
 672         * Cardbus is not handled here.
 673         * 
 674         * To determine what voltage to use we must read the VS1 and VS2 pin.
 675         * Depending on what socket type is present,
 676         * different combinations mean different things.
 677         *
 678         * Card Key  Socket Key   VS1   VS2   Card         Vcc for CIS parse
 679         *   
 680         * 5V        5V, LV*      NC    NC    5V only       5V (if available)
 681         *           
 682         * 5V        5V, LV*      GND   NC    5 or 3.3V     as low as possible
 683         *
 684         * 5V        5V, LV*      GND   GND   5, 3.3, x.xV  as low as possible
 685         *
 686         * LV*       5V            -     -    shall not fit into socket
 687         *
 688         * LV*       LV*          GND   NC    3.3V only     3.3V
 689         *
 690         * LV*       LV*          NC    GND   x.xV          x.xV (if avail.)
 691         *
 692         * LV*       LV*          GND   GND   3.3 or x.xV   as low as possible
 693         *
 694         * *LV means Low Voltage
 695         *
 696         *
 697         * That gives us the following table:
 698         *
 699         * Socket    VS1  VS2   Voltage
 700         *
 701         * 5V        NC   NC    5V
 702         * 5V        NC   GND   none (should not be possible)
 703         * 5V        GND  NC    >= 3.3V
 704         * 5V        GND  GND   >= x.xV 
 705         *
 706         * LV        NC   NC    5V   (if available)
 707         * LV        NC   GND   x.xV (if available)
 708         * LV        GND  NC    3.3V 
 709         * LV        GND  GND   >= x.xV 
 710         * 
 711         * So, how do I determine if I have a 5V or a LV
 712         * socket on my board?  Look at the socket!
 713         *
 714         * 
 715         * Socket with 5V key:
 716         * ++--------------------------------------------+
 717         * ||                                            |
 718         * ||                                           ||
 719         * ||                                           ||
 720         * |                                             |
 721         * +---------------------------------------------+
 722         *
 723         * Socket with LV key:
 724         * ++--------------------------------------------+
 725         * ||                                            |
 726         * |                                            ||
 727         * |                                            ||
 728         * |                                             |
 729         * +---------------------------------------------+
 730         *
 731         *
 732         * With other words - LV only cards does not fit
 733         * into the 5V socket!
 734         */
 735
 736        /* read out VS1 and VS2 */
 737
 738        reg = (pipr & M8XX_PCMCIA_VS_MASK(_slot_)) 
 739                >> M8XX_PCMCIA_VS_SHIFT(_slot_);
 740
 741        if(socket_get(_slot_) == PCMCIA_SOCKET_KEY_LV) {
 742                switch(reg) {
 743                case 1: *value |= SS_3VCARD; break; /* GND, NC - 3.3V only */
 744                case 2: *value |= SS_XVCARD; break; /* NC. GND - x.xV only */
 745                };
 746        }
 747
 748        DEBUG(3,"GetStatus(%d) = %#2.2x\n", lsock, *value);
 749        return 0;
 750}
 751  
 752/* ------------------------------------------------------------------------- */
 753
 754static int m8xx_inquire_socket(unsigned int lsock, socket_cap_t *cap)
 755{
 756        *cap = capabilities;
 757
 758        return 0;
 759}
 760
 761/* ------------------------------------------------------------------------- */
 762
 763static int m8xx_get_socket(unsigned int lsock, socket_state_t *state)
 764{
 765        *state = socket[lsock].state; /* copy the whole structure */
 766
 767        DEBUG(3,"GetSocket(%d) = flags %#3.3x, Vcc %d, Vpp %d, "
 768              "io_irq %d, csc_mask %#2.2x\n", lsock, state->flags,
 769              state->Vcc, state->Vpp, state->io_irq, state->csc_mask);
 770        return 0;
 771}
 772
 773/* ------------------------------------------------------------------------- */
 774
 775static int m8xx_set_socket(unsigned int lsock, socket_state_t *state)
 776{
 777        socket_info_t *s = &socket[lsock];
 778        event_table_t *e;
 779        u_int reg;
 780        u_long flags;
 781
 782        DEBUG(3, "SetSocket(%d, flags %#3.3x, Vcc %d, Vpp %d, "
 783              "io_irq %d, csc_mask %#2.2x)\n", lsock, state->flags,
 784              state->Vcc, state->Vpp, state->io_irq, state->csc_mask);
 785
 786        /* First, set voltage - bail out if invalid */
 787    
 788        if(voltage_set(_slot_, state->Vcc, state->Vpp))
 789                return -EINVAL;
 790
 791
 792        /* Take care of reset... */
 793
 794        if(state->flags & SS_RESET) 
 795                M8XX_PGCRX(_slot_) |=  M8XX_PGCRX_CXRESET; /* active high */
 796        else
 797                M8XX_PGCRX(_slot_) &= ~M8XX_PGCRX_CXRESET; 
 798
 799        /* ... and output enable. */
 800
 801        /* The CxOE signal is connected to a 74541 on the ADS.
 802           I guess most other boards used the ADS as a reference.
 803           I tried to control the CxOE signal with SS_OUTPUT_ENA,
 804           but the reset signal seems connected via the 541. 
 805           If the CxOE is left high are some signals tristated and
 806           no pullups are present -> the cards act wierd.
 807           So right now the buffers are enabled if the power is on. */
 808
 809        if(state->Vcc || state->Vpp)
 810                M8XX_PGCRX(_slot_) &= ~M8XX_PGCRX_CXOE; /* active low */
 811        else
 812                M8XX_PGCRX(_slot_) |=  M8XX_PGCRX_CXOE;
 813        
 814        /* 
 815         * We'd better turn off interrupts before 
 816         * we mess with the events-table..
 817         */
 818
 819        save_flags(flags);
 820        cli();
 821
 822        /*
 823         * Play around with the interrupt mask to be able to
 824         * give the events the generic pcmcia driver wants us to.
 825         */
 826
 827        e = &s->events[0]; 
 828        reg = 0;
 829
 830        if(state->csc_mask & SS_DETECT) {
 831                e->eventbit = SS_DETECT;
 832                reg |= e->regbit = (M8XX_PCMCIA_CD2(_slot_) 
 833                                    | M8XX_PCMCIA_CD1(_slot_));
 834                e++;
 835        }
 836
 837        if(state->flags & SS_IOCARD) {
 838
 839                /* 
 840                 * I/O card
 841                 */
 842
 843                if(state->csc_mask & SS_STSCHG) {
 844                        e->eventbit = SS_STSCHG;
 845                        reg |= e->regbit = M8XX_PCMCIA_BVD1(_slot_);
 846                        e++;
 847                }
 848                
 849
 850                /*
 851                 * If io_irq is non-zero we should enable irq.
 852                 */
 853
 854                if(state->io_irq) {
 855                        M8XX_PGCRX(_slot_) |= 
 856                                mk_int_int_mask(state->io_irq) << 24;
 857
 858                        /*
 859                         * Strange thing here:
 860                         * The manual does not tell us which interrupt
 861                         * the sources generate.
 862                         * Anyhow, I found out that RDY_L generates IREQLVL.
 863                         *
 864                         * We use level triggerd interrupts, and they don't
 865                         * have to be cleared in PSCR in the interrupt handler.
 866                         */
 867
 868                        reg |= M8XX_PCMCIA_RDY_L(_slot_);  
 869                }
 870                else
 871                        M8XX_PGCRX(_slot_) &= 0x00ffffff;
 872                
 873        }
 874        else {
 875                
 876                /*
 877                 * Memory card
 878                 */
 879                
 880                if(state->csc_mask & SS_BATDEAD) {
 881                        e->eventbit = SS_BATDEAD;
 882                        reg |= e->regbit = M8XX_PCMCIA_BVD1(_slot_);
 883                        e++;
 884                }
 885                
 886                if(state->csc_mask & SS_BATWARN) {
 887                        e->eventbit = SS_BATWARN;
 888                        reg |= e->regbit = M8XX_PCMCIA_BVD2(_slot_);
 889                        e++;
 890                }
 891                
 892                /* What should I trigger on - low/high,raise,fall? */
 893                if(state->csc_mask & SS_READY) {
 894                        e->eventbit = SS_READY;
 895                        reg |= e->regbit = 0; //??
 896                        e++;
 897                }
 898        }
 899        
 900        e->regbit = 0;  /* terminate list */
 901        
 902        /* 
 903         * Clear the status changed .
 904         * Port A and Port B share the same port.
 905         * Writing ones will clear the bits.
 906         */
 907        
 908        ((immap_t *)IMAP_ADDR)->im_pcmcia.pcmc_pscr = reg;
 909        
 910        /*
 911         * Write the mask.
 912         * Port A and Port B share the same port.
 913         * Need for read-modify-write. 
 914         * Ones will enable the interrupt.
 915         */
 916
 917        reg |= ((immap_t *)IMAP_ADDR)->im_pcmcia.pcmc_per 
 918                & M8XX_PCMCIA_MASK(_slot_);
 919        
 920        ((immap_t *)IMAP_ADDR)->im_pcmcia.pcmc_per = reg;
 921        
 922        restore_flags(flags);
 923
 924        /* copy the struct and modify the copy */
 925        
 926        s->state = *state;
 927        
 928        return 0;
 929}
 930
 931/* ------------------------------------------------------------------------- */
 932
 933static int m8xx_get_io_map(unsigned int lsock, struct pccard_io_map *io)
 934{
 935        if(io->map >= PCMCIA_IO_WIN_NO)
 936                return -EINVAL;
 937
 938        *io = socket[lsock].io_win[io->map]; /* copy the struct */
 939
 940        DEBUG(3,"GetIOMap(%d, %d) = %#2.2x, %d ns, "
 941              "%#4.4x-%#4.4x\n", lsock, io->map, io->flags,
 942              io->speed, io->start, io->stop);
 943        return 0;
 944}
 945
 946/* ------------------------------------------------------------------------- */
 947
 948static int m8xx_set_io_map(unsigned int lsock, struct pccard_io_map *io)
 949{
 950        socket_info_t *s = &socket[lsock];
 951        pcmcia_win_t *w;
 952        u_int reg, winnr;
 953        
 954
 955#define M8XX_SIZE (io->stop - io->start + 1)   
 956#define M8XX_BASE (PCMCIA_IO_WIN_BASE + io->start)
 957
 958        DEBUG(3, "SetIOMap(%d, %d, %#2.2x, %d ns, "
 959              "%#4.4x-%#4.4x)\n", lsock, io->map, io->flags,
 960              io->speed, io->start, io->stop);
 961
 962        if ((io->map >= PCMCIA_IO_WIN_NO) || (io->start > 0xffff) 
 963            || (io->stop > 0xffff) || (io->stop < io->start)) 
 964                return -EINVAL;
 965        
 966        if((reg = m8xx_get_graycode(M8XX_SIZE)) == -1)
 967                return -EINVAL;
 968
 969        if(io->flags & MAP_ACTIVE) {
 970
 971                winnr = (PCMCIA_MEM_WIN_NO * PCMCIA_SOCKETS_NO) 
 972                        + (lsock * PCMCIA_IO_WIN_NO) + io->map;
 973        
 974                /* setup registers */
 975
 976                w = (void *) &((immap_t *)IMAP_ADDR)->im_pcmcia.pcmc_pbr0;
 977                w += winnr;
 978        
 979                w->or = 0; /* turn off window first */
 980                w->br = M8XX_BASE;
 981        
 982                reg <<= 27;     
 983                reg |= 0x00018 + (_slot_ << 2);
 984
 985                reg |= m8xx_get_speed(io->speed, 1);
 986
 987                if(io->flags & MAP_WRPROT) 
 988                        reg |= 0x00000002;
 989                
 990                if(io->flags & (MAP_16BIT | MAP_AUTOSZ))
 991                        reg |= 0x00000040;
 992        
 993                if(io->flags & MAP_ACTIVE) 
 994                        reg |= 0x00000001;
 995        
 996                w->or = reg;
 997
 998                DEBUG(3,"Socket %u: Mapped io window %u at %#8.8x, "
 999                      "OR = %#8.8x.\n", lsock, io->map, w->br, w->or);
1000        }
1001
1002
1003        /* copy the struct and modify the copy */
1004        
1005        s->io_win[io->map] = *io; 
1006        s->io_win[io->map].flags &= (MAP_WRPROT 
1007                                     | MAP_16BIT
1008                                     | MAP_ACTIVE);
1009        return 0;
1010}
1011
1012/* ------------------------------------------------------------------------- */
1013
1014static int m8xx_get_mem_map(unsigned int lsock, struct pccard_mem_map *mem)
1015{
1016        if(mem->map >= PCMCIA_MEM_WIN_NO)
1017                return -EINVAL;
1018        
1019        *mem = socket[lsock].mem_win[mem->map]; /* copy the struct */
1020        
1021        DEBUG(3, "GetMemMap(%d, %d) = %#2.2x, %d ns, "
1022              "%#5.5lx-%#5.5lx, %#5.5x\n", lsock, mem->map, mem->flags,
1023              mem->speed, mem->sys_start, mem->sys_stop, mem->card_start);
1024        return 0;
1025}
1026
1027/* ------------------------------------------------------------------------- */
1028
1029static int m8xx_set_mem_map(unsigned int lsock, struct pccard_mem_map *mem)
1030{
1031        socket_info_t *s = &socket[lsock];
1032        pcmcia_win_t *w;
1033        struct pccard_mem_map *old;
1034        u_int reg, winnr;
1035        
1036        DEBUG(3, "SetMemMap(%d, %d, %#2.2x, %d ns, "
1037              "%#5.5lx-%#5.5lx, %#5.5x)\n", lsock, mem->map, mem->flags,
1038              mem->speed, mem->sys_start, mem->sys_stop, mem->card_start);
1039
1040        if ((mem->map >= PCMCIA_MEM_WIN_NO) || (mem->sys_start > mem->sys_stop)
1041            || ((mem->sys_stop - mem->sys_start) >= PCMCIA_MEM_WIN_SIZE)
1042            || (mem->card_start >= 0x04000000) 
1043            || (mem->sys_start & 0xfff)                /* 4KByte resolution */
1044            || (mem->card_start & 0xfff))                   
1045                return -EINVAL;
1046        
1047        if((reg = m8xx_get_graycode(PCMCIA_MEM_WIN_SIZE)) == -1) {
1048                printk( "Cannot set size to 0x%08x.\n", PCMCIA_MEM_WIN_SIZE);
1049                return -EINVAL;
1050        }
1051
1052        winnr = (lsock * PCMCIA_MEM_WIN_NO) + mem->map;
1053        
1054        /* Setup the window in the pcmcia controller */
1055        
1056        w = (void *) &((immap_t *)IMAP_ADDR)->im_pcmcia.pcmc_pbr0;
1057        w += winnr;
1058        
1059        reg <<= 27;
1060        reg |= _slot_ << 2;
1061        
1062        reg |= m8xx_get_speed(mem->speed, 0);
1063
1064        if(mem->flags & MAP_ATTRIB) 
1065                reg |= 0x00000010;
1066        
1067        if(mem->flags & MAP_WRPROT) 
1068                reg |= 0x00000002;
1069        
1070        if(mem->flags & MAP_16BIT) 
1071                reg |= 0x00000040;
1072        
1073        if(mem->flags & MAP_ACTIVE) 
1074                reg |= 0x00000001;
1075        
1076        w->or = reg;
1077
1078        DEBUG(3, "Socket %u: Mapped memory window %u at %#8.8x, "
1079              "OR = %#8.8x.\n", lsock, mem->map, w->br, w->or);
1080
1081        if(mem->flags & MAP_ACTIVE) {
1082
1083                mem->sys_stop -= mem->sys_start;
1084
1085                /* get the new base address */
1086                
1087                mem->sys_start = PCMCIA_MEM_WIN_BASE + 
1088                        (PCMCIA_MEM_WIN_SIZE * winnr)
1089                        + mem->card_start; 
1090
1091                mem->sys_stop += mem->sys_start;
1092        }
1093
1094DEBUG(3, "SetMemMap(%d, %d, %#2.2x, %d ns, "
1095              "%#5.5lx-%#5.5lx, %#5.5x)\n", lsock, mem->map, mem->flags,
1096              mem->speed, mem->sys_start, mem->sys_stop, mem->card_start);
1097
1098        /* copy the struct and modify the copy */
1099        
1100        old = &s->mem_win[mem->map];
1101        
1102        *old = *mem;
1103        old->flags &= (MAP_ATTRIB
1104                       | MAP_WRPROT 
1105                       | MAP_16BIT
1106                       | MAP_ACTIVE);
1107
1108        return 0;
1109}
1110
1111static int m8xx_sock_init(unsigned int s)
1112{
1113        int i;
1114        pccard_io_map io = { 0, 0, 0, 0, 1 };
1115        pccard_mem_map mem = { 0, 0, 0, 0, 0, 0 };
1116
1117        DEBUG(3, "sock_init(%d)\n", s);
1118
1119        mem.sys_stop = 0x1000;
1120        m8xx_set_socket(s, &dead_socket);
1121        for (i = 0; i < PCMCIA_IO_WIN_NO; i++) {
1122                io.map = i;
1123                m8xx_set_io_map(s, &io);
1124        }
1125        for (i = 0; i < PCMCIA_MEM_WIN_NO; i++) {
1126                mem.map = i;
1127                m8xx_set_mem_map(s, &mem);
1128        }
1129
1130        return 0;
1131                
1132}
1133
1134static int m8xx_suspend(unsigned int s)
1135{
1136                return(m8xx_set_socket(s, &dead_socket));
1137}
1138static void m8xx_proc_setup(unsigned int sock, struct proc_dir_entry *base)
1139{
1140}
1141/* ------------------------------------------------------------------------- */
1142    
1143static struct pccard_operations m8xx_services = {
1144        &m8xx_sock_init,        
1145        &m8xx_suspend,
1146        &m8xx_register_callback,
1147        &m8xx_inquire_socket,
1148        &m8xx_get_status,
1149        &m8xx_get_socket,
1150        &m8xx_set_socket,
1151        &m8xx_get_io_map,
1152        &m8xx_set_io_map,
1153        &m8xx_get_mem_map,
1154        &m8xx_set_mem_map,
1155        &m8xx_proc_setup
1156};
1157
1158static int __init m8xx_init(void)
1159{
1160        servinfo_t serv;
1161        pcmcia_win_t *w;
1162        u_int m;
1163
1164        PCMCIA_INFO("%s\n", version);
1165        CardServices(GetCardServicesInfo, &serv);
1166        if (serv.Revision != CS_RELEASE_CODE) {
1167                PCMCIA_ERROR("Card Services release does not match!\n");
1168                return -1;
1169        }
1170
1171        PCMCIA_INFO(PCMCIA_BOARD_MSG " using " PCMCIA_SLOT_MSG 
1172                    " with IRQ %u.\n", pcmcia_schlvl); 
1173
1174        /* Configure Status change interrupt */
1175
1176        if(request_8xxirq(pcmcia_schlvl, m8xx_interrupt, 0, 
1177                           "m8xx_pcmcia", NULL)) {
1178                PCMCIA_ERROR("Cannot allocate IRQ %u for SCHLVL!\n", 
1179                             pcmcia_schlvl);
1180                return -1;
1181        }
1182
1183
1184        w = (void *) &((immap_t *)IMAP_ADDR)->im_pcmcia.pcmc_pbr0;
1185
1186        socket[0].slot = _slot_;
1187            
1188        ((immap_t *)IMAP_ADDR)->im_pcmcia.pcmc_pscr = 
1189                M8XX_PCMCIA_MASK(_slot_); 
1190        ((immap_t *)IMAP_ADDR)->im_pcmcia.pcmc_per 
1191                &= ~M8XX_PCMCIA_MASK(_slot_);
1192 
1193/* connect interrupt and disable CxOE */
1194
1195        M8XX_PGCRX(_slot_) = M8XX_PGCRX_CXOE |
1196                (mk_int_int_mask(pcmcia_schlvl) << 16);
1197
1198/* intialize the fixed memory windows */
1199
1200        for(m = 0; m < PCMCIA_MEM_WIN_NO; m++) {
1201                w->br = PCMCIA_MEM_WIN_BASE + 
1202                        (PCMCIA_MEM_WIN_SIZE 
1203                         * (m + 0 * PCMCIA_MEM_WIN_NO));
1204
1205                w->or = 0;  /* set to not valid */
1206
1207                DEBUG(3,"Socket %u: MemWin %u: Base 0x%08x.\n",
1208                      0, m, w->br);
1209
1210                w++;
1211        }
1212
1213/* turn off voltage */
1214        voltage_set(_slot_, 0, 0);
1215
1216/* Enable external hardware */
1217        hardware_enable(_slot_);
1218
1219        if(register_ss_entry(PCMCIA_SOCKETS_NO, &m8xx_services) != 0) {
1220            PCMCIA_ERROR("register_ss_entry() failed.\n");
1221            m8xx_shutdown();
1222            return -ENODEV;
1223        }
1224
1225        return 0;
1226}
1227
1228static void __exit m8xx_exit(void)
1229{
1230        unregister_ss_entry(&m8xx_services);
1231
1232        m8xx_shutdown();
1233}
1234
1235module_init(m8xx_init);
1236module_exit(m8xx_exit);
1237
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.