Apologies if I missed something but to me it looks like this was neither commited nor declined.
This is about src/sys/dev/isa/soekris.c (nonexistent) and not src/sys/arch/amd64/amd64/bios.c Revision 1.23 Fake 'SMBIOS detection' for the Soekris boxes, by Matt Dainty References: http://marc.info/?l=openbsd-tech&m=136317575910043 http://marc.info/?l=openbsd-tech&m=137130692221862 Bye, Marcus [email protected] (Matt Dainty), 2013.03.13 (Wed) 12:55 (CET): > * Matt Dainty <[email protected]> [2013-01-14 11:13:59]: > > Attached is a patch that adds soekris(4) which provides access to the > > GPIO and LEDs as implemented by the onboard Xilinx FPGA on the Soekris > > net6501. The driver provides two GPIO buses; one for the 16 real GPIO > > pins exposed on the board, and another which has the LEDs coerced into > > the GPIO framework as output-only pins. > > > > I kept them separate to prevent confusion and make the code slightly > > simpler, if it's preferred to have just one GPIO bus let me know. > > > > It's enabled in the kernel config with: > > > > soekris0 at isa? port 0x680 > > gpio* at soekris? > > > > The driver cannot be enabled by default as there's no reliable way to > > detect the hardware, it's just a handful of I/O ports at a known > > address, (GPIO isn't enabled by default in GENERIC so a kernel compile > > is required regardless). > > > > This is what is shown at boot: > > > > soekris0 at isa0 port 0x680/32 > > gpio0 at soekris0: 16 pins > > gpio1 at soekris0: 2 pins > > > > I then have the following in /etc/rc.securelevel: > > > > gpioctl -q gpio1 0 set out error_led > > gpioctl -q gpio1 1 set out ready_led > > > > If this driver is acceptable I can send a further patch with man pages. > > Tested on a Soekris net6501 running amd64, LEDs work and I've put > > simple LED and pushbutton circuits on the GPIO pins. > > Here's an updated patch for the driver, the only change is in the > *_match() function that is now simplified and much more reliable thanks > to the committed Soekris comBIOS patch to bios(4). > > I've still left the GENERIC config unchanged as there's no other gpio(4) > drivers enabled, I'm guessing as general policy. > > I'll send a separate patch with the various man page changes. > > Matt > > --- /dev/null Wed Mar 13 10:27:40 2013 > +++ sys/dev/isa/soekris.c Tue Feb 19 08:31:10 2013 > @@ -0,0 +1,239 @@ > +/* $OpenBSD$ */ > + > +/* > + * Copyright (c) 2013 Matt Dainty <[email protected]> > + * > + * Permission to use, copy, modify, and distribute this software for any > + * purpose with or without fee is hereby granted, provided that the above > + * copyright notice and this permission notice appear in all copies. > + * > + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES > + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF > + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR > + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES > + * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER IN > + * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT > + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. > + */ > + > +/* > + * Soekris net6501 GPIO and LEDs as implemented by the onboard Xilinx FPGA > + */ > + > +#include <sys/param.h> > +#include <sys/systm.h> > +#include <sys/device.h> > +#include <sys/gpio.h> > + > +#include <machine/bus.h> > +#include <machine/intr.h> > + > +#include <dev/isa/isavar.h> > + > +#include <dev/gpio/gpiovar.h> > + > +#define SOEKRIS_BASE 0x680 /* Base address of FPGA I/O */ > +#define SOEKRIS_IOSIZE 32 /* I/O region size */ > + > +#define SOEKRIS_NPINS 16 /* Number of Pins */ > +#define SOEKRIS_GPIO_INPUT 0x000 /* Current state of pins */ > +#define SOEKRIS_GPIO_OUTPUT 0x004 /* Set state of output pins */ > +#define SOEKRIS_GPIO_RESET 0x008 /* Reset output pins */ > +#define SOEKRIS_GPIO_SET 0x00c /* Set output pins */ > +#define SOEKRIS_GPIO_DIR 0x010 /* Direction, set for output */ > + > +#define SOEKRIS_NLEDS 2 /* Number of LEDs */ > +#define SOEKRIS_LED_ERROR 0x01c /* Offset to error LED */ > +#define SOEKRIS_LED_READY 0x01d /* Offset to ready LED */ > + > +extern char *hw_vendor, *hw_prod; > + > +const u_int soekris_led_offset[SOEKRIS_NLEDS] = { > + SOEKRIS_LED_ERROR, SOEKRIS_LED_READY > +}; > + > +struct soekris_softc { > + struct device sc_dev; > + > + bus_space_tag_t sc_iot; > + bus_space_handle_t sc_ioh; > + > + struct gpio_chipset_tag sc_gpio_gc; > + gpio_pin_t sc_gpio_pins[SOEKRIS_NPINS]; > + > + /* Fake GPIO device for the LEDs */ > + struct gpio_chipset_tag sc_led_gc; > + gpio_pin_t sc_led_pins[SOEKRIS_NLEDS]; > +}; > + > +int soekris_match(struct device *, void *, void *); > +void soekris_attach(struct device *, struct device *, void *); > +int soekris_gpio_read(void *, int); > +void soekris_gpio_write(void *, int, int); > +void soekris_gpio_ctl(void *, int, int); > +int soekris_led_read(void *, int); > +void soekris_led_write(void *, int, int); > +void soekris_led_ctl(void *, int, int); > + > +struct cfattach soekris_ca = { > + sizeof(struct soekris_softc), soekris_match, soekris_attach > +}; > + > +struct cfdriver soekris_cd = { > + NULL, "soekris", DV_DULL > +}; > + > +int > +soekris_match(struct device *parent, void *match, void *aux) > +{ > + struct isa_attach_args *ia = aux; > + bus_space_handle_t ioh; > + > + if (strcmp(hw_vendor, "Soekris Engineering") || > + strcmp(hw_prod, "net6501")) > + return (0); > + > + if (ia->ia_iobase != SOEKRIS_BASE || bus_space_map(ia->ia_iot, > + ia->ia_iobase, SOEKRIS_IOSIZE, 0, &ioh) != 0) > + return (0); > + > + bus_space_unmap(ia->ia_iot, ioh, SOEKRIS_IOSIZE); > + ia->ia_iosize = SOEKRIS_IOSIZE; > + ia->ipa_nio = 1; > + ia->ipa_nmem = 0; > + ia->ipa_nirq = 0; > + ia->ipa_ndrq = 0; > + > + return (1); > +} > + > +void > +soekris_attach(struct device *parent, struct device *self, void *aux) > +{ > + struct soekris_softc *sc = (void *)self; > + struct isa_attach_args *ia = aux; > + struct gpiobus_attach_args gba1, gba2; > + u_int data; > + int i; > + > + if (bus_space_map(ia->ia_iot, ia->ia_iobase, ia->ia_iosize, 0, > + &sc->sc_ioh) != 0) { > + printf(": can't map i/o space\n"); > + return; > + } > + > + printf("\n"); > + > + sc->sc_iot = ia->ia_iot; > + > + data = bus_space_read_2(sc->sc_iot, sc->sc_ioh, SOEKRIS_GPIO_DIR); > + > + for (i = 0; i < SOEKRIS_NPINS; i++) { > + sc->sc_gpio_pins[i].pin_num = i; > + sc->sc_gpio_pins[i].pin_caps = GPIO_PIN_INPUT | > + GPIO_PIN_OUTPUT; > + sc->sc_gpio_pins[i].pin_flags = (data & (1 << i)) ? > + GPIO_PIN_OUTPUT : GPIO_PIN_INPUT; > + sc->sc_gpio_pins[i].pin_state = soekris_gpio_read(sc, i); > + } > + > + sc->sc_gpio_gc.gp_cookie = sc; > + sc->sc_gpio_gc.gp_pin_read = soekris_gpio_read; > + sc->sc_gpio_gc.gp_pin_write = soekris_gpio_write; > + sc->sc_gpio_gc.gp_pin_ctl = soekris_gpio_ctl; > + > + gba1.gba_name = "gpio"; > + gba1.gba_gc = &sc->sc_gpio_gc; > + gba1.gba_pins = sc->sc_gpio_pins; > + gba1.gba_npins = SOEKRIS_NPINS; > + > + (void)config_found(&sc->sc_dev, &gba1, gpiobus_print); > + > + for (i = 0; i < SOEKRIS_NLEDS; i++) { > + sc->sc_led_pins[i].pin_num = i; > + sc->sc_led_pins[i].pin_caps = GPIO_PIN_OUTPUT; > + sc->sc_led_pins[i].pin_flags = GPIO_PIN_OUTPUT; > + sc->sc_led_pins[i].pin_state = soekris_led_read(sc, i); > + } > + > + sc->sc_led_gc.gp_cookie = sc; > + sc->sc_led_gc.gp_pin_read = soekris_led_read; > + sc->sc_led_gc.gp_pin_write = soekris_led_write; > + sc->sc_led_gc.gp_pin_ctl = soekris_led_ctl; > + > + gba2.gba_name = "gpio"; > + gba2.gba_gc = &sc->sc_led_gc; > + gba2.gba_pins = sc->sc_led_pins; > + gba2.gba_npins = SOEKRIS_NLEDS; > + > + (void)config_found(&sc->sc_dev, &gba2, gpiobus_print); > +} > + > +int > +soekris_gpio_read(void *arg, int pin) > +{ > + struct soekris_softc *sc = arg; > + u_int16_t data; > + > + data = bus_space_read_2(sc->sc_iot, sc->sc_ioh, SOEKRIS_GPIO_INPUT); > + > + return (data & (1 << pin)) ? GPIO_PIN_HIGH : GPIO_PIN_LOW; > +} > + > +void > +soekris_gpio_write(void *arg, int pin, int value) > +{ > + struct soekris_softc *sc = arg; > + u_int16_t data; > + > + data = bus_space_read_2(sc->sc_iot, sc->sc_ioh, SOEKRIS_GPIO_INPUT); > + > + if (value == GPIO_PIN_LOW) > + data &= ~(1 << pin); > + else if (value == GPIO_PIN_HIGH) > + data |= (1 << pin); > + > + bus_space_write_2(sc->sc_iot, sc->sc_ioh, SOEKRIS_GPIO_OUTPUT, data); > +} > + > +void > +soekris_gpio_ctl(void *arg, int pin, int flags) > +{ > + struct soekris_softc *sc = arg; > + u_int16_t data; > + > + data = bus_space_read_2(sc->sc_iot, sc->sc_ioh, SOEKRIS_GPIO_DIR); > + > + if (flags & GPIO_PIN_INPUT) > + data &= ~(1 << pin); > + if (flags & GPIO_PIN_OUTPUT) > + data |= (1 << pin); > + > + bus_space_write_2(sc->sc_iot, sc->sc_ioh, SOEKRIS_GPIO_DIR, data); > +} > + > +int > +soekris_led_read(void *arg, int pin) > +{ > + struct soekris_softc *sc = arg; > + u_int8_t value; > + > + value = bus_space_read_1(sc->sc_iot, sc->sc_ioh, > + soekris_led_offset[pin]); > + > + return (value & 0x1) ? GPIO_PIN_HIGH : GPIO_PIN_LOW; > +} > + > +void > +soekris_led_write(void *arg, int pin, int value) > +{ > + struct soekris_softc *sc = arg; > + > + bus_space_write_1(sc->sc_iot, sc->sc_ioh, soekris_led_offset[pin], > + value); > +} > + > +void > +soekris_led_ctl(void *arg, int pin, int flags) > +{ > +} > --- sys/arch/amd64/conf/files.amd64.orig Tue Jan 8 15:13:27 2013 > +++ sys/arch/amd64/conf/files.amd64 Tue Jan 8 15:15:45 2013 > @@ -195,6 +195,11 @@ > attach fd at fdc > file dev/isa/fd.c fd needs-flag > > +# Soekris GPIO & LEDs driver > +device soekris: gpiobus > +attach soekris at isa > +file dev/isa/soekris.c soekris > + > pseudo-device pctr > file arch/amd64/amd64/pctr.c pctr needs-flag > > --- sys/arch/i386/conf/files.i386.orig Tue Jan 8 15:13:43 2013 > +++ sys/arch/i386/conf/files.i386 Tue Jan 8 15:17:10 2013 > @@ -227,6 +227,11 @@ > attach ahc at isa with ahc_isa > file arch/i386/isa/ahc_isa.c ahc_isa > > +# Soekris GPIO & LEDs driver > +device soekris: gpiobus > +attach soekris at isa > +file dev/isa/soekris.c soekris > + > # Pentium performance counters > pseudo-device pctr > file arch/i386/i386/pctr.c pctr needs-flag > > > !DSPAM:51406985175351234514069! >
