linux/drivers/pcmcia/sa1100_simpad.c
<<
>>
Prefs
   1/*
   2 * drivers/pcmcia/sa1100_simpad.c
   3 *
   4 * PCMCIA implementation routines for simpad
   5 *
   6 */
   7#include <linux/module.h>
   8#include <linux/kernel.h>
   9#include <linux/device.h>
  10#include <linux/init.h>
  11
  12#include <mach/hardware.h>
  13#include <asm/mach-types.h>
  14#include <asm/irq.h>
  15#include <mach/simpad.h>
  16#include "sa1100_generic.h"
  17 
  18extern long get_cs3_shadow(void);
  19extern void set_cs3_bit(int value); 
  20extern void clear_cs3_bit(int value);
  21
  22static struct pcmcia_irqs irqs[] = {
  23        { 1, IRQ_GPIO_CF_CD, "CF_CD" },
  24};
  25
  26static int simpad_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
  27{
  28
  29        clear_cs3_bit(VCC_3V_EN|VCC_5V_EN|EN0|EN1);
  30
  31        skt->irq = IRQ_GPIO_CF_IRQ;
  32
  33        return soc_pcmcia_request_irqs(skt, irqs, ARRAY_SIZE(irqs));
  34}
  35
  36static void simpad_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt)
  37{
  38        soc_pcmcia_free_irqs(skt, irqs, ARRAY_SIZE(irqs));
  39
  40        /* Disable CF bus: */
  41        //set_cs3_bit(PCMCIA_BUFF_DIS);
  42        clear_cs3_bit(PCMCIA_RESET);       
  43}
  44
  45static void
  46simpad_pcmcia_socket_state(struct soc_pcmcia_socket *skt,
  47                           struct pcmcia_state *state)
  48{
  49        unsigned long levels = GPLR;
  50        long cs3reg = get_cs3_shadow();
  51
  52        state->detect=((levels & GPIO_CF_CD)==0)?1:0;
  53        state->ready=(levels & GPIO_CF_IRQ)?1:0;
  54        state->bvd1=1; /* Not available on Simpad. */
  55        state->bvd2=1; /* Not available on Simpad. */
  56        state->wrprot=0; /* Not available on Simpad. */
  57  
  58        if((cs3reg & 0x0c) == 0x0c) {
  59                state->vs_3v=0;
  60                state->vs_Xv=0;
  61        } else {
  62                state->vs_3v=1;
  63                state->vs_Xv=0;
  64        }
  65}
  66
  67static int
  68simpad_pcmcia_configure_socket(struct soc_pcmcia_socket *skt,
  69                               const socket_state_t *state)
  70{
  71        unsigned long flags;
  72
  73        local_irq_save(flags);
  74
  75        /* Murphy: see table of MIC2562a-1 */
  76        switch (state->Vcc) {
  77        case 0:
  78                clear_cs3_bit(VCC_3V_EN|VCC_5V_EN|EN0|EN1);
  79                break;
  80
  81        case 33:  
  82                clear_cs3_bit(VCC_3V_EN|EN1);
  83                set_cs3_bit(VCC_5V_EN|EN0);
  84                break;
  85
  86        case 50:
  87                clear_cs3_bit(VCC_5V_EN|EN1);
  88                set_cs3_bit(VCC_3V_EN|EN0);
  89                break;
  90
  91        default:
  92                printk(KERN_ERR "%s(): unrecognized Vcc %u\n",
  93                        __func__, state->Vcc);
  94                clear_cs3_bit(VCC_3V_EN|VCC_5V_EN|EN0|EN1);
  95                local_irq_restore(flags);
  96                return -1;
  97        }
  98
  99
 100        local_irq_restore(flags);
 101
 102        return 0;
 103}
 104
 105static void simpad_pcmcia_socket_init(struct soc_pcmcia_socket *skt)
 106{
 107        soc_pcmcia_enable_irqs(skt, irqs, ARRAY_SIZE(irqs));
 108}
 109
 110static void simpad_pcmcia_socket_suspend(struct soc_pcmcia_socket *skt)
 111{
 112        soc_pcmcia_disable_irqs(skt, irqs, ARRAY_SIZE(irqs));
 113        set_cs3_bit(PCMCIA_RESET);
 114}
 115
 116static struct pcmcia_low_level simpad_pcmcia_ops = { 
 117        .owner                  = THIS_MODULE,
 118        .hw_init                = simpad_pcmcia_hw_init,
 119        .hw_shutdown            = simpad_pcmcia_hw_shutdown,
 120        .socket_state           = simpad_pcmcia_socket_state,
 121        .configure_socket       = simpad_pcmcia_configure_socket,
 122        .socket_init            = simpad_pcmcia_socket_init,
 123        .socket_suspend         = simpad_pcmcia_socket_suspend,
 124};
 125
 126int __init pcmcia_simpad_init(struct device *dev)
 127{
 128        int ret = -ENODEV;
 129
 130        if (machine_is_simpad())
 131                ret = sa11xx_drv_pcmcia_probe(dev, &simpad_pcmcia_ops, 1, 1);
 132
 133        return ret;
 134}
 135