linux/drivers/pcmcia/sa1100_simpad.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0
   2/*
   3 * drivers/pcmcia/sa1100_simpad.c
   4 *
   5 * PCMCIA implementation routines for simpad
   6 *
   7 */
   8#include <linux/module.h>
   9#include <linux/kernel.h>
  10#include <linux/device.h>
  11#include <linux/init.h>
  12
  13#include <mach/hardware.h>
  14#include <asm/mach-types.h>
  15#include <asm/irq.h>
  16#include <mach/simpad.h>
  17#include "sa1100_generic.h"
  18 
  19static int simpad_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
  20{
  21
  22        simpad_clear_cs3_bit(VCC_3V_EN|VCC_5V_EN|EN0|EN1);
  23
  24        skt->stat[SOC_STAT_CD].gpio = GPIO_CF_CD;
  25        skt->stat[SOC_STAT_CD].name = "CF_CD";
  26        skt->stat[SOC_STAT_RDY].gpio = GPIO_CF_IRQ;
  27        skt->stat[SOC_STAT_RDY].name = "CF_RDY";
  28
  29        return 0;
  30}
  31
  32static void simpad_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt)
  33{
  34        /* Disable CF bus: */
  35        /*simpad_set_cs3_bit(PCMCIA_BUFF_DIS);*/
  36        simpad_clear_cs3_bit(PCMCIA_RESET);
  37}
  38
  39static void
  40simpad_pcmcia_socket_state(struct soc_pcmcia_socket *skt,
  41                           struct pcmcia_state *state)
  42{
  43        long cs3reg = simpad_get_cs3_ro();
  44
  45        /* the detect signal is inverted - fix that up here */
  46        state->detect = !state->detect;
  47
  48        state->bvd1 = 1; /* Might be cs3reg & PCMCIA_BVD1 */
  49        state->bvd2 = 1; /* Might be cs3reg & PCMCIA_BVD2 */
  50
  51        if ((cs3reg & (PCMCIA_VS1|PCMCIA_VS2)) ==
  52                        (PCMCIA_VS1|PCMCIA_VS2)) {
  53                state->vs_3v=0;
  54                state->vs_Xv=0;
  55        } else {
  56                state->vs_3v=1;
  57                state->vs_Xv=0;
  58        }
  59}
  60
  61static int
  62simpad_pcmcia_configure_socket(struct soc_pcmcia_socket *skt,
  63                               const socket_state_t *state)
  64{
  65        unsigned long flags;
  66
  67        local_irq_save(flags);
  68
  69        /* Murphy: see table of MIC2562a-1 */
  70        switch (state->Vcc) {
  71        case 0:
  72                simpad_clear_cs3_bit(VCC_3V_EN|VCC_5V_EN|EN0|EN1);
  73                break;
  74
  75        case 33:  
  76                simpad_clear_cs3_bit(VCC_3V_EN|EN1);
  77                simpad_set_cs3_bit(VCC_5V_EN|EN0);
  78                break;
  79
  80        case 50:
  81                simpad_clear_cs3_bit(VCC_5V_EN|EN1);
  82                simpad_set_cs3_bit(VCC_3V_EN|EN0);
  83                break;
  84
  85        default:
  86                printk(KERN_ERR "%s(): unrecognized Vcc %u\n",
  87                        __func__, state->Vcc);
  88                simpad_clear_cs3_bit(VCC_3V_EN|VCC_5V_EN|EN0|EN1);
  89                local_irq_restore(flags);
  90                return -1;
  91        }
  92
  93
  94        local_irq_restore(flags);
  95
  96        return 0;
  97}
  98
  99static void simpad_pcmcia_socket_suspend(struct soc_pcmcia_socket *skt)
 100{
 101        simpad_set_cs3_bit(PCMCIA_RESET);
 102}
 103
 104static struct pcmcia_low_level simpad_pcmcia_ops = { 
 105        .owner                  = THIS_MODULE,
 106        .hw_init                = simpad_pcmcia_hw_init,
 107        .hw_shutdown            = simpad_pcmcia_hw_shutdown,
 108        .socket_state           = simpad_pcmcia_socket_state,
 109        .configure_socket       = simpad_pcmcia_configure_socket,
 110        .socket_suspend         = simpad_pcmcia_socket_suspend,
 111};
 112
 113int pcmcia_simpad_init(struct device *dev)
 114{
 115        int ret = -ENODEV;
 116
 117        if (machine_is_simpad())
 118                ret = sa11xx_drv_pcmcia_probe(dev, &simpad_pcmcia_ops, 1, 1);
 119
 120        return ret;
 121}
 122