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