root/drivers/pcmcia/pxa2xx_colibri.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. colibri_pcmcia_hw_init
  2. colibri_pcmcia_hw_shutdown
  3. colibri_pcmcia_socket_state
  4. colibri_pcmcia_configure_socket
  5. colibri_pcmcia_init
  6. colibri_pcmcia_exit

   1 // SPDX-License-Identifier: GPL-2.0-only
   2 /*
   3  * linux/drivers/pcmcia/pxa2xx_colibri.c
   4  *
   5  * Driver for Toradex Colibri PXA270 CF socket
   6  *
   7  * Copyright (C) 2010 Marek Vasut <marek.vasut@gmail.com>
   8  */
   9 
  10 #include <linux/module.h>
  11 #include <linux/platform_device.h>
  12 #include <linux/delay.h>
  13 #include <linux/gpio.h>
  14 
  15 #include <asm/mach-types.h>
  16 
  17 #include "soc_common.h"
  18 
  19 #define COLIBRI270_RESET_GPIO   53
  20 #define COLIBRI270_PPEN_GPIO    107
  21 #define COLIBRI270_BVD1_GPIO    83
  22 #define COLIBRI270_BVD2_GPIO    82
  23 #define COLIBRI270_DETECT_GPIO  84
  24 #define COLIBRI270_READY_GPIO   1
  25 
  26 #define COLIBRI320_RESET_GPIO   77
  27 #define COLIBRI320_PPEN_GPIO    57
  28 #define COLIBRI320_BVD1_GPIO    53
  29 #define COLIBRI320_BVD2_GPIO    79
  30 #define COLIBRI320_DETECT_GPIO  81
  31 #define COLIBRI320_READY_GPIO   29
  32 
  33 enum {
  34         DETECT = 0,
  35         READY = 1,
  36         BVD1 = 2,
  37         BVD2 = 3,
  38         PPEN = 4,
  39         RESET = 5,
  40 };
  41 
  42 /* Contents of this array are configured on-the-fly in init function */
  43 static struct gpio colibri_pcmcia_gpios[] = {
  44         { 0,    GPIOF_IN,       "PCMCIA Detect" },
  45         { 0,    GPIOF_IN,       "PCMCIA Ready" },
  46         { 0,    GPIOF_IN,       "PCMCIA BVD1" },
  47         { 0,    GPIOF_IN,       "PCMCIA BVD2" },
  48         { 0,    GPIOF_INIT_LOW, "PCMCIA PPEN" },
  49         { 0,    GPIOF_INIT_HIGH,"PCMCIA Reset" },
  50 };
  51 
  52 static int colibri_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
  53 {
  54         int ret;
  55 
  56         ret = gpio_request_array(colibri_pcmcia_gpios,
  57                                 ARRAY_SIZE(colibri_pcmcia_gpios));
  58         if (ret)
  59                 goto err1;
  60 
  61         skt->socket.pci_irq = gpio_to_irq(colibri_pcmcia_gpios[READY].gpio);
  62         skt->stat[SOC_STAT_CD].irq = gpio_to_irq(colibri_pcmcia_gpios[DETECT].gpio);
  63         skt->stat[SOC_STAT_CD].name = "PCMCIA CD";
  64 
  65 err1:
  66         return ret;
  67 }
  68 
  69 static void colibri_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt)
  70 {
  71         gpio_free_array(colibri_pcmcia_gpios,
  72                         ARRAY_SIZE(colibri_pcmcia_gpios));
  73 }
  74 
  75 static void colibri_pcmcia_socket_state(struct soc_pcmcia_socket *skt,
  76                                         struct pcmcia_state *state)
  77 {
  78 
  79         state->detect = !!gpio_get_value(colibri_pcmcia_gpios[DETECT].gpio);
  80         state->ready  = !!gpio_get_value(colibri_pcmcia_gpios[READY].gpio);
  81         state->bvd1   = !!gpio_get_value(colibri_pcmcia_gpios[BVD1].gpio);
  82         state->bvd2   = !!gpio_get_value(colibri_pcmcia_gpios[BVD2].gpio);
  83         state->vs_3v  = 1;
  84         state->vs_Xv  = 0;
  85 }
  86 
  87 static int
  88 colibri_pcmcia_configure_socket(struct soc_pcmcia_socket *skt,
  89                                 const socket_state_t *state)
  90 {
  91         gpio_set_value(colibri_pcmcia_gpios[PPEN].gpio,
  92                         !(state->Vcc == 33 && state->Vpp < 50));
  93         gpio_set_value(colibri_pcmcia_gpios[RESET].gpio,
  94                         state->flags & SS_RESET);
  95         return 0;
  96 }
  97 
  98 static struct pcmcia_low_level colibri_pcmcia_ops = {
  99         .owner                  = THIS_MODULE,
 100 
 101         .first                  = 0,
 102         .nr                     = 1,
 103 
 104         .hw_init                = colibri_pcmcia_hw_init,
 105         .hw_shutdown            = colibri_pcmcia_hw_shutdown,
 106 
 107         .socket_state           = colibri_pcmcia_socket_state,
 108         .configure_socket       = colibri_pcmcia_configure_socket,
 109 };
 110 
 111 static struct platform_device *colibri_pcmcia_device;
 112 
 113 static int __init colibri_pcmcia_init(void)
 114 {
 115         int ret;
 116 
 117         if (!machine_is_colibri() && !machine_is_colibri320())
 118                 return -ENODEV;
 119 
 120         colibri_pcmcia_device = platform_device_alloc("pxa2xx-pcmcia", -1);
 121         if (!colibri_pcmcia_device)
 122                 return -ENOMEM;
 123 
 124         /* Colibri PXA270 */
 125         if (machine_is_colibri()) {
 126                 colibri_pcmcia_gpios[RESET].gpio        = COLIBRI270_RESET_GPIO;
 127                 colibri_pcmcia_gpios[PPEN].gpio         = COLIBRI270_PPEN_GPIO;
 128                 colibri_pcmcia_gpios[BVD1].gpio         = COLIBRI270_BVD1_GPIO;
 129                 colibri_pcmcia_gpios[BVD2].gpio         = COLIBRI270_BVD2_GPIO;
 130                 colibri_pcmcia_gpios[DETECT].gpio       = COLIBRI270_DETECT_GPIO;
 131                 colibri_pcmcia_gpios[READY].gpio        = COLIBRI270_READY_GPIO;
 132         /* Colibri PXA320 */
 133         } else if (machine_is_colibri320()) {
 134                 colibri_pcmcia_gpios[RESET].gpio        = COLIBRI320_RESET_GPIO;
 135                 colibri_pcmcia_gpios[PPEN].gpio         = COLIBRI320_PPEN_GPIO;
 136                 colibri_pcmcia_gpios[BVD1].gpio         = COLIBRI320_BVD1_GPIO;
 137                 colibri_pcmcia_gpios[BVD2].gpio         = COLIBRI320_BVD2_GPIO;
 138                 colibri_pcmcia_gpios[DETECT].gpio       = COLIBRI320_DETECT_GPIO;
 139                 colibri_pcmcia_gpios[READY].gpio        = COLIBRI320_READY_GPIO;
 140         }
 141 
 142         ret = platform_device_add_data(colibri_pcmcia_device,
 143                 &colibri_pcmcia_ops, sizeof(colibri_pcmcia_ops));
 144 
 145         if (!ret)
 146                 ret = platform_device_add(colibri_pcmcia_device);
 147 
 148         if (ret)
 149                 platform_device_put(colibri_pcmcia_device);
 150 
 151         return ret;
 152 }
 153 
 154 static void __exit colibri_pcmcia_exit(void)
 155 {
 156         platform_device_unregister(colibri_pcmcia_device);
 157 }
 158 
 159 module_init(colibri_pcmcia_init);
 160 module_exit(colibri_pcmcia_exit);
 161 
 162 MODULE_AUTHOR("Marek Vasut <marek.vasut@gmail.com>");
 163 MODULE_DESCRIPTION("PCMCIA support for Toradex Colibri PXA270/PXA320");
 164 MODULE_ALIAS("platform:pxa2xx-pcmcia");
 165 MODULE_LICENSE("GPL");

/* [<][>][^][v][top][bottom][index][help] */