From 17dda5276893e9e0c3eb72070dd003c864f42865 Mon Sep 17 00:00:00 2001 From: shige Date: Sun, 23 Jan 2005 19:22:22 +0000 Subject: [PATCH] Add driver for On-chip General Purpose I/O. --- sys/arch/powerpc/ibm4xx/dev/gpio_opb.c | 216 +++++++++++++++++++++++++ sys/arch/powerpc/ibm4xx/dev/gpioreg.h | 33 +++- sys/arch/powerpc/ibm4xx/dev/gpiovar.h | 63 ++++++++ 3 files changed, 306 insertions(+), 6 deletions(-) create mode 100644 sys/arch/powerpc/ibm4xx/dev/gpio_opb.c create mode 100644 sys/arch/powerpc/ibm4xx/dev/gpiovar.h diff --git a/sys/arch/powerpc/ibm4xx/dev/gpio_opb.c b/sys/arch/powerpc/ibm4xx/dev/gpio_opb.c new file mode 100644 index 000000000000..48dc7fef4d54 --- /dev/null +++ b/sys/arch/powerpc/ibm4xx/dev/gpio_opb.c @@ -0,0 +1,216 @@ +/* $NetBSD: gpio_opb.c,v 1.1 2005/01/23 19:22:22 shige Exp $ */ + +/* + * Copyright (c) 2004 Shigeyuki Fukushima. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * 3. The name of the author may not be used to endorse or promote + * products derived from this software without specific prior + * written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "locators.h" + +#include +#include +#include + +#include + +#include +#include +#include +#include + +struct gpio_softc { + struct device sc_dev; /* device generic */ + struct gpio_controller sc_gpio; /* GPIO controller */ + u_long sc_addr; /* GPIO controller address */ +}; + +static int gpio_print(void *, const char *); +static int gpio_search(struct device *, struct cfdata *, + const locdesc_t *ldesc, void *aux); +static int gpio_match(struct device *, struct cfdata *, void *); +static void gpio_attach(struct device *, struct device *, void *); + +static int gpio_or_read(void *, int); +static int gpio_tcr_read(void *, int); +static int gpio_odr_read(void *, int); +static int gpio_ir_read(void *, int); +static void gpio_or_write(void *arg, int addr, int bit); +static void gpio_tcr_write(void *arg, int addr, int bit); +static void gpio_odr_write(void *arg, int addr, int bit); + +static int gpio_read_bit(void *, int, int); +static void gpio_write_bit(void *, int, int, int); +static uint32_t gpio_read(void *, int); +static void gpio_write(void *, int, uint32_t); + +CFATTACH_DECL(gpio, sizeof(struct gpio_softc), + gpio_match, gpio_attach, NULL, NULL); + +static int +gpio_print(void *aux, const char *pnp) +{ + struct gpio_attach_args *gaa = aux; + + aprint_normal(" addr GPIO#%d", gaa->ga_addr); + + return (UNCONF); +} + +static int +gpio_search(struct device *parent, struct cfdata *cf, + const locdesc_t *ldesc, void *aux) +{ + struct gpio_softc *sc = (void *)parent; + struct gpio_attach_args gaa; + + gaa.ga_tag = &sc->sc_gpio; + gaa.ga_addr = cf->cf_loc[GPIOCF_ADDR]; + + if (config_match(parent, cf, &gaa) > 0) + config_attach(parent, cf, &gaa, gpio_print); + + return (0); +} + +static int +gpio_match(struct device *parent, struct cfdata *cf, void *args) +{ + struct opb_attach_args *oaa = args; + + if (strcmp(oaa->opb_name, cf->cf_name) != 0) + return (0); + + return (1); +} + +static void +gpio_attach(struct device *parent, struct device *self, void *aux) +{ + struct gpio_softc *sc = (struct gpio_softc *)self; + struct opb_attach_args *oaa = aux; + + aprint_naive(": GPIO controller\n"); + aprint_normal(": On-Chip GPIO controller\n"); + + sc->sc_addr = oaa->opb_addr; + sc->sc_gpio.cookie = sc; + sc->sc_gpio.io_or_read = gpio_or_read; + sc->sc_gpio.io_tcr_read = gpio_tcr_read; + sc->sc_gpio.io_odr_read = gpio_odr_read; + sc->sc_gpio.io_ir_read = gpio_ir_read; + sc->sc_gpio.io_or_write = gpio_or_write; + sc->sc_gpio.io_tcr_write = gpio_tcr_write; + sc->sc_gpio.io_odr_write = gpio_odr_write; + + (void) config_search_ia(gpio_search, self, "gpio", NULL); +} + +static int +gpio_or_read(void *arg, int addr) +{ + return (gpio_read_bit(arg, GPIO_OR, addr)); +} + +static int +gpio_tcr_read(void *arg, int addr) +{ + return (gpio_read_bit(arg, GPIO_TCR, addr)); +} + +static int +gpio_odr_read(void *arg, int addr) +{ + return (gpio_read_bit(arg, GPIO_ODR, addr)); +} + +static int +gpio_ir_read(void *arg, int addr) +{ + gpio_write_bit(arg, GPIO_ODR, addr, 0); + gpio_write_bit(arg, GPIO_TCR, addr, 0); + return (gpio_read_bit(arg, GPIO_ODR, addr)); +} + +static void +gpio_or_write(void *arg, int addr, int bit) +{ + gpio_write_bit(arg, GPIO_ODR, addr, 0); + gpio_write_bit(arg, GPIO_TCR, addr, 1); + gpio_write_bit(arg, GPIO_OR, addr, bit); +} + +static void +gpio_tcr_write(void *arg, int addr, int bit) +{ + gpio_write_bit(arg, GPIO_TCR, addr, bit); +} + +static void +gpio_odr_write(void *arg, int addr, int bit) +{ + gpio_write_bit(arg, GPIO_ODR, addr, bit); +} + +static int +gpio_read_bit(void *arg, int offset, int addr) +{ + uint32_t rv = gpio_read(arg, offset); + uint32_t mask = GPIO_SBIT(addr); + + return ((rv & mask) >> GPIO_SHIFT(addr)); +} + +void +gpio_write_bit(void *arg, int offset, int addr, int bit) +{ + uint32_t rv = gpio_read(arg, offset); + uint32_t mask = GPIO_SBIT(addr); + + rv = rv & ~mask; + rv = rv | ((bit << GPIO_SHIFT(addr)) & mask); + gpio_write(arg, offset, rv); +} + +static uint32_t +gpio_read(void *arg, int offset) +{ + struct gpio_softc *sc = arg; + uint32_t rv; + + rv = inl(sc->sc_addr + offset); + + return rv; +} + +static void +gpio_write(void *arg, int offset, uint32_t out) +{ + struct gpio_softc *sc = arg; + + outl((sc->sc_addr + offset), out); +} diff --git a/sys/arch/powerpc/ibm4xx/dev/gpioreg.h b/sys/arch/powerpc/ibm4xx/dev/gpioreg.h index 2ed7ecffbe9d..485570b36138 100644 --- a/sys/arch/powerpc/ibm4xx/dev/gpioreg.h +++ b/sys/arch/powerpc/ibm4xx/dev/gpioreg.h @@ -1,4 +1,4 @@ -/* $NetBSD: gpioreg.h,v 1.1 2002/08/13 04:57:49 simonb Exp $ */ +/* $NetBSD: gpioreg.h,v 1.2 2005/01/23 19:22:22 shige Exp $ */ /* * Copyright 2001 Wasabi Systems, Inc. @@ -38,9 +38,30 @@ #ifndef _IBM4XX_GPIOREG_H_ #define _IBM4XX_GPIOREG_H_ -/* GPIO Registers */ -#define GPIO_OR 0x00 /* Output */ -#define GPIO_TCR 0x04 /* Three-State Control */ -#define GPIO_ODR 0x18 /* Open Drain */ -#define GPIO_IR 0x1c /* Input */ +/* + * GPIO Registers + */ + +/* + * GPIO ODR Control Logic: + * ODR OR Out TCR TS_Ctrl Module I/O 3-State Driver + * 0 X X 0 0 Forced to high impedance state + * 0 0 0 1 1 Drive 0 + * 0 1 1 1 1 Drive 1 + * 1 0 0 X 1 Drive 0 + * 1 1 0 X 0 Forced to high impedance state + */ + +/* GPIO Registers 0x00-0x7f */ +#define GPIO_NREG (0x80) + +#define GPIO_SHIFT(n) (31 - n) +#define GPIO_SBIT(n) (1 << GPIO_SHIFT(n)) + +/* Offset */ +#define GPIO_OR (0x00) /* Output */ +#define GPIO_TCR (0x04) /* Three-State Control */ +#define GPIO_ODR (0x18) /* Open Drain */ +#define GPIO_IR (0x1c) /* Input */ + #endif /* _IBM4XX_GPIOREG_H_ */ diff --git a/sys/arch/powerpc/ibm4xx/dev/gpiovar.h b/sys/arch/powerpc/ibm4xx/dev/gpiovar.h new file mode 100644 index 000000000000..107ed35e5eaa --- /dev/null +++ b/sys/arch/powerpc/ibm4xx/dev/gpiovar.h @@ -0,0 +1,63 @@ +/* $NetBSD: gpiovar.h,v 1.1 2005/01/23 19:22:22 shige Exp $ */ + +/* + * Copyright (c) 2003 Wasabi Systems, Inc. + * All rights reserved. + * + * Written by Steve C. Woodford and Jason R. Thorpe for Wasabi Systems, Inc. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed for the NetBSD Project by + * Wasabi Systems, Inc. + * 4. The name of Wasabi Systems, Inc. may not be used to endorse + * or promote products derived from this software without specific prior + * written permission. + * + * THIS SOFTWARE IS PROVIDED BY WASABI SYSTEMS, INC. ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL WASABI SYSTEMS, INC + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _IBM4XX_DEV_GPIOVAR_H_ +#define _IBM4XX_DEV_GPIOVAR_H_ + +#include + +/* + * This structure provides the interface of ibm4xx GPIO controller. + */ +typedef struct gpio_controller { + int (*io_or_read)(void *, int); + int (*io_tcr_read)(void *, int); + int (*io_odr_read)(void *, int); + int (*io_ir_read)(void *, int); + void (*io_or_write)(void *, int, int); + void (*io_tcr_write)(void *, int, int); + void (*io_odr_write)(void *, int, int); + void *cookie; +} *gpio_tag_t; + +/* Used to attach devices on the GPIO controller */ +struct gpio_attach_args { + gpio_tag_t ga_tag; /* our controller */ + int ga_addr; /* address of device */ +}; + +#endif /* _IBM4XX_DEV_GPIOVAR_H_ */