root/drivers/pcmcia/pxa2xx_palmtc.c

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

DEFINITIONS

This source file includes following definitions.
  1. palmtc_pcmcia_hw_init
  2. palmtc_pcmcia_hw_shutdown
  3. palmtc_pcmcia_socket_state
  4. palmtc_wifi_powerdown
  5. palmtc_wifi_powerup
  6. palmtc_pcmcia_configure_socket
  7. palmtc_pcmcia_init
  8. palmtc_pcmcia_exit

   1 // SPDX-License-Identifier: GPL-2.0-only
   2 /*
   3  * linux/drivers/pcmcia/pxa2xx_palmtc.c
   4  *
   5  * Driver for Palm Tungsten|C PCMCIA
   6  *
   7  * Copyright (C) 2008 Alex Osborne <ato@meshy.org>
   8  * Copyright (C) 2009-2011 Marek Vasut <marek.vasut@gmail.com>
   9  */
  10 
  11 #include <linux/module.h>
  12 #include <linux/platform_device.h>
  13 #include <linux/gpio.h>
  14 #include <linux/delay.h>
  15 
  16 #include <asm/mach-types.h>
  17 #include <mach/palmtc.h>
  18 #include "soc_common.h"
  19 
  20 static struct gpio palmtc_pcmcia_gpios[] = {
  21         { GPIO_NR_PALMTC_PCMCIA_POWER1, GPIOF_INIT_LOW, "PCMCIA Power 1" },
  22         { GPIO_NR_PALMTC_PCMCIA_POWER2, GPIOF_INIT_LOW, "PCMCIA Power 2" },
  23         { GPIO_NR_PALMTC_PCMCIA_POWER3, GPIOF_INIT_LOW, "PCMCIA Power 3" },
  24         { GPIO_NR_PALMTC_PCMCIA_RESET,  GPIOF_INIT_HIGH,"PCMCIA Reset" },
  25         { GPIO_NR_PALMTC_PCMCIA_PWRREADY, GPIOF_IN,     "PCMCIA Power Ready" },
  26 };
  27 
  28 static int palmtc_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
  29 {
  30         int ret;
  31 
  32         ret = gpio_request_array(palmtc_pcmcia_gpios,
  33                                 ARRAY_SIZE(palmtc_pcmcia_gpios));
  34 
  35         skt->stat[SOC_STAT_RDY].gpio = GPIO_NR_PALMTC_PCMCIA_READY;
  36         skt->stat[SOC_STAT_RDY].name = "PCMCIA Ready";
  37 
  38         return ret;
  39 }
  40 
  41 static void palmtc_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt)
  42 {
  43         gpio_free_array(palmtc_pcmcia_gpios, ARRAY_SIZE(palmtc_pcmcia_gpios));
  44 }
  45 
  46 static void palmtc_pcmcia_socket_state(struct soc_pcmcia_socket *skt,
  47                                         struct pcmcia_state *state)
  48 {
  49         state->detect = 1; /* always inserted */
  50         state->vs_3v  = 1;
  51         state->vs_Xv  = 0;
  52 }
  53 
  54 static int palmtc_wifi_powerdown(void)
  55 {
  56         gpio_set_value(GPIO_NR_PALMTC_PCMCIA_RESET, 1);
  57         gpio_set_value(GPIO_NR_PALMTC_PCMCIA_POWER2, 0);
  58         mdelay(40);
  59         gpio_set_value(GPIO_NR_PALMTC_PCMCIA_POWER1, 0);
  60         return 0;
  61 }
  62 
  63 static int palmtc_wifi_powerup(void)
  64 {
  65         int timeout = 50;
  66 
  67         gpio_set_value(GPIO_NR_PALMTC_PCMCIA_POWER3, 1);
  68         mdelay(50);
  69 
  70         /* Power up the card, 1.8V first, after a while 3.3V */
  71         gpio_set_value(GPIO_NR_PALMTC_PCMCIA_POWER1, 1);
  72         mdelay(100);
  73         gpio_set_value(GPIO_NR_PALMTC_PCMCIA_POWER2, 1);
  74 
  75         /* Wait till the card is ready */
  76         while (!gpio_get_value(GPIO_NR_PALMTC_PCMCIA_PWRREADY) &&
  77                 timeout) {
  78                 mdelay(1);
  79                 timeout--;
  80         }
  81 
  82         /* Power down the WiFi in case of error */
  83         if (!timeout) {
  84                 palmtc_wifi_powerdown();
  85                 return 1;
  86         }
  87 
  88         /* Reset the card */
  89         gpio_set_value(GPIO_NR_PALMTC_PCMCIA_RESET, 1);
  90         mdelay(20);
  91         gpio_set_value(GPIO_NR_PALMTC_PCMCIA_RESET, 0);
  92         mdelay(25);
  93 
  94         gpio_set_value(GPIO_NR_PALMTC_PCMCIA_POWER3, 0);
  95 
  96         return 0;
  97 }
  98 
  99 static int palmtc_pcmcia_configure_socket(struct soc_pcmcia_socket *skt,
 100                                         const socket_state_t *state)
 101 {
 102         int ret = 1;
 103 
 104         if (state->Vcc == 0)
 105                 ret = palmtc_wifi_powerdown();
 106         else if (state->Vcc == 33)
 107                 ret = palmtc_wifi_powerup();
 108 
 109         return ret;
 110 }
 111 
 112 static struct pcmcia_low_level palmtc_pcmcia_ops = {
 113         .owner                  = THIS_MODULE,
 114 
 115         .first                  = 0,
 116         .nr                     = 1,
 117 
 118         .hw_init                = palmtc_pcmcia_hw_init,
 119         .hw_shutdown            = palmtc_pcmcia_hw_shutdown,
 120 
 121         .socket_state           = palmtc_pcmcia_socket_state,
 122         .configure_socket       = palmtc_pcmcia_configure_socket,
 123 };
 124 
 125 static struct platform_device *palmtc_pcmcia_device;
 126 
 127 static int __init palmtc_pcmcia_init(void)
 128 {
 129         int ret;
 130 
 131         if (!machine_is_palmtc())
 132                 return -ENODEV;
 133 
 134         palmtc_pcmcia_device = platform_device_alloc("pxa2xx-pcmcia", -1);
 135         if (!palmtc_pcmcia_device)
 136                 return -ENOMEM;
 137 
 138         ret = platform_device_add_data(palmtc_pcmcia_device, &palmtc_pcmcia_ops,
 139                                         sizeof(palmtc_pcmcia_ops));
 140 
 141         if (!ret)
 142                 ret = platform_device_add(palmtc_pcmcia_device);
 143 
 144         if (ret)
 145                 platform_device_put(palmtc_pcmcia_device);
 146 
 147         return ret;
 148 }
 149 
 150 static void __exit palmtc_pcmcia_exit(void)
 151 {
 152         platform_device_unregister(palmtc_pcmcia_device);
 153 }
 154 
 155 module_init(palmtc_pcmcia_init);
 156 module_exit(palmtc_pcmcia_exit);
 157 
 158 MODULE_AUTHOR("Alex Osborne <ato@meshy.org>,"
 159             " Marek Vasut <marek.vasut@gmail.com>");
 160 MODULE_DESCRIPTION("PCMCIA support for Palm Tungsten|C");
 161 MODULE_ALIAS("platform:pxa2xx-pcmcia");
 162 MODULE_LICENSE("GPL");

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