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