linux/drivers/pcmcia/pxa2xx_cm_x270.c
<<
>>
Prefs
   1/*
   2 * linux/drivers/pcmcia/pxa/pxa_cm_x270.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_S0_CD_VALID (84)
  22#define GPIO_PCMCIA_S0_RDYINT   (82)
  23#define GPIO_PCMCIA_RESET       (53)
  24
  25#define PCMCIA_S0_CD_VALID      gpio_to_irq(GPIO_PCMCIA_S0_CD_VALID)
  26#define PCMCIA_S0_RDYINT        gpio_to_irq(GPIO_PCMCIA_S0_RDYINT)
  27
  28
  29static struct pcmcia_irqs irqs[] = {
  30        { .sock = 0, .str = "PCMCIA0 CD" },
  31};
  32
  33static int cmx270_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
  34{
  35        int ret = gpio_request(GPIO_PCMCIA_RESET, "PCCard reset");
  36        if (ret)
  37                return ret;
  38        gpio_direction_output(GPIO_PCMCIA_RESET, 0);
  39
  40        skt->socket.pci_irq = PCMCIA_S0_RDYINT;
  41        irqs[0].irq = PCMCIA_S0_CD_VALID;
  42        ret = soc_pcmcia_request_irqs(skt, irqs, ARRAY_SIZE(irqs));
  43        if (!ret)
  44                gpio_free(GPIO_PCMCIA_RESET);
  45
  46        return ret;
  47}
  48
  49static void cmx270_pcmcia_shutdown(struct soc_pcmcia_socket *skt)
  50{
  51        soc_pcmcia_free_irqs(skt, irqs, ARRAY_SIZE(irqs));
  52        gpio_free(GPIO_PCMCIA_RESET);
  53}
  54
  55
  56static void cmx270_pcmcia_socket_state(struct soc_pcmcia_socket *skt,
  57                                       struct pcmcia_state *state)
  58{
  59        state->detect = (gpio_get_value(GPIO_PCMCIA_S0_CD_VALID) == 0) ? 1 : 0;
  60        state->ready  = (gpio_get_value(GPIO_PCMCIA_S0_RDYINT) == 0) ? 0 : 1;
  61        state->bvd1   = 1;
  62        state->bvd2   = 1;
  63        state->vs_3v  = 0;
  64        state->vs_Xv  = 0;
  65        state->wrprot = 0;  /* not available */
  66}
  67
  68
  69static int cmx270_pcmcia_configure_socket(struct soc_pcmcia_socket *skt,
  70                                          const socket_state_t *state)
  71{
  72        switch (skt->nr) {
  73        case 0:
  74                if (state->flags & SS_RESET) {
  75                        gpio_set_value(GPIO_PCMCIA_RESET, 1);
  76                        udelay(10);
  77                        gpio_set_value(GPIO_PCMCIA_RESET, 0);
  78                }
  79                break;
  80        }
  81
  82        return 0;
  83}
  84
  85static struct pcmcia_low_level cmx270_pcmcia_ops __initdata = {
  86        .owner                  = THIS_MODULE,
  87        .hw_init                = cmx270_pcmcia_hw_init,
  88        .hw_shutdown            = cmx270_pcmcia_shutdown,
  89        .socket_state           = cmx270_pcmcia_socket_state,
  90        .configure_socket       = cmx270_pcmcia_configure_socket,
  91        .nr                     = 1,
  92};
  93
  94static struct platform_device *cmx270_pcmcia_device;
  95
  96int __init cmx270_pcmcia_init(void)
  97{
  98        int ret;
  99
 100        cmx270_pcmcia_device = platform_device_alloc("pxa2xx-pcmcia", -1);
 101
 102        if (!cmx270_pcmcia_device)
 103                return -ENOMEM;
 104
 105        ret = platform_device_add_data(cmx270_pcmcia_device, &cmx270_pcmcia_ops,
 106                                       sizeof(cmx270_pcmcia_ops));
 107
 108        if (ret == 0) {
 109                printk(KERN_INFO "Registering cm-x270 PCMCIA interface.\n");
 110                ret = platform_device_add(cmx270_pcmcia_device);
 111        }
 112
 113        if (ret)
 114                platform_device_put(cmx270_pcmcia_device);
 115
 116        return ret;
 117}
 118
 119void __exit cmx270_pcmcia_exit(void)
 120{
 121        platform_device_unregister(cmx270_pcmcia_device);
 122}
 123