Blame view
drivers/pcmcia/pxa2xx_vpac270.c
4.3 KB
addff0fae [ARM] pxa: add su... |
1 2 3 4 5 |
/* * linux/drivers/pcmcia/pxa2xx_vpac270.c * * Driver for Voipac PXA270 PCMCIA and CF sockets * |
9ed3fbf1c ARM: pxa: Update ... |
6 |
* Copyright (C) 2010-2011 Marek Vasut <marek.vasut@gmail.com> |
addff0fae [ARM] pxa: add su... |
7 8 9 10 11 12 |
* * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. * */ |
158f1e951 gpio: include lin... |
13 |
#include <linux/gpio.h> |
addff0fae [ARM] pxa: add su... |
14 15 16 17 |
#include <linux/module.h> #include <linux/platform_device.h> #include <asm/mach-types.h> |
50ac01fbd ARM: gpio: pxa: c... |
18 |
#include <asm/gpio.h> |
addff0fae [ARM] pxa: add su... |
19 20 21 |
#include <mach/vpac270.h> #include "soc_common.h" |
e27af7edd ARM: pxa: Use gpi... |
22 23 24 25 26 27 28 29 30 31 32 33 |
static struct gpio vpac270_pcmcia_gpios[] = { { GPIO84_VPAC270_PCMCIA_CD, GPIOF_IN, "PCMCIA Card Detect" }, { GPIO35_VPAC270_PCMCIA_RDY, GPIOF_IN, "PCMCIA Ready" }, { GPIO107_VPAC270_PCMCIA_PPEN, GPIOF_INIT_LOW, "PCMCIA PPEN" }, { GPIO11_VPAC270_PCMCIA_RESET, GPIOF_INIT_LOW, "PCMCIA Reset" }, }; static struct gpio vpac270_cf_gpios[] = { { GPIO17_VPAC270_CF_CD, GPIOF_IN, "CF Card Detect" }, { GPIO12_VPAC270_CF_RDY, GPIOF_IN, "CF Ready" }, { GPIO16_VPAC270_CF_RESET, GPIOF_INIT_LOW, "CF Reset" }, }; |
addff0fae [ARM] pxa: add su... |
34 35 36 |
static struct pcmcia_irqs cd_irqs[] = { { .sock = 0, |
addff0fae [ARM] pxa: add su... |
37 38 39 40 |
.str = "PCMCIA CD" }, { .sock = 1, |
addff0fae [ARM] pxa: add su... |
41 42 43 44 45 46 47 48 49 |
.str = "CF CD" }, }; static int vpac270_pcmcia_hw_init(struct soc_pcmcia_socket *skt) { int ret; if (skt->nr == 0) { |
e27af7edd ARM: pxa: Use gpi... |
50 51 |
ret = gpio_request_array(vpac270_pcmcia_gpios, ARRAY_SIZE(vpac270_pcmcia_gpios)); |
addff0fae [ARM] pxa: add su... |
52 53 |
skt->socket.pci_irq = gpio_to_irq(GPIO35_VPAC270_PCMCIA_RDY); |
34641de2e pcmcia: pxa: repl... |
54 |
cd_irqs[0].irq = gpio_to_irq(GPIO84_VPAC270_PCMCIA_CD); |
addff0fae [ARM] pxa: add su... |
55 |
|
e27af7edd ARM: pxa: Use gpi... |
56 57 |
if (!ret) ret = soc_pcmcia_request_irqs(skt, &cd_irqs[0], 1); |
addff0fae [ARM] pxa: add su... |
58 |
} else { |
e27af7edd ARM: pxa: Use gpi... |
59 60 |
ret = gpio_request_array(vpac270_cf_gpios, ARRAY_SIZE(vpac270_cf_gpios)); |
addff0fae [ARM] pxa: add su... |
61 62 |
skt->socket.pci_irq = gpio_to_irq(GPIO12_VPAC270_CF_RDY); |
34641de2e pcmcia: pxa: repl... |
63 |
cd_irqs[1].irq = gpio_to_irq(GPIO17_VPAC270_CF_CD); |
addff0fae [ARM] pxa: add su... |
64 |
|
e27af7edd ARM: pxa: Use gpi... |
65 66 |
if (!ret) ret = soc_pcmcia_request_irqs(skt, &cd_irqs[1], 1); |
addff0fae [ARM] pxa: add su... |
67 |
} |
e27af7edd ARM: pxa: Use gpi... |
68 69 |
return ret; |
addff0fae [ARM] pxa: add su... |
70 71 72 73 |
} static void vpac270_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt) { |
e27af7edd ARM: pxa: Use gpi... |
74 |
if (skt->nr == 0) |
512b7938f pcmcia: pxa2xx/vp... |
75 |
gpio_free_array(vpac270_pcmcia_gpios, |
e27af7edd ARM: pxa: Use gpi... |
76 77 |
ARRAY_SIZE(vpac270_pcmcia_gpios)); else |
512b7938f pcmcia: pxa2xx/vp... |
78 |
gpio_free_array(vpac270_cf_gpios, |
e27af7edd ARM: pxa: Use gpi... |
79 |
ARRAY_SIZE(vpac270_cf_gpios)); |
addff0fae [ARM] pxa: add su... |
80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 |
} static void vpac270_pcmcia_socket_state(struct soc_pcmcia_socket *skt, struct pcmcia_state *state) { if (skt->nr == 0) { state->detect = !gpio_get_value(GPIO84_VPAC270_PCMCIA_CD); state->ready = !!gpio_get_value(GPIO35_VPAC270_PCMCIA_RDY); } else { state->detect = !gpio_get_value(GPIO17_VPAC270_CF_CD); state->ready = !!gpio_get_value(GPIO12_VPAC270_CF_RDY); } state->bvd1 = 1; state->bvd2 = 1; state->wrprot = 0; state->vs_3v = 1; state->vs_Xv = 0; } static int vpac270_pcmcia_configure_socket(struct soc_pcmcia_socket *skt, const socket_state_t *state) { if (skt->nr == 0) { gpio_set_value(GPIO11_VPAC270_PCMCIA_RESET, (state->flags & SS_RESET)); gpio_set_value(GPIO107_VPAC270_PCMCIA_PPEN, !(state->Vcc == 33 || state->Vcc == 50)); } else { gpio_set_value(GPIO16_VPAC270_CF_RESET, (state->flags & SS_RESET)); } return 0; } static void vpac270_pcmcia_socket_init(struct soc_pcmcia_socket *skt) { } static void vpac270_pcmcia_socket_suspend(struct soc_pcmcia_socket *skt) { } static struct pcmcia_low_level vpac270_pcmcia_ops = { .owner = THIS_MODULE, .first = 0, .nr = 2, .hw_init = vpac270_pcmcia_hw_init, .hw_shutdown = vpac270_pcmcia_hw_shutdown, .socket_state = vpac270_pcmcia_socket_state, .configure_socket = vpac270_pcmcia_configure_socket, .socket_init = vpac270_pcmcia_socket_init, .socket_suspend = vpac270_pcmcia_socket_suspend, }; static struct platform_device *vpac270_pcmcia_device; static int __init vpac270_pcmcia_init(void) { int ret; if (!machine_is_vpac270()) return -ENODEV; vpac270_pcmcia_device = platform_device_alloc("pxa2xx-pcmcia", -1); if (!vpac270_pcmcia_device) return -ENOMEM; ret = platform_device_add_data(vpac270_pcmcia_device, &vpac270_pcmcia_ops, sizeof(vpac270_pcmcia_ops)); if (!ret) ret = platform_device_add(vpac270_pcmcia_device); if (ret) platform_device_put(vpac270_pcmcia_device); return ret; } static void __exit vpac270_pcmcia_exit(void) { platform_device_unregister(vpac270_pcmcia_device); } module_init(vpac270_pcmcia_init); module_exit(vpac270_pcmcia_exit); MODULE_AUTHOR("Marek Vasut <marek.vasut@gmail.com>"); MODULE_DESCRIPTION("PCMCIA support for Voipac PXA270"); MODULE_ALIAS("platform:pxa2xx-pcmcia"); MODULE_LICENSE("GPL"); |