linux/drivers/pcmcia/au1000_db1x00.c
<<
>>
Prefs
   1/*
   2 *
   3 * Alchemy Semi Db1x00 boards specific pcmcia routines.
   4 *
   5 * Copyright 2002 MontaVista Software Inc.
   6 * Author: MontaVista Software, Inc.
   7 *              ppopov@mvista.com or source@mvista.com
   8 *
   9 * Copyright 2004 Pete Popov, updated the driver to 2.6.
  10 * Followed the sa11xx API and largely copied many of the hardware
  11 * independent functions.
  12 *
  13 * ########################################################################
  14 *
  15 *  This program is free software; you can distribute it and/or modify it
  16 *  under the terms of the GNU General Public License (Version 2) as
  17 *  published by the Free Software Foundation.
  18 *
  19 *  This program is distributed in the hope it will be useful, but WITHOUT
  20 *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  21 *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  22 *  for more details.
  23 *
  24 *  You should have received a copy of the GNU General Public License along
  25 *  with this program; if not, write to the Free Software Foundation, Inc.,
  26 *  59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
  27 *
  28 * ########################################################################
  29 *
  30 *
  31 */
  32
  33#include <linux/module.h>
  34#include <linux/kernel.h>
  35#include <linux/errno.h>
  36#include <linux/interrupt.h>
  37#include <linux/device.h>
  38#include <linux/init.h>
  39
  40#include <asm/irq.h>
  41#include <asm/signal.h>
  42#include <asm/mach-au1x00/au1000.h>
  43
  44#if defined(CONFIG_MIPS_DB1200)
  45        #include <db1200.h>
  46#elif defined(CONFIG_MIPS_PB1200)
  47        #include <pb1200.h>
  48#else
  49        #include <asm/mach-db1x00/db1x00.h>
  50        static BCSR * const bcsr = (BCSR *)BCSR_KSEG1_ADDR;
  51#endif
  52
  53#include "au1000_generic.h"
  54
  55#if 0
  56#define debug(x,args...) printk(KERN_DEBUG "%s: " x, __func__ , ##args)
  57#else
  58#define debug(x,args...)
  59#endif
  60
  61
  62struct au1000_pcmcia_socket au1000_pcmcia_socket[PCMCIA_NUM_SOCKS];
  63extern int au1x00_pcmcia_socket_probe(struct device *, struct pcmcia_low_level *, int, int);
  64
  65static int db1x00_pcmcia_hw_init(struct au1000_pcmcia_socket *skt)
  66{
  67#ifdef CONFIG_MIPS_DB1550
  68        skt->irq = skt->nr ? AU1000_GPIO_5 : AU1000_GPIO_3;
  69#elif defined(CONFIG_MIPS_DB1200) || defined(CONFIG_MIPS_PB1200)
  70        skt->irq = skt->nr ? BOARD_PC1_INT : BOARD_PC0_INT;
  71#else
  72        skt->irq = skt->nr ? AU1000_GPIO_5 : AU1000_GPIO_2;
  73#endif
  74        return 0;
  75}
  76
  77static void db1x00_pcmcia_shutdown(struct au1000_pcmcia_socket *skt)
  78{
  79        bcsr->pcmcia = 0; /* turn off power */
  80        au_sync_delay(2);
  81}
  82
  83static void
  84db1x00_pcmcia_socket_state(struct au1000_pcmcia_socket *skt, struct pcmcia_state *state)
  85{
  86        u32 inserted;
  87        unsigned char vs;
  88
  89        state->ready = 0;
  90        state->vs_Xv = 0;
  91        state->vs_3v = 0;
  92        state->detect = 0;
  93
  94        switch (skt->nr) {
  95        case 0:
  96                vs = bcsr->status & 0x3;
  97#if defined(CONFIG_MIPS_DB1200) || defined(CONFIG_MIPS_PB1200)
  98                inserted = BOARD_CARD_INSERTED(0);
  99#else
 100                inserted = !(bcsr->status & (1<<4));
 101#endif
 102                break;
 103        case 1:
 104                vs = (bcsr->status & 0xC)>>2;
 105#if defined(CONFIG_MIPS_DB1200) || defined(CONFIG_MIPS_PB1200)
 106                inserted = BOARD_CARD_INSERTED(1);
 107#else
 108                inserted = !(bcsr->status & (1<<5));
 109#endif
 110                break;
 111        default:/* should never happen */
 112                return;
 113        }
 114
 115        if (inserted)
 116                debug("db1x00 socket %d: inserted %d, vs %d pcmcia %x\n",
 117                                skt->nr, inserted, vs, bcsr->pcmcia);
 118
 119        if (inserted) {
 120                switch (vs) {
 121                        case 0:
 122                        case 2:
 123                                state->vs_3v=1;
 124                                break;
 125                        case 3: /* 5V */
 126                                break;
 127                        default:
 128                                /* return without setting 'detect' */
 129                                printk(KERN_ERR "db1x00 bad VS (%d)\n",
 130                                                vs);
 131                }
 132                state->detect = 1;
 133                state->ready = 1;
 134        }
 135        else {
 136                /* if the card was previously inserted and then ejected,
 137                 * we should turn off power to it
 138                 */
 139                if ((skt->nr == 0) && (bcsr->pcmcia & BCSR_PCMCIA_PC0RST)) {
 140                        bcsr->pcmcia &= ~(BCSR_PCMCIA_PC0RST |
 141                                        BCSR_PCMCIA_PC0DRVEN |
 142                                        BCSR_PCMCIA_PC0VPP |
 143                                        BCSR_PCMCIA_PC0VCC);
 144                        au_sync_delay(10);
 145                }
 146                else if ((skt->nr == 1) && bcsr->pcmcia & BCSR_PCMCIA_PC1RST) {
 147                        bcsr->pcmcia &= ~(BCSR_PCMCIA_PC1RST |
 148                                        BCSR_PCMCIA_PC1DRVEN |
 149                                        BCSR_PCMCIA_PC1VPP |
 150                                        BCSR_PCMCIA_PC1VCC);
 151                        au_sync_delay(10);
 152                }
 153        }
 154
 155        state->bvd1=1;
 156        state->bvd2=1;
 157        state->wrprot=0;
 158}
 159
 160static int
 161db1x00_pcmcia_configure_socket(struct au1000_pcmcia_socket *skt, struct socket_state_t *state)
 162{
 163        u16 pwr;
 164        int sock = skt->nr;
 165
 166        debug("config_skt %d Vcc %dV Vpp %dV, reset %d\n",
 167                        sock, state->Vcc, state->Vpp,
 168                        state->flags & SS_RESET);
 169
 170        /* pcmcia reg was set to zero at init time. Be careful when
 171         * initializing a socket not to wipe out the settings of the
 172         * other socket.
 173         */
 174        pwr = bcsr->pcmcia;
 175        pwr &= ~(0xf << sock*8); /* clear voltage settings */
 176
 177        state->Vpp = 0;
 178        switch(state->Vcc){
 179                case 0:  /* Vcc 0 */
 180                        pwr |= SET_VCC_VPP(0,0,sock);
 181                        break;
 182                case 50: /* Vcc 5V */
 183                        switch(state->Vpp) {
 184                                case 0:
 185                                        pwr |= SET_VCC_VPP(2,0,sock);
 186                                        break;
 187                                case 50:
 188                                        pwr |= SET_VCC_VPP(2,1,sock);
 189                                        break;
 190                                case 12:
 191                                        pwr |= SET_VCC_VPP(2,2,sock);
 192                                        break;
 193                                case 33:
 194                                default:
 195                                        pwr |= SET_VCC_VPP(0,0,sock);
 196                                        printk("%s: bad Vcc/Vpp (%d:%d)\n",
 197                                                        __func__,
 198                                                        state->Vcc,
 199                                                        state->Vpp);
 200                                        break;
 201                        }
 202                        break;
 203                case 33: /* Vcc 3.3V */
 204                        switch(state->Vpp) {
 205                                case 0:
 206                                        pwr |= SET_VCC_VPP(1,0,sock);
 207                                        break;
 208                                case 12:
 209                                        pwr |= SET_VCC_VPP(1,2,sock);
 210                                        break;
 211                                case 33:
 212                                        pwr |= SET_VCC_VPP(1,1,sock);
 213                                        break;
 214                                case 50:
 215                                default:
 216                                        pwr |= SET_VCC_VPP(0,0,sock);
 217                                        printk("%s: bad Vcc/Vpp (%d:%d)\n",
 218                                                        __func__,
 219                                                        state->Vcc,
 220                                                        state->Vpp);
 221                                        break;
 222                        }
 223                        break;
 224                default: /* what's this ? */
 225                        pwr |= SET_VCC_VPP(0,0,sock);
 226                        printk(KERN_ERR "%s: bad Vcc %d\n",
 227                                        __func__, state->Vcc);
 228                        break;
 229        }
 230
 231        bcsr->pcmcia = pwr;
 232        au_sync_delay(300);
 233
 234        if (sock == 0) {
 235                if (!(state->flags & SS_RESET)) {
 236                        pwr |= BCSR_PCMCIA_PC0DRVEN;
 237                        bcsr->pcmcia = pwr;
 238                        au_sync_delay(300);
 239                        pwr |= BCSR_PCMCIA_PC0RST;
 240                        bcsr->pcmcia = pwr;
 241                        au_sync_delay(100);
 242                }
 243                else {
 244                        pwr &= ~(BCSR_PCMCIA_PC0RST | BCSR_PCMCIA_PC0DRVEN);
 245                        bcsr->pcmcia = pwr;
 246                        au_sync_delay(100);
 247                }
 248        }
 249        else {
 250                if (!(state->flags & SS_RESET)) {
 251                        pwr |= BCSR_PCMCIA_PC1DRVEN;
 252                        bcsr->pcmcia = pwr;
 253                        au_sync_delay(300);
 254                        pwr |= BCSR_PCMCIA_PC1RST;
 255                        bcsr->pcmcia = pwr;
 256                        au_sync_delay(100);
 257                }
 258                else {
 259                        pwr &= ~(BCSR_PCMCIA_PC1RST | BCSR_PCMCIA_PC1DRVEN);
 260                        bcsr->pcmcia = pwr;
 261                        au_sync_delay(100);
 262                }
 263        }
 264        return 0;
 265}
 266
 267/*
 268 * Enable card status IRQs on (re-)initialisation.  This can
 269 * be called at initialisation, power management event, or
 270 * pcmcia event.
 271 */
 272void db1x00_socket_init(struct au1000_pcmcia_socket *skt)
 273{
 274        /* nothing to do for now */
 275}
 276
 277/*
 278 * Disable card status IRQs and PCMCIA bus on suspend.
 279 */
 280void db1x00_socket_suspend(struct au1000_pcmcia_socket *skt)
 281{
 282        /* nothing to do for now */
 283}
 284
 285struct pcmcia_low_level db1x00_pcmcia_ops = {
 286        .owner                  = THIS_MODULE,
 287
 288        .hw_init                = db1x00_pcmcia_hw_init,
 289        .hw_shutdown            = db1x00_pcmcia_shutdown,
 290
 291        .socket_state           = db1x00_pcmcia_socket_state,
 292        .configure_socket       = db1x00_pcmcia_configure_socket,
 293
 294        .socket_init            = db1x00_socket_init,
 295        .socket_suspend         = db1x00_socket_suspend
 296};
 297
 298int au1x_board_init(struct device *dev)
 299{
 300        int ret = -ENODEV;
 301        bcsr->pcmcia = 0; /* turn off power, if it's not already off */
 302        au_sync_delay(2);
 303        ret = au1x00_pcmcia_socket_probe(dev, &db1x00_pcmcia_ops, 0, 2);
 304        return ret;
 305}
 306