linux/drivers/pcmcia/au1000_pb1x00.c
<<
>>
Prefs
   1/*
   2 *
   3 * Alchemy Semi Pb1x00 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 * ########################################################################
  10 *
  11 *  This program is free software; you can distribute it and/or modify it
  12 *  under the terms of the GNU General Public License (Version 2) as
  13 *  published by the Free Software Foundation.
  14 *
  15 *  This program is distributed in the hope it will be useful, but WITHOUT
  16 *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  17 *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  18 *  for more details.
  19 *
  20 *  You should have received a copy of the GNU General Public License along
  21 *  with this program; if not, write to the Free Software Foundation, Inc.,
  22 *  59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
  23 */
  24#include <linux/module.h>
  25#include <linux/init.h>
  26#include <linux/delay.h>
  27#include <linux/ioport.h>
  28#include <linux/kernel.h>
  29#include <linux/tqueue.h>
  30#include <linux/timer.h>
  31#include <linux/mm.h>
  32#include <linux/proc_fs.h>
  33#include <linux/types.h>
  34
  35#include <pcmcia/cs_types.h>
  36#include <pcmcia/cs.h>
  37#include <pcmcia/ss.h>
  38#include <pcmcia/cistpl.h>
  39#include <pcmcia/bus_ops.h>
  40
  41#include <asm/io.h>
  42#include <asm/irq.h>
  43#include <asm/system.h>
  44
  45#include <asm/au1000.h>
  46#include <asm/au1000_pcmcia.h>
  47
  48#define debug(fmt, arg...) do { } while (0)
  49
  50#ifdef CONFIG_MIPS_PB1000
  51#include <asm/pb1000.h>
  52#define PCMCIA_IRQ AU1000_GPIO_15
  53#elif defined (CONFIG_MIPS_PB1500)
  54#include <asm/pb1500.h>
  55#define PCMCIA_IRQ AU1500_GPIO_203
  56#elif defined (CONFIG_MIPS_PB1100)
  57#include <asm/pb1100.h>
  58#define PCMCIA_IRQ AU1000_GPIO_11
  59#endif
  60
  61static int pb1x00_pcmcia_init(struct pcmcia_init *init)
  62{
  63#ifdef CONFIG_MIPS_PB1000
  64        u16 pcr;
  65        pcr = PCR_SLOT_0_RST | PCR_SLOT_1_RST;
  66
  67        au_writel(0x8000, PB1000_MDR); /* clear pcmcia interrupt */
  68        au_sync_delay(100);
  69        au_writel(0x4000, PB1000_MDR); /* enable pcmcia interrupt */
  70        au_sync();
  71
  72        pcr |= SET_VCC_VPP(VCC_HIZ,VPP_HIZ,0);
  73        pcr |= SET_VCC_VPP(VCC_HIZ,VPP_HIZ,1);
  74        au_writel(pcr, PB1000_PCR);
  75        au_sync_delay(20);
  76          
  77        return PCMCIA_NUM_SOCKS;
  78
  79#else /* fixme -- take care of the Pb1500 at some point */
  80
  81        u16 pcr;
  82        pcr = au_readw(PCMCIA_BOARD_REG) & ~0xf; /* turn off power */
  83        pcr &= ~(PC_DEASSERT_RST | PC_DRV_EN);
  84        au_writew(pcr, PCMCIA_BOARD_REG);
  85        au_sync_delay(500);
  86        return PCMCIA_NUM_SOCKS;
  87#endif
  88}
  89
  90static int pb1x00_pcmcia_shutdown(void)
  91{
  92#ifdef CONFIG_MIPS_PB1000
  93        u16 pcr;
  94        pcr = PCR_SLOT_0_RST | PCR_SLOT_1_RST;
  95        pcr |= SET_VCC_VPP(VCC_HIZ,VPP_HIZ,0);
  96        pcr |= SET_VCC_VPP(VCC_HIZ,VPP_HIZ,1);
  97        au_writel(pcr, PB1000_PCR);
  98        au_sync_delay(20);
  99        return 0;
 100#else
 101        u16 pcr;
 102        pcr = au_readw(PCMCIA_BOARD_REG) & ~0xf; /* turn off power */
 103        pcr &= ~(PC_DEASSERT_RST | PC_DRV_EN);
 104        au_writew(pcr, PCMCIA_BOARD_REG);
 105        au_sync_delay(2);
 106        return 0;
 107#endif
 108}
 109
 110static int 
 111pb1x00_pcmcia_socket_state(unsigned sock, struct pcmcia_state *state)
 112{
 113        u32 inserted0, inserted1;
 114        u16 vs0, vs1;
 115
 116#ifdef CONFIG_MIPS_PB1000
 117        vs0 = vs1 = (u16)au_readl(PB1000_ACR1);
 118        inserted0 = !(vs0 & (ACR1_SLOT_0_CD1 | ACR1_SLOT_0_CD2));
 119        inserted1 = !(vs1 & (ACR1_SLOT_1_CD1 | ACR1_SLOT_1_CD2));
 120        vs0 = (vs0 >> 4) & 0x3;
 121        vs1 = (vs1 >> 12) & 0x3;
 122#else
 123        vs0 = (au_readw(BOARD_STATUS_REG) >> 4) & 0x3;
 124#ifdef CONFIG_MIPS_PB1500
 125        inserted0 = !((au_readl(GPIO2_PINSTATE) >> 1) & 0x1); /* gpio 201 */
 126#else /* Pb1100 */
 127        inserted0 = !((au_readl(SYS_PINSTATERD) >> 9) & 0x1); /* gpio 9 */
 128#endif
 129        inserted1 = 0;
 130#endif
 131
 132        state->ready = 0;
 133        state->vs_Xv = 0;
 134        state->vs_3v = 0;
 135        state->detect = 0;
 136
 137        if (sock == 0) {
 138                if (inserted0) {
 139                        switch (vs0) {
 140                                case 0:
 141                                case 2:
 142                                        state->vs_3v=1;
 143                                        break;
 144                                case 3: /* 5V */
 145                                        break;
 146                                default:
 147                                        /* return without setting 'detect' */
 148                                        printk(KERN_ERR "pb1x00 bad VS (%d)\n",
 149                                                        vs0);
 150                                        return 0;
 151                        }
 152                        state->detect = 1;
 153                }
 154        }
 155        else  {
 156                if (inserted1) {
 157                        switch (vs1) {
 158                                case 0:
 159                                case 2:
 160                                        state->vs_3v=1;
 161                                        break;
 162                                case 3: /* 5V */
 163                                        break;
 164                                default:
 165                                        /* return without setting 'detect' */
 166                                        printk(KERN_ERR "pb1x00 bad VS (%d)\n",
 167                                                        vs1);
 168                                        return 0;
 169                        }
 170                        state->detect = 1;
 171                }
 172        }
 173
 174        if (state->detect) {
 175                state->ready = 1;
 176        }
 177
 178        state->bvd1=1;
 179        state->bvd2=1;
 180        state->wrprot=0; 
 181        return 1;
 182}
 183
 184
 185static int pb1x00_pcmcia_get_irq_info(struct pcmcia_irq_info *info)
 186{
 187
 188        if(info->sock > PCMCIA_MAX_SOCK) return -1;
 189
 190        /*
 191         * Even in the case of the Pb1000, both sockets are connected
 192         * to the same irq line.
 193         */
 194        info->irq = PCMCIA_IRQ;
 195
 196        return 0;
 197}
 198
 199
 200static int 
 201pb1x00_pcmcia_configure_socket(const struct pcmcia_configure *configure)
 202{
 203        u16 pcr;
 204
 205        if(configure->sock > PCMCIA_MAX_SOCK) return -1;
 206
 207#ifdef CONFIG_MIPS_PB1000
 208        pcr = au_readl(PB1000_PCR);
 209
 210        if (configure->sock == 0) {
 211                pcr &= ~(PCR_SLOT_0_VCC0 | PCR_SLOT_0_VCC1 | 
 212                                PCR_SLOT_0_VPP0 | PCR_SLOT_0_VPP1);
 213        }
 214        else  {
 215                pcr &= ~(PCR_SLOT_1_VCC0 | PCR_SLOT_1_VCC1 | 
 216                                PCR_SLOT_1_VPP0 | PCR_SLOT_1_VPP1);
 217        }
 218
 219        pcr &= ~PCR_SLOT_0_RST;
 220        debug("Vcc %dV Vpp %dV, pcr %x\n", 
 221                        configure->vcc, configure->vpp, pcr);
 222        switch(configure->vcc){
 223                case 0:  /* Vcc 0 */
 224                        switch(configure->vpp) {
 225                                case 0:
 226                                        pcr |= SET_VCC_VPP(VCC_HIZ,VPP_GND,
 227                                                        configure->sock);
 228                                        break;
 229                                case 12:
 230                                        pcr |= SET_VCC_VPP(VCC_HIZ,VPP_12V,
 231                                                        configure->sock);
 232                                        break;
 233                                case 50:
 234                                        pcr |= SET_VCC_VPP(VCC_HIZ,VPP_5V,
 235                                                        configure->sock);
 236                                        break;
 237                                case 33:
 238                                        pcr |= SET_VCC_VPP(VCC_HIZ,VPP_3V,
 239                                                        configure->sock);
 240                                        break;
 241                                default:
 242                                        pcr |= SET_VCC_VPP(VCC_HIZ,VPP_HIZ,
 243                                                        configure->sock);
 244                                        printk("%s: bad Vcc/Vpp (%d:%d)\n", 
 245                                                        __func__,
 246                                                        configure->vcc, 
 247                                                        configure->vpp);
 248                                        break;
 249                        }
 250                        break;
 251                case 50: /* Vcc 5V */
 252                        switch(configure->vpp) {
 253                                case 0:
 254                                        pcr |= SET_VCC_VPP(VCC_5V,VPP_GND,
 255                                                        configure->sock);
 256                                        break;
 257                                case 50:
 258                                        pcr |= SET_VCC_VPP(VCC_5V,VPP_5V,
 259                                                        configure->sock);
 260                                        break;
 261                                case 12:
 262                                        pcr |= SET_VCC_VPP(VCC_5V,VPP_12V,
 263                                                        configure->sock);
 264                                        break;
 265                                case 33:
 266                                        pcr |= SET_VCC_VPP(VCC_5V,VPP_3V,
 267                                                        configure->sock);
 268                                        break;
 269                                default:
 270                                        pcr |= SET_VCC_VPP(VCC_HIZ,VPP_HIZ,
 271                                                        configure->sock);
 272                                        printk("%s: bad Vcc/Vpp (%d:%d)\n", 
 273                                                        __func__,
 274                                                        configure->vcc, 
 275                                                        configure->vpp);
 276                                        break;
 277                        }
 278                        break;
 279                case 33: /* Vcc 3.3V */
 280                        switch(configure->vpp) {
 281                                case 0:
 282                                        pcr |= SET_VCC_VPP(VCC_3V,VPP_GND,
 283                                                        configure->sock);
 284                                        break;
 285                                case 50:
 286                                        pcr |= SET_VCC_VPP(VCC_3V,VPP_5V,
 287                                                        configure->sock);
 288                                        break;
 289                                case 12:
 290                                        pcr |= SET_VCC_VPP(VCC_3V,VPP_12V,
 291                                                        configure->sock);
 292                                        break;
 293                                case 33:
 294                                        pcr |= SET_VCC_VPP(VCC_3V,VPP_3V,
 295                                                        configure->sock);
 296                                        break;
 297                                default:
 298                                        pcr |= SET_VCC_VPP(VCC_HIZ,VPP_HIZ,
 299                                                        configure->sock);
 300                                        printk("%s: bad Vcc/Vpp (%d:%d)\n", 
 301                                                        __func__,
 302                                                        configure->vcc, 
 303                                                        configure->vpp);
 304                                        break;
 305                        }
 306                        break;
 307                default: /* what's this ? */
 308                        pcr |= SET_VCC_VPP(VCC_HIZ,VPP_HIZ,configure->sock);
 309                        printk(KERN_ERR "%s: bad Vcc %d\n", 
 310                                        __func__, configure->vcc);
 311                        break;
 312        }
 313
 314        if (configure->sock == 0) {
 315        pcr &= ~(PCR_SLOT_0_RST);
 316                if (configure->reset)
 317                pcr |= PCR_SLOT_0_RST;
 318        }
 319        else {
 320                pcr &= ~(PCR_SLOT_1_RST);
 321                if (configure->reset)
 322                        pcr |= PCR_SLOT_1_RST;
 323        }
 324        au_writel(pcr, PB1000_PCR);
 325        au_sync_delay(300);
 326
 327#else
 328
 329        pcr = au_readw(PCMCIA_BOARD_REG) & ~0xf;
 330
 331        debug("Vcc %dV Vpp %dV, pcr %x, reset %d\n", 
 332                        configure->vcc, configure->vpp, pcr, configure->reset);
 333
 334
 335        switch(configure->vcc){
 336                case 0:  /* Vcc 0 */
 337                        pcr |= SET_VCC_VPP(0,0);
 338                        break;
 339                case 50: /* Vcc 5V */
 340                        switch(configure->vpp) {
 341                                case 0:
 342                                        pcr |= SET_VCC_VPP(2,0);
 343                                        break;
 344                                case 50:
 345                                        pcr |= SET_VCC_VPP(2,1);
 346                                        break;
 347                                case 12:
 348                                        pcr |= SET_VCC_VPP(2,2);
 349                                        break;
 350                                case 33:
 351                                default:
 352                                        pcr |= SET_VCC_VPP(0,0);
 353                                        printk("%s: bad Vcc/Vpp (%d:%d)\n", 
 354                                                        __func__,
 355                                                        configure->vcc, 
 356                                                        configure->vpp);
 357                                        break;
 358                        }
 359                        break;
 360                case 33: /* Vcc 3.3V */
 361                        switch(configure->vpp) {
 362                                case 0:
 363                                        pcr |= SET_VCC_VPP(1,0);
 364                                        break;
 365                                case 12:
 366                                        pcr |= SET_VCC_VPP(1,2);
 367                                        break;
 368                                case 33:
 369                                        pcr |= SET_VCC_VPP(1,1);
 370                                        break;
 371                                case 50:
 372                                default:
 373                                        pcr |= SET_VCC_VPP(0,0);
 374                                        printk("%s: bad Vcc/Vpp (%d:%d)\n", 
 375                                                        __func__,
 376                                                        configure->vcc, 
 377                                                        configure->vpp);
 378                                        break;
 379                        }
 380                        break;
 381                default: /* what's this ? */
 382                        pcr |= SET_VCC_VPP(0,0);
 383                        printk(KERN_ERR "%s: bad Vcc %d\n", 
 384                                        __func__, configure->vcc);
 385                        break;
 386        }
 387
 388        au_writew(pcr, PCMCIA_BOARD_REG);
 389        au_sync_delay(300);
 390
 391        if (!configure->reset) {
 392                pcr |= PC_DRV_EN;
 393                au_writew(pcr, PCMCIA_BOARD_REG);
 394                au_sync_delay(100);
 395                pcr |= PC_DEASSERT_RST;
 396                au_writew(pcr, PCMCIA_BOARD_REG);
 397                au_sync_delay(100);
 398        }
 399        else {
 400                pcr &= ~(PC_DEASSERT_RST | PC_DRV_EN);
 401                au_writew(pcr, PCMCIA_BOARD_REG);
 402                au_sync_delay(100);
 403        }
 404#endif
 405        return 0;
 406}
 407
 408
 409struct pcmcia_low_level pb1x00_pcmcia_ops = { 
 410        pb1x00_pcmcia_init,
 411        pb1x00_pcmcia_shutdown,
 412        pb1x00_pcmcia_socket_state,
 413        pb1x00_pcmcia_get_irq_info,
 414        pb1x00_pcmcia_configure_socket
 415};
 416