Here is a driver I ported from NetBSD while learning things about OpenBSD ACPI stack. Not very useful.
hpacel0 at acpi0: HP 3D DriveGuard accelerometer hw.sensors.hpacel0.raw0=-14 (x-acceleration), OK hw.sensors.hpacel0.raw1=32 (y-acceleration), OK hw.sensors.hpacel0.raw2=957 (z-acceleration), OK Testing and comments appreciated. --- sys.clean/arch/amd64/conf/GENERIC Mon Jul 9 10:33:18 2012 +++ sys/arch/amd64/conf/GENERIC Fri Aug 3 16:52:22 2012 @@ -58,6 +58,7 @@ acpivout* at acpivideo? acpipwrres* at acpi? aibs* at acpi? +hpacel* at acpi? mpbios0 at bios0 --- sys.clean/arch/i386/conf/GENERIC Thu Jul 12 13:45:56 2012 +++ sys/arch/i386/conf/GENERIC Fri Aug 3 16:51:52 2012 @@ -65,6 +65,7 @@ acpivout* at acpivideo? acpipwrres* at acpi? aibs* at acpi? +hpacel* at acpi? option PCIVERBOSE option EISAVERBOSE --- sys.clean/dev/acpi/files.acpi Fri Jun 17 03:02:11 2011 +++ sys/dev/acpi/files.acpi Fri Aug 3 16:58:55 2012 @@ -111,3 +120,8 @@ device aibs attach aibs at acpi file dev/acpi/atk0110.c aibs + +# ACPI HP 3D Drive Guard +device hpacel +attach hpacel at acpi +file dev/acpi/hpacel.c hpacel diff -urN sys.clean/dev/acpi/acpireg.h sys/dev/acpi/acpireg.h --- sys.clean/dev/acpi/acpireg.h Fri Jul 13 15:51:41 2012 +++ sys/dev/acpi/acpireg.h Fri Aug 3 04:05:39 2012 @@ -738,6 +739,7 @@ #define ACPI_DEV_ASUS1 "ATK0100" /* ASUS Special Device */ #define ACPI_DEV_IBM "IBM0068" /* IBM ThinkPad support */ #define ACPI_DEV_LENOVO "LEN0068" /* Lenovo ThinkPad support */ +#define ACPI_DEV_HPACEL "HPQ0004" /* HP 3D Drive Guard */ #define ACPI_DEV_ASUSAIBOOSTER "ATK0110" /* ASUSTeK AI Booster */ #define ACPI_DEV_TOSHIBA_LIBRETTO "TOS6200" /* Toshiba Libretto support */ #define ACPI_DEV_TOSHIBA_DYNABOOK "TOS6207" /* Toshiba Dynabook support */ diff -urN sys.clean/dev/acpi/files.acpi sys/dev/acpi/files.acpi --- sys.clean/dev/acpi/files.acpi Fri Jun 17 03:02:11 2011 +++ sys/dev/acpi/files.acpi Fri Aug 3 16:58:55 2012 @@ -111,3 +120,8 @@ device aibs attach aibs at acpi file dev/acpi/atk0110.c aibs + +# ACPI HP 3D Drive Guard +device hpacel +attach hpacel at acpi +file dev/acpi/hpacel.c hpacel diff -urN sys.clean/dev/acpi/hpacel.c sys/dev/acpi/hpacel.c --- sys.clean/dev/acpi/hpacel.c Thu Jan 1 03:00:00 1970 +++ sys/dev/acpi/hpacel.c Fri Aug 3 16:35:47 2012 @@ -0,0 +1,533 @@ +/* $OpenBSD$ */ +/* $NetBSD: hpacel_acpi.c,v 1.3 2011/09/07 08:43:20 cegger Exp $ */ + +/*- + * Copyright (c) 2009, 2011 Jukka Ruohonen <[email protected]> + * 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/param.h> +#include <sys/device.h> +#include <sys/systm.h> +#include <sys/workq.h> +#include <sys/types.h> +#include <sys/time.h> +#include <sys/malloc.h> +#include <sys/sensors.h> +#include <sys/kthread.h> + +#include <dev/acpi/acpireg.h> +#include <dev/acpi/acpivar.h> +#include <dev/acpi/acpidev.h> +#include <dev/acpi/amltypes.h> +#include <dev/acpi/dsdt.h> +#include <dev/acpi/acpiwmivar.h> + +/* + * An ACPI driver for Hewlett-Packard 3D DriveGuard accelerometer. + * + * The supported chipset is LIS3LV02DL from STMicroelectronics: + * + * http://www.st.com/stonline/products/literature/anp/12441.pdf + * + * (Obtained on Sat Apr 25 00:32:04 EEST 2009.) + * + * The chip is a three axes digital output linear accelerometer + * that is controllable through I2C / SPI serial interface. This + * implementation however supports only indirect connection through + * ACPI. Other chips from the same family, such as LIS3LV02DQ, may + * also work with the driver, provided that there is a suitable DSDT. + * + * The chip can generate wake-up, direction detection and free-fall + * interrupts. The latter could be used to evoke emergency action. + * None of this is however supported. Only sysmon_envsys(9) is used. + */ +enum { + HPACEL_SENSOR_X = 0, + HPACEL_SENSOR_Y, + HPACEL_SENSOR_Z, + HPACEL_SENSOR_COUNT +}; + +#define LIS3LV02DL_ID 0x3A + +enum lis3lv02dl_reg { + WHO_AM_I = 0x0F, /* r */ + OFFSET_X = 0x16, /* rw */ + OFFSET_Y = 0x17, /* rw */ + OFFSET_Z = 0x18, /* rw */ + GAIN_X = 0x19, /* rw */ + GAIN_Y = 0x1A, /* rw */ + GAIN_Z = 0x1B, /* rw */ + CTRL_REG1 = 0x20, /* rw */ + CTRL_REG2 = 0x21, /* rw */ + CTRL_REG3 = 0x22, /* rw */ + HP_FILTER_RESET = 0x23, /* r */ + STATUS_REG = 0x27, /* rw */ + OUTX_L = 0x28, /* r */ + OUTX_H = 0x29, /* r */ + OUTY_L = 0x2A, /* r */ + OUTY_H = 0x2B, /* r */ + OUTZ_L = 0x2C, /* r */ + OUTZ_H = 0x2D, /* r */ + FF_WU_CFG = 0x30, /* r */ + FF_WU_SRC = 0x31, /* rw */ + FF_WU_ACK = 0x32, /* r */ + FF_WU_THS_L = 0x34, /* rw */ + FF_WU_THS_H = 0x35, /* rw */ + FF_WU_DURATION = 0x36, /* rw */ + DD_CFG = 0x38, /* rw */ + DD_SRC = 0x39, /* rw */ + DD_ACK = 0x3A, /* r */ + DD_THSI_L = 0x3C, /* rw */ + DD_THSI_H = 0x3D, /* rw */ + DD_THSE_L = 0x3E, /* rw */ + DD_THSE_H = 0x3F /* rw */ +}; + +enum lis3lv02dl_ctrl1 { + CTRL1_Xen = (1 << 0), /* X-axis enable */ + CTRL1_Yen = (1 << 1), /* Y-axis enable */ + CTRL1_Zen = (1 << 2), /* Z-axis enable */ + CTRL1_ST = (1 << 3), /* Self test enable */ + CTRL1_DF0 = (1 << 4), /* Decimation factor control */ + CTRL1_DF1 = (1 << 5), /* Decimation factor control */ + CTRL1_PD0 = (1 << 6), /* Power down control */ + CTRL1_PD1 = (1 << 7) /* Power down control */ +}; + +enum lis3lv02dl_ctrl2 { + CTRL2_DAS = (1 << 0), /* Data alignment selection */ + CTRL2_SIM = (1 << 1), /* SPI serial interface mode */ + CTRL2_DRDY = (1 << 2), /* Enable data-ready generation */ + CTRL2_IEN = (1 << 3), /* Enable interrupt mode */ + CTRL2_BOOT = (1 << 4), /* Reboot memory contents */ + CTRL2_BLE = (1 << 5), /* Endian mode */ + CTRL2_BDU = (1 << 6), /* Block data update */ + CTRL2_FS = (1 << 7) /* Full scale selection */ +}; + +enum lis3lv02dl_ctrl3 { + CTRL3_CFS0 = (1 << 0), /* High-pass filter cut-off frequency */ + CTRL3_CFS1 = (1 << 1), /* High-pass filter cut-off frequency */ + CTRL3_FDS = (1 << 4), /* Filtered data selection */ + CTRL3_HPFF = (1 << 5), /* High pass filter for free-fall */ + CTRL3_HPDD = (1 << 6), /* High pass filter for DD */ + CTRL3_ECK = (1 << 7) /* External clock */ +}; + +struct hpacel_softc { + struct device sc_dev; + struct aml_node *sc_node; + struct acpi_softc *sc_acpi; + int sc_state; + uint8_t sc_whoami; + uint8_t sc_ctrl[3]; + struct ksensordev sc_sensordev; + struct ksensor sc_sensor[HPACEL_SENSOR_COUNT]; + struct timeout sc_timeout; +}; + +const char * hpacel_ids[] = { + "HPQ0004", + NULL +}; + +#define LENGTH(_a) (sizeof(_a)/sizeof(_a[0])) +#define static +static int hpacel_activate(struct device *, int); +static int hpacel_match(struct device *, void *, void *); +static void hpacel_attach(struct device *, struct device *, void *); +static int hpacel_reg_init(struct hpacel_softc *); +static int hpacel_reg_info(struct hpacel_softc *); +static int hpacel_reg_read(struct hpacel_softc *, uint64_t, uint8_t *); +static int hpacel_reg_write(struct hpacel_softc *, uint64_t, uint8_t); +static int hpacel_reg_xyz(struct hpacel_softc *, const int, int16_t *); +static int hpacel_power(struct hpacel_softc *, int); +static int hpacel_sensor_init(struct hpacel_softc *); +static void hpacel_sensor_refresh(void *); +static void hpacel_create_thread(void *arg); + +struct cfattach hpacel_ca = { + sizeof(struct hpacel_softc), hpacel_match, hpacel_attach, + hpacel_activate +}; + +struct cfdriver hpacel_cd = { + NULL, "hpacel", DV_DULL +}; + +static int +hpacel_match(struct device *parent, void *match, void *aux) +{ + struct acpi_attach_args *aa = aux; + struct cfdata *cf = match; + + return acpi_matchhids(aa, hpacel_ids, cf->cf_driver->cd_name); +} + +static void +hpacel_attach(struct device *parent, struct device *self, void *aux) +{ + struct hpacel_softc *sc = (struct hpacel_softc *)self; + struct acpi_attach_args *aa = aux; + + sc->sc_acpi = (struct acpi_softc *)parent; + sc->sc_state = 0; + sc->sc_node = aa->aaa_node; + + printf(": HP 3D DriveGuard accelerometer\n"); + + if (hpacel_reg_init(sc) != 1) + return; + + if (hpacel_sensor_init(sc) != 0) + (void)hpacel_power(sc, 1); + + sc->sc_state = 1; +} + +static int +hpacel_activate(struct device *self, int act) +{ + struct hpacel_softc *sc = (struct hpacel_softc *)self; + + if (!sc->sc_state) + return 0; + switch (act) { + case DVACT_SUSPEND: + hpacel_power(sc, 0); + break; + case DVACT_RESUME: + hpacel_power(sc, 1); + break; + } + return 0; +} + +static int +hpacel_reg_init(struct hpacel_softc *sc) +{ + int rv; + uint8_t val; + + rv = aml_evalname(sc->sc_acpi, sc->sc_node, "_INI", 0, NULL, NULL); + + if (rv != 0) + goto out; + + /* + * Since the "_INI" is practically + * a black box, it is better to verify + * the control registers manually. + */ + rv = hpacel_reg_info(sc); + + if (rv != 0) + goto out; + + val = sc->sc_ctrl[0]; + + if ((sc->sc_ctrl[0] & CTRL1_Xen) == 0) + val |= CTRL1_Xen; + + if ((sc->sc_ctrl[0] & CTRL1_Yen) == 0) + val |= CTRL1_Yen; + + if ((sc->sc_ctrl[0] & CTRL1_Zen) == 0) + val |= CTRL1_Zen; + + if (val != sc->sc_ctrl[0]) { + + rv = hpacel_reg_write(sc, CTRL_REG1, val); + + if (rv != 0) + return rv; + } + + val = sc->sc_ctrl[1]; + + if ((sc->sc_ctrl[1] & CTRL2_BDU) == 0) + val |= CTRL2_BDU; + + if ((sc->sc_ctrl[1] & CTRL2_BLE) != 0) + val &= ~CTRL2_BLE; + + if ((sc->sc_ctrl[1] & CTRL2_DAS) != 0) + val &= ~CTRL2_DAS; + + /* + * Given the use of sysmon_envsys(9), + * there is no need for the data-ready pin. + */ + if ((sc->sc_ctrl[1] & CTRL2_DRDY) != 0) + val &= ~CTRL2_DRDY; + + /* + * Disable interrupt mode. + */ + if ((sc->sc_ctrl[1] & CTRL2_IEN) != 0) + val &= ~CTRL2_IEN; + + if (val != sc->sc_ctrl[1]) { + + rv = hpacel_reg_write(sc, CTRL_REG2, val); + + if (rv != 0) + return rv; + } + + /* + * Clear possible interrupt setups from + * the direction-detection register and + * from the free-fall-wake-up register. + */ + (void)hpacel_reg_write(sc, DD_CFG, 0x00); + (void)hpacel_reg_write(sc, FF_WU_CFG, 0x00); + + /* + * Update the register information. + */ + (void)hpacel_reg_info(sc); + +out: + if (rv != 0) + printf("%s: failed to initialize " + "device: %s\n", DEVNAME(sc)); + + return (rv != 0) ? 0 : 1; +} + +static int +hpacel_reg_info(struct hpacel_softc *sc) +{ + int rv; + size_t i; + + rv = hpacel_reg_read(sc, WHO_AM_I, &sc->sc_whoami); + + if (rv != 0) + return rv; + + for (i = 0; i < LENGTH(sc->sc_sensor); i++) { + + rv = hpacel_reg_read(sc, CTRL_REG1 + i, &sc->sc_ctrl[i]); + + if (rv != 0) + return rv; + } + + return 0; +} + +static int +hpacel_reg_read(struct hpacel_softc *sc, uint64_t reg, uint8_t *valp) +{ + int64_t val; + int rv; + struct aml_value obj; + + obj.type = AML_OBJTYPE_INTEGER; + obj.v_integer = reg; + + rv = aml_evalinteger(sc->sc_acpi, sc->sc_node, "ALRD", 1, &obj, &val); + if (rv != 0) + return rv; + if (val > 255) + return 1; + *valp = val; + return 0; +} + +static int +hpacel_reg_write(struct hpacel_softc *sc, uint64_t reg, uint8_t val) +{ + int rv; + struct aml_value obj[2]; + struct aml_value buf; + struct aml_node *node; + + obj[0].type = obj[1].type = AML_OBJTYPE_INTEGER; + obj[0].v_integer = reg; + obj[1].v_integer = val; + node = aml_searchname(sc->sc_node, "ALWR"); + + rv = aml_evalnode(sc->sc_acpi, node, 2, obj, &buf); + if (rv != 0) + return rv; + return 0; +} + +static int +hpacel_reg_xyz(struct hpacel_softc *sc, const int xyz, int16_t *out) +{ + uint64_t reg[2]; + int rv[2]; + uint8_t hi, lo; + + switch (xyz) { + + case HPACEL_SENSOR_X: + reg[0] = OUTX_L; + reg[1] = OUTX_H; + break; + + case HPACEL_SENSOR_Y: + reg[0] = OUTY_L; + reg[1] = OUTY_H; + break; + + case HPACEL_SENSOR_Z: + reg[0] = OUTZ_L; + reg[1] = OUTZ_H; + break; + + default: + return ACPI_E_BADVALUE; + } + + rv[0] = hpacel_reg_read(sc, reg[0], &lo); + rv[1] = hpacel_reg_read(sc, reg[1], &hi); + + if (rv[0] != 0 || rv[1] != 0) + return 1; + + /* + * These registers are read in "12 bit right + * justified mode", meaning that the four + * most significant bits are replaced with + * the value of bit 12. Note the signed type. + */ + hi = (hi & 0x10) ? hi | 0xE0 : hi & ~0xE0; + + *out = (hi << 8) | lo; + + return 0; +} + +static int +hpacel_power(struct hpacel_softc *sc, int enable) +{ + struct aml_value obj; + struct aml_node *node; + int rv; + uint8_t val; + + rv = hpacel_reg_info(sc); + + if (rv != 0) + return rv; + + val = sc->sc_ctrl[0]; + + if (enable != 0) + val |= CTRL1_PD0 | CTRL1_PD1; + else { + val &= ~(CTRL1_PD0 | CTRL1_PD1); + } + + if (val != sc->sc_ctrl[0]) { + + rv = hpacel_reg_write(sc, CTRL_REG1, val); + + if (rv != 0) + return rv; + } + + obj.type = AML_OBJTYPE_INTEGER; + obj.v_integer = enable; + + /* + * This should turn on/off a led, if available. + */ + node = aml_searchname(sc->sc_node, "ALED"); + aml_evalnode(sc->sc_acpi, node, 1, &obj, NULL); + + return rv; +} + +static void +hpacel_create_thread(void *arg) +{ + struct hpacel_softc *sc = (struct hpacel_softc *)arg; + + kthread_create(hpacel_sensor_refresh, sc, NULL, "hpaccel"); +} + +static int +hpacel_sensor_init(struct hpacel_softc *sc) +{ + const char zyx[HPACEL_SENSOR_COUNT] = { 'x', 'y', 'z' }; + size_t i; + + strlcpy(sc->sc_sensordev.xname, DEVNAME(sc), + sizeof(sc->sc_sensordev.xname)); + for (i = 0; i < LENGTH(sc->sc_sensor); i++) { + sc->sc_sensor[i].type = SENSOR_INTEGER; + sc->sc_sensor[i].status = SENSOR_S_UNSPEC; + + (void)snprintf(sc->sc_sensor[i].desc, + sizeof(sc->sc_sensor[i].desc), "%c-acceleration", zyx[i]); + + sensor_attach(&sc->sc_sensordev, &sc->sc_sensor[i]); + } + + /* + * We only do polling, given the hopelessly + * slow way of reading registers with ACPI. + */ + sensordev_install(&sc->sc_sensordev); + kthread_create_deferred(hpacel_create_thread, sc); + return 0; +} + +static void +hpacel_sensor_refresh(void *arg) +{ + struct hpacel_softc *sc = (struct hpacel_softc *)arg; + int rv; + int16_t val; + size_t i; + struct timeval tv; + int timo; + + memset(&tv, 0, sizeof(tv)); + tv.tv_sec = 1; + timo = tvtohz(&tv); + while (1) { + for (i = 0; i < LENGTH(sc->sc_sensor); i++) { + rv = hpacel_reg_xyz(sc, i, &val); + + if (rv == 0) { + sc->sc_sensor[i].value = val; + sc->sc_sensor[i].status = SENSOR_S_OK; + continue; + } + + sc->sc_sensor[i].status = SENSOR_S_UNSPEC; + } + tsleep(&rv, PWAIT, "timeout", timo); + } +} diff -urN sys.clean/dev/acpi/acpi.c sys/dev/acpi/acpi.c --- sys.clean/dev/acpi/acpi.c Thu Jan 1 03:00:00 1970 +++ sys/dev/acpi/acpi.c Fri Aug 3 16:35:47 2012 @@ -2346,9 +2347,9 @@ !strcmp(dev, ACPI_DEV_TOSHIBA_SPA40)) { aaa.aaa_name = "acpitoshiba"; acpi_toshiba_enabled = 1; - } + } else if (!strcmp(dev, ACPI_DEV_HPACEL)) + aaa.aaa_name = "hpacel"; - if (aaa.aaa_name) config_found(self, &aaa, acpi_print); And here's the manual page. Where do I put it? share/man/man4 or machine-dependent subdirectory? .\" $NetBSD: hpacel.4,v 1.4 2011/09/07 08:54:41 jruoho Exp $ .\" .\" Copyright (c) 2011 Jukka Ruohonen <[email protected]> .\" 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. Neither the name of the author nor the names of any .\" contributors may be used to endorse or promote products derived .\" from this software without specific prior written permission. .\" .\" 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 FOUNDATION 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. .\" .Dd September 7, 2011 .Dt HPACEL 4 .Os .Sh NAME .Nm hpacel .Nd HP 3D DriveGuard accelerometer .Sh SYNOPSIS .Cd "hpacel* at acpi?" .Sh DESCRIPTION The .Nm device driver supports accelerometers that are commonly available in Hewlett-Packard laptops. The supported chip is .Dv LIS3LV02DL from STMicroelectronics, although other chips from the same family, such as .Dv LIS3LV02DQ , may also work, provided that the vendor has implemented suitable .Dv ACPI access methods. .Pp The .Nm driver reports the acceleration readings of the X-, Y-, and Z-axis via the .Xr sysctl 8 interface. .Sh SEE ALSO .Xr acpi 4 , .Xr aps 4 , .Xr sensorsd 8 .Rs .%A STMicroelectronics .%T "LIS3LV02DL: 3-Axis - \*(Pm\* 2g/\*(Pm\* 6g digital output \ low voltage linear accelerometer. AN2381 Application Note" .%N Revision 1 .%D June, 2006 .%U http://www.st.com/stonline/products/literature/anp/12441.pdf .Re .Sh HISTORY The .Nm device driver appeared in .Nx 6.0 . .Sh AUTHORS .An Jukka Ruohonen .Aq [email protected] .Sh BUGS The used accelerometer chip is capable of generating wake-up, direction detection, and free-fall interrupts. In the ideal situation these could be used to evoke possible emergency action. However, the .Nm driver only reports the readings from the accelerometer via .Xr sysctl 8 .
