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