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

          Line data    Source code
       1             : /*      $OpenBSD: bytgpio.c,v 1.13 2018/04/30 18:47:48 kettenis Exp $   */
       2             : /*
       3             :  * Copyright (c) 2016 Mark Kettenis
       4             :  *
       5             :  * Permission to use, copy, modify, and distribute this software for any
       6             :  * purpose with or without fee is hereby granted, provided that the above
       7             :  * copyright notice and this permission notice appear in all copies.
       8             :  *
       9             :  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
      10             :  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
      11             :  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
      12             :  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
      13             :  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
      14             :  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
      15             :  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
      16             :  */
      17             : 
      18             : #include <sys/param.h>
      19             : #include <sys/malloc.h>
      20             : #include <sys/systm.h>
      21             : 
      22             : #include <dev/acpi/acpireg.h>
      23             : #include <dev/acpi/acpivar.h>
      24             : #include <dev/acpi/acpidev.h>
      25             : #include <dev/acpi/amltypes.h>
      26             : #include <dev/acpi/dsdt.h>
      27             : 
      28             : #define BYTGPIO_CONF_GD_LEVEL   0x01000000
      29             : #define BYTGPIO_CONF_GD_TPE     0x02000000
      30             : #define BYTGPIO_CONF_GD_TNE     0x04000000
      31             : #define BYTGPIO_CONF_GD_MASK    0x07000000
      32             : #define BYTGPIO_CONF_DIRECT_IRQ_EN      0x08000000
      33             : 
      34             : #define BYTGPIO_PAD_VAL         0x00000001
      35             : 
      36             : #define BYTGPIO_IRQ_TS_0        0x800
      37             : #define BYTGPIO_IRQ_TS_1        0x804
      38             : #define BYTGPIO_IRQ_TS_2        0x808
      39             : 
      40             : struct bytgpio_intrhand {
      41             :         int (*ih_func)(void *);
      42             :         void *ih_arg;
      43             : };
      44             : 
      45             : struct bytgpio_softc {
      46             :         struct device sc_dev;
      47             :         struct acpi_softc *sc_acpi;
      48             :         struct aml_node *sc_node;
      49             : 
      50             :         bus_space_tag_t sc_memt;
      51             :         bus_space_handle_t sc_memh;
      52             :         bus_addr_t sc_addr;
      53             :         bus_size_t sc_size;
      54             : 
      55             :         int sc_irq;
      56             :         int sc_irq_flags;
      57             :         void *sc_ih;
      58             : 
      59             :         const int *sc_pins;
      60             :         int sc_npins;
      61             :         struct bytgpio_intrhand *sc_pin_ih;
      62             : 
      63             :         struct acpi_gpio sc_gpio;
      64             : };
      65             : 
      66             : int     bytgpio_match(struct device *, void *, void *);
      67             : void    bytgpio_attach(struct device *, struct device *, void *);
      68             : 
      69             : struct cfattach bytgpio_ca = {
      70             :         sizeof(struct bytgpio_softc), bytgpio_match, bytgpio_attach
      71             : };
      72             : 
      73             : struct cfdriver bytgpio_cd = {
      74             :         NULL, "bytgpio", DV_DULL
      75             : };
      76             : 
      77             : const char *bytgpio_hids[] = {
      78             :         "INT33FC",
      79             :         NULL
      80             : };
      81             : 
      82             : /*
      83             :  * The pads for the pins are randomly ordered.
      84             :  */
      85             : 
      86             : const int byt_score_pins[] = {
      87             :         85, 89, 93, 96, 99, 102, 98, 101, 34, 37, 36, 38, 39, 35, 40,
      88             :         84, 62, 61, 64, 59, 54, 56, 60, 55, 63, 57, 51, 50, 53, 47,
      89             :         52, 49, 48, 43, 46, 41, 45, 42, 58, 44, 95, 105, 70, 68, 67,
      90             :         66, 69, 71, 65, 72, 86, 90, 88, 92, 103, 77, 79, 83, 78, 81,
      91             :         80, 82, 13, 12, 15, 14, 17, 18, 19, 16, 2, 1, 0, 4, 6, 7, 9,
      92             :         8, 33, 32, 31, 30, 29, 27, 25, 28, 26, 23, 21, 20, 24, 22, 5,
      93             :         3, 10, 11, 106, 87, 91, 104, 97, 100
      94             : };
      95             : 
      96             : const int byt_ncore_pins[] = {
      97             :         19, 18, 17, 20, 21, 22, 24, 25, 23, 16, 14, 15, 12, 26, 27,
      98             :         1, 4, 8, 11, 0, 3, 6, 10, 13, 2, 5, 9, 7
      99             : };
     100             : 
     101             : const int byt_sus_pins[] = {
     102             :         29, 33, 30, 31, 32, 34, 36, 35, 38, 37, 18, 7, 11, 20, 17, 1,
     103             :         8, 10, 19, 12, 0, 2, 23, 39, 28, 27, 22, 21, 24, 25, 26, 51,
     104             :         56, 54, 49, 55, 48, 57, 50, 58, 52, 53, 59, 40
     105             : };
     106             : 
     107             : int     bytgpio_parse_resources(int, union acpi_resource *, void *);
     108             : int     bytgpio_read_pin(void *, int);
     109             : void    bytgpio_write_pin(void *, int, int);
     110             : void    bytgpio_intr_establish(void *, int, int, int (*)(), void *);
     111             : int     bytgpio_intr(void *);
     112             : 
     113             : int
     114           0 : bytgpio_match(struct device *parent, void *match, void *aux)
     115             : {
     116           0 :         struct acpi_attach_args *aaa = aux;
     117           0 :         struct cfdata *cf = match;
     118             : 
     119           0 :         return acpi_matchhids(aaa, bytgpio_hids, cf->cf_driver->cd_name);
     120             : }
     121             : 
     122             : void
     123           0 : bytgpio_attach(struct device *parent, struct device *self, void *aux)
     124             : {
     125           0 :         struct acpi_attach_args *aaa = aux;
     126           0 :         struct bytgpio_softc *sc = (struct bytgpio_softc *)self;
     127           0 :         struct aml_value res;
     128           0 :         int64_t uid;
     129             :         uint32_t reg;
     130             :         int i;
     131             : 
     132           0 :         sc->sc_acpi = (struct acpi_softc *)parent;
     133           0 :         sc->sc_node = aaa->aaa_node;
     134           0 :         printf(": %s", sc->sc_node->name);
     135             : 
     136           0 :         if (aml_evalinteger(sc->sc_acpi, sc->sc_node, "_UID", 0, NULL, &uid)) {
     137           0 :                 printf(", can't find uid\n");
     138           0 :                 return;
     139             :         }
     140             : 
     141           0 :         printf(" uid %lld", uid);
     142             : 
     143           0 :         switch (uid) {
     144             :         case 1:
     145           0 :                 sc->sc_pins = byt_score_pins;
     146           0 :                 sc->sc_npins = nitems(byt_score_pins);
     147           0 :                 break;
     148             :         case 2:
     149           0 :                 sc->sc_pins = byt_ncore_pins;
     150           0 :                 sc->sc_npins = nitems(byt_ncore_pins);
     151           0 :                 break;
     152             :         case 3:
     153           0 :                 sc->sc_pins = byt_sus_pins;
     154           0 :                 sc->sc_npins = nitems(byt_sus_pins);
     155           0 :                 break;
     156             :         default:
     157           0 :                 printf("\n");
     158           0 :                 return;
     159             :         }
     160             : 
     161           0 :         if (aml_evalname(sc->sc_acpi, sc->sc_node, "_CRS", 0, NULL, &res)) {
     162           0 :                 printf(", can't find registers\n");
     163           0 :                 return;
     164             :         }
     165             : 
     166           0 :         aml_parse_resource(&res, bytgpio_parse_resources, sc);
     167           0 :         printf(" addr 0x%lx/0x%lx", sc->sc_addr, sc->sc_size);
     168           0 :         if (sc->sc_addr == 0 || sc->sc_size == 0) {
     169           0 :                 printf("\n");
     170           0 :                 return;
     171             :         }
     172           0 :         aml_freevalue(&res);
     173             : 
     174           0 :         sc->sc_pin_ih = mallocarray(sc->sc_npins, sizeof(*sc->sc_pin_ih),
     175             :             M_DEVBUF, M_NOWAIT | M_ZERO);
     176           0 :         if (sc->sc_pin_ih == NULL) {
     177           0 :                 printf("\n");
     178           0 :                 return;
     179             :         }
     180             : 
     181           0 :         printf(" irq %d", sc->sc_irq);
     182             : 
     183           0 :         sc->sc_memt = aaa->aaa_memt;
     184           0 :         if (bus_space_map(sc->sc_memt, sc->sc_addr, sc->sc_size, 0,
     185           0 :             &sc->sc_memh)) {
     186           0 :                 printf(", can't map registers\n");
     187           0 :                 goto free;
     188             :         }
     189             : 
     190           0 :         sc->sc_ih = acpi_intr_establish(sc->sc_irq, sc->sc_irq_flags, IPL_BIO,
     191           0 :             bytgpio_intr, sc, sc->sc_dev.dv_xname);
     192           0 :         if (sc->sc_ih == NULL) {
     193           0 :                 printf(", can't establish interrupt\n");
     194             :                 goto unmap;
     195             :         }
     196             : 
     197           0 :         sc->sc_gpio.cookie = sc;
     198           0 :         sc->sc_gpio.read_pin = bytgpio_read_pin;
     199           0 :         sc->sc_gpio.write_pin = bytgpio_write_pin;
     200           0 :         sc->sc_gpio.intr_establish = bytgpio_intr_establish;
     201           0 :         sc->sc_node->gpio = &sc->sc_gpio;
     202             : 
     203             :         /* Mask all interrupts. */
     204           0 :         for (i = 0; i < sc->sc_npins; i++) {
     205           0 :                 reg = bus_space_read_4(sc->sc_memt, sc->sc_memh, sc->sc_pins[i] * 16);
     206             : 
     207             :                 /*
     208             :                  * Skip pins configured as direct IRQ.  Those are tied
     209             :                  * directly to the APIC.
     210             :                  */
     211           0 :                 if (reg & BYTGPIO_CONF_DIRECT_IRQ_EN)
     212             :                         continue;
     213             : 
     214           0 :                 reg &= ~BYTGPIO_CONF_GD_MASK;
     215           0 :                 bus_space_write_4(sc->sc_memt, sc->sc_memh, sc->sc_pins[i] * 16, reg);
     216           0 :         }
     217             : 
     218           0 :         printf(", %d pins\n", sc->sc_npins);
     219             : 
     220           0 :         acpi_register_gpio(sc->sc_acpi, sc->sc_node);
     221           0 :         return;
     222             : 
     223             : unmap:
     224           0 :         bus_space_unmap(sc->sc_memt, sc->sc_memh, sc->sc_size);
     225             : free:
     226           0 :         free(sc->sc_pin_ih, M_DEVBUF, sc->sc_npins * sizeof(*sc->sc_pin_ih));
     227           0 : }
     228             : 
     229             : int
     230           0 : bytgpio_parse_resources(int crsidx, union acpi_resource *crs, void *arg)
     231             : {
     232           0 :         struct bytgpio_softc *sc = arg;
     233           0 :         int type = AML_CRSTYPE(crs);
     234             : 
     235           0 :         switch (type) {
     236             :         case LR_MEM32FIXED:
     237           0 :                 sc->sc_addr = crs->lr_m32fixed._bas;
     238           0 :                 sc->sc_size = crs->lr_m32fixed._len;
     239           0 :                 break;
     240             :         case LR_EXTIRQ:
     241           0 :                 sc->sc_irq = crs->lr_extirq.irq[0];
     242           0 :                 sc->sc_irq_flags = crs->lr_extirq.flags;
     243           0 :                 break;
     244             :         default:
     245           0 :                 printf(" type 0x%x\n", type);
     246           0 :                 break;
     247             :         }
     248             : 
     249           0 :         return 0;
     250             : }
     251             : 
     252             : int
     253           0 : bytgpio_read_pin(void *cookie, int pin)
     254             : {
     255           0 :         struct bytgpio_softc *sc = cookie;
     256             :         uint32_t reg;
     257             : 
     258           0 :         reg = bus_space_read_4(sc->sc_memt, sc->sc_memh, sc->sc_pins[pin] * 16 + 8);
     259           0 :         return (reg & BYTGPIO_PAD_VAL);
     260             : }
     261             : 
     262             : void
     263           0 : bytgpio_write_pin(void *cookie, int pin, int value)
     264             : {
     265           0 :         struct bytgpio_softc *sc = cookie;
     266             :         uint32_t reg;
     267             : 
     268           0 :         reg = bus_space_read_4(sc->sc_memt, sc->sc_memh, sc->sc_pins[pin] * 16 + 8);
     269           0 :         if (value)
     270           0 :                 reg |= BYTGPIO_PAD_VAL;
     271             :         else
     272           0 :                 reg &= ~BYTGPIO_PAD_VAL;
     273           0 :         bus_space_write_4(sc->sc_memt, sc->sc_memh, sc->sc_pins[pin] * 16 + 8, reg);
     274           0 : }
     275             : 
     276             : void
     277           0 : bytgpio_intr_establish(void *cookie, int pin, int flags,
     278             :     int (*func)(void *), void *arg)
     279             : {
     280           0 :         struct bytgpio_softc *sc = cookie;
     281             :         uint32_t reg;
     282             : 
     283           0 :         KASSERT(pin >= 0 && pin < sc->sc_npins);
     284             : 
     285           0 :         sc->sc_pin_ih[pin].ih_func = func;
     286           0 :         sc->sc_pin_ih[pin].ih_arg = arg;
     287             : 
     288           0 :         reg = bus_space_read_4(sc->sc_memt, sc->sc_memh, sc->sc_pins[pin] * 16);
     289           0 :         reg &= ~BYTGPIO_CONF_GD_MASK;
     290           0 :         if ((flags & LR_GPIO_MODE) == 0)
     291           0 :                 reg |= BYTGPIO_CONF_GD_LEVEL;
     292           0 :         if ((flags & LR_GPIO_POLARITY) == LR_GPIO_ACTLO)
     293           0 :                 reg |= BYTGPIO_CONF_GD_TNE;
     294           0 :         if ((flags & LR_GPIO_POLARITY) == LR_GPIO_ACTHI)
     295           0 :                 reg |= BYTGPIO_CONF_GD_TPE;
     296           0 :         if ((flags & LR_GPIO_POLARITY) == LR_GPIO_ACTBOTH)
     297           0 :                 reg |= BYTGPIO_CONF_GD_TNE | BYTGPIO_CONF_GD_TPE;
     298           0 :         bus_space_write_4(sc->sc_memt, sc->sc_memh, sc->sc_pins[pin] * 16, reg);
     299           0 : }
     300             : 
     301             : int
     302           0 : bytgpio_intr(void *arg)
     303             : {
     304           0 :         struct bytgpio_softc *sc = arg;
     305             :         uint32_t reg;
     306             :         int rc = 0;
     307             :         int pin;
     308             : 
     309           0 :         for (pin = 0; pin < sc->sc_npins; pin++) {
     310           0 :                 if (pin % 32 == 0) {
     311           0 :                         reg = bus_space_read_4(sc->sc_memt, sc->sc_memh,
     312             :                             BYTGPIO_IRQ_TS_0 + (pin / 8));
     313           0 :                         bus_space_write_4(sc->sc_memt, sc->sc_memh,
     314             :                             BYTGPIO_IRQ_TS_0 + (pin / 8), reg);
     315           0 :                 }
     316           0 :                 if (reg & (1 << (pin % 32))) {
     317           0 :                         if (sc->sc_pin_ih[pin].ih_func)
     318           0 :                                 sc->sc_pin_ih[pin].ih_func(sc->sc_pin_ih[pin].ih_arg);
     319             :                         rc = 1;
     320           0 :                 }
     321             :         }
     322             : 
     323           0 :         return rc;
     324             : }

Generated by: LCOV version 1.13