This source file includes following definitions.
- gpio_match
- gpio_attach
- gpio_detach
- gpio_search
- gpio_print
- gpiobus_print
- gpio_pin_map
- gpio_pin_unmap
- gpio_pin_read
- gpio_pin_write
- gpio_pin_ctl
- gpio_pin_caps
- gpio_npins
- gpioopen
- gpioclose
- gpioioctl
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23 #include <sys/param.h>
24 #include <sys/systm.h>
25 #include <sys/conf.h>
26 #include <sys/device.h>
27 #include <sys/fcntl.h>
28 #include <sys/ioctl.h>
29 #include <sys/gpio.h>
30 #include <sys/vnode.h>
31
32 #include <dev/gpio/gpiovar.h>
33
34 struct gpio_softc {
35 struct device sc_dev;
36
37 gpio_chipset_tag_t sc_gc;
38 gpio_pin_t *sc_pins;
39 int sc_npins;
40
41 int sc_opened;
42 };
43
44 int gpio_match(struct device *, void *, void *);
45 void gpio_attach(struct device *, struct device *, void *);
46 int gpio_detach(struct device *, int);
47 int gpio_search(struct device *, void *, void *);
48 int gpio_print(void *, const char *);
49
50 struct cfattach gpio_ca = {
51 sizeof (struct gpio_softc),
52 gpio_match,
53 gpio_attach,
54 gpio_detach
55 };
56
57 struct cfdriver gpio_cd = {
58 NULL, "gpio", DV_DULL
59 };
60
61 int
62 gpio_match(struct device *parent, void *match, void *aux)
63 {
64 struct cfdata *cf = match;
65 struct gpiobus_attach_args *gba = aux;
66
67 if (strcmp(gba->gba_name, cf->cf_driver->cd_name) != 0)
68 return (0);
69
70 return (1);
71 }
72
73 void
74 gpio_attach(struct device *parent, struct device *self, void *aux)
75 {
76 struct gpio_softc *sc = (struct gpio_softc *)self;
77 struct gpiobus_attach_args *gba = aux;
78
79 sc->sc_gc = gba->gba_gc;
80 sc->sc_pins = gba->gba_pins;
81 sc->sc_npins = gba->gba_npins;
82
83 printf(": %d pins\n", sc->sc_npins);
84
85
86
87
88
89 config_search(gpio_search, self, sc);
90 }
91
92 int
93 gpio_detach(struct device *self, int flags)
94 {
95 int maj, mn;
96
97
98 for (maj = 0; maj < nchrdev; maj++)
99 if (cdevsw[maj].d_open == gpioopen)
100 break;
101
102
103 mn = self->dv_unit;
104 vdevgone(maj, mn, mn, VCHR);
105
106 return (0);
107 }
108
109 int
110 gpio_search(struct device *parent, void *arg, void *aux)
111 {
112 struct cfdata *cf = arg;
113 struct gpio_attach_args ga;
114
115 ga.ga_gpio = aux;
116 ga.ga_offset = cf->cf_loc[0];
117 ga.ga_mask = cf->cf_loc[1];
118
119 if (cf->cf_attach->ca_match(parent, cf, &ga) > 0)
120 config_attach(parent, cf, &ga, gpio_print);
121
122 return (0);
123 }
124
125 int
126 gpio_print(void *aux, const char *pnp)
127 {
128 struct gpio_attach_args *ga = aux;
129 int i;
130
131 printf(" pins");
132 for (i = 0; i < 32; i++)
133 if (ga->ga_mask & (1 << i))
134 printf(" %d", ga->ga_offset + i);
135
136 return (UNCONF);
137 }
138
139 int
140 gpiobus_print(void *aux, const char *pnp)
141 {
142 struct gpiobus_attach_args *gba = aux;
143
144 if (pnp != NULL)
145 printf("%s at %s", gba->gba_name, pnp);
146
147 return (UNCONF);
148 }
149
150 int
151 gpio_pin_map(void *gpio, int offset, u_int32_t mask, struct gpio_pinmap *map)
152 {
153 struct gpio_softc *sc = gpio;
154 int npins, pin, i;
155
156 npins = gpio_npins(mask);
157 if (npins > sc->sc_npins)
158 return (1);
159
160 for (npins = 0, i = 0; i < 32; i++)
161 if (mask & (1 << i)) {
162 pin = offset + i;
163 if (pin < 0 || pin >= sc->sc_npins)
164 return (1);
165 if (sc->sc_pins[pin].pin_mapped)
166 return (1);
167 sc->sc_pins[pin].pin_mapped = 1;
168 map->pm_map[npins++] = pin;
169 }
170 map->pm_size = npins;
171
172 return (0);
173 }
174
175 void
176 gpio_pin_unmap(void *gpio, struct gpio_pinmap *map)
177 {
178 struct gpio_softc *sc = gpio;
179 int pin, i;
180
181 for (i = 0; i < map->pm_size; i++) {
182 pin = map->pm_map[i];
183 sc->sc_pins[pin].pin_mapped = 0;
184 }
185 }
186
187 int
188 gpio_pin_read(void *gpio, struct gpio_pinmap *map, int pin)
189 {
190 struct gpio_softc *sc = gpio;
191
192 return (gpiobus_pin_read(sc->sc_gc, map->pm_map[pin]));
193 }
194
195 void
196 gpio_pin_write(void *gpio, struct gpio_pinmap *map, int pin, int value)
197 {
198 struct gpio_softc *sc = gpio;
199
200 return (gpiobus_pin_write(sc->sc_gc, map->pm_map[pin], value));
201 }
202
203 void
204 gpio_pin_ctl(void *gpio, struct gpio_pinmap *map, int pin, int flags)
205 {
206 struct gpio_softc *sc = gpio;
207
208 return (gpiobus_pin_ctl(sc->sc_gc, map->pm_map[pin], flags));
209 }
210
211 int
212 gpio_pin_caps(void *gpio, struct gpio_pinmap *map, int pin)
213 {
214 struct gpio_softc *sc = gpio;
215
216 return (sc->sc_pins[map->pm_map[pin]].pin_caps);
217 }
218
219 int
220 gpio_npins(u_int32_t mask)
221 {
222 int npins, i;
223
224 for (npins = 0, i = 0; i < 32; i++)
225 if (mask & (1 << i))
226 npins++;
227
228 return (npins);
229 }
230
231 int
232 gpioopen(dev_t dev, int flag, int mode, struct proc *p)
233 {
234 struct gpio_softc *sc;
235
236 sc = (struct gpio_softc *)device_lookup(&gpio_cd, minor(dev));
237 if (sc == NULL)
238 return (ENXIO);
239
240 if (sc->sc_opened)
241 return (EBUSY);
242 sc->sc_opened = 1;
243
244 return (0);
245 }
246
247 int
248 gpioclose(dev_t dev, int flag, int mode, struct proc *p)
249 {
250 struct gpio_softc *sc;
251
252 sc = (struct gpio_softc *)device_lookup(&gpio_cd, minor(dev));
253 sc->sc_opened = 0;
254
255 return (0);
256 }
257
258 int
259 gpioioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p)
260 {
261 struct gpio_softc *sc;
262 gpio_chipset_tag_t gc;
263 struct gpio_info *info;
264 struct gpio_pin_op *op;
265 struct gpio_pin_ctl *ctl;
266 int pin, value, flags;
267
268 sc = (struct gpio_softc *)device_lookup(&gpio_cd, minor(dev));
269 gc = sc->sc_gc;
270
271 switch (cmd) {
272 case GPIOINFO:
273 info = (struct gpio_info *)data;
274
275 info->gpio_npins = sc->sc_npins;
276 break;
277 case GPIOPINREAD:
278 op = (struct gpio_pin_op *)data;
279
280 pin = op->gp_pin;
281 if (pin < 0 || pin >= sc->sc_npins)
282 return (EINVAL);
283
284
285 op->gp_value = gpiobus_pin_read(gc, pin);
286 break;
287 case GPIOPINWRITE:
288 if ((flag & FWRITE) == 0)
289 return (EBADF);
290
291 op = (struct gpio_pin_op *)data;
292
293 pin = op->gp_pin;
294 if (pin < 0 || pin >= sc->sc_npins)
295 return (EINVAL);
296 if (sc->sc_pins[pin].pin_mapped)
297 return (EBUSY);
298
299 value = op->gp_value;
300 if (value != GPIO_PIN_LOW && value != GPIO_PIN_HIGH)
301 return (EINVAL);
302
303 gpiobus_pin_write(gc, pin, value);
304
305 op->gp_value = sc->sc_pins[pin].pin_state;
306
307 sc->sc_pins[pin].pin_state = value;
308 break;
309 case GPIOPINTOGGLE:
310 if ((flag & FWRITE) == 0)
311 return (EBADF);
312
313 op = (struct gpio_pin_op *)data;
314
315 pin = op->gp_pin;
316 if (pin < 0 || pin >= sc->sc_npins)
317 return (EINVAL);
318 if (sc->sc_pins[pin].pin_mapped)
319 return (EBUSY);
320
321 value = (sc->sc_pins[pin].pin_state == GPIO_PIN_LOW ?
322 GPIO_PIN_HIGH : GPIO_PIN_LOW);
323 gpiobus_pin_write(gc, pin, value);
324
325 op->gp_value = sc->sc_pins[pin].pin_state;
326
327 sc->sc_pins[pin].pin_state = value;
328 break;
329 case GPIOPINCTL:
330 if ((flag & FWRITE) == 0)
331 return (EBADF);
332
333 ctl = (struct gpio_pin_ctl *)data;
334
335 pin = ctl->gp_pin;
336 if (pin < 0 || pin >= sc->sc_npins)
337 return (EINVAL);
338 if (sc->sc_pins[pin].pin_mapped)
339 return (EBUSY);
340
341 flags = ctl->gp_flags;
342
343 if ((flags & sc->sc_pins[pin].pin_caps) != flags)
344 return (ENODEV);
345
346 ctl->gp_caps = sc->sc_pins[pin].pin_caps;
347
348 ctl->gp_flags = sc->sc_pins[pin].pin_flags;
349 if (flags > 0) {
350 gpiobus_pin_ctl(gc, pin, flags);
351
352 sc->sc_pins[pin].pin_flags = flags;
353 }
354 break;
355 default:
356 return (ENOTTY);
357 }
358
359 return (0);
360 }