Add driver for On-chip General Purpose I/O.
This commit is contained in:
parent
924b155d98
commit
17dda52768
|
@ -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 <sys/param.h>
|
||||
#include <sys/device.h>
|
||||
#include <sys/systm.h>
|
||||
|
||||
#include <machine/pio.h>
|
||||
|
||||
#include <powerpc/ibm4xx/dcr405gp.h>
|
||||
#include <powerpc/ibm4xx/dev/opbvar.h>
|
||||
#include <powerpc/ibm4xx/dev/gpioreg.h>
|
||||
#include <powerpc/ibm4xx/dev/gpiovar.h>
|
||||
|
||||
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);
|
||||
}
|
|
@ -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_ */
|
||||
|
|
|
@ -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 <sys/device.h>
|
||||
|
||||
/*
|
||||
* 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_ */
|
Loading…
Reference in New Issue