Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /*
0003  * linux/drivers/pcmcia/pxa2xx_vpac270.c
0004  *
0005  * Driver for Voipac PXA270 PCMCIA and CF sockets
0006  *
0007  * Copyright (C) 2010-2011 Marek Vasut <marek.vasut@gmail.com>
0008  */
0009 
0010 #include <linux/gpio.h>
0011 #include <linux/module.h>
0012 #include <linux/platform_device.h>
0013 
0014 #include <asm/mach-types.h>
0015 
0016 #include "vpac270.h"
0017 
0018 #include <pcmcia/soc_common.h>
0019 
0020 static struct gpio vpac270_pcmcia_gpios[] = {
0021     { GPIO107_VPAC270_PCMCIA_PPEN,  GPIOF_INIT_LOW, "PCMCIA PPEN" },
0022     { GPIO11_VPAC270_PCMCIA_RESET,  GPIOF_INIT_LOW, "PCMCIA Reset" },
0023 };
0024 
0025 static struct gpio vpac270_cf_gpios[] = {
0026     { GPIO16_VPAC270_CF_RESET,  GPIOF_INIT_LOW, "CF Reset" },
0027 };
0028 
0029 static int vpac270_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
0030 {
0031     int ret;
0032 
0033     if (skt->nr == 0) {
0034         ret = gpio_request_array(vpac270_pcmcia_gpios,
0035                 ARRAY_SIZE(vpac270_pcmcia_gpios));
0036 
0037         skt->stat[SOC_STAT_CD].gpio = GPIO84_VPAC270_PCMCIA_CD;
0038         skt->stat[SOC_STAT_CD].name = "PCMCIA CD";
0039         skt->stat[SOC_STAT_RDY].gpio = GPIO35_VPAC270_PCMCIA_RDY;
0040         skt->stat[SOC_STAT_RDY].name = "PCMCIA Ready";
0041     } else {
0042         ret = gpio_request_array(vpac270_cf_gpios,
0043                 ARRAY_SIZE(vpac270_cf_gpios));
0044 
0045         skt->stat[SOC_STAT_CD].gpio = GPIO17_VPAC270_CF_CD;
0046         skt->stat[SOC_STAT_CD].name = "CF CD";
0047         skt->stat[SOC_STAT_RDY].gpio = GPIO12_VPAC270_CF_RDY;
0048         skt->stat[SOC_STAT_RDY].name = "CF Ready";
0049     }
0050 
0051     return ret;
0052 }
0053 
0054 static void vpac270_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt)
0055 {
0056     if (skt->nr == 0)
0057         gpio_free_array(vpac270_pcmcia_gpios,
0058                     ARRAY_SIZE(vpac270_pcmcia_gpios));
0059     else
0060         gpio_free_array(vpac270_cf_gpios,
0061                     ARRAY_SIZE(vpac270_cf_gpios));
0062 }
0063 
0064 static void vpac270_pcmcia_socket_state(struct soc_pcmcia_socket *skt,
0065                     struct pcmcia_state *state)
0066 {
0067     state->vs_3v  = 1;
0068     state->vs_Xv  = 0;
0069 }
0070 
0071 static int
0072 vpac270_pcmcia_configure_socket(struct soc_pcmcia_socket *skt,
0073                 const socket_state_t *state)
0074 {
0075     if (skt->nr == 0) {
0076         gpio_set_value(GPIO11_VPAC270_PCMCIA_RESET,
0077             (state->flags & SS_RESET));
0078         gpio_set_value(GPIO107_VPAC270_PCMCIA_PPEN,
0079             !(state->Vcc == 33 || state->Vcc == 50));
0080     } else {
0081         gpio_set_value(GPIO16_VPAC270_CF_RESET,
0082             (state->flags & SS_RESET));
0083     }
0084 
0085     return 0;
0086 }
0087 
0088 static struct pcmcia_low_level vpac270_pcmcia_ops = {
0089     .owner          = THIS_MODULE,
0090 
0091     .first          = 0,
0092     .nr         = 2,
0093 
0094     .hw_init        = vpac270_pcmcia_hw_init,
0095     .hw_shutdown        = vpac270_pcmcia_hw_shutdown,
0096 
0097     .socket_state       = vpac270_pcmcia_socket_state,
0098     .configure_socket   = vpac270_pcmcia_configure_socket,
0099 };
0100 
0101 static struct platform_device *vpac270_pcmcia_device;
0102 
0103 static int __init vpac270_pcmcia_init(void)
0104 {
0105     int ret;
0106 
0107     if (!machine_is_vpac270())
0108         return -ENODEV;
0109 
0110     vpac270_pcmcia_device = platform_device_alloc("pxa2xx-pcmcia", -1);
0111     if (!vpac270_pcmcia_device)
0112         return -ENOMEM;
0113 
0114     ret = platform_device_add_data(vpac270_pcmcia_device,
0115         &vpac270_pcmcia_ops, sizeof(vpac270_pcmcia_ops));
0116 
0117     if (!ret)
0118         ret = platform_device_add(vpac270_pcmcia_device);
0119 
0120     if (ret)
0121         platform_device_put(vpac270_pcmcia_device);
0122 
0123     return ret;
0124 }
0125 
0126 static void __exit vpac270_pcmcia_exit(void)
0127 {
0128     platform_device_unregister(vpac270_pcmcia_device);
0129 }
0130 
0131 module_init(vpac270_pcmcia_init);
0132 module_exit(vpac270_pcmcia_exit);
0133 
0134 MODULE_AUTHOR("Marek Vasut <marek.vasut@gmail.com>");
0135 MODULE_DESCRIPTION("PCMCIA support for Voipac PXA270");
0136 MODULE_ALIAS("platform:pxa2xx-pcmcia");
0137 MODULE_LICENSE("GPL");