This source file includes following definitions.
- sa11x0_cf_hw_init
- sa11x0_cf_configure_socket
- sa11x0_drv_pcmcia_legacy_probe
- sa11x0_drv_pcmcia_legacy_remove
- sa11x0_drv_pcmcia_probe
- sa11x0_drv_pcmcia_remove
- sa11x0_pcmcia_init
- sa11x0_pcmcia_exit
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33 #include <linux/module.h>
34 #include <linux/gpio/consumer.h>
35 #include <linux/init.h>
36 #include <linux/regulator/consumer.h>
37 #include <linux/slab.h>
38 #include <linux/platform_device.h>
39
40 #include <pcmcia/ss.h>
41
42 #include <asm/hardware/scoop.h>
43
44 #include "sa1100_generic.h"
45
46 static const char *sa11x0_cf_gpio_names[] = {
47 [SOC_STAT_CD] = "detect",
48 [SOC_STAT_BVD1] = "bvd1",
49 [SOC_STAT_BVD2] = "bvd2",
50 [SOC_STAT_RDY] = "ready",
51 };
52
53 static int sa11x0_cf_hw_init(struct soc_pcmcia_socket *skt)
54 {
55 struct device *dev = skt->socket.dev.parent;
56 int i;
57
58 skt->gpio_reset = devm_gpiod_get(dev, "reset", GPIOD_OUT_HIGH);
59 if (IS_ERR(skt->gpio_reset))
60 return PTR_ERR(skt->gpio_reset);
61
62 skt->gpio_bus_enable = devm_gpiod_get_optional(dev, "bus-enable",
63 GPIOD_OUT_HIGH);
64 if (IS_ERR(skt->gpio_bus_enable))
65 return PTR_ERR(skt->gpio_bus_enable);
66
67 skt->vcc.reg = devm_regulator_get_optional(dev, "vcc");
68 if (IS_ERR(skt->vcc.reg))
69 return PTR_ERR(skt->vcc.reg);
70
71 if (!skt->vcc.reg)
72 dev_warn(dev,
73 "no Vcc regulator provided, ignoring Vcc controls\n");
74
75 for (i = 0; i < ARRAY_SIZE(sa11x0_cf_gpio_names); i++) {
76 skt->stat[i].name = sa11x0_cf_gpio_names[i];
77 skt->stat[i].desc = devm_gpiod_get_optional(dev,
78 sa11x0_cf_gpio_names[i], GPIOD_IN);
79 if (IS_ERR(skt->stat[i].desc))
80 return PTR_ERR(skt->stat[i].desc);
81 }
82 return 0;
83 }
84
85 static int sa11x0_cf_configure_socket(struct soc_pcmcia_socket *skt,
86 const socket_state_t *state)
87 {
88 return soc_pcmcia_regulator_set(skt, &skt->vcc, state->Vcc);
89 }
90
91 static struct pcmcia_low_level sa11x0_cf_ops = {
92 .owner = THIS_MODULE,
93 .hw_init = sa11x0_cf_hw_init,
94 .socket_state = soc_common_cf_socket_state,
95 .configure_socket = sa11x0_cf_configure_socket,
96 };
97
98 int __init pcmcia_collie_init(struct device *dev);
99
100 static int (*sa11x0_pcmcia_legacy_hw_init[])(struct device *dev) = {
101 #if defined(CONFIG_SA1100_H3100) || defined(CONFIG_SA1100_H3600)
102 pcmcia_h3600_init,
103 #endif
104 #ifdef CONFIG_SA1100_SIMPAD
105 pcmcia_simpad_init,
106 #endif
107 #ifdef CONFIG_SA1100_COLLIE
108 pcmcia_collie_init,
109 #endif
110 };
111
112 static int sa11x0_drv_pcmcia_legacy_probe(struct platform_device *dev)
113 {
114 int i, ret = -ENODEV;
115
116
117
118
119 for (i = 0; i < ARRAY_SIZE(sa11x0_pcmcia_legacy_hw_init); i++) {
120 ret = sa11x0_pcmcia_legacy_hw_init[i](&dev->dev);
121 if (ret == 0)
122 break;
123 }
124
125 return ret;
126 }
127
128 static int sa11x0_drv_pcmcia_legacy_remove(struct platform_device *dev)
129 {
130 struct skt_dev_info *sinfo = platform_get_drvdata(dev);
131 int i;
132
133 platform_set_drvdata(dev, NULL);
134
135 for (i = 0; i < sinfo->nskt; i++)
136 soc_pcmcia_remove_one(&sinfo->skt[i]);
137
138 return 0;
139 }
140
141 static int sa11x0_drv_pcmcia_probe(struct platform_device *pdev)
142 {
143 struct soc_pcmcia_socket *skt;
144 struct device *dev = &pdev->dev;
145
146 if (pdev->id == -1)
147 return sa11x0_drv_pcmcia_legacy_probe(pdev);
148
149 skt = devm_kzalloc(dev, sizeof(*skt), GFP_KERNEL);
150 if (!skt)
151 return -ENOMEM;
152
153 platform_set_drvdata(pdev, skt);
154
155 skt->nr = pdev->id;
156 skt->clk = devm_clk_get(dev, NULL);
157 if (IS_ERR(skt->clk))
158 return PTR_ERR(skt->clk);
159
160 sa11xx_drv_pcmcia_ops(&sa11x0_cf_ops);
161 soc_pcmcia_init_one(skt, &sa11x0_cf_ops, dev);
162
163 return sa11xx_drv_pcmcia_add_one(skt);
164 }
165
166 static int sa11x0_drv_pcmcia_remove(struct platform_device *dev)
167 {
168 struct soc_pcmcia_socket *skt;
169
170 if (dev->id == -1)
171 return sa11x0_drv_pcmcia_legacy_remove(dev);
172
173 skt = platform_get_drvdata(dev);
174
175 soc_pcmcia_remove_one(skt);
176
177 return 0;
178 }
179
180 static struct platform_driver sa11x0_pcmcia_driver = {
181 .driver = {
182 .name = "sa11x0-pcmcia",
183 },
184 .probe = sa11x0_drv_pcmcia_probe,
185 .remove = sa11x0_drv_pcmcia_remove,
186 };
187
188
189
190
191
192
193
194
195
196 static int __init sa11x0_pcmcia_init(void)
197 {
198 return platform_driver_register(&sa11x0_pcmcia_driver);
199 }
200
201
202
203
204
205
206 static void __exit sa11x0_pcmcia_exit(void)
207 {
208 platform_driver_unregister(&sa11x0_pcmcia_driver);
209 }
210
211 MODULE_AUTHOR("John Dorsey <john+@cs.cmu.edu>");
212 MODULE_DESCRIPTION("Linux PCMCIA Card Services: SA-11x0 Socket Controller");
213 MODULE_LICENSE("Dual MPL/GPL");
214
215 fs_initcall(sa11x0_pcmcia_init);
216 module_exit(sa11x0_pcmcia_exit);