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
  25static int cmx270_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
  26{
  27        int ret = gpio_request(GPIO_PCMCIA_RESET, "PCCard reset");
  28        if (ret)
  29                return ret;
  30        gpio_direction_output(GPIO_PCMCIA_RESET, 0);
  31
  32        skt->stat[SOC_STAT_CD].gpio = GPIO_PCMCIA_S0_CD_VALID;
  33        skt->stat[SOC_STAT_CD].name = "PCMCIA0 CD";
  34        skt->stat[SOC_STAT_RDY].gpio = GPIO_PCMCIA_S0_RDYINT;
  35        skt->stat[SOC_STAT_RDY].name = "PCMCIA0 RDY";
  36
  37        return ret;
  38}
  39
  40static void cmx270_pcmcia_shutdown(struct soc_pcmcia_socket *skt)
  41{
  42        gpio_free(GPIO_PCMCIA_RESET);
  43}
  44
  45
  46static void cmx270_pcmcia_socket_state(struct soc_pcmcia_socket *skt,
  47                                       struct pcmcia_state *state)
  48{
  49        state->vs_3v  = 0;
  50        state->vs_Xv  = 0;
  51}
  52
  53
  54static int cmx270_pcmcia_configure_socket(struct soc_pcmcia_socket *skt,
  55                                          const socket_state_t *state)
  56{
  57        switch (skt->nr) {
  58        case 0:
  59                if (state->flags & SS_RESET) {
  60                        gpio_set_value(GPIO_PCMCIA_RESET, 1);
  61                        udelay(10);
  62                        gpio_set_value(GPIO_PCMCIA_RESET, 0);
  63                }
  64                break;
  65        }
  66
  67        return 0;
  68}
  69
  70static struct pcmcia_low_level cmx270_pcmcia_ops __initdata = {
  71        .owner                  = THIS_MODULE,
  72        .hw_init                = cmx270_pcmcia_hw_init,
  73        .hw_shutdown            = cmx270_pcmcia_shutdown,
  74        .socket_state           = cmx270_pcmcia_socket_state,
  75        .configure_socket       = cmx270_pcmcia_configure_socket,
  76        .nr                     = 1,
  77};
  78
  79static struct platform_device *cmx270_pcmcia_device;
  80
  81int __init cmx270_pcmcia_init(void)
  82{
  83        int ret;
  84
  85        cmx270_pcmcia_device = platform_device_alloc("pxa2xx-pcmcia", -1);
  86
  87        if (!cmx270_pcmcia_device)
  88                return -ENOMEM;
  89
  90        ret = platform_device_add_data(cmx270_pcmcia_device, &cmx270_pcmcia_ops,
  91                                       sizeof(cmx270_pcmcia_ops));
  92
  93        if (ret == 0) {
  94                printk(KERN_INFO "Registering cm-x270 PCMCIA interface.\n");
  95                ret = platform_device_add(cmx270_pcmcia_device);
  96        }
  97
  98        if (ret)
  99                platform_device_put(cmx270_pcmcia_device);
 100
 101        return ret;
 102}
 103
 104void __exit cmx270_pcmcia_exit(void)
 105{
 106        platform_device_unregister(cmx270_pcmcia_device);
 107}
 108