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