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