xref: /openbsd/sys/dev/gpio/gpio.c (revision 264ca280)
1 /*	$OpenBSD: gpio.c,v 1.14 2015/08/27 05:48:40 deraadt Exp $	*/
2 
3 /*
4  * Copyright (c) 2008 Marc Balmer <mbalmer@openbsd.org>
5  * Copyright (c) 2004, 2006 Alexander Yurchenko <grange@openbsd.org>
6  *
7  * Permission to use, copy, modify, and distribute this software for any
8  * purpose with or without fee is hereby granted, provided that the above
9  * copyright notice and this permission notice appear in all copies.
10  *
11  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
12  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
13  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
14  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
15  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
16  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
17  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
18  */
19 
20 /*
21  * General Purpose Input/Output framework.
22  */
23 
24 #include <sys/param.h>
25 #include <sys/systm.h>
26 #include <sys/conf.h>
27 #include <sys/device.h>
28 #include <sys/fcntl.h>
29 #include <sys/ioctl.h>
30 #include <sys/gpio.h>
31 #include <sys/vnode.h>
32 #include <sys/malloc.h>
33 #include <sys/queue.h>
34 
35 #include <dev/gpio/gpiovar.h>
36 
37 struct gpio_softc {
38 	struct device sc_dev;
39 
40 	gpio_chipset_tag_t		 sc_gc;		/* GPIO controller */
41 	gpio_pin_t			*sc_pins;	/* pins array */
42 	int				 sc_npins;	/* number of pins */
43 
44 	int sc_opened;
45 	LIST_HEAD(, gpio_dev)		 sc_devs;	/* devices */
46 	LIST_HEAD(, gpio_name) 	 	 sc_names;	/* named pins */
47 };
48 
49 int	gpio_match(struct device *, void *, void *);
50 int	gpio_submatch(struct device *, void *, void *);
51 void	gpio_attach(struct device *, struct device *, void *);
52 int	gpio_detach(struct device *, int);
53 int	gpio_search(struct device *, void *, void *);
54 int	gpio_print(void *, const char *);
55 int	gpio_pinbyname(struct gpio_softc *, char *gp_name);
56 
57 struct cfattach gpio_ca = {
58 	sizeof (struct gpio_softc),
59 	gpio_match,
60 	gpio_attach,
61 	gpio_detach
62 };
63 
64 struct cfdriver gpio_cd = {
65 	NULL, "gpio", DV_DULL
66 };
67 
68 int
69 gpio_match(struct device *parent, void *match, void *aux)
70 {
71 	struct cfdata *cf = match;
72 	struct gpiobus_attach_args *gba = aux;
73 
74 	return (strcmp(gba->gba_name, cf->cf_driver->cd_name) == 0);
75 }
76 
77 int
78 gpio_submatch(struct device *parent, void *match, void *aux)
79 {
80 	struct cfdata *cf = match;
81 	struct gpio_attach_args *ga = aux;
82 
83 	if (strcmp(ga->ga_dvname, cf->cf_driver->cd_name) != 0)
84 		return (0);
85 
86 	return ((*cf->cf_attach->ca_match)(parent, match, aux));
87 }
88 
89 void
90 gpio_attach(struct device *parent, struct device *self, void *aux)
91 {
92 	struct gpio_softc *sc = (struct gpio_softc *)self;
93 	struct gpiobus_attach_args *gba = aux;
94 
95 	sc->sc_gc = gba->gba_gc;
96 	sc->sc_pins = gba->gba_pins;
97 	sc->sc_npins = gba->gba_npins;
98 
99 	printf(": %d pins\n", sc->sc_npins);
100 
101 	/*
102 	 * Attach all devices that can be connected to the GPIO pins
103 	 * described in the kernel configuration file.
104 	 */
105 	config_search(gpio_search, self, sc);
106 }
107 
108 int
109 gpio_detach(struct device *self, int flags)
110 {
111 	int maj, mn;
112 
113 	/* Locate the major number */
114 	for (maj = 0; maj < nchrdev; maj++)
115 		if (cdevsw[maj].d_open == gpioopen)
116 			break;
117 
118 	/* Nuke the vnodes for any open instances (calls close) */
119 	mn = self->dv_unit;
120 	vdevgone(maj, mn, mn, VCHR);
121 
122 	return (0);
123 }
124 
125 int
126 gpio_search(struct device *parent, void *arg, void *aux)
127 {
128 	struct cfdata *cf = arg;
129 	struct gpio_attach_args ga;
130 
131 	ga.ga_gpio = aux;
132 	ga.ga_offset = cf->cf_loc[0];
133 	ga.ga_mask = cf->cf_loc[1];
134 	ga.ga_flags = cf->cf_loc[2];
135 
136 	if (cf->cf_attach->ca_match(parent, cf, &ga) > 0)
137 		config_attach(parent, cf, &ga, gpio_print);
138 
139 	return (0);
140 }
141 
142 int
143 gpio_print(void *aux, const char *pnp)
144 {
145 	struct gpio_attach_args *ga = aux;
146 	int i;
147 
148 	printf(" pins");
149 	for (i = 0; i < 32; i++)
150 		if (ga->ga_mask & (1 << i))
151 			printf(" %d", ga->ga_offset + i);
152 
153 	return (UNCONF);
154 }
155 
156 int
157 gpiobus_print(void *aux, const char *pnp)
158 {
159 	struct gpiobus_attach_args *gba = aux;
160 
161 	if (pnp != NULL)
162 		printf("%s at %s", gba->gba_name, pnp);
163 
164 	return (UNCONF);
165 }
166 
167 int
168 gpio_pin_map(void *gpio, int offset, u_int32_t mask, struct gpio_pinmap *map)
169 {
170 	struct gpio_softc *sc = gpio;
171 	int npins, pin, i;
172 
173 	npins = gpio_npins(mask);
174 	if (npins > sc->sc_npins)
175 		return (1);
176 
177 	for (npins = 0, i = 0; i < 32; i++)
178 		if (mask & (1 << i)) {
179 			pin = offset + i;
180 			if (pin < 0 || pin >= sc->sc_npins)
181 				return (1);
182 			if (sc->sc_pins[pin].pin_mapped)
183 				return (1);
184 			sc->sc_pins[pin].pin_mapped = 1;
185 			map->pm_map[npins++] = pin;
186 		}
187 	map->pm_size = npins;
188 
189 	return (0);
190 }
191 
192 void
193 gpio_pin_unmap(void *gpio, struct gpio_pinmap *map)
194 {
195 	struct gpio_softc *sc = gpio;
196 	int pin, i;
197 
198 	for (i = 0; i < map->pm_size; i++) {
199 		pin = map->pm_map[i];
200 		sc->sc_pins[pin].pin_mapped = 0;
201 	}
202 }
203 
204 int
205 gpio_pin_read(void *gpio, struct gpio_pinmap *map, int pin)
206 {
207 	struct gpio_softc *sc = gpio;
208 
209 	return (gpiobus_pin_read(sc->sc_gc, map->pm_map[pin]));
210 }
211 
212 void
213 gpio_pin_write(void *gpio, struct gpio_pinmap *map, int pin, int value)
214 {
215 	struct gpio_softc *sc = gpio;
216 
217 	return (gpiobus_pin_write(sc->sc_gc, map->pm_map[pin], value));
218 }
219 
220 void
221 gpio_pin_ctl(void *gpio, struct gpio_pinmap *map, int pin, int flags)
222 {
223 	struct gpio_softc *sc = gpio;
224 
225 	return (gpiobus_pin_ctl(sc->sc_gc, map->pm_map[pin], flags));
226 }
227 
228 int
229 gpio_pin_caps(void *gpio, struct gpio_pinmap *map, int pin)
230 {
231 	struct gpio_softc *sc = gpio;
232 
233 	return (sc->sc_pins[map->pm_map[pin]].pin_caps);
234 }
235 
236 int
237 gpio_npins(u_int32_t mask)
238 {
239 	int npins, i;
240 
241 	for (npins = 0, i = 0; i < 32; i++)
242 		if (mask & (1 << i))
243 			npins++;
244 
245 	return (npins);
246 }
247 
248 int
249 gpioopen(dev_t dev, int flag, int mode, struct proc *p)
250 {
251 	struct gpio_softc *sc;
252 
253 	sc = (struct gpio_softc *)device_lookup(&gpio_cd, minor(dev));
254 	if (sc == NULL)
255 		return (ENXIO);
256 
257 	if (sc->sc_opened)
258 		return (EBUSY);
259 	sc->sc_opened = 1;
260 
261 	return (0);
262 }
263 
264 int
265 gpioclose(dev_t dev, int flag, int mode, struct proc *p)
266 {
267 	struct gpio_softc *sc;
268 
269 	sc = (struct gpio_softc *)device_lookup(&gpio_cd, minor(dev));
270 	sc->sc_opened = 0;
271 
272 	return (0);
273 }
274 
275 int
276 gpio_pinbyname(struct gpio_softc *sc, char *gp_name)
277 {
278 	struct gpio_name *nm;
279 
280 	LIST_FOREACH(nm, &sc->sc_names, gp_next)
281 		if (!strcmp(nm->gp_name, gp_name))
282 			return (nm->gp_pin);
283 	return (-1);
284 }
285 
286 int
287 gpioioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p)
288 {
289 	struct gpio_softc *sc;
290 	gpio_chipset_tag_t gc;
291 	struct gpio_info *info;
292 	struct gpio_pin_op *op;
293 	struct gpio_attach *attach;
294 	struct gpio_attach_args ga;
295 	struct gpio_dev *gdev;
296 	struct gpio_name *nm;
297 	struct gpio_pin_set *set;
298 	struct device *dv;
299 	int pin, value, flags, npins, found;
300 
301 	sc = (struct gpio_softc *)device_lookup(&gpio_cd, minor(dev));
302 	gc = sc->sc_gc;
303 
304 	switch (cmd) {
305 	case GPIOINFO:
306 		info = (struct gpio_info *)data;
307 		if (securelevel < 1)
308 			info->gpio_npins = sc->sc_npins;
309 		else {
310 			for (pin = npins = 0; pin < sc->sc_npins; pin++)
311 				if (sc->sc_pins[pin].pin_flags & GPIO_PIN_SET)
312 					++npins;
313 			info->gpio_npins = npins;
314 		}
315 		break;
316 	case GPIOPINREAD:
317 		op = (struct gpio_pin_op *)data;
318 
319 		if (op->gp_name[0] != '\0') {
320 			pin = gpio_pinbyname(sc, op->gp_name);
321 			if (pin == -1)
322 				return (EINVAL);
323 		} else
324 			pin = op->gp_pin;
325 
326 		if (pin < 0 || pin >= sc->sc_npins)
327 			return (EINVAL);
328 
329 		if (!(sc->sc_pins[pin].pin_flags & GPIO_PIN_SET) &&
330 		    securelevel > 0)
331 			return (EPERM);
332 
333 		/* return read value */
334 		op->gp_value = gpiobus_pin_read(gc, pin);
335 		break;
336 	case GPIOPINWRITE:
337 		if ((flag & FWRITE) == 0)
338 			return (EBADF);
339 
340 		op = (struct gpio_pin_op *)data;
341 
342 		if (op->gp_name[0] != '\0') {
343 			pin = gpio_pinbyname(sc, op->gp_name);
344 			if (pin == -1)
345 				return (EINVAL);
346 		} else
347 			pin = op->gp_pin;
348 
349 		if (pin < 0 || pin >= sc->sc_npins)
350 			return (EINVAL);
351 
352 		if (sc->sc_pins[pin].pin_mapped)
353 			return (EBUSY);
354 
355 		if (!(sc->sc_pins[pin].pin_flags & GPIO_PIN_SET) &&
356 		    securelevel > 0)
357 			return (EPERM);
358 
359 		value = op->gp_value;
360 		if (value != GPIO_PIN_LOW && value != GPIO_PIN_HIGH)
361 			return (EINVAL);
362 
363 		gpiobus_pin_write(gc, pin, value);
364 		/* return old value */
365 		op->gp_value = sc->sc_pins[pin].pin_state;
366 		/* update current value */
367 		sc->sc_pins[pin].pin_state = value;
368 		break;
369 	case GPIOPINTOGGLE:
370 		if ((flag & FWRITE) == 0)
371 			return (EBADF);
372 
373 		op = (struct gpio_pin_op *)data;
374 
375 		if (op->gp_name[0] != '\0') {
376 			pin = gpio_pinbyname(sc, op->gp_name);
377 			if (pin == -1)
378 				return (EINVAL);
379 		} else
380 			pin = op->gp_pin;
381 
382 		if (pin < 0 || pin >= sc->sc_npins)
383 			return (EINVAL);
384 
385 		if (sc->sc_pins[pin].pin_mapped)
386 			return (EBUSY);
387 
388 		if (!(sc->sc_pins[pin].pin_flags & GPIO_PIN_SET) &&
389 		    securelevel > 0)
390 			return (EPERM);
391 
392 		value = (sc->sc_pins[pin].pin_state == GPIO_PIN_LOW ?
393 		    GPIO_PIN_HIGH : GPIO_PIN_LOW);
394 		gpiobus_pin_write(gc, pin, value);
395 		/* return old value */
396 		op->gp_value = sc->sc_pins[pin].pin_state;
397 		/* update current value */
398 		sc->sc_pins[pin].pin_state = value;
399 		break;
400 	case GPIOATTACH:
401 		if (securelevel > 0)
402 			return (EPERM);
403 
404 		attach = (struct gpio_attach *)data;
405 		bzero(&ga, sizeof(ga));
406 		ga.ga_gpio = sc;
407 		ga.ga_dvname = attach->ga_dvname;
408 		ga.ga_offset = attach->ga_offset;
409 		ga.ga_mask = attach->ga_mask;
410 		ga.ga_flags = attach->ga_flags;
411 		dv = config_found_sm((struct device *)sc, &ga, gpiobus_print,
412 		    gpio_submatch);
413 		if (dv != NULL) {
414 			gdev = malloc(sizeof(*gdev), M_DEVBUF,
415 			    M_WAITOK);
416 			gdev->sc_dev = dv;
417 			LIST_INSERT_HEAD(&sc->sc_devs, gdev, sc_next);
418 		}
419 		break;
420 	case GPIODETACH:
421 		if (securelevel > 0)
422 			return (EPERM);
423 
424 		attach = (struct gpio_attach *)data;
425 		LIST_FOREACH(gdev, &sc->sc_devs, sc_next) {
426 			if (strcmp(gdev->sc_dev->dv_xname, attach->ga_dvname)
427 			    == 0) {
428 				if (config_detach(gdev->sc_dev, 0) == 0) {
429 					LIST_REMOVE(gdev, sc_next);
430 					free(gdev, M_DEVBUF, sizeof(*gdev));
431 				}
432 				break;
433 			}
434 		}
435 		break;
436 	case GPIOPINSET:
437 		if (securelevel > 0)
438 			return (EPERM);
439 
440 		set = (struct gpio_pin_set *)data;
441 
442 		if (set->gp_name[0] != '\0') {
443 			pin = gpio_pinbyname(sc, set->gp_name);
444 			if (pin == -1)
445 				return (EINVAL);
446 		} else
447 			pin = set->gp_pin;
448 		if (pin < 0 || pin >= sc->sc_npins)
449 			return (EINVAL);
450 		flags = set->gp_flags;
451 		/* check that the controller supports all requested flags */
452 		if ((flags & sc->sc_pins[pin].pin_caps) != flags)
453 			return (ENODEV);
454 		flags = set->gp_flags | GPIO_PIN_SET;
455 
456 		set->gp_caps = sc->sc_pins[pin].pin_caps;
457 		/* return old value */
458 		set->gp_flags = sc->sc_pins[pin].pin_flags;
459 		if (flags > 0) {
460 			gpiobus_pin_ctl(gc, pin, flags);
461 			/* update current value */
462 			sc->sc_pins[pin].pin_flags = flags;
463 		}
464 
465 		/* rename pin or new pin? */
466 		if (set->gp_name2[0] != '\0') {
467 			found = 0;
468 			LIST_FOREACH(nm, &sc->sc_names, gp_next)
469 				if (nm->gp_pin == pin) {
470 					strlcpy(nm->gp_name, set->gp_name2,
471 					    sizeof(nm->gp_name));
472 					found = 1;
473 					break;
474 				}
475 			if (!found) {
476 				nm = malloc(sizeof(*nm), M_DEVBUF, M_WAITOK);
477 				strlcpy(nm->gp_name, set->gp_name2,
478 				    sizeof(nm->gp_name));
479 				nm->gp_pin = set->gp_pin;
480 				LIST_INSERT_HEAD(&sc->sc_names, nm, gp_next);
481 			}
482 		}
483 		break;
484 	case GPIOPINUNSET:
485 		if (securelevel > 0)
486 			return (EPERM);
487 
488 		set = (struct gpio_pin_set *)data;
489 		if (set->gp_name[0] != '\0') {
490 			pin = gpio_pinbyname(sc, set->gp_name);
491 			if (pin == -1)
492 				return (EINVAL);
493 		} else
494 			pin = set->gp_pin;
495 
496 		if (pin < 0 || pin >= sc->sc_npins)
497 			return (EINVAL);
498 		if (sc->sc_pins[pin].pin_mapped)
499 			return (EBUSY);
500 		if (!(sc->sc_pins[pin].pin_flags & GPIO_PIN_SET))
501 			return (EINVAL);
502 
503 		LIST_FOREACH(nm, &sc->sc_names, gp_next) {
504 			if (nm->gp_pin == pin) {
505 				LIST_REMOVE(nm, gp_next);
506 				free(nm, M_DEVBUF, sizeof(*nm));
507 				break;
508 			}
509 		}
510 		sc->sc_pins[pin].pin_flags &= ~GPIO_PIN_SET;
511 		break;
512 	default:
513 		return (ENOTTY);
514 	}
515 
516 	return (0);
517 }
518