linux/drivers/pcmcia/db1xxx_ss.c
<<
>>
Prefs
   1/*
   2 * PCMCIA socket code for the Alchemy Db1xxx/Pb1xxx boards.
   3 *
   4 * Copyright (c) 2009 Manuel Lauss <manuel.lauss@gmail.com>
   5 *
   6 */
   7
   8/* This is a fairly generic PCMCIA socket driver suitable for the
   9 * following Alchemy Development boards:
  10 *  Db1000, Db/Pb1500, Db/Pb1100, Db/Pb1550, Db/Pb1200.
  11 *
  12 * The Db1000 is used as a reference:  Per-socket card-, carddetect- and
  13 *  statuschange IRQs connected to SoC GPIOs, control and status register
  14 *  bits arranged in per-socket groups in an external PLD.  All boards
  15 *  listed here use this layout, including bit positions and meanings.
  16 *  Of course there are exceptions in later boards:
  17 *
  18 *      - Pb1100/Pb1500:  single socket only; voltage key bits VS are
  19 *                        at STATUS[5:4] (instead of STATUS[1:0]).
  20 *      - Au1200-based:   additional card-eject irqs, irqs not gpios!
  21 */
  22
  23#include <linux/delay.h>
  24#include <linux/gpio.h>
  25#include <linux/interrupt.h>
  26#include <linux/pm.h>
  27#include <linux/platform_device.h>
  28#include <linux/resource.h>
  29#include <linux/slab.h>
  30#include <linux/spinlock.h>
  31
  32#include <pcmcia/ss.h>
  33
  34#include <asm/mach-au1x00/au1000.h>
  35#include <asm/mach-db1x00/bcsr.h>
  36
  37#define MEM_MAP_SIZE    0x400000
  38#define IO_MAP_SIZE     0x1000
  39
  40struct db1x_pcmcia_sock {
  41        struct pcmcia_socket    socket;
  42        int             nr;             /* socket number */
  43        void            *virt_io;
  44
  45        phys_addr_t     phys_io;
  46        phys_addr_t     phys_attr;
  47        phys_addr_t     phys_mem;
  48
  49        /* previous flags for set_socket() */
  50        unsigned int old_flags;
  51
  52        /* interrupt sources: linux irq numbers! */
  53        int     insert_irq;     /* default carddetect irq */
  54        int     stschg_irq;     /* card-status-change irq */
  55        int     card_irq;       /* card irq */
  56        int     eject_irq;      /* db1200/pb1200 have these */
  57
  58#define BOARD_TYPE_DEFAULT      0       /* most boards */
  59#define BOARD_TYPE_DB1200       1       /* IRQs aren't gpios */
  60#define BOARD_TYPE_PB1100       2       /* VS bits slightly different */
  61        int     board_type;
  62};
  63
  64#define to_db1x_socket(x) container_of(x, struct db1x_pcmcia_sock, socket)
  65
  66/* DB/PB1200: check CPLD SIGSTATUS register bit 10/12 */
  67static int db1200_card_inserted(struct db1x_pcmcia_sock *sock)
  68{
  69        unsigned short sigstat;
  70
  71        sigstat = bcsr_read(BCSR_SIGSTAT);
  72        return sigstat & 1 << (8 + 2 * sock->nr);
  73}
  74
  75/* carddetect gpio: low-active */
  76static int db1000_card_inserted(struct db1x_pcmcia_sock *sock)
  77{
  78        return !gpio_get_value(irq_to_gpio(sock->insert_irq));
  79}
  80
  81static int db1x_card_inserted(struct db1x_pcmcia_sock *sock)
  82{
  83        switch (sock->board_type) {
  84        case BOARD_TYPE_DB1200:
  85                return db1200_card_inserted(sock);
  86        default:
  87                return db1000_card_inserted(sock);
  88        }
  89}
  90
  91/* STSCHG tends to bounce heavily when cards are inserted/ejected.
  92 * To avoid this, the interrupt is normally disabled and only enabled
  93 * after reset to a card has been de-asserted.
  94 */
  95static inline void set_stschg(struct db1x_pcmcia_sock *sock, int en)
  96{
  97        if (sock->stschg_irq != -1) {
  98                if (en)
  99                        enable_irq(sock->stschg_irq);
 100                else
 101                        disable_irq(sock->stschg_irq);
 102        }
 103}
 104
 105static irqreturn_t db1000_pcmcia_cdirq(int irq, void *data)
 106{
 107        struct db1x_pcmcia_sock *sock = data;
 108
 109        pcmcia_parse_events(&sock->socket, SS_DETECT);
 110
 111        return IRQ_HANDLED;
 112}
 113
 114static irqreturn_t db1000_pcmcia_stschgirq(int irq, void *data)
 115{
 116        struct db1x_pcmcia_sock *sock = data;
 117
 118        pcmcia_parse_events(&sock->socket, SS_STSCHG);
 119
 120        return IRQ_HANDLED;
 121}
 122
 123static irqreturn_t db1200_pcmcia_cdirq(int irq, void *data)
 124{
 125        struct db1x_pcmcia_sock *sock = data;
 126
 127        /* Db/Pb1200 have separate per-socket insertion and ejection
 128         * interrupts which stay asserted as long as the card is
 129         * inserted/missing.  The one which caused us to be called
 130         * needs to be disabled and the other one enabled.
 131         */
 132        if (irq == sock->insert_irq) {
 133                disable_irq_nosync(sock->insert_irq);
 134                enable_irq(sock->eject_irq);
 135        } else {
 136                disable_irq_nosync(sock->eject_irq);
 137                enable_irq(sock->insert_irq);
 138        }
 139
 140        pcmcia_parse_events(&sock->socket, SS_DETECT);
 141
 142        return IRQ_HANDLED;
 143}
 144
 145static int db1x_pcmcia_setup_irqs(struct db1x_pcmcia_sock *sock)
 146{
 147        int ret;
 148
 149        if (sock->stschg_irq != -1) {
 150                ret = request_irq(sock->stschg_irq, db1000_pcmcia_stschgirq,
 151                                  0, "pcmcia_stschg", sock);
 152                if (ret)
 153                        return ret;
 154        }
 155
 156        /* Db/Pb1200 have separate per-socket insertion and ejection
 157         * interrupts, which should show edge behaviour but don't.
 158         * So interrupts are disabled until both insertion and
 159         * ejection handler have been registered and the currently
 160         * active one disabled.
 161         */
 162        if (sock->board_type == BOARD_TYPE_DB1200) {
 163                ret = request_irq(sock->insert_irq, db1200_pcmcia_cdirq,
 164                                  IRQF_DISABLED, "pcmcia_insert", sock);
 165                if (ret)
 166                        goto out1;
 167
 168                ret = request_irq(sock->eject_irq, db1200_pcmcia_cdirq,
 169                                  IRQF_DISABLED, "pcmcia_eject", sock);
 170                if (ret) {
 171                        free_irq(sock->insert_irq, sock);
 172                        goto out1;
 173                }
 174
 175                /* enable the currently silent one */
 176                if (db1200_card_inserted(sock))
 177                        enable_irq(sock->eject_irq);
 178                else
 179                        enable_irq(sock->insert_irq);
 180        } else {
 181                /* all other (older) Db1x00 boards use a GPIO to show
 182                 * card detection status:  use both-edge triggers.
 183                 */
 184                irq_set_irq_type(sock->insert_irq, IRQ_TYPE_EDGE_BOTH);
 185                ret = request_irq(sock->insert_irq, db1000_pcmcia_cdirq,
 186                                  0, "pcmcia_carddetect", sock);
 187
 188                if (ret)
 189                        goto out1;
 190        }
 191
 192        return 0;       /* all done */
 193
 194out1:
 195        if (sock->stschg_irq != -1)
 196                free_irq(sock->stschg_irq, sock);
 197
 198        return ret;
 199}
 200
 201static void db1x_pcmcia_free_irqs(struct db1x_pcmcia_sock *sock)
 202{
 203        if (sock->stschg_irq != -1)
 204                free_irq(sock->stschg_irq, sock);
 205
 206        free_irq(sock->insert_irq, sock);
 207        if (sock->eject_irq != -1)
 208                free_irq(sock->eject_irq, sock);
 209}
 210
 211/*
 212 * configure a PCMCIA socket on the Db1x00 series of boards (and
 213 * compatibles).
 214 *
 215 * 2 external registers are involved:
 216 *   pcmcia_status (offset 0x04): bits [0:1/2:3]: read card voltage id
 217 *   pcmcia_control(offset 0x10):
 218 *      bits[0:1] set vcc for card
 219 *      bits[2:3] set vpp for card
 220 *      bit 4:  enable data buffers
 221 *      bit 7:  reset# for card
 222 *      add 8 for second socket.
 223 */
 224static int db1x_pcmcia_configure(struct pcmcia_socket *skt,
 225                                 struct socket_state_t *state)
 226{
 227        struct db1x_pcmcia_sock *sock = to_db1x_socket(skt);
 228        unsigned short cr_clr, cr_set;
 229        unsigned int changed;
 230        int v, p, ret;
 231
 232        /* card voltage setup */
 233        cr_clr = (0xf << (sock->nr * 8)); /* clear voltage settings */
 234        cr_set = 0;
 235        v = p = ret = 0;
 236
 237        switch (state->Vcc) {
 238        case 50:
 239                ++v;
 240        case 33:
 241                ++v;
 242        case 0:
 243                break;
 244        default:
 245                printk(KERN_INFO "pcmcia%d unsupported Vcc %d\n",
 246                        sock->nr, state->Vcc);
 247        }
 248
 249        switch (state->Vpp) {
 250        case 12:
 251                ++p;
 252        case 33:
 253        case 50:
 254                ++p;
 255        case 0:
 256                break;
 257        default:
 258                printk(KERN_INFO "pcmcia%d unsupported Vpp %d\n",
 259                        sock->nr, state->Vpp);
 260        }
 261
 262        /* sanity check: Vpp must be 0, 12, or Vcc */
 263        if (((state->Vcc == 33) && (state->Vpp == 50)) ||
 264            ((state->Vcc == 50) && (state->Vpp == 33))) {
 265                printk(KERN_INFO "pcmcia%d bad Vcc/Vpp combo (%d %d)\n",
 266                        sock->nr, state->Vcc, state->Vpp);
 267                v = p = 0;
 268                ret = -EINVAL;
 269        }
 270
 271        /* create new voltage code */
 272        cr_set |= ((v << 2) | p) << (sock->nr * 8);
 273
 274        changed = state->flags ^ sock->old_flags;
 275
 276        if (changed & SS_RESET) {
 277                if (state->flags & SS_RESET) {
 278                        set_stschg(sock, 0);
 279                        /* assert reset, disable io buffers */
 280                        cr_clr |= (1 << (7 + (sock->nr * 8)));
 281                        cr_clr |= (1 << (4 + (sock->nr * 8)));
 282                } else {
 283                        /* de-assert reset, enable io buffers */
 284                        cr_set |= 1 << (7 + (sock->nr * 8));
 285                        cr_set |= 1 << (4 + (sock->nr * 8));
 286                }
 287        }
 288
 289        /* update PCMCIA configuration */
 290        bcsr_mod(BCSR_PCMCIA, cr_clr, cr_set);
 291
 292        sock->old_flags = state->flags;
 293
 294        /* reset was taken away: give card time to initialize properly */
 295        if ((changed & SS_RESET) && !(state->flags & SS_RESET)) {
 296                msleep(500);
 297                set_stschg(sock, 1);
 298        }
 299
 300        return ret;
 301}
 302
 303/* VCC bits at [3:2]/[11:10] */
 304#define GET_VCC(cr, socknr)             \
 305        ((((cr) >> 2) >> ((socknr) * 8)) & 3)
 306
 307/* VS bits at [0:1]/[3:2] */
 308#define GET_VS(sr, socknr)              \
 309        (((sr) >> (2 * (socknr))) & 3)
 310
 311/* reset bits at [7]/[15] */
 312#define GET_RESET(cr, socknr)           \
 313        ((cr) & (1 << (7 + (8 * (socknr)))))
 314
 315static int db1x_pcmcia_get_status(struct pcmcia_socket *skt,
 316                                  unsigned int *value)
 317{
 318        struct db1x_pcmcia_sock *sock = to_db1x_socket(skt);
 319        unsigned short cr, sr;
 320        unsigned int status;
 321
 322        status = db1x_card_inserted(sock) ? SS_DETECT : 0;
 323
 324        cr = bcsr_read(BCSR_PCMCIA);
 325        sr = bcsr_read(BCSR_STATUS);
 326
 327        /* PB1100/PB1500: voltage key bits are at [5:4] */
 328        if (sock->board_type == BOARD_TYPE_PB1100)
 329                sr >>= 4;
 330
 331        /* determine card type */
 332        switch (GET_VS(sr, sock->nr)) {
 333        case 0:
 334        case 2:
 335                status |= SS_3VCARD;    /* 3V card */
 336        case 3:
 337                break;                  /* 5V card: set nothing */
 338        default:
 339                status |= SS_XVCARD;    /* treated as unsupported in core */
 340        }
 341
 342        /* if Vcc is not zero, we have applied power to a card */
 343        status |= GET_VCC(cr, sock->nr) ? SS_POWERON : 0;
 344
 345        /* reset de-asserted? then we're ready */
 346        status |= (GET_RESET(cr, sock->nr)) ? SS_READY : SS_RESET;
 347
 348        *value = status;
 349
 350        return 0;
 351}
 352
 353static int db1x_pcmcia_sock_init(struct pcmcia_socket *skt)
 354{
 355        return 0;
 356}
 357
 358static int db1x_pcmcia_sock_suspend(struct pcmcia_socket *skt)
 359{
 360        return 0;
 361}
 362
 363static int au1x00_pcmcia_set_io_map(struct pcmcia_socket *skt,
 364                                    struct pccard_io_map *map)
 365{
 366        struct db1x_pcmcia_sock *sock = to_db1x_socket(skt);
 367
 368        map->start = (u32)sock->virt_io;
 369        map->stop = map->start + IO_MAP_SIZE;
 370
 371        return 0;
 372}
 373
 374static int au1x00_pcmcia_set_mem_map(struct pcmcia_socket *skt,
 375                                     struct pccard_mem_map *map)
 376{
 377        struct db1x_pcmcia_sock *sock = to_db1x_socket(skt);
 378
 379        if (map->flags & MAP_ATTRIB)
 380                map->static_start = sock->phys_attr + map->card_start;
 381        else
 382                map->static_start = sock->phys_mem + map->card_start;
 383
 384        return 0;
 385}
 386
 387static struct pccard_operations db1x_pcmcia_operations = {
 388        .init                   = db1x_pcmcia_sock_init,
 389        .suspend                = db1x_pcmcia_sock_suspend,
 390        .get_status             = db1x_pcmcia_get_status,
 391        .set_socket             = db1x_pcmcia_configure,
 392        .set_io_map             = au1x00_pcmcia_set_io_map,
 393        .set_mem_map            = au1x00_pcmcia_set_mem_map,
 394};
 395
 396static int __devinit db1x_pcmcia_socket_probe(struct platform_device *pdev)
 397{
 398        struct db1x_pcmcia_sock *sock;
 399        struct resource *r;
 400        int ret, bid;
 401
 402        sock = kzalloc(sizeof(struct db1x_pcmcia_sock), GFP_KERNEL);
 403        if (!sock)
 404                return -ENOMEM;
 405
 406        sock->nr = pdev->id;
 407
 408        bid = BCSR_WHOAMI_BOARD(bcsr_read(BCSR_WHOAMI));
 409        switch (bid) {
 410        case BCSR_WHOAMI_PB1500:
 411        case BCSR_WHOAMI_PB1500R2:
 412        case BCSR_WHOAMI_PB1100:
 413                sock->board_type = BOARD_TYPE_PB1100;
 414                break;
 415        case BCSR_WHOAMI_DB1000 ... BCSR_WHOAMI_PB1550_SDR:
 416                sock->board_type = BOARD_TYPE_DEFAULT;
 417                break;
 418        case BCSR_WHOAMI_PB1200 ... BCSR_WHOAMI_DB1200:
 419                sock->board_type = BOARD_TYPE_DB1200;
 420                break;
 421        default:
 422                printk(KERN_INFO "db1xxx-ss: unknown board %d!\n", bid);
 423                ret = -ENODEV;
 424                goto out0;
 425        };
 426
 427        /*
 428         * gather resources necessary and optional nice-to-haves to
 429         * operate a socket:
 430         * This includes IRQs for Carddetection/ejection, the card
 431         *  itself and optional status change detection.
 432         * Also, the memory areas covered by a socket.  For these
 433         *  we require the real 36bit addresses (see the au1000.h
 434         *  header for more information).
 435         */
 436
 437        /* card: irq assigned to the card itself. */
 438        r = platform_get_resource_byname(pdev, IORESOURCE_IRQ, "card");
 439        sock->card_irq = r ? r->start : 0;
 440
 441        /* insert: irq which triggers on card insertion/ejection */
 442        r = platform_get_resource_byname(pdev, IORESOURCE_IRQ, "insert");
 443        sock->insert_irq = r ? r->start : -1;
 444
 445        /* stschg: irq which trigger on card status change (optional) */
 446        r = platform_get_resource_byname(pdev, IORESOURCE_IRQ, "stschg");
 447        sock->stschg_irq = r ? r->start : -1;
 448
 449        /* eject: irq which triggers on ejection (DB1200/PB1200 only) */
 450        r = platform_get_resource_byname(pdev, IORESOURCE_IRQ, "eject");
 451        sock->eject_irq = r ? r->start : -1;
 452
 453        ret = -ENODEV;
 454
 455        /* 36bit PCMCIA Attribute area address */
 456        r = platform_get_resource_byname(pdev, IORESOURCE_MEM, "pcmcia-attr");
 457        if (!r) {
 458                printk(KERN_ERR "pcmcia%d has no 'pseudo-attr' resource!\n",
 459                        sock->nr);
 460                goto out0;
 461        }
 462        sock->phys_attr = r->start;
 463
 464        /* 36bit PCMCIA Memory area address */
 465        r = platform_get_resource_byname(pdev, IORESOURCE_MEM, "pcmcia-mem");
 466        if (!r) {
 467                printk(KERN_ERR "pcmcia%d has no 'pseudo-mem' resource!\n",
 468                        sock->nr);
 469                goto out0;
 470        }
 471        sock->phys_mem = r->start;
 472
 473        /* 36bit PCMCIA IO area address */
 474        r = platform_get_resource_byname(pdev, IORESOURCE_MEM, "pcmcia-io");
 475        if (!r) {
 476                printk(KERN_ERR "pcmcia%d has no 'pseudo-io' resource!\n",
 477                        sock->nr);
 478                goto out0;
 479        }
 480        sock->phys_io = r->start;
 481
 482        /*
 483         * PCMCIA client drivers use the inb/outb macros to access
 484         * the IO registers.  Since mips_io_port_base is added
 485         * to the access address of the mips implementation of
 486         * inb/outb, we need to subtract it here because we want
 487         * to access the I/O or MEM address directly, without
 488         * going through this "mips_io_port_base" mechanism.
 489         */
 490        sock->virt_io = (void *)(ioremap(sock->phys_io, IO_MAP_SIZE) -
 491                                 mips_io_port_base);
 492
 493        if (!sock->virt_io) {
 494                printk(KERN_ERR "pcmcia%d: cannot remap IO area\n",
 495                        sock->nr);
 496                ret = -ENOMEM;
 497                goto out0;
 498        }
 499
 500        sock->socket.ops        = &db1x_pcmcia_operations;
 501        sock->socket.owner      = THIS_MODULE;
 502        sock->socket.pci_irq    = sock->card_irq;
 503        sock->socket.features   = SS_CAP_STATIC_MAP | SS_CAP_PCCARD;
 504        sock->socket.map_size   = MEM_MAP_SIZE;
 505        sock->socket.io_offset  = (unsigned long)sock->virt_io;
 506        sock->socket.dev.parent = &pdev->dev;
 507        sock->socket.resource_ops = &pccard_static_ops;
 508
 509        platform_set_drvdata(pdev, sock);
 510
 511        ret = db1x_pcmcia_setup_irqs(sock);
 512        if (ret) {
 513                printk(KERN_ERR "pcmcia%d cannot setup interrupts\n",
 514                        sock->nr);
 515                goto out1;
 516        }
 517
 518        set_stschg(sock, 0);
 519
 520        ret = pcmcia_register_socket(&sock->socket);
 521        if (ret) {
 522                printk(KERN_ERR "pcmcia%d failed to register\n", sock->nr);
 523                goto out2;
 524        }
 525
 526        printk(KERN_INFO "Alchemy Db/Pb1xxx pcmcia%d @ io/attr/mem %09llx"
 527                "(%p) %09llx %09llx  card/insert/stschg/eject irqs @ %d "
 528                "%d %d %d\n", sock->nr, sock->phys_io, sock->virt_io,
 529                sock->phys_attr, sock->phys_mem, sock->card_irq,
 530                sock->insert_irq, sock->stschg_irq, sock->eject_irq);
 531
 532        return 0;
 533
 534out2:
 535        db1x_pcmcia_free_irqs(sock);
 536out1:
 537        iounmap((void *)(sock->virt_io + (u32)mips_io_port_base));
 538out0:
 539        kfree(sock);
 540        return ret;
 541}
 542
 543static int __devexit db1x_pcmcia_socket_remove(struct platform_device *pdev)
 544{
 545        struct db1x_pcmcia_sock *sock = platform_get_drvdata(pdev);
 546
 547        db1x_pcmcia_free_irqs(sock);
 548        pcmcia_unregister_socket(&sock->socket);
 549        iounmap((void *)(sock->virt_io + (u32)mips_io_port_base));
 550        kfree(sock);
 551
 552        return 0;
 553}
 554
 555static struct platform_driver db1x_pcmcia_socket_driver = {
 556        .driver = {
 557                .name   = "db1xxx_pcmcia",
 558                .owner  = THIS_MODULE,
 559        },
 560        .probe          = db1x_pcmcia_socket_probe,
 561        .remove         = __devexit_p(db1x_pcmcia_socket_remove),
 562};
 563
 564int __init db1x_pcmcia_socket_load(void)
 565{
 566        return platform_driver_register(&db1x_pcmcia_socket_driver);
 567}
 568
 569void  __exit db1x_pcmcia_socket_unload(void)
 570{
 571        platform_driver_unregister(&db1x_pcmcia_socket_driver);
 572}
 573
 574module_init(db1x_pcmcia_socket_load);
 575module_exit(db1x_pcmcia_socket_unload);
 576
 577MODULE_LICENSE("GPL");
 578MODULE_DESCRIPTION("PCMCIA Socket Services for Alchemy Db/Pb1x00 boards");
 579MODULE_AUTHOR("Manuel Lauss");
 580