linux/drivers/pcmcia/pxa2xx_cm_x255.c
<<
>>
Prefs
   1/*
   2 * linux/drivers/pcmcia/pxa/pxa_cm_x255.c
   3 *
   4 * This program is free software; you can redistribute it and/or modify
   5 * it under the terms of the GNU General Public License version 2 as
   6 * published by the Free Software Foundation.
   7 *
   8 * Compulab Ltd., 2003, 2007, 2008
   9 * Mike Rapoport <mike@compulab.co.il>
  10 *
  11 */
  12
  13#include <linux/platform_device.h>
  14#include <linux/irq.h>
  15#include <linux/delay.h>
  16#include <linux/gpio.h>
  17#include <linux/export.h>
  18
  19#include "soc_common.h"
  20
  21#define GPIO_PCMCIA_SKTSEL      (54)
  22#define GPIO_PCMCIA_S0_CD_VALID (16)
  23#define GPIO_PCMCIA_S1_CD_VALID (17)
  24#define GPIO_PCMCIA_S0_RDYINT   (6)
  25#define GPIO_PCMCIA_S1_RDYINT   (8)
  26#define GPIO_PCMCIA_RESET       (9)
  27
  28static int cmx255_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
  29{
  30        int ret = gpio_request(GPIO_PCMCIA_RESET, "PCCard reset");
  31        if (ret)
  32                return ret;
  33        gpio_direction_output(GPIO_PCMCIA_RESET, 0);
  34
  35        if (skt->nr == 0) {
  36                skt->stat[SOC_STAT_CD].gpio = GPIO_PCMCIA_S0_CD_VALID;
  37                skt->stat[SOC_STAT_CD].name = "PCMCIA0 CD";
  38                skt->stat[SOC_STAT_RDY].gpio = GPIO_PCMCIA_S0_RDYINT;
  39                skt->stat[SOC_STAT_RDY].name = "PCMCIA0 RDY";
  40        } else {
  41                skt->stat[SOC_STAT_CD].gpio = GPIO_PCMCIA_S1_CD_VALID;
  42                skt->stat[SOC_STAT_CD].name = "PCMCIA1 CD";
  43                skt->stat[SOC_STAT_RDY].gpio = GPIO_PCMCIA_S1_RDYINT;
  44                skt->stat[SOC_STAT_RDY].name = "PCMCIA1 RDY";
  45        }
  46
  47        return 0;
  48}
  49
  50static void cmx255_pcmcia_shutdown(struct soc_pcmcia_socket *skt)
  51{
  52        gpio_free(GPIO_PCMCIA_RESET);
  53}
  54
  55
  56static void cmx255_pcmcia_socket_state(struct soc_pcmcia_socket *skt,
  57                                       struct pcmcia_state *state)
  58{
  59        state->vs_3v  = 0;
  60        state->vs_Xv  = 0;
  61}
  62
  63
  64static int cmx255_pcmcia_configure_socket(struct soc_pcmcia_socket *skt,
  65                                          const socket_state_t *state)
  66{
  67        switch (skt->nr) {
  68        case 0:
  69                if (state->flags & SS_RESET) {
  70                        gpio_set_value(GPIO_PCMCIA_SKTSEL, 0);
  71                        udelay(1);
  72                        gpio_set_value(GPIO_PCMCIA_RESET, 1);
  73                        udelay(10);
  74                        gpio_set_value(GPIO_PCMCIA_RESET, 0);
  75                }
  76                break;
  77        case 1:
  78                if (state->flags & SS_RESET) {
  79                        gpio_set_value(GPIO_PCMCIA_SKTSEL, 1);
  80                        udelay(1);
  81                        gpio_set_value(GPIO_PCMCIA_RESET, 1);
  82                        udelay(10);
  83                        gpio_set_value(GPIO_PCMCIA_RESET, 0);
  84                }
  85                break;
  86        }
  87
  88        return 0;
  89}
  90
  91static struct pcmcia_low_level cmx255_pcmcia_ops __initdata = {
  92        .owner                  = THIS_MODULE,
  93        .hw_init                = cmx255_pcmcia_hw_init,
  94        .hw_shutdown            = cmx255_pcmcia_shutdown,
  95        .socket_state           = cmx255_pcmcia_socket_state,
  96        .configure_socket       = cmx255_pcmcia_configure_socket,
  97        .nr                     = 1,
  98};
  99
 100static struct platform_device *cmx255_pcmcia_device;
 101
 102int __init cmx255_pcmcia_init(void)
 103{
 104        int ret;
 105
 106        cmx255_pcmcia_device = platform_device_alloc("pxa2xx-pcmcia", -1);
 107
 108        if (!cmx255_pcmcia_device)
 109                return -ENOMEM;
 110
 111        ret = platform_device_add_data(cmx255_pcmcia_device, &cmx255_pcmcia_ops,
 112                                       sizeof(cmx255_pcmcia_ops));
 113
 114        if (ret == 0) {
 115                printk(KERN_INFO "Registering cm-x255 PCMCIA interface.\n");
 116                ret = platform_device_add(cmx255_pcmcia_device);
 117        }
 118
 119        if (ret)
 120                platform_device_put(cmx255_pcmcia_device);
 121
 122        return ret;
 123}
 124
 125void __exit cmx255_pcmcia_exit(void)
 126{
 127        platform_device_unregister(cmx255_pcmcia_device);
 128}
 129