summaryrefslogtreecommitdiff
path: root/sys/dev/ppbus
diff options
context:
space:
mode:
authorcegger <cegger@NetBSD.org>2008-04-29 14:07:36 +0000
committercegger <cegger@NetBSD.org>2008-04-29 14:07:36 +0000
commitb574865ea4d4da28ea2f2309c46767cc49d53bcd (patch)
treebafebcbfd5daed34f16616e42e72d817ba216311 /sys/dev/ppbus
parenta1ddfabe35e7e4f63df5d89b275f08e21e7f6c8f (diff)
gpio(4): Extend with open/close to request/release the ppbus(4) on open/close.
ppbus(4): Extend to attach on gpiobus. From Hans Rosenfeld from tech-kern: http://mail-index.netbsd.org/tech-kern/2008/04/28/msg001168.html Hint: Hans sent me this diff which differs in the one from tech-kern in: - 2-clause license - sprinkled some consts
Diffstat (limited to 'sys/dev/ppbus')
-rw-r--r--sys/dev/ppbus/files.ppbus5
-rw-r--r--sys/dev/ppbus/ppbus_conf.c9
-rw-r--r--sys/dev/ppbus/ppbus_conf.h17
-rw-r--r--sys/dev/ppbus/ppbus_gpio.c158
4 files changed, 184 insertions, 5 deletions
diff --git a/sys/dev/ppbus/files.ppbus b/sys/dev/ppbus/files.ppbus
index fe94b41551b..133d4975cde 100644
--- a/sys/dev/ppbus/files.ppbus
+++ b/sys/dev/ppbus/files.ppbus
@@ -1,4 +1,4 @@
-# $NetBSD: files.ppbus,v 1.7 2005/12/11 12:23:28 christos Exp $
+# $NetBSD: files.ppbus,v 1.8 2008/04/29 14:07:36 cegger Exp $
#
# Config file and device description for machine-independent parallel port bus
# code.
@@ -10,12 +10,13 @@ defflag opt_ppbus_1284.h DONTPROBE_1284 DEBUG_1284
define parport { }
# ppbus related files
-device ppbus { }
+device ppbus { }: gpiobus
attach ppbus at parport
file dev/ppbus/ppbus_conf.c ppbus needs-flag
file dev/ppbus/ppbus_base.c ppbus
file dev/ppbus/ppbus_msq.c ppbus
file dev/ppbus/ppbus_1284.c ppbus
+file dev/ppbus/ppbus_gpio.c ppbus & gpio
# lpt driver
defflag opt_ppbus_lpt.h LPT_DEBUG LPT_VERBOSE
diff --git a/sys/dev/ppbus/ppbus_conf.c b/sys/dev/ppbus/ppbus_conf.c
index 0f174acf103..31a15d62e33 100644
--- a/sys/dev/ppbus/ppbus_conf.c
+++ b/sys/dev/ppbus/ppbus_conf.c
@@ -1,4 +1,4 @@
-/* $NetBSD: ppbus_conf.c,v 1.15 2008/04/18 14:56:40 cegger Exp $ */
+/* $NetBSD: ppbus_conf.c,v 1.16 2008/04/29 14:07:37 cegger Exp $ */
/*-
* Copyright (c) 1997, 1998, 1999 Nicolas Souchu
@@ -30,11 +30,13 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: ppbus_conf.c,v 1.15 2008/04/18 14:56:40 cegger Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ppbus_conf.c,v 1.16 2008/04/29 14:07:37 cegger Exp $");
#include "opt_ppbus.h"
#include "opt_ppbus_1284.h"
+#include "gpio.h"
+
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/kernel.h>
@@ -169,6 +171,9 @@ ppbus_attach(device_t parent, device_t self, void *aux)
SLIST_INIT(&(ppbus->sc_childlist_head));
config_search_ia(ppbus_search_children, self, "ppbus", &args);
+#if NGPIO > 0
+ gpio_ppbus_attach(ppbus);
+#endif
return;
}
diff --git a/sys/dev/ppbus/ppbus_conf.h b/sys/dev/ppbus/ppbus_conf.h
index bff9c9a7c63..33cb0bc6f35 100644
--- a/sys/dev/ppbus/ppbus_conf.h
+++ b/sys/dev/ppbus/ppbus_conf.h
@@ -1,4 +1,4 @@
-/* $NetBSD: ppbus_conf.h,v 1.10 2008/04/15 15:02:29 cegger Exp $ */
+/* $NetBSD: ppbus_conf.h,v 1.11 2008/04/29 14:07:37 cegger Exp $ */
/*-
* Copyright (c) 1997, 1998, 1999 Nicolas Souchu
@@ -31,6 +31,8 @@
#ifndef __PPBUS_CONF_H
#define __PPBUS_CONF_H
+#include "gpio.h"
+
#include <sys/device.h>
#include <sys/mutex.h>
#include <sys/queue.h>
@@ -40,6 +42,10 @@
#include <dev/ppbus/ppbus_msq.h>
#include <dev/ppbus/ppbus_device.h>
+#if NGPIO > 0
+#include <dev/gpio/gpiovar.h>
+#define PPBUS_NPINS 17
+#endif
/* Function pointer types used for interface */
typedef u_char (*PARPORT_IO_T)(device_t, int, u_char *, int, u_char);
@@ -130,6 +136,15 @@ struct ppbus_softc {
PARPORT_DMA_FREE_T ppbus_dma_free;
PARPORT_ADD_HANDLER_T ppbus_add_handler;
PARPORT_REMOVE_HANDLER_T ppbus_remove_handler;
+
+#if NGPIO > 0
+ struct gpio_chipset_tag sc_gpio_gc;
+ gpio_pin_t sc_gpio_pins[PPBUS_NPINS];
+#endif
};
+#if NGPIO > 0
+void gpio_ppbus_attach(struct ppbus_softc *);
+#endif
+
#endif /* __PPBUS_CONF_H */
diff --git a/sys/dev/ppbus/ppbus_gpio.c b/sys/dev/ppbus/ppbus_gpio.c
new file mode 100644
index 00000000000..35388d2a964
--- /dev/null
+++ b/sys/dev/ppbus/ppbus_gpio.c
@@ -0,0 +1,158 @@
+/* $NetBSD: ppbus_gpio.c,v 1.1 2008/04/29 14:07:37 cegger Exp $ */
+
+/*
+ * Copyright (c) 2008, Hans Rosenfeld <rosenfeld@grumpf.hope-2000.org>
+ * 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``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 OR CONTRIBUTORS 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 <sys/cdefs.h>
+__KERNEL_RCSID(0, "$NetBSD: ppbus_gpio.c,v 1.1 2008/04/29 14:07:37 cegger Exp $");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/device.h>
+#include <sys/gpio.h>
+#include <sys/kernel.h>
+
+#include <dev/gpio/gpiovar.h>
+
+#include <dev/ppbus/ppbus_conf.h>
+#include <dev/ppbus/ppbus_base.h>
+#include <dev/ppbus/ppbus_io.h>
+
+static int gpio_ppbus_open(void *, device_t);
+static void gpio_ppbus_close(void *, device_t);
+static int gpio_ppbus_pin_read(void *, int);
+static void gpio_ppbus_pin_write(void *, int, int);
+static void gpio_ppbus_pin_ctl(void *, int, int);
+
+
+#define PORT(r, b, i) { PPBUS_R##r##TR, PPBUS_W##r##TR, b, i}
+static const struct {
+ u_char rreg;
+ u_char wreg;
+ u_char bit;
+ u_char inv;
+} ppbus_port[PPBUS_NPINS] = { /* parallel port wiring: */
+ PORT(C, 0, 1), /* 1: /C0 Output */
+ PORT(D, 0, 0), /* 2: D0 Output */
+ PORT(D, 1, 0), /* 3: D1 Output */
+ PORT(D, 2, 0), /* 4: D2 Output */
+ PORT(D, 3, 0), /* 5: D3 Output */
+ PORT(D, 4, 0), /* 6: D4 Output */
+ PORT(D, 5, 0), /* 7: D5 Output */
+ PORT(D, 6, 0), /* 8: D6 Output */
+ PORT(D, 7, 0), /* 9: D7 Output */
+ PORT(S, 6, 0), /* 10: S6 Input */
+ PORT(S, 7, 1), /* 11: /S7 Input */
+ PORT(S, 5, 0), /* 12: S5 Input */
+ PORT(S, 4, 0), /* 13: S4 Input */
+ PORT(C, 1, 1), /* 14: /C1 Output */
+ PORT(S, 3, 0), /* 15: S3 Input */
+ PORT(C, 2, 0), /* 16: C2 Output */
+ PORT(C, 3, 1), /* 17: /C3 Output */
+}; /* 18-25: GND */
+
+void
+gpio_ppbus_attach(struct ppbus_softc *sc)
+{
+ struct gpiobus_attach_args gba;
+ gpio_pin_t *pin;
+ int i;
+
+ for (pin = &sc->sc_gpio_pins[0], i = 0; i < PPBUS_NPINS; pin++, i++) {
+ pin->pin_num = i;
+
+ if (((i >= 9) && (i <= 12)) || (i == 14)) {
+ pin->pin_caps = GPIO_PIN_INPUT;
+ pin->pin_flags = GPIO_PIN_INPUT;
+ pin->pin_state = gpio_ppbus_pin_read(sc, i);
+ } else {
+ pin->pin_caps = GPIO_PIN_OUTPUT;
+ pin->pin_flags = GPIO_PIN_OUTPUT;
+ pin->pin_state = GPIO_PIN_LOW;
+ gpio_ppbus_pin_write(sc, i, pin->pin_state);
+ }
+
+ gpio_ppbus_pin_ctl(sc, i, pin->pin_flags);
+ }
+
+ sc->sc_gpio_gc.gp_cookie = sc;
+ sc->sc_gpio_gc.gp_gc_open = gpio_ppbus_open;
+ sc->sc_gpio_gc.gp_gc_close = gpio_ppbus_close;
+ sc->sc_gpio_gc.gp_pin_read = gpio_ppbus_pin_read;
+ sc->sc_gpio_gc.gp_pin_write = gpio_ppbus_pin_write;
+ sc->sc_gpio_gc.gp_pin_ctl = gpio_ppbus_pin_ctl;
+
+ gba.gba_gc = &sc->sc_gpio_gc;
+ gba.gba_pins = sc->sc_gpio_pins;
+ gba.gba_npins = PPBUS_NPINS;
+
+ config_found_ia(sc->sc_dev, "gpiobus", &gba, gpiobus_print);
+}
+
+static int
+gpio_ppbus_open(void *arg, device_t dev)
+{
+ struct ppbus_softc *sc = arg;
+
+ return ppbus_request_bus(sc->sc_dev, dev, PPBUS_WAIT|PPBUS_INTR, (hz));
+}
+
+static void
+gpio_ppbus_close(void *arg, device_t dev)
+{
+ struct ppbus_softc *sc = arg;
+
+ (void) ppbus_release_bus(sc->sc_dev, dev, PPBUS_WAIT|PPBUS_INTR, (hz));
+}
+
+static int
+gpio_ppbus_pin_read(void *arg, int pin)
+{
+ struct ppbus_softc *sc = arg;
+ u_char port = ppbus_io(sc->sc_dev, ppbus_port[pin].rreg, NULL, 0, 0);
+
+ return ((port >> ppbus_port[pin].bit) & 1) ^ ppbus_port[pin].inv;
+}
+
+static void
+gpio_ppbus_pin_write(void *arg, int pin, int value)
+{
+ struct ppbus_softc *sc = arg;
+ u_char port = ppbus_io(sc->sc_dev, ppbus_port[pin].rreg, NULL, 0, 0);
+
+ value ^= ppbus_port[pin].inv;
+ value <<= ppbus_port[pin].bit;
+ port &= ~(1 << ppbus_port[pin].bit);
+ port |= value;
+
+ ppbus_io(sc->sc_dev, ppbus_port[pin].wreg, NULL, 0, port);
+}
+
+static void
+gpio_ppbus_pin_ctl(void *arg, int pin, int flags)
+{
+ /* can't change parallel port pin configuration */
+}