Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src Add a ga_flags field to the gpio_attach structure to hand dr...
details: https://anonhg.NetBSD.org/src/rev/251f6990b4c5
branches: trunk
changeset: 770047:251f6990b4c5
user: mbalmer <mbalmer%NetBSD.org@localhost>
date: Sun Oct 02 09:33:18 2011 +0000
description:
Add a ga_flags field to the gpio_attach structure to hand driver
specific flags to drivers being attached at gpio pins. gpioiic(4)
uses this to reverse the SDA/SCL signal order. gpioctl(8) accepts
the flag values as optional argument to the attach command.
While here, make sure we retain backwards compatability and wrap compat
code in #ifdef COMPAT_50/#endif.
diffstat:
share/man/man4/gpio.4 | 13 ++++---
share/man/man4/gpioiic.4 | 12 ++++---
sys/dev/gpio/gpio.c | 42 +++++++++++++++++++++----
sys/dev/gpio/gpioiic.c | 76 ++++++++++++++++++++++++++++++++++++++-------
sys/dev/gpio/gpiovar.h | 3 +-
sys/sys/gpio.h | 41 +++++++++++++++---------
usr.sbin/gpioctl/gpioctl.8 | 5 +-
usr.sbin/gpioctl/gpioctl.c | 28 +++++++++++++---
8 files changed, 165 insertions(+), 55 deletions(-)
diffs (truncated from 591 to 300 lines):
diff -r 7d0f20359050 -r 251f6990b4c5 share/man/man4/gpio.4
--- a/share/man/man4/gpio.4 Sun Oct 02 01:51:00 2011 +0000
+++ b/share/man/man4/gpio.4 Sun Oct 02 09:33:18 2011 +0000
@@ -1,4 +1,4 @@
-.\" $NetBSD: gpio.4,v 1.19 2011/08/28 07:48:50 mbalmer Exp $
+.\" $NetBSD: gpio.4,v 1.20 2011/10/02 09:33:18 mbalmer Exp $
.\" $OpenBSD: gpio.4,v 1.5 2004/11/23 09:39:29 reyk Exp $
.\"
.\" Copyright (c) 2004 Alexander Yurchenko <grange%openbsd.org@localhost>
@@ -15,7 +15,7 @@
.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
.\"
-.Dd August 21, 2011
+.Dd October 2, 2011
.Dt GPIO 4
.Os
.Sh NAME
@@ -216,18 +216,19 @@
struct gpio_attach {
char ga_dvname[16]; /* device name */
int ga_offset; /* pin number */
- u_int32_t ga_mask; /* binary mask */
+ uint32_t ga_mask; /* binary mask */
+ uint32_t ga_flags; /* driver dependent */
};
.Ed
-.Pp
.It Dv GPIODETACH (struct gpio_attach)
Detach a device from this gpio device that was previously attached using the
.Dv GPIOATTACH
.Xr ioctl 2 .
The
-.Fa ga_offset
+.Fa ga_offset ,
+.Fa ga_mask ,
and
-.Fa ga_mask
+.Fa ga_flags
fields of the
.Fa gpio_attach
structure are ignored.
diff -r 7d0f20359050 -r 251f6990b4c5 share/man/man4/gpioiic.4
--- a/share/man/man4/gpioiic.4 Sun Oct 02 01:51:00 2011 +0000
+++ b/share/man/man4/gpioiic.4 Sun Oct 02 09:33:18 2011 +0000
@@ -1,4 +1,4 @@
-.\" $NetBSD: gpioiic.4,v 1.2 2009/08/09 08:44:30 wiz Exp $
+.\" $NetBSD: gpioiic.4,v 1.3 2011/10/02 09:33:18 mbalmer Exp $
.\" $OpenBSD: gpioiic.4,v 1.6 2008/11/24 15:30:21 jmc Exp $
.\"
.\" Copyright (c) 2006 Alexander Yurchenko <grange%openbsd.org@localhost>
@@ -15,22 +15,24 @@
.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
.\"
-.Dd August 8, 2009
+.Dd October 2, 2011
.Dt GPIOIIC 4
.Os
.Sh NAME
.Nm gpioiic
.Nd GPIO I2C controller
.Sh SYNOPSIS
-.Cd "gpioiic* at gpio? offset 0 mask 0x3"
+.Cd "gpioiic* at gpio? offset 0 mask 0x3 flags 0x0"
.Cd "gpioiic* at gpio?"
.Cd "iic* at gpioiic?"
.Sh DESCRIPTION
The
.Nm
driver allows bit-banging an I2C bus as a master using two GPIO pins.
-The first pin is used as a serial data (SDA) signal and the second as
-a serial clock (SCL).
+By default the first pin is used as a serial data (SDA) signal and the
+second as a serial clock (SCL).
+If the flags locator is set to 0x01, the order of the SDA and SCL signals
+is reversed.
Both GPIO pins must be able to drive an output and the SDA pin must be
also able to read an input.
.Pp
diff -r 7d0f20359050 -r 251f6990b4c5 sys/dev/gpio/gpio.c
--- a/sys/dev/gpio/gpio.c Sun Oct 02 01:51:00 2011 +0000
+++ b/sys/dev/gpio/gpio.c Sun Oct 02 09:33:18 2011 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: gpio.c,v 1.41 2011/09/02 06:50:20 mbalmer Exp $ */
+/* $NetBSD: gpio.c,v 1.42 2011/10/02 09:33:19 mbalmer Exp $ */
/* $OpenBSD: gpio.c,v 1.6 2006/01/14 12:33:49 grange Exp $ */
/*
@@ -19,7 +19,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: gpio.c,v 1.41 2011/09/02 06:50:20 mbalmer Exp $");
+__KERNEL_RCSID(0, "$NetBSD: gpio.c,v 1.42 2011/10/02 09:33:19 mbalmer Exp $");
/*
* General Purpose Input/Output framework.
@@ -83,9 +83,11 @@
static int gpio_ioctl(struct gpio_softc *, u_long, void *, int,
struct lwp *);
+#ifdef COMPAT_50
/* Old API */
static int gpio_ioctl_oapi(struct gpio_softc *, u_long, void *, int,
kauth_cred_t);
+#endif
CFATTACH_DECL3_NEW(gpio, sizeof(struct gpio_softc),
gpio_match, gpio_attach, gpio_detach, NULL, gpio_rescan,
@@ -255,6 +257,7 @@
ga.ga_gpio = aux;
ga.ga_offset = cf->cf_loc[GPIOCF_OFFSET];
ga.ga_mask = cf->cf_loc[GPIOCF_MASK];
+ ga.ga_flags = cf->cf_loc[GPIOCF_FLAG];
if (config_match(parent, cf, &ga) > 0)
config_attach(parent, cf, &ga, gpio_print);
@@ -516,6 +519,7 @@
int error, pin, value, flags, npins;
gc = sc->sc_gc;
+ ga.ga_flags = 0;
if (cmd != GPIOINFO && !device_is_active(sc->sc_dev)) {
DPRINTF(("%s: device is not active\n",
@@ -667,12 +671,24 @@
sc->sc_pins[pin].pin_state = value;
break;
case GPIOATTACH:
+ attach = (struct gpio_attach *)data;
+ ga.ga_flags = attach->ga_flags;
+#ifdef COMPAT_50
+ /* FALLTHROUGH */
+ case GPIOATTACH50:
+ /*
+ * The double assignment to 'attach' in case of GPIOATTACH
+ * and COMPAT_50 is on purpose. It ensures backward
+ * compatability in case we are called through the old
+ * GPIOATTACH50 ioctl(2), which had not the ga_flags field
+ * in struct gpio_attach.
+ */
+ attach = (struct gpio_attach *)data;
+#endif
if (kauth_authorize_device(cred, KAUTH_DEVICE_GPIO_PINSET,
NULL, NULL, NULL, NULL))
return EPERM;
- attach = (struct gpio_attach *)data;
-
/* do not try to attach if the pins are already mapped */
if (!gpio_pin_can_map(sc, attach->ga_offset, attach->ga_mask))
return EBUSY;
@@ -691,15 +707,17 @@
return EBUSY;
ga.ga_gpio = sc;
+ /* Don't access attach->ga_flags here. */
ga.ga_dvname = attach->ga_dvname;
ga.ga_offset = attach->ga_offset;
ga.ga_mask = attach->ga_mask;
- DPRINTF(("%s: attach %s with offset %d and mask "
- "0x%02x\n", device_xname(sc->sc_dev), ga.ga_dvname,
- ga.ga_offset, ga.ga_mask));
+ DPRINTF(("%s: attach %s with offset %d, mask "
+ "0x%02x, and flags 0x%02x\n", device_xname(sc->sc_dev),
+ ga.ga_dvname, ga.ga_offset, ga.ga_mask, ga.ga_flags));
locs[GPIOCF_OFFSET] = ga.ga_offset;
locs[GPIOCF_MASK] = ga.ga_mask;
+ locs[GPIOCF_FLAG] = ga.ga_flags;
cf = config_search_loc(NULL, sc->sc_dev, "gpio", locs, &ga);
if (cf != NULL) {
@@ -719,6 +737,10 @@
cv_signal(&sc->sc_attach);
mutex_exit(&sc->sc_mtx);
return error;
+#ifdef COMPAT_50
+ case GPIODETACH50:
+ /* FALLTHOUGH */
+#endif
case GPIODETACH:
if (kauth_authorize_device(cred, KAUTH_DEVICE_GPIO_PINSET,
NULL, NULL, NULL, NULL))
@@ -841,13 +863,18 @@
sc->sc_pins[pin].pin_flags &= ~GPIO_PIN_SET;
break;
default:
+#ifdef COMPAT_50
/* Try the old API */
DPRINTF(("%s: trying the old API\n", device_xname(sc->sc_dev)));
return gpio_ioctl_oapi(sc, cmd, data, flag, cred);
+#else
+ return ENOTTY;
+#endif
}
return 0;
}
+#ifdef COMPAT_50
static int
gpio_ioctl_oapi(struct gpio_softc *sc, u_long cmd, void *data, int flag,
kauth_cred_t cred)
@@ -965,6 +992,7 @@
}
return 0;
}
+#endif /* COMPAT_50 */
MODULE(MODULE_CLASS_DRIVER, gpio, NULL);
diff -r 7d0f20359050 -r 251f6990b4c5 sys/dev/gpio/gpioiic.c
--- a/sys/dev/gpio/gpioiic.c Sun Oct 02 01:51:00 2011 +0000
+++ b/sys/dev/gpio/gpioiic.c Sun Oct 02 09:33:18 2011 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: gpioiic.c,v 1.4 2011/08/31 12:25:05 mbalmer Exp $ */
+/* $NetBSD: gpioiic.c,v 1.5 2011/10/02 09:33:19 mbalmer Exp $ */
/* $OpenBSD: gpioiic.c,v 1.8 2008/11/24 12:12:12 mbalmer Exp $ */
/*
@@ -18,7 +18,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: gpioiic.c,v 1.4 2011/08/31 12:25:05 mbalmer Exp $");
+__KERNEL_RCSID(0, "$NetBSD: gpioiic.c,v 1.5 2011/10/02 09:33:19 mbalmer Exp $");
/*
* I2C bus bit-banging through GPIO pins.
@@ -29,6 +29,7 @@
#include <sys/device.h>
#include <sys/gpio.h>
#include <sys/rwlock.h>
+#include <sys/module.h>
#include <dev/gpio/gpiovar.h>
@@ -42,6 +43,8 @@
#define GPIOIIC_SDA 0x01
#define GPIOIIC_SCL 0x02
+#define GPIOIIC_PIN_REVERSE 0x01
+
struct gpioiic_softc {
void * sc_gpio;
struct gpio_pinmap sc_map;
@@ -51,6 +54,9 @@
device_t sc_i2c_dev;
krwlock_t sc_i2c_lock;
+ int sc_pin_sda;
+ int sc_pin_scl;
+
int sc_sda;
int sc_scl;
};
@@ -114,14 +120,24 @@
/* Map pins */
sc->sc_gpio = ga->ga_gpio;
sc->sc_map.pm_map = sc->_map;
+
+
if (gpio_pin_map(sc->sc_gpio, ga->ga_offset, ga->ga_mask,
&sc->sc_map)) {
aprint_error(": can't map pins\n");
return;
}
+ if (ga->ga_flags & GPIOIIC_PIN_REVERSE) {
+ sc->sc_pin_sda = GPIOIIC_PIN_SCL;
+ sc->sc_pin_scl = GPIOIIC_PIN_SDA;
+ } else {
+ sc->sc_pin_sda = GPIOIIC_PIN_SDA;
+ sc->sc_pin_scl = GPIOIIC_PIN_SCL;
+ }
+
/* Configure SDA pin */
- caps = gpio_pin_caps(sc->sc_gpio, &sc->sc_map, GPIOIIC_PIN_SDA);
+ caps = gpio_pin_caps(sc->sc_gpio, &sc->sc_map, sc->sc_pin_sda);
if (!(caps & GPIO_PIN_OUTPUT)) {
aprint_error(": SDA pin is unable to drive output\n");
goto fail;
@@ -130,7 +146,7 @@
aprint_error(": SDA pin is unable to read input\n");
goto fail;
}
- aprint_normal(": SDA[%d]", sc->sc_map.pm_map[GPIOIIC_PIN_SDA]);
+ aprint_normal(": SDA[%d]", sc->sc_map.pm_map[sc->sc_pin_sda]);
sc->sc_sda = GPIO_PIN_OUTPUT;
if (caps & GPIO_PIN_OPENDRAIN) {
aprint_normal(" open-drain");
@@ -143,15 +159,15 @@
aprint_normal(" pull-up");
sc->sc_sda |= GPIO_PIN_PULLUP;
}
- gpio_pin_ctl(sc->sc_gpio, &sc->sc_map, GPIOIIC_PIN_SDA, sc->sc_sda);
+ gpio_pin_ctl(sc->sc_gpio, &sc->sc_map, sc->sc_pin_sda, sc->sc_sda);
/* Configure SCL pin */
Home |
Main Index |
Thread Index |
Old Index