Re: Raspberry Pi GPIO

2020-04-27 Thread Mark Kettenis
> Date: Mon, 27 Apr 2020 12:33:24 +0100
> From: Stuart Henderson 
> 
> On 2020/04/26 12:56, Mark Kettenis wrote:
> > Diff below adds GPIO support to bcmgpio(4).  It also adds the bits to
> > attach gpio(4) such that GPIO pins can be controlled from userland.
> > This makes sense on boards like the Raspberry Pi and the
> > implementation makes sure that pins used by kernel drivers can't be
> > touched.
> > 
> > ok?
> 
> Only tested with inputs so far, but works for me. OK sthen@
> 

If you put:

  /usr/sbin/gpioctl gpio0 42 set out led0

in /etc/rc.securelevel you can turn on the green LED with:

  gpioctl gpio0 led0 on

Cheers,

Mark



Re: Raspberry Pi GPIO

2020-04-27 Thread Stuart Henderson
On 2020/04/26 12:56, Mark Kettenis wrote:
> Diff below adds GPIO support to bcmgpio(4).  It also adds the bits to
> attach gpio(4) such that GPIO pins can be controlled from userland.
> This makes sense on boards like the Raspberry Pi and the
> implementation makes sure that pins used by kernel drivers can't be
> touched.
> 
> ok?

Only tested with inputs so far, but works for me. OK sthen@



Raspberry Pi GPIO

2020-04-26 Thread Mark Kettenis
Diff below adds GPIO support to bcmgpio(4).  It also adds the bits to
attach gpio(4) such that GPIO pins can be controlled from userland.
This makes sense on boards like the Raspberry Pi and the
implementation makes sure that pins used by kernel drivers can't be
touched.

ok?


Index: arch/arm64/conf/GENERIC
===
RCS file: /cvs/src/sys/arch/arm64/conf/GENERIC,v
retrieving revision 1.161
diff -u -p -r1.161 GENERIC
--- arch/arm64/conf/GENERIC 25 Apr 2020 22:28:12 -  1.161
+++ arch/arm64/conf/GENERIC 26 Apr 2020 10:51:19 -
@@ -148,6 +148,7 @@ bcmclock*   at fdt? early 1
 bcmdmac*   at fdt? early 1
 bcmdog*at fdt?
 bcmgpio*   at fdt? early 1
+gpio*  at bcmgpio?
 bcmintc*   at fdt? early 1
 bcmirng*   at fdt?
 bcmmbox*   at fdt? early 1
Index: dev/fdt/bcm2835_gpio.c
===
RCS file: /cvs/src/sys/dev/fdt/bcm2835_gpio.c,v
retrieving revision 1.2
diff -u -p -r1.2 bcm2835_gpio.c
--- dev/fdt/bcm2835_gpio.c  25 Apr 2020 22:15:00 -  1.2
+++ dev/fdt/bcm2835_gpio.c  26 Apr 2020 10:51:20 -
@@ -17,16 +17,21 @@
 
 #include 
 #include 
+#include 
 #include 
 #include 
 
 #include 
 #include 
 
+#include 
 #include 
+#include 
 #include 
 #include 
 
+#include "gpio.h"
+
 /* Registers */
 #define GPFSEL(n)  (0x00 + ((n) * 4))
 #define  GPFSEL_MASK   0x7
@@ -38,6 +43,9 @@
 #define  GPFSEL_ALT3   0x7
 #define  GPFSEL_ALT4   0x3
 #define  GPFSEL_ALT5   0x2
+#define GPSET(n)   (0x1c + ((n) * 4))
+#define GPCLR(n)   (0x28 + ((n) * 4))
+#define GPLEV(n)   (0x34 + ((n) * 4))
 #define GPPUD  0x94
 #define  GPPUD_PUD 0x3
 #define  GPPUD_PUD_OFF 0x0
@@ -47,6 +55,8 @@
 #define GPPULL(n)  (0xe4 + ((n) * 4))
 #define  GPPULL_MASK   0x3
 
+#define BCMGPIO_MAX_PINS   58
+
 #define HREAD4(sc, reg)
\
(bus_space_read_4((sc)->sc_iot, (sc)->sc_ioh, (reg)))
 #define HWRITE4(sc, reg, val)  \
@@ -58,6 +68,13 @@ struct bcmgpio_softc {
bus_space_handle_t  sc_ioh;
 
void(*sc_config_pull)(struct bcmgpio_softc *, int, int);
+   int sc_num_pins;
+
+   struct gpio_controller  sc_gc;
+
+   struct gpio_chipset_tag sc_gpio_tag;
+   gpio_pin_t  sc_gpio_pins[BCMGPIO_MAX_PINS];
+   int sc_gpio_claimed[BCMGPIO_MAX_PINS];
 };
 
 intbcmgpio_match(struct device *, void *, void *);
@@ -74,6 +91,10 @@ struct cfdriver bcmgpio_cd = {
 void   bcm2711_config_pull(struct bcmgpio_softc *, int, int);
 void   bcm2835_config_pull(struct bcmgpio_softc *, int, int);
 intbcmgpio_pinctrl(uint32_t, void *);
+void   bcmgpio_config_pin(void *, uint32_t *, int);
+intbcmgpio_get_pin(void *, uint32_t *);
+void   bcmgpio_set_pin(void *, uint32_t *, int);
+void   bcmgpio_attach_gpio(struct device *);
 
 int
 bcmgpio_match(struct device *parent, void *match, void *aux)
@@ -104,12 +125,24 @@ bcmgpio_attach(struct device *parent, st
 
printf("\n");
 
-   if (OF_is_compatible(faa->fa_node, "brcm,bcm2711-gpio"))
+   if (OF_is_compatible(faa->fa_node, "brcm,bcm2711-gpio")) {
sc->sc_config_pull = bcm2711_config_pull;
-   else
+   sc->sc_num_pins = 58;
+   } else {
sc->sc_config_pull = bcm2835_config_pull;
+   sc->sc_num_pins = 54;
+   }
 
pinctrl_register(faa->fa_node, bcmgpio_pinctrl, sc);
+
+   sc->sc_gc.gc_node = faa->fa_node;
+   sc->sc_gc.gc_cookie = sc;
+   sc->sc_gc.gc_config_pin = bcmgpio_config_pin;
+   sc->sc_gc.gc_get_pin = bcmgpio_get_pin;
+   sc->sc_gc.gc_set_pin = bcmgpio_set_pin;
+   gpio_controller_register(>sc_gc);
+
+   config_mountroot(self, bcmgpio_attach_gpio);
 }
 
 void
@@ -186,6 +219,7 @@ bcmgpio_pinctrl(uint32_t phandle, void *
bcmgpio_config_func(sc, pins[i], func);
if (plen > 0 && i < plen / sizeof(uint32_t))
sc->sc_config_pull(sc, pins[i], pull[i]);
+   sc->sc_gpio_claimed[pins[i]] = 1;
}
 
free(pull, M_TEMP, plen);
@@ -196,4 +230,176 @@ fail:
free(pull, M_TEMP, plen);
free(pins, M_TEMP, len);
return -1;
+}
+
+void
+bcmgpio_config_pin(void *cookie, uint32_t *cells, int config)
+{
+   struct bcmgpio_softc *sc = cookie;
+   uint32_t pin = cells[0];
+
+   if (pin >= sc->sc_num_pins)
+   return;
+
+   if (config & GPIO_CONFIG_OUTPUT)
+   bcmgpio_config_func(sc, pin, GPFSEL_GPIO_OUT);
+   else
+   bcmgpio_config_func(sc, pin, GPFSEL_GPIO_OUT);
+   if (config & GPIO_CONFIG_PULL_UP)
+   sc->sc_config_pull(sc, pin, GPPUD_PUD_UP);
+   else if