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 <mach/simpad.h>
  16#include "sa1100_generic.h"
  17
  18static int simpad_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
  19{
  20
  21        simpad_clear_cs3_bit(VCC_3V_EN|VCC_5V_EN|EN0|EN1);
  22
  23        skt->stat[SOC_STAT_CD].name = "cf-detect";
  24        skt->stat[SOC_STAT_RDY].name = "cf-ready";
  25
  26        return soc_pcmcia_request_gpiods(skt);
  27}
  28
  29static void simpad_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt)
  30{
  31        /* Disable CF bus: */
  32        /*simpad_set_cs3_bit(PCMCIA_BUFF_DIS);*/
  33        simpad_clear_cs3_bit(PCMCIA_RESET);
  34}
  35
  36static void
  37simpad_pcmcia_socket_state(struct soc_pcmcia_socket *skt,
  38                           struct pcmcia_state *state)
  39{
  40        long cs3reg = simpad_get_cs3_ro();
  41
  42        /* bvd1 might be cs3reg & PCMCIA_BVD1 */
  43        /* bvd2 might be cs3reg & PCMCIA_BVD2 */
  44
  45        if ((cs3reg & (PCMCIA_VS1|PCMCIA_VS2)) ==
  46                        (PCMCIA_VS1|PCMCIA_VS2)) {
  47                state->vs_3v=0;
  48                state->vs_Xv=0;
  49        } else {
  50                state->vs_3v=1;
  51                state->vs_Xv=0;
  52        }
  53}
  54
  55static int
  56simpad_pcmcia_configure_socket(struct soc_pcmcia_socket *skt,
  57                               const socket_state_t *state)
  58{
  59        unsigned long flags;
  60
  61        local_irq_save(flags);
  62
  63        /* Murphy: see table of MIC2562a-1 */
  64        switch (state->Vcc) {
  65        case 0:
  66                simpad_clear_cs3_bit(VCC_3V_EN|VCC_5V_EN|EN0|EN1);
  67                break;
  68
  69        case 33:
  70                simpad_clear_cs3_bit(VCC_3V_EN|EN1);
  71                simpad_set_cs3_bit(VCC_5V_EN|EN0);
  72                break;
  73
  74        case 50:
  75                simpad_clear_cs3_bit(VCC_5V_EN|EN1);
  76                simpad_set_cs3_bit(VCC_3V_EN|EN0);
  77                break;
  78
  79        default:
  80                printk(KERN_ERR "%s(): unrecognized Vcc %u\n",
  81                        __func__, state->Vcc);
  82                simpad_clear_cs3_bit(VCC_3V_EN|VCC_5V_EN|EN0|EN1);
  83                local_irq_restore(flags);
  84                return -1;
  85        }
  86
  87
  88        local_irq_restore(flags);
  89
  90        return 0;
  91}
  92
  93static void simpad_pcmcia_socket_suspend(struct soc_pcmcia_socket *skt)
  94{
  95        simpad_set_cs3_bit(PCMCIA_RESET);
  96}
  97
  98static struct pcmcia_low_level simpad_pcmcia_ops = {
  99        .owner                  = THIS_MODULE,
 100        .hw_init                = simpad_pcmcia_hw_init,
 101        .hw_shutdown            = simpad_pcmcia_hw_shutdown,
 102        .socket_state           = simpad_pcmcia_socket_state,
 103        .configure_socket       = simpad_pcmcia_configure_socket,
 104        .socket_suspend         = simpad_pcmcia_socket_suspend,
 105};
 106
 107int pcmcia_simpad_init(struct device *dev)
 108{
 109        int ret = -ENODEV;
 110
 111        if (machine_is_simpad())
 112                ret = sa11xx_drv_pcmcia_probe(dev, &simpad_pcmcia_ops, 1, 1);
 113
 114        return ret;
 115}
 116