LCOV - code coverage report
Current view: top level - dev/isa - skgpio.c (source / functions) Hit Total Coverage
Test: 6.4 Lines: 0 90 0.0 %
Date: 2018-10-19 03:25:38 Functions: 0 8 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*      $OpenBSD: skgpio.c,v 1.3 2015/03/14 03:38:47 jsg Exp $ */
       2             : 
       3             : /*
       4             :  * Copyright (c) 2014 Matt Dainty <matt@bodgit-n-scarper.com>
       5             :  *
       6             :  * Permission to use, copy, modify, and distribute this software for any
       7             :  * purpose with or without fee is hereby granted, provided that the above
       8             :  * copyright notice and this permission notice appear in all copies.
       9             :  *
      10             :  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
      11             :  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
      12             :  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
      13             :  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
      14             :  * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER IN
      15             :  * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
      16             :  * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
      17             :  */
      18             : 
      19             : /*
      20             :  * Soekris net6501 GPIO and LEDs as implemented by the onboard Xilinx FPGA 
      21             :  */
      22             : 
      23             : #include <sys/param.h>
      24             : #include <sys/systm.h>
      25             : #include <sys/device.h>
      26             : #include <sys/gpio.h>
      27             : 
      28             : #include <machine/bus.h>
      29             : 
      30             : #include <dev/isa/isavar.h>
      31             : 
      32             : #include <dev/gpio/gpiovar.h>
      33             : 
      34             : #define SKGPIO_BASE             0x680   /* Base address of FPGA I/O */
      35             : #define SKGPIO_IOSIZE           32      /* I/O region size */
      36             : 
      37             : #define SKGPIO_NPINS            16      /* Number of Pins */
      38             : #define SKGPIO_GPIO_INPUT       0x000   /* Current state of pins */
      39             : #define SKGPIO_GPIO_OUTPUT      0x004   /* Set state of output pins */
      40             : #define SKGPIO_GPIO_RESET       0x008   /* Reset output pins */
      41             : #define SKGPIO_GPIO_SET         0x00c   /* Set output pins */
      42             : #define SKGPIO_GPIO_DIR         0x010   /* Direction, set for output */
      43             : 
      44             : #define SKGPIO_NLEDS            2       /* Number of LEDs */
      45             : #define SKGPIO_LED_ERROR        0x01c   /* Offset to error LED */
      46             : #define SKGPIO_LED_READY        0x01d   /* Offset to ready LED */
      47             : 
      48             : extern char *hw_vendor, *hw_prod;
      49             : 
      50             : const u_int skgpio_led_offset[SKGPIO_NLEDS] = {
      51             :         SKGPIO_LED_ERROR, SKGPIO_LED_READY
      52             : };
      53             : 
      54             : struct skgpio_softc {
      55             :         struct device            sc_dev;
      56             : 
      57             :         bus_space_tag_t          sc_iot;
      58             :         bus_space_handle_t       sc_ioh;
      59             : 
      60             :         struct gpio_chipset_tag  sc_gpio_gc;
      61             :         gpio_pin_t               sc_gpio_pins[SKGPIO_NPINS];
      62             : 
      63             :         /* Fake GPIO device for the LEDs */
      64             :         struct gpio_chipset_tag  sc_led_gc;
      65             :         gpio_pin_t               sc_led_pins[SKGPIO_NLEDS];
      66             : };
      67             : 
      68             : int      skgpio_match(struct device *, void *, void *);
      69             : void     skgpio_attach(struct device *, struct device *, void *);
      70             : int      skgpio_gpio_read(void *, int);
      71             : void     skgpio_gpio_write(void *, int, int);
      72             : void     skgpio_gpio_ctl(void *, int, int);
      73             : int      skgpio_led_read(void *, int);
      74             : void     skgpio_led_write(void *, int, int);
      75             : void     skgpio_led_ctl(void *, int, int);
      76             : 
      77             : struct cfattach skgpio_ca = {
      78             :         sizeof(struct skgpio_softc), skgpio_match, skgpio_attach
      79             : };
      80             : 
      81             : struct cfdriver skgpio_cd = {
      82             :         NULL, "skgpio", DV_DULL
      83             : };
      84             : 
      85             : int
      86           0 : skgpio_match(struct device *parent, void *match, void *aux)
      87             : {
      88           0 :         struct isa_attach_args *ia = aux;
      89           0 :         bus_space_handle_t ioh;
      90             : 
      91           0 :         if (hw_vendor == NULL || hw_prod == NULL ||
      92           0 :             strcmp(hw_vendor, "Soekris Engineering") != 0 ||
      93           0 :             strcmp(hw_prod, "net6501") != 0)
      94           0 :                 return (0);
      95             : 
      96           0 :         if (ia->ia_iobase != SKGPIO_BASE || bus_space_map(ia->ia_iot,
      97           0 :             ia->ia_iobase, SKGPIO_IOSIZE, 0, &ioh) != 0)
      98           0 :                 return (0);
      99             : 
     100           0 :         bus_space_unmap(ia->ia_iot, ioh, SKGPIO_IOSIZE);
     101           0 :         ia->ia_iosize = SKGPIO_IOSIZE;
     102           0 :         ia->ipa_nio = 1;
     103           0 :         ia->ipa_nmem = 0;
     104           0 :         ia->ipa_nirq = 0;
     105           0 :         ia->ipa_ndrq = 0;
     106             : 
     107           0 :         return (1);
     108           0 : }
     109             : 
     110             : void
     111           0 : skgpio_attach(struct device *parent, struct device *self, void *aux)
     112             : {
     113           0 :         struct skgpio_softc *sc = (void *)self;
     114           0 :         struct isa_attach_args *ia = aux;
     115           0 :         struct gpiobus_attach_args gba1, gba2;
     116             :         u_int data;
     117             :         int i;
     118             : 
     119           0 :         if (bus_space_map(ia->ia_iot, ia->ia_iobase, ia->ia_iosize, 0,
     120           0 :             &sc->sc_ioh) != 0) {
     121           0 :                 printf(": can't map i/o space\n");
     122           0 :                 return;
     123             :         }
     124             : 
     125           0 :         printf("\n");
     126             : 
     127           0 :         sc->sc_iot = ia->ia_iot;
     128             : 
     129           0 :         data = bus_space_read_2(sc->sc_iot, sc->sc_ioh, SKGPIO_GPIO_DIR);
     130             : 
     131           0 :         for (i = 0; i < SKGPIO_NPINS; i++) {
     132           0 :                 sc->sc_gpio_pins[i].pin_num = i;
     133           0 :                 sc->sc_gpio_pins[i].pin_caps = GPIO_PIN_INPUT |
     134             :                     GPIO_PIN_OUTPUT;
     135           0 :                 sc->sc_gpio_pins[i].pin_flags = (data & (1 << i)) ?
     136             :                     GPIO_PIN_OUTPUT : GPIO_PIN_INPUT;
     137           0 :                 sc->sc_gpio_pins[i].pin_state = skgpio_gpio_read(sc, i);
     138             :         }
     139             : 
     140           0 :         sc->sc_gpio_gc.gp_cookie = sc;
     141           0 :         sc->sc_gpio_gc.gp_pin_read = skgpio_gpio_read;
     142           0 :         sc->sc_gpio_gc.gp_pin_write = skgpio_gpio_write;
     143           0 :         sc->sc_gpio_gc.gp_pin_ctl = skgpio_gpio_ctl;
     144             : 
     145           0 :         gba1.gba_name = "gpio";
     146           0 :         gba1.gba_gc = &sc->sc_gpio_gc;
     147           0 :         gba1.gba_pins = sc->sc_gpio_pins;
     148           0 :         gba1.gba_npins = SKGPIO_NPINS;
     149             : 
     150           0 :         (void)config_found(&sc->sc_dev, &gba1, gpiobus_print);
     151             : 
     152           0 :         for (i = 0; i < SKGPIO_NLEDS; i++) {
     153           0 :                 sc->sc_led_pins[i].pin_num = i;
     154           0 :                 sc->sc_led_pins[i].pin_caps = GPIO_PIN_OUTPUT;
     155           0 :                 sc->sc_led_pins[i].pin_flags = GPIO_PIN_OUTPUT;
     156           0 :                 sc->sc_led_pins[i].pin_state = skgpio_led_read(sc, i);
     157             :         }
     158             : 
     159           0 :         sc->sc_led_gc.gp_cookie = sc;
     160           0 :         sc->sc_led_gc.gp_pin_read = skgpio_led_read;
     161           0 :         sc->sc_led_gc.gp_pin_write = skgpio_led_write;
     162           0 :         sc->sc_led_gc.gp_pin_ctl = skgpio_led_ctl;
     163             : 
     164           0 :         gba2.gba_name = "gpio";
     165           0 :         gba2.gba_gc = &sc->sc_led_gc;
     166           0 :         gba2.gba_pins = sc->sc_led_pins;
     167           0 :         gba2.gba_npins = SKGPIO_NLEDS;
     168             : 
     169           0 :         (void)config_found(&sc->sc_dev, &gba2, gpiobus_print);
     170           0 : }
     171             : 
     172             : int
     173           0 : skgpio_gpio_read(void *arg, int pin)
     174             : {
     175           0 :         struct skgpio_softc *sc = arg;
     176             :         u_int16_t data;
     177             : 
     178           0 :         data = bus_space_read_2(sc->sc_iot, sc->sc_ioh, SKGPIO_GPIO_INPUT);
     179             : 
     180           0 :         return (data & (1 << pin)) ? GPIO_PIN_HIGH : GPIO_PIN_LOW;
     181             : }
     182             : 
     183             : void
     184           0 : skgpio_gpio_write(void *arg, int pin, int value)
     185             : {
     186           0 :         struct skgpio_softc *sc = arg;
     187             :         u_int16_t data;
     188             : 
     189           0 :         data = bus_space_read_2(sc->sc_iot, sc->sc_ioh, SKGPIO_GPIO_INPUT);
     190             : 
     191           0 :         if (value == GPIO_PIN_LOW)
     192           0 :                 data &= ~(1 << pin);
     193           0 :         else if (value == GPIO_PIN_HIGH)
     194           0 :                 data |= (1 << pin);
     195             : 
     196           0 :         bus_space_write_2(sc->sc_iot, sc->sc_ioh, SKGPIO_GPIO_OUTPUT, data);
     197           0 : }
     198             : 
     199             : void
     200           0 : skgpio_gpio_ctl(void *arg, int pin, int flags)
     201             : {
     202           0 :         struct skgpio_softc *sc = arg;
     203             :         u_int16_t data;
     204             : 
     205           0 :         data = bus_space_read_2(sc->sc_iot, sc->sc_ioh, SKGPIO_GPIO_DIR);
     206             : 
     207           0 :         if (flags & GPIO_PIN_INPUT)
     208           0 :                 data &= ~(1 << pin);
     209           0 :         if (flags & GPIO_PIN_OUTPUT)
     210           0 :                 data |= (1 << pin);
     211             : 
     212           0 :         bus_space_write_2(sc->sc_iot, sc->sc_ioh, SKGPIO_GPIO_DIR, data);
     213           0 : }
     214             : 
     215             : int
     216           0 : skgpio_led_read(void *arg, int pin)
     217             : {
     218           0 :         struct skgpio_softc *sc = arg;
     219             :         u_int8_t value;
     220             : 
     221           0 :         value = bus_space_read_1(sc->sc_iot, sc->sc_ioh,
     222             :             skgpio_led_offset[pin]);
     223             : 
     224           0 :         return (value & 0x1) ? GPIO_PIN_HIGH : GPIO_PIN_LOW;
     225             : }
     226             : 
     227             : void
     228           0 : skgpio_led_write(void *arg, int pin, int value)
     229             : {
     230           0 :         struct skgpio_softc *sc = arg;
     231             : 
     232           0 :         bus_space_write_1(sc->sc_iot, sc->sc_ioh, skgpio_led_offset[pin],
     233             :             value);
     234           0 : }
     235             : 
     236             : void
     237           0 : skgpio_led_ctl(void *arg, int pin, int flags)
     238             : {
     239           0 : }

Generated by: LCOV version 1.13