1 /* $NetBSD: gpio.c,v 1.29 2009/11/05 18:20:40 dyoung Exp $ */
2 /* $OpenBSD: gpio.c,v 1.6 2006/01/14 12:33:49 grange Exp $ */
5 * Copyright (c) 2008, 2009 Marc Balmer <marc@msys.ch>
6 * Copyright (c) 2004, 2006 Alexander Yurchenko <grange@openbsd.org>
8 * Permission to use, copy, modify, and distribute this software for any
9 * purpose with or without fee is hereby granted, provided that the above
10 * copyright notice and this permission notice appear in all copies.
12 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
13 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
14 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
15 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
16 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
17 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
18 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
21 #include <sys/cdefs.h>
22 __KERNEL_RCSID(0, "$NetBSD: gpio.c,v 1.29 2009/11/05 18:20:40 dyoung Exp $");
25 * General Purpose Input/Output framework.
28 #include <sys/param.h>
29 #include <sys/systm.h>
31 #include <sys/device.h>
32 #include <sys/fcntl.h>
33 #include <sys/ioctl.h>
35 #include <sys/vnode.h>
37 #include <sys/queue.h>
38 #include <sys/kauth.h>
40 #include <dev/gpio/gpiovar.h>
45 #define DPRINTFN(n, x) do { if (gpiodebug > (n)) printf x; } while (0)
48 #define DPRINTFN(n, x)
50 #define DPRINTF(x) DPRINTFN(0, x)
55 gpio_chipset_tag_t sc_gc
; /* GPIO controller */
56 gpio_pin_t
*sc_pins
; /* pins array */
57 int sc_npins
; /* number of pins */
60 LIST_HEAD(, gpio_dev
) sc_devs
; /* devices */
61 LIST_HEAD(, gpio_name
) sc_names
; /* named pins */
64 int gpio_match(device_t
, cfdata_t
, void *);
65 int gpio_submatch(device_t
, cfdata_t
, const int *, void *);
66 void gpio_attach(device_t
, device_t
, void *);
67 int gpio_rescan(device_t
, const char *, const int *);
68 void gpio_childdetached(device_t
, device_t
);
69 bool gpio_resume(device_t
, pmf_qual_t
);
70 int gpio_detach(device_t
, int);
71 int gpio_search(device_t
, cfdata_t
, const int *, void *);
72 int gpio_print(void *, const char *);
73 int gpio_pinbyname(struct gpio_softc
*, char *);
76 int gpio_ioctl_oapi(struct gpio_softc
*, u_long
, void *, int, kauth_cred_t
);
78 CFATTACH_DECL3_NEW(gpio
, sizeof(struct gpio_softc
),
79 gpio_match
, gpio_attach
, gpio_detach
, NULL
, gpio_rescan
,
80 gpio_childdetached
, DVF_DETACH_SHUTDOWN
);
82 dev_type_open(gpioopen
);
83 dev_type_close(gpioclose
);
84 dev_type_ioctl(gpioioctl
);
86 const struct cdevsw gpio_cdevsw
= {
87 gpioopen
, gpioclose
, noread
, nowrite
, gpioioctl
,
88 nostop
, notty
, nopoll
, nommap
, nokqfilter
, D_OTHER
,
91 extern struct cfdriver gpio_cd
;
94 gpio_match(device_t parent
, cfdata_t cf
, void *aux
)
100 gpio_submatch(device_t parent
, cfdata_t cf
, const int *ip
, void *aux
)
102 struct gpio_attach_args
*ga
= aux
;
104 if (ga
->ga_offset
== -1)
107 return strcmp(ga
->ga_dvname
, cf
->cf_name
) == 0;
111 gpio_resume(device_t self
, pmf_qual_t qual
)
113 struct gpio_softc
*sc
= device_private(self
);
116 for (pin
= 0; pin
< sc
->sc_npins
; pin
++) {
117 gpiobus_pin_ctl(sc
->sc_gc
, pin
, sc
->sc_pins
[pin
].pin_flags
);
118 gpiobus_pin_write(sc
->sc_gc
, pin
, sc
->sc_pins
[pin
].pin_state
);
124 gpio_childdetached(device_t self
, device_t child
)
126 /* gpio(4) keeps no references to its children, so do nothing. */
130 gpio_rescan(device_t self
, const char *ifattr
, const int *locators
)
132 struct gpio_softc
*sc
= device_private(self
);
134 config_search_loc(gpio_search
, self
, ifattr
, locators
, sc
);
140 gpio_attach(device_t parent
, device_t self
, void *aux
)
142 struct gpio_softc
*sc
= device_private(self
);
143 struct gpiobus_attach_args
*gba
= aux
;
146 sc
->sc_gc
= gba
->gba_gc
;
147 sc
->sc_pins
= gba
->gba_pins
;
148 sc
->sc_npins
= gba
->gba_npins
;
150 printf(": %d pins\n", sc
->sc_npins
);
152 if (!pmf_device_register(self
, NULL
, gpio_resume
))
153 aprint_error_dev(self
, "couldn't establish power handler\n");
156 * Attach all devices that can be connected to the GPIO pins
157 * described in the kernel configuration file.
159 gpio_rescan(self
, "gpio", NULL
);
163 gpio_detach(device_t self
, int flags
)
167 if ((rc
= config_detach_children(self
, flags
)) != 0)
173 /* Locate the major number */
174 for (maj
= 0; maj
< nchrdev
; maj
++)
175 if (cdevsw
[maj
].d_open
== gpioopen
)
178 /* Nuke the vnodes for any open instances (calls close) */
179 mn
= device_unit(self
);
180 vdevgone(maj
, mn
, mn
, VCHR
);
186 gpio_search(device_t parent
, cfdata_t cf
,
187 const int *ldesc
, void *aux
)
189 struct gpio_attach_args ga
;
192 ga
.ga_offset
= cf
->cf_loc
[GPIOCF_OFFSET
];
193 ga
.ga_mask
= cf
->cf_loc
[GPIOCF_MASK
];
195 if (config_match(parent
, cf
, &ga
) > 0)
196 config_attach(parent
, cf
, &ga
, gpio_print
);
202 gpio_print(void *aux
, const char *pnp
)
204 struct gpio_attach_args
*ga
= aux
;
208 for (i
= 0; i
< 32; i
++)
209 if (ga
->ga_mask
& (1 << i
))
210 printf(" %d", ga
->ga_offset
+ i
);
216 gpiobus_print(void *aux
, const char *pnp
)
219 struct gpiobus_attach_args
*gba
= aux
;
222 printf("gpiobus at %s", pnp
);
227 /* return 1 if all pins can be mapped, 0 if not */
230 gpio_pin_can_map(void *gpio
, int offset
, u_int32_t mask
)
232 struct gpio_softc
*sc
= gpio
;
235 npins
= gpio_npins(mask
);
236 if (npins
> sc
->sc_npins
)
239 for (npins
= 0, i
= 0; i
< 32; i
++)
240 if (mask
& (1 << i
)) {
242 if (pin
< 0 || pin
>= sc
->sc_npins
)
244 if (sc
->sc_pins
[pin
].pin_mapped
)
252 gpio_pin_map(void *gpio
, int offset
, u_int32_t mask
, struct gpio_pinmap
*map
)
254 struct gpio_softc
*sc
= gpio
;
257 npins
= gpio_npins(mask
);
258 if (npins
> sc
->sc_npins
)
261 for (npins
= 0, i
= 0; i
< 32; i
++)
262 if (mask
& (1 << i
)) {
264 if (pin
< 0 || pin
>= sc
->sc_npins
)
266 if (sc
->sc_pins
[pin
].pin_mapped
)
268 sc
->sc_pins
[pin
].pin_mapped
= 1;
269 map
->pm_map
[npins
++] = pin
;
271 map
->pm_size
= npins
;
277 gpio_pin_unmap(void *gpio
, struct gpio_pinmap
*map
)
279 struct gpio_softc
*sc
= gpio
;
282 for (i
= 0; i
< map
->pm_size
; i
++) {
283 pin
= map
->pm_map
[i
];
284 sc
->sc_pins
[pin
].pin_mapped
= 0;
289 gpio_pin_read(void *gpio
, struct gpio_pinmap
*map
, int pin
)
291 struct gpio_softc
*sc
= gpio
;
293 return gpiobus_pin_read(sc
->sc_gc
, map
->pm_map
[pin
]);
297 gpio_pin_write(void *gpio
, struct gpio_pinmap
*map
, int pin
, int value
)
299 struct gpio_softc
*sc
= gpio
;
301 gpiobus_pin_write(sc
->sc_gc
, map
->pm_map
[pin
], value
);
302 sc
->sc_pins
[map
->pm_map
[pin
]].pin_state
= value
;
306 gpio_pin_ctl(void *gpio
, struct gpio_pinmap
*map
, int pin
, int flags
)
308 struct gpio_softc
*sc
= gpio
;
310 return gpiobus_pin_ctl(sc
->sc_gc
, map
->pm_map
[pin
], flags
);
314 gpio_pin_caps(void *gpio
, struct gpio_pinmap
*map
, int pin
)
316 struct gpio_softc
*sc
= gpio
;
318 return sc
->sc_pins
[map
->pm_map
[pin
]].pin_caps
;
322 gpio_npins(u_int32_t mask
)
326 for (npins
= 0, i
= 0; i
< 32; i
++)
334 gpioopen(dev_t dev
, int flag
, int mode
, struct lwp
*l
)
336 struct gpio_softc
*sc
;
339 sc
= device_lookup_private(&gpio_cd
, minor(dev
));
342 DPRINTF(("%s: opening\n", device_xname(sc
->sc_dev
)));
344 DPRINTF(("%s: already opened\n", device_xname(sc
->sc_dev
)));
348 if ((ret
= gpiobus_open(sc
->sc_gc
, sc
->sc_dev
))) {
349 DPRINTF(("%s: gpiobus_open returned %d\n",
350 device_xname(sc
->sc_dev
),
361 gpioclose(dev_t dev
, int flag
, int mode
, struct lwp
*l
)
363 struct gpio_softc
*sc
;
365 sc
= device_lookup_private(&gpio_cd
, minor(dev
));
366 DPRINTF(("%s: closing\n", device_xname(sc
->sc_dev
)));
367 gpiobus_close(sc
->sc_gc
, sc
->sc_dev
);
374 gpio_pinbyname(struct gpio_softc
*sc
, char *gp_name
)
376 struct gpio_name
*nm
;
378 LIST_FOREACH(nm
, &sc
->sc_names
, gp_next
)
379 if (!strcmp(nm
->gp_name
, gp_name
))
385 gpioioctl(dev_t dev
, u_long cmd
, void *data
, int flag
, struct lwp
*l
)
387 struct gpio_softc
*sc
;
388 gpio_chipset_tag_t gc
;
389 struct gpio_info
*info
;
390 struct gpio_attach
*attach
;
391 struct gpio_attach_args ga
;
392 struct gpio_dev
*gdev
;
393 struct gpio_req
*req
;
394 struct gpio_name
*nm
;
395 struct gpio_set
*set
;
399 int locs
[GPIOCF_NLOCS
];
400 int pin
, value
, flags
, npins
;
402 sc
= device_lookup_private(&gpio_cd
, minor(dev
));
405 if (cmd
!= GPIOINFO
&& !device_is_active(sc
->sc_dev
)) {
406 DPRINTF(("%s: device is not active\n",
407 device_xname(sc
->sc_dev
)));
411 cred
= kauth_cred_get();
415 info
= (struct gpio_info
*)data
;
416 if (!kauth_authorize_device(cred
, KAUTH_DEVICE_GPIO_PINSET
,
417 NULL
, NULL
, NULL
, NULL
))
418 info
->gpio_npins
= sc
->sc_npins
;
420 for (pin
= npins
= 0; pin
< sc
->sc_npins
; pin
++)
421 if (sc
->sc_pins
[pin
].pin_flags
& GPIO_PIN_SET
)
423 info
->gpio_npins
= npins
;
427 req
= (struct gpio_req
*)data
;
429 if (req
->gp_name
[0] != '\0') {
430 pin
= gpio_pinbyname(sc
, req
->gp_name
);
436 if (pin
< 0 || pin
>= sc
->sc_npins
)
439 if (!(sc
->sc_pins
[pin
].pin_flags
& GPIO_PIN_SET
) &&
440 kauth_authorize_device(cred
, KAUTH_DEVICE_GPIO_PINSET
,
441 NULL
, NULL
, NULL
, NULL
))
444 /* return read value */
445 req
->gp_value
= gpiobus_pin_read(gc
, pin
);
448 if ((flag
& FWRITE
) == 0)
451 req
= (struct gpio_req
*)data
;
453 if (req
->gp_name
[0] != '\0') {
454 pin
= gpio_pinbyname(sc
, req
->gp_name
);
460 if (pin
< 0 || pin
>= sc
->sc_npins
)
463 if (sc
->sc_pins
[pin
].pin_mapped
)
466 if (!(sc
->sc_pins
[pin
].pin_flags
& GPIO_PIN_SET
) &&
467 kauth_authorize_device(cred
, KAUTH_DEVICE_GPIO_PINSET
,
468 NULL
, NULL
, NULL
, NULL
))
471 value
= req
->gp_value
;
472 if (value
!= GPIO_PIN_LOW
&& value
!= GPIO_PIN_HIGH
)
475 gpiobus_pin_write(gc
, pin
, value
);
476 /* return old value */
477 req
->gp_value
= sc
->sc_pins
[pin
].pin_state
;
478 /* update current value */
479 sc
->sc_pins
[pin
].pin_state
= value
;
482 if ((flag
& FWRITE
) == 0)
485 req
= (struct gpio_req
*)data
;
487 if (req
->gp_name
[0] != '\0') {
488 pin
= gpio_pinbyname(sc
, req
->gp_name
);
494 if (pin
< 0 || pin
>= sc
->sc_npins
)
497 if (sc
->sc_pins
[pin
].pin_mapped
)
500 if (!(sc
->sc_pins
[pin
].pin_flags
& GPIO_PIN_SET
) &&
501 kauth_authorize_device(cred
, KAUTH_DEVICE_GPIO_PINSET
,
502 NULL
, NULL
, NULL
, NULL
))
505 value
= (sc
->sc_pins
[pin
].pin_state
== GPIO_PIN_LOW
?
506 GPIO_PIN_HIGH
: GPIO_PIN_LOW
);
507 gpiobus_pin_write(gc
, pin
, value
);
508 /* return old value */
509 req
->gp_value
= sc
->sc_pins
[pin
].pin_state
;
510 /* update current value */
511 sc
->sc_pins
[pin
].pin_state
= value
;
514 if (kauth_authorize_device(cred
, KAUTH_DEVICE_GPIO_PINSET
,
515 NULL
, NULL
, NULL
, NULL
))
518 attach
= (struct gpio_attach
*)data
;
520 /* do not try to attach if the pins are already mapped */
521 if (!gpio_pin_can_map(sc
, attach
->ga_offset
, attach
->ga_mask
))
525 ga
.ga_dvname
= attach
->ga_dvname
;
526 ga
.ga_offset
= attach
->ga_offset
;
527 ga
.ga_mask
= attach
->ga_mask
;
528 DPRINTF(("%s: attach %s with offset %d and mask 0x%02x\n",
529 device_xname(sc
->sc_dev
), ga
.ga_dvname
, ga
.ga_offset
,
532 locs
[GPIOCF_OFFSET
] = ga
.ga_offset
;
533 locs
[GPIOCF_MASK
] = ga
.ga_mask
;
535 cf
= config_search_loc(NULL
, sc
->sc_dev
, "gpio", locs
, &ga
);
537 dv
= config_attach_loc(sc
->sc_dev
, cf
, locs
, &ga
,
540 gdev
= kmem_alloc(sizeof(struct gpio_dev
),
543 LIST_INSERT_HEAD(&sc
->sc_devs
, gdev
, sc_next
);
550 if (kauth_authorize_device(cred
, KAUTH_DEVICE_GPIO_PINSET
,
551 NULL
, NULL
, NULL
, NULL
))
554 attach
= (struct gpio_attach
*)data
;
555 LIST_FOREACH(gdev
, &sc
->sc_devs
, sc_next
) {
556 if (strcmp(device_xname(gdev
->sc_dev
),
557 attach
->ga_dvname
) == 0) {
558 if (config_detach(gdev
->sc_dev
, 0) == 0) {
559 LIST_REMOVE(gdev
, sc_next
);
561 sizeof(struct gpio_dev
));
570 if (kauth_authorize_device(cred
, KAUTH_DEVICE_GPIO_PINSET
,
571 NULL
, NULL
, NULL
, NULL
))
574 set
= (struct gpio_set
*)data
;
576 if (set
->gp_name
[0] != '\0') {
577 pin
= gpio_pinbyname(sc
, set
->gp_name
);
582 if (pin
< 0 || pin
>= sc
->sc_npins
)
584 flags
= set
->gp_flags
;
586 /* check that the controller supports all requested flags */
587 if ((flags
& sc
->sc_pins
[pin
].pin_caps
) != flags
)
589 flags
= set
->gp_flags
| GPIO_PIN_SET
;
591 set
->gp_caps
= sc
->sc_pins
[pin
].pin_caps
;
592 /* return old value */
593 set
->gp_flags
= sc
->sc_pins
[pin
].pin_flags
;
595 gpiobus_pin_ctl(gc
, pin
, flags
);
596 /* update current value */
597 sc
->sc_pins
[pin
].pin_flags
= flags
;
600 /* rename pin or new pin? */
601 if (set
->gp_name2
[0] != '\0') {
602 struct gpio_name
*gnm
;
605 LIST_FOREACH(nm
, &sc
->sc_names
, gp_next
) {
606 if (!strcmp(nm
->gp_name
, set
->gp_name2
) &&
608 return EINVAL
; /* duplicate name */
609 if (nm
->gp_pin
== pin
)
613 strlcpy(gnm
->gp_name
, set
->gp_name2
,
614 sizeof(gnm
->gp_name
));
616 nm
= kmem_alloc(sizeof(struct gpio_name
),
618 strlcpy(nm
->gp_name
, set
->gp_name2
,
619 sizeof(nm
->gp_name
));
620 nm
->gp_pin
= set
->gp_pin
;
621 LIST_INSERT_HEAD(&sc
->sc_names
, nm
, gp_next
);
626 if (kauth_authorize_device(cred
, KAUTH_DEVICE_GPIO_PINSET
,
627 NULL
, NULL
, NULL
, NULL
))
630 set
= (struct gpio_set
*)data
;
631 if (set
->gp_name
[0] != '\0') {
632 pin
= gpio_pinbyname(sc
, set
->gp_name
);
638 if (pin
< 0 || pin
>= sc
->sc_npins
)
640 if (sc
->sc_pins
[pin
].pin_mapped
)
642 if (!(sc
->sc_pins
[pin
].pin_flags
& GPIO_PIN_SET
))
645 LIST_FOREACH(nm
, &sc
->sc_names
, gp_next
) {
646 if (nm
->gp_pin
== pin
) {
647 LIST_REMOVE(nm
, gp_next
);
648 kmem_free(nm
, sizeof(struct gpio_name
));
652 sc
->sc_pins
[pin
].pin_flags
&= ~GPIO_PIN_SET
;
655 /* Try the old API */
656 DPRINTF(("%s: trying the old API\n", device_xname(sc
->sc_dev
)));
657 return gpio_ioctl_oapi(sc
, cmd
, data
, flag
, cred
);
663 gpio_ioctl_oapi(struct gpio_softc
*sc
, u_long cmd
, void *data
, int flag
,
666 gpio_chipset_tag_t gc
;
667 struct gpio_pin_op
*op
;
668 struct gpio_pin_ctl
*ctl
;
669 int pin
, value
, flags
;
675 op
= (struct gpio_pin_op
*)data
;
679 if (pin
< 0 || pin
>= sc
->sc_npins
)
682 if (!(sc
->sc_pins
[pin
].pin_flags
& GPIO_PIN_SET
) &&
683 kauth_authorize_device(cred
, KAUTH_DEVICE_GPIO_PINSET
,
684 NULL
, NULL
, NULL
, NULL
))
687 /* return read value */
688 op
->gp_value
= gpiobus_pin_read(gc
, pin
);
691 if ((flag
& FWRITE
) == 0)
694 op
= (struct gpio_pin_op
*)data
;
698 if (pin
< 0 || pin
>= sc
->sc_npins
)
701 if (sc
->sc_pins
[pin
].pin_mapped
)
704 if (!(sc
->sc_pins
[pin
].pin_flags
& GPIO_PIN_SET
) &&
705 kauth_authorize_device(cred
, KAUTH_DEVICE_GPIO_PINSET
,
706 NULL
, NULL
, NULL
, NULL
))
709 value
= op
->gp_value
;
710 if (value
!= GPIO_PIN_LOW
&& value
!= GPIO_PIN_HIGH
)
713 gpiobus_pin_write(gc
, pin
, value
);
714 /* return old value */
715 op
->gp_value
= sc
->sc_pins
[pin
].pin_state
;
716 /* update current value */
717 sc
->sc_pins
[pin
].pin_state
= value
;
720 if ((flag
& FWRITE
) == 0)
723 op
= (struct gpio_pin_op
*)data
;
727 if (pin
< 0 || pin
>= sc
->sc_npins
)
730 if (sc
->sc_pins
[pin
].pin_mapped
)
733 if (!(sc
->sc_pins
[pin
].pin_flags
& GPIO_PIN_SET
) &&
734 kauth_authorize_device(cred
, KAUTH_DEVICE_GPIO_PINSET
,
735 NULL
, NULL
, NULL
, NULL
))
738 value
= (sc
->sc_pins
[pin
].pin_state
== GPIO_PIN_LOW
?
739 GPIO_PIN_HIGH
: GPIO_PIN_LOW
);
740 gpiobus_pin_write(gc
, pin
, value
);
741 /* return old value */
742 op
->gp_value
= sc
->sc_pins
[pin
].pin_state
;
743 /* update current value */
744 sc
->sc_pins
[pin
].pin_state
= value
;
747 ctl
= (struct gpio_pin_ctl
*) data
;
749 if (kauth_authorize_device(cred
, KAUTH_DEVICE_GPIO_PINSET
,
750 NULL
, NULL
, NULL
, NULL
))
755 if (pin
< 0 || pin
>= sc
->sc_npins
)
757 if (sc
->sc_pins
[pin
].pin_mapped
)
759 flags
= ctl
->gp_flags
;
761 /* check that the controller supports all requested flags */
762 if ((flags
& sc
->sc_pins
[pin
].pin_caps
) != flags
)
765 ctl
->gp_caps
= sc
->sc_pins
[pin
].pin_caps
;
766 /* return old value */
767 ctl
->gp_flags
= sc
->sc_pins
[pin
].pin_flags
;
769 gpiobus_pin_ctl(gc
, pin
, flags
);
770 /* update current value */
771 sc
->sc_pins
[pin
].pin_flags
= flags
;