Home | History | Annotate | Line # | Download | only in ebus
gpio_ebus.c revision 1.3.68.1
      1  1.3.68.1  thorpej /*	$NetBSD: gpio_ebus.c,v 1.3.68.1 2021/03/21 21:08:57 thorpej Exp $	*/
      2       1.1    pooka 
      3       1.1    pooka /*-
      4       1.1    pooka  * Copyright (c) 2010 The NetBSD Foundation, Inc.
      5       1.1    pooka  * All rights reserved.
      6       1.1    pooka  *
      7       1.1    pooka  * This code was written by Alessandro Forin and Neil Pittman
      8       1.1    pooka  * at Microsoft Research and contributed to The NetBSD Foundation
      9       1.1    pooka  * by Microsoft Corporation.
     10       1.1    pooka  *
     11       1.1    pooka  * Redistribution and use in source and binary forms, with or without
     12       1.1    pooka  * modification, are permitted provided that the following conditions
     13       1.1    pooka  * are met:
     14       1.1    pooka  * 1. Redistributions of source code must retain the above copyright
     15       1.1    pooka  *    notice, this list of conditions and the following disclaimer.
     16       1.1    pooka  * 2. Redistributions in binary form must reproduce the above copyright
     17       1.1    pooka  *    notice, this list of conditions and the following disclaimer in the
     18       1.1    pooka  *    documentation and/or other materials provided with the distribution.
     19       1.1    pooka  *
     20       1.1    pooka  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
     21       1.1    pooka  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
     22       1.1    pooka  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     23       1.1    pooka  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
     24       1.1    pooka  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     25       1.1    pooka  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
     26       1.1    pooka  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
     27       1.1    pooka  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
     28       1.1    pooka  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
     29       1.1    pooka  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
     30       1.1    pooka  * POSSIBILITY OF SUCH DAMAGE.
     31       1.1    pooka  */
     32       1.1    pooka 
     33       1.1    pooka #include <sys/cdefs.h>			/* RCS ID & Copyright macro defns */
     34  1.3.68.1  thorpej __KERNEL_RCSID(0, "$NetBSD: gpio_ebus.c,v 1.3.68.1 2021/03/21 21:08:57 thorpej Exp $");
     35       1.1    pooka 
     36       1.1    pooka #include <sys/param.h>
     37       1.1    pooka #include <sys/device.h>
     38       1.1    pooka #include <sys/systm.h>
     39       1.1    pooka #include <sys/gpio.h>
     40       1.1    pooka #include <dev/gpio/gpiovar.h>
     41       1.1    pooka 
     42       1.1    pooka #include <emips/ebus/ebusvar.h>
     43       1.1    pooka #include <emips/emips/machdep.h>
     44       1.1    pooka #include <machine/emipsreg.h>
     45       1.1    pooka 
     46       1.1    pooka /*
     47       1.1    pooka  * Device softc
     48       1.1    pooka  */
     49       1.1    pooka #define GPIO_NPINS 32
     50       1.1    pooka 
     51       1.1    pooka struct epio_softc {
     52       1.3  tsutsui 	device_t sc_dev;
     53       1.1    pooka 	struct _Pio *sc_dp;
     54       1.1    pooka 	struct gpio_chipset_tag	sc_gpio_gc;
     55       1.2  tsutsui 	gpio_pin_t sc_gpio_pins[GPIO_NPINS];
     56       1.1    pooka };
     57       1.1    pooka 
     58       1.2  tsutsui static int	epio_ebus_match(device_t, cfdata_t, void *);
     59       1.2  tsutsui static void	epio_ebus_attach(device_t, device_t, void *);
     60       1.1    pooka 
     61       1.3  tsutsui CFATTACH_DECL_NEW(epio, sizeof (struct epio_softc),
     62       1.1    pooka     epio_ebus_match, epio_ebus_attach, NULL, NULL);
     63       1.1    pooka 
     64       1.1    pooka static int	epio_pin_read(void *, int);
     65       1.1    pooka static void	epio_pin_write(void *, int, int);
     66       1.1    pooka static void	epio_pin_ctl(void *, int, int);
     67       1.1    pooka 
     68       1.1    pooka static int
     69       1.2  tsutsui epio_ebus_match(device_t parent, cfdata_t cf, void *aux)
     70       1.1    pooka {
     71       1.1    pooka 	struct ebus_attach_args *ia = aux;
     72       1.2  tsutsui 	struct _Pio *f = (struct _Pio *)ia->ia_vaddr;
     73       1.1    pooka 
     74       1.1    pooka 	if (strcmp("gpio", ia->ia_name) != 0)
     75       1.2  tsutsui 		return 0;
     76       1.2  tsutsui 	if ((f == NULL) ||
     77       1.2  tsutsui 		(f->Tag != PMTTAG_GPIO))
     78       1.2  tsutsui 		return 0;
     79       1.1    pooka 
     80       1.2  tsutsui 	return 1;
     81       1.1    pooka }
     82       1.1    pooka 
     83       1.1    pooka static void
     84       1.2  tsutsui epio_ebus_attach(device_t parent, device_t self, void *aux)
     85       1.1    pooka {
     86       1.3  tsutsui 	struct epio_softc *sc = device_private(self);
     87       1.1    pooka 	struct ebus_attach_args *ia =aux;
     88       1.1    pooka 	struct gpiobus_attach_args gba;
     89       1.2  tsutsui 	int i;
     90       1.1    pooka 	uint32_t data;
     91       1.1    pooka 
     92       1.3  tsutsui 	sc->sc_dev = self;
     93       1.2  tsutsui 	sc->sc_dp = (struct _Pio *)ia->ia_vaddr;
     94       1.1    pooka 	data = sc->sc_dp->PinData;
     95       1.1    pooka 
     96       1.1    pooka #if DEBUG
     97       1.2  tsutsui 	printf(" virt=%p data=%zx", (void*)sc->sc_dp, data);
     98       1.1    pooka #endif
     99       1.1    pooka 	printf(": GPIO controller\n");
    100       1.1    pooka 
    101       1.1    pooka 	/* BUGBUG Initialize pins properly */
    102       1.1    pooka 	for (i = 0 ; i < GPIO_NPINS ; i++) {
    103       1.1    pooka 		sc->sc_gpio_pins[i].pin_num = i;
    104       1.2  tsutsui 		sc->sc_gpio_pins[i].pin_caps =
    105       1.2  tsutsui 		    GPIO_PIN_INOUT |
    106       1.2  tsutsui 		    GPIO_PIN_OPENDRAIN |
    107       1.2  tsutsui 		    GPIO_PIN_TRISTATE;
    108       1.1    pooka 
    109       1.1    pooka 		/* current defaults */
    110       1.1    pooka 		sc->sc_gpio_pins[i].pin_flags = GPIO_PIN_INOUT;
    111       1.2  tsutsui 		sc->sc_gpio_pins[i].pin_state =
    112       1.2  tsutsui 		    (data & (1 << i)) ? GPIO_PIN_HIGH : GPIO_PIN_LOW;
    113       1.1    pooka 		sc->sc_gpio_pins[i].pin_mapped = 0;
    114       1.1    pooka 	}
    115       1.1    pooka 
    116       1.1    pooka 	/* Create controller tag */
    117       1.1    pooka 	sc->sc_gpio_gc.gp_cookie = sc;
    118       1.1    pooka 	sc->sc_gpio_gc.gp_pin_read = epio_pin_read;
    119       1.1    pooka 	sc->sc_gpio_gc.gp_pin_write = epio_pin_write;
    120       1.1    pooka 	sc->sc_gpio_gc.gp_pin_ctl = epio_pin_ctl;
    121       1.1    pooka 
    122       1.1    pooka 	gba.gba_gc = &sc->sc_gpio_gc;
    123       1.1    pooka 	gba.gba_pins = sc->sc_gpio_pins;
    124       1.1    pooka 	gba.gba_npins = GPIO_NPINS;
    125       1.1    pooka 
    126       1.1    pooka 	/* Attach GPIO framework */
    127  1.3.68.1  thorpej 	(void)config_found(self, &gba, gpiobus_print, CFARG_EOL);
    128       1.1    pooka }
    129       1.1    pooka 
    130       1.1    pooka static int
    131       1.1    pooka epio_pin_read(void *arg, int pin)
    132       1.1    pooka {
    133       1.1    pooka 	struct epio_softc *sc = arg;
    134       1.1    pooka 	uint32_t data = sc->sc_dp->PinData;
    135       1.1    pooka 	int p;
    136       1.1    pooka 
    137       1.1    pooka 	p = pin % GPIO_NPINS;
    138       1.1    pooka 	return (data >> p) & 0x01;
    139       1.1    pooka }
    140       1.1    pooka 
    141       1.1    pooka static void
    142       1.1    pooka epio_pin_write(void *arg, int pin, int value)
    143       1.1    pooka {
    144       1.1    pooka 	struct epio_softc *sc = arg;
    145       1.1    pooka 	uint32_t data;
    146       1.1    pooka 	int p;
    147       1.1    pooka 
    148       1.1    pooka 	p = pin % GPIO_NPINS;
    149       1.2  tsutsui 	data = 1 << p;
    150       1.2  tsutsui 	if (value)
    151       1.2  tsutsui 		sc->sc_dp->PinData = data;
    152       1.2  tsutsui 	else
    153       1.2  tsutsui 		sc->sc_dp->ClearData = data;
    154       1.1    pooka }
    155       1.1    pooka 
    156       1.1    pooka static void
    157       1.1    pooka epio_pin_ctl(void *arg, int pin, int flags)
    158       1.1    pooka {
    159       1.1    pooka 	struct epio_softc *sc = arg;
    160       1.1    pooka 	uint32_t data;
    161       1.1    pooka 	int p;
    162       1.1    pooka 
    163       1.1    pooka 	p = pin % GPIO_NPINS;
    164       1.2  tsutsui 	data = (1 << p);
    165       1.1    pooka 
    166       1.1    pooka 	if (flags & GPIO_PIN_INOUT) {
    167       1.2  tsutsui 		sc->sc_dp->Direction = data;
    168       1.1    pooka 	}
    169       1.1    pooka 
    170       1.1    pooka 	if (flags & GPIO_PIN_TRISTATE) {
    171       1.2  tsutsui 		sc->sc_dp->OutDisable = data;
    172       1.1    pooka 	}
    173       1.1    pooka 
    174       1.1    pooka 	if (flags & GPIO_PIN_OPENDRAIN) {
    175       1.2  tsutsui 		sc->sc_dp->Enable = data;
    176       1.1    pooka 	}
    177       1.1    pooka }
    178