summaryrefslogtreecommitdiff
path: root/sys/dev
diff options
context:
space:
mode:
authorConstantine A. Murenin <cnst@cvs.openbsd.org>2009-08-12 14:51:21 +0000
committerConstantine A. Murenin <cnst@cvs.openbsd.org>2009-08-12 14:51:21 +0000
commit2fecdb755746b90f914eb6293ba03f3d1c6bd93b (patch)
tree3de39dbbdf6e846111f77aec07adad287c025123 /sys/dev
parent41f7beea342b39552a07eda8d3b742194d8e7d63 (diff)
New lisa(4) driver for ST LIS331DL accelerometer in HP 2133 Mini-Note PC; ok deraadt
Diffstat (limited to 'sys/dev')
-rw-r--r--sys/dev/i2c/files.i2c7
-rw-r--r--sys/dev/i2c/i2c_scan.c10
-rw-r--r--sys/dev/i2c/lis331dl.c141
3 files changed, 156 insertions, 2 deletions
diff --git a/sys/dev/i2c/files.i2c b/sys/dev/i2c/files.i2c
index 79143eaebe1..2c9d3ef8c51 100644
--- a/sys/dev/i2c/files.i2c
+++ b/sys/dev/i2c/files.i2c
@@ -1,4 +1,4 @@
-# $OpenBSD: files.i2c,v 1.46 2008/04/21 04:48:25 deraadt Exp $
+# $OpenBSD: files.i2c,v 1.47 2009/08/12 14:51:20 cnst Exp $
# $NetBSD: files.i2c,v 1.3 2003/10/20 16:24:10 briggs Exp $
define i2c {[addr = -1], [size = -1]}
@@ -161,3 +161,8 @@ file dev/i2c/sdtemp.c sdtemp
device adtfsm
attach adtfsm at i2c
file dev/i2c/adt7462.c adtfsm
+
+# STMicroelectronics LIS331DL MEMS motion sensor
+device lisa
+attach lisa at i2c
+file dev/i2c/lis331dl.c
diff --git a/sys/dev/i2c/i2c_scan.c b/sys/dev/i2c/i2c_scan.c
index b06e86b9648..5235b2a5671 100644
--- a/sys/dev/i2c/i2c_scan.c
+++ b/sys/dev/i2c/i2c_scan.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: i2c_scan.c,v 1.133 2009/07/10 19:58:41 cnst Exp $ */
+/* $OpenBSD: i2c_scan.c,v 1.134 2009/08/12 14:51:20 cnst Exp $ */
/*
* Copyright (c) 2005 Theo de Raadt <deraadt@openbsd.org>
@@ -883,6 +883,14 @@ iic_probe_sensor(struct device *self, u_int8_t addr)
(iicprobew(0x07) & 0xffe0) == 0x0800 &&
iicprobew(0x00) == 0x001f) {
name = "cat34ts02"; /* or cat6095 */
+ } else if ((addr & 0x7e) == 0x1c && iicprobe(0x0f) == 0x3b &&
+ (iicprobe(0x21) & 0x60) == 0x00 &&
+ iicprobe(0x0f) == iicprobe(0x8f) && /* registers address is 7 bits */
+ iicprobe(0x20) == iicprobe(0xa0) &&
+ iicprobe(0x21) == iicprobe(0xa1) &&
+ iicprobe(0x22) == iicprobe(0xa2) &&
+ iicprobe(0x07) == 0x00) { /* 0x00 to 0x0e are reserved */
+ name = "lis331dl";
} else if (name == NULL &&
(addr & 0x78) == 0x48) { /* addr 0b1001xxx */
name = lm75probe();
diff --git a/sys/dev/i2c/lis331dl.c b/sys/dev/i2c/lis331dl.c
new file mode 100644
index 00000000000..76cef4b2df0
--- /dev/null
+++ b/sys/dev/i2c/lis331dl.c
@@ -0,0 +1,141 @@
+/* $OpenBSD: lis331dl.c,v 1.1 2009/08/12 14:51:20 cnst Exp $ */
+
+/*
+ * Copyright (c) 2009 Constantine A. Murenin <cnst+openbsd@bugmail.mojo.ru>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/device.h>
+#include <sys/sensors.h>
+
+#include <dev/i2c/i2cvar.h>
+
+/*
+ * STMicroelectronics LIS331DL
+ * MEMS motion sensor
+ * http://www.stm.com/stonline/products/literature/ds/13951.pdf
+ * April 2008
+ */
+
+/* 3-axis accelerometer */
+#define LISA_NUM_AXIS 3
+static const struct {
+ const char *name;
+ const uint8_t reg;
+} lisa_axis[LISA_NUM_AXIS] = {
+ { "OUT_X", 0x29 },
+ { "OUT_Y", 0x2b },
+ { "OUT_Z", 0x2d }
+};
+
+struct lisa_softc {
+ struct device sc_dev;
+ i2c_tag_t sc_tag;
+ i2c_addr_t sc_addr;
+
+ struct ksensor sc_sensors[LISA_NUM_AXIS];
+ struct ksensordev sc_sensordev;
+};
+
+
+int lisa_match(struct device *, void *, void *);
+void lisa_attach(struct device *, struct device *, void *);
+void lisa_refresh(void *);
+
+uint8_t lisa_readreg(struct lisa_softc *, uint8_t);
+void lisa_writereg(struct lisa_softc *, uint8_t, uint8_t);
+
+
+struct cfattach lisa_ca = {
+ sizeof(struct lisa_softc), lisa_match, lisa_attach
+};
+
+struct cfdriver lisa_cd = {
+ NULL, "lisa", DV_DULL
+};
+
+
+int
+lisa_match(struct device *parent, void *match, void *aux)
+{
+ struct i2c_attach_args *ia = aux;
+
+ if (strcmp(ia->ia_name, "lis331dl") == 0)
+ return 1;
+ return 0;
+}
+
+void
+lisa_attach(struct device *parent, struct device *self, void *aux)
+{
+ struct lisa_softc *sc = (struct lisa_softc *)self;
+ struct i2c_attach_args *ia = aux;
+ int i;
+
+ sc->sc_tag = ia->ia_tag;
+ sc->sc_addr = ia->ia_addr;
+
+ printf(": %s", ia->ia_name);
+
+ strlcpy(sc->sc_sensordev.xname, sc->sc_dev.dv_xname,
+ sizeof(sc->sc_sensordev.xname));
+
+ for (i = 0; i < LISA_NUM_AXIS; i++) {
+ strlcpy(sc->sc_sensors[i].desc, lisa_axis[i].name,
+ sizeof(sc->sc_sensors[i].desc));
+ sc->sc_sensors[i].type = SENSOR_INTEGER;
+ sensor_attach(&sc->sc_sensordev, &sc->sc_sensors[i]);
+ }
+
+ if (sensor_task_register(sc, lisa_refresh, 1) == NULL) {
+ printf(", unable to register update task\n");
+ return;
+ }
+
+ sensordev_install(&sc->sc_sensordev);
+ printf("\n");
+}
+
+void
+lisa_refresh(void *arg)
+{
+ struct lisa_softc *sc = arg;
+ struct ksensor *s = sc->sc_sensors;
+ int i;
+
+ iic_acquire_bus(sc->sc_tag, 0);
+ for (i = 0; i < LISA_NUM_AXIS; i++)
+ s[i].value = (int8_t)lisa_readreg(sc, lisa_axis[i].reg);
+ iic_release_bus(sc->sc_tag, 0);
+}
+
+uint8_t
+lisa_readreg(struct lisa_softc *sc, uint8_t reg)
+{
+ uint8_t data;
+
+ iic_exec(sc->sc_tag, I2C_OP_READ_WITH_STOP,
+ sc->sc_addr, &reg, sizeof reg, &data, sizeof data, 0);
+
+ return data;
+}
+
+void
+lisa_writereg(struct lisa_softc *sc, uint8_t reg, uint8_t data)
+{
+ iic_exec(sc->sc_tag, I2C_OP_WRITE_WITH_STOP,
+ sc->sc_addr, &reg, sizeof reg, &data, sizeof data, 0);
+}