You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@nuttx.apache.org by xi...@apache.org on 2024/03/09 03:54:03 UTC

(nuttx) branch master updated (11efa29192 -> b7db53b6e1)

This is an automated email from the ASF dual-hosted git repository.

xiaoxiang pushed a change to branch master
in repository https://gitbox.apache.org/repos/asf/nuttx.git


    from 11efa29192 esp32h2/scripts: Add simpleboot support for esp32h2
     new 79e8aa5e21 sensors: add uorb support for lsm9ds1
     new b7db53b6e1 nrf52/common: support for lsm9ds1 uorb

The 2 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:
 boards/arm/nrf52/common/src/nrf52_lsm9ds1.c   |   36 +-
 drivers/sensors/CMakeLists.txt                |    7 +-
 drivers/sensors/Kconfig                       |   32 +-
 drivers/sensors/Make.defs                     |    7 +-
 drivers/sensors/lsm9ds1.c                     | 1125 +------------------------
 drivers/sensors/lsm9ds1_base.c                |  717 ++++++++++++++++
 drivers/sensors/{lsm9ds1.c => lsm9ds1_base.h} | 1060 +----------------------
 drivers/sensors/lsm9ds1_uorb.c                |  803 ++++++++++++++++++
 include/nuttx/sensors/lsm9ds1.h               |   30 +
 include/nuttx/sensors/sensor.h                |    2 +-
 10 files changed, 1653 insertions(+), 2166 deletions(-)
 create mode 100644 drivers/sensors/lsm9ds1_base.c
 copy drivers/sensors/{lsm9ds1.c => lsm9ds1_base.h} (54%)
 create mode 100644 drivers/sensors/lsm9ds1_uorb.c


(nuttx) 01/02: sensors: add uorb support for lsm9ds1

Posted by xi...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

xiaoxiang pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/nuttx.git

commit 79e8aa5e21e8e802b5fb56712c695ced00503213
Author: raiden00pl <ra...@railab.me>
AuthorDate: Sat Aug 26 15:44:52 2023 +0200

    sensors: add uorb support for lsm9ds1
---
 drivers/sensors/CMakeLists.txt                |    7 +-
 drivers/sensors/Kconfig                       |   32 +-
 drivers/sensors/Make.defs                     |    7 +-
 drivers/sensors/lsm9ds1.c                     | 1125 +------------------------
 drivers/sensors/lsm9ds1_base.c                |  717 ++++++++++++++++
 drivers/sensors/{lsm9ds1.c => lsm9ds1_base.h} | 1060 +----------------------
 drivers/sensors/lsm9ds1_uorb.c                |  803 ++++++++++++++++++
 include/nuttx/sensors/lsm9ds1.h               |   30 +
 include/nuttx/sensors/sensor.h                |    2 +-
 9 files changed, 1618 insertions(+), 2165 deletions(-)

diff --git a/drivers/sensors/CMakeLists.txt b/drivers/sensors/CMakeLists.txt
index 34010f349e..a5e6c49b57 100644
--- a/drivers/sensors/CMakeLists.txt
+++ b/drivers/sensors/CMakeLists.txt
@@ -113,7 +113,12 @@ if(CONFIG_SENSORS)
     endif()
 
     if(CONFIG_SENSORS_LSM9DS1)
-      list(APPEND SRCS lsm9ds1.c)
+      list(APPEND SRCS lsm9ds1_base.c)
+      if(CONFIG_SENSORS_LSM9DS1_UORB)
+        list(APPEND SRCS lsm9ds1_uorb.c)
+      else()
+        list(APPEND SRCS lsm9ds1.c)
+      endif()
     endif()
 
     if(CONFIG_SENSORS_MSA301)
diff --git a/drivers/sensors/Kconfig b/drivers/sensors/Kconfig
index 342daa2ff4..3a3a419f69 100644
--- a/drivers/sensors/Kconfig
+++ b/drivers/sensors/Kconfig
@@ -605,6 +605,36 @@ config SENSORS_LSM9DS1
 	---help---
 		Enable driver support for the STMicro LSM9DS1.
 
+config SENSORS_LSM9DS1_UORB
+	bool "LSM9DS1 UORB Interface"
+	default n
+	depends on SENSORS_LSM9DS1
+
+if SENSORS_LSM9DS1_UORB
+
+config SENSORS_LSM9DS1_POLL
+	bool "Enables polling sensor data"
+	default n
+	---help---
+		Enables polling of sensor.
+
+config SENSORS_LSM9DS1_POLL_INTERVAL
+	int "Polling interval in microseconds, default 1 sec"
+	depends on SENSORS_LSM9DS1_POLL
+	default 1000000
+	range 0 4294967295
+	---help---
+		The interval until a new sensor measurement will be triggered.
+
+config SENSORS_LSM9DS1_THREAD_STACKSIZE
+	int "Worker thread stack size"
+	depends on SENSORS_LSM9DS1_POLL
+	default 1024
+	---help---
+		The stack size for the worker thread.
+
+endif #SENSORS_LSM9DS1_UORB
+
 config SENSORS_MSA301
 	bool "MSA301 support"
 	default n
@@ -616,7 +646,7 @@ config LSM9DS1_I2C_FREQUENCY
 	int "LSM9DS1 I2C frequency"
 	default 400000
 	range 1 400000
-	depends on SENSORS_LSM9DS1
+	depends on SENSORS_LSM9DS1 || SENSORS_LSM9DS1_UORB
 
 config SENSORS_LPS25H
 	bool "STMicro LPS25H pressure sensor"
diff --git a/drivers/sensors/Make.defs b/drivers/sensors/Make.defs
index 8e513ab06e..19ad604aff 100644
--- a/drivers/sensors/Make.defs
+++ b/drivers/sensors/Make.defs
@@ -121,7 +121,12 @@ ifeq ($(CONFIG_SENSORS_LSM6DSL),y)
 endif
 
 ifeq ($(CONFIG_SENSORS_LSM9DS1),y)
-  CSRCS += lsm9ds1.c
+  CSRCS += lsm9ds1_base.c
+  ifeq ($(CONFIG_SENSORS_LSM9DS1_UORB),y)
+    CSRCS += lsm9ds1_uorb.c
+  else
+    CSRCS += lsm9ds1.c
+  endif
 endif
 
 ifeq ($(CONFIG_SENSORS_MSA301),y)
diff --git a/drivers/sensors/lsm9ds1.c b/drivers/sensors/lsm9ds1.c
index 23e578d4d1..ece7affa77 100644
--- a/drivers/sensors/lsm9ds1.c
+++ b/drivers/sensors/lsm9ds1.c
@@ -24,542 +24,14 @@
 
 #include <nuttx/config.h>
 
-#include <assert.h>
-#include <errno.h>
-#include <debug.h>
-#include <stdlib.h>
-
-#include <nuttx/kmalloc.h>
-#include <nuttx/random.h>
-#include <nuttx/fs/fs.h>
-#include <nuttx/i2c/i2c_master.h>
-#include <nuttx/sensors/lsm9ds1.h>
+#include "lsm9ds1_base.h"
 
 #if defined(CONFIG_I2C) && defined(CONFIG_SENSORS_LSM9DS1)
 
-/****************************************************************************
- * Pre-processor Definitions
- ****************************************************************************/
-
-#ifndef CONFIG_LSM9DS1_I2C_FREQUENCY
-#  define CONFIG_LSM9DS1_I2C_FREQUENCY 400000
-#endif
-
-/* Register Addresses *******************************************************/
-
-/* Accelerometer and gyroscope registers */
-
-#define LSM9DS1_ACT_THS                         0x04 /* Inactivity threshold */
-#define LSM9DS1_ACT_DUR                         0x05 /* Inactivity duration */
-#define LSM9DS1_INT_GEN_CFG_XL                  0x06 /* Accelerometer interrupt configuration */
-#define LSM9DS1_INT_GEN_THS_X_XL                0x07 /* Accelerometer X interrupt threshold */
-#define LSM9DS1_INT_GEN_THS_Y_XL                0x08 /* Accelerometer Y interrupt threshold */
-#define LSM9DS1_INT_GEN_THS_Z_XL                0x09 /* Accelerometer Z interrupt threshold */
-#define LSM9DS1_INT_GEN_DUR_XL                  0x0a /* Accelerometer interrupt duration */
-#define LSM9DS1_REFERENCE_G                     0x0b /* Gyroscope reference value for high-pass filter */
-#define LSM9DS1_INT1_CTRL                       0x0c /* INT1_A/G pin control */
-#define LSM9DS1_INT2_CTRL                       0x0d /* INT2_A/G pin control */
-#define LSM9DS1_WHO_AM_I                        0x0f /* Accelerometer and gyroscope device identification */
-#define LSM9DS1_CTRL_REG1_G                     0x10 /* Gyroscope control register 1 */
-#define LSM9DS1_CTRL_REG2_G                     0x11 /* Gyroscope control register 2 */
-#define LSM9DS1_CTRL_REG3_G                     0x12 /* Gyroscope control register 3 */
-#define LSM9DS1_ORIENT_CFG_G                    0x13 /* Gyroscope sign and orientation */
-#define LSM9DS1_INT_GEN_SRC_G                   0x14 /* Gyroscope interrupt source */
-#define LSM9DS1_OUT_TEMP_L                      0x15 /* Temperature low byte */
-#define LSM9DS1_OUT_TEMP_H                      0x16 /* Temperature high byte */
-#define LSM9DS1_STATUS_REG                      0x17 /* Status register */
-#define LSM9DS1_OUT_X_L_G                       0x18 /* Gyroscope pitch (X) low byte */
-#define LSM9DS1_OUT_X_H_G                       0x19 /* Gyroscope pitch (X) high byte */
-#define LSM9DS1_OUT_Y_L_G                       0x1a /* Gyroscope roll (Y) low byte */
-#define LSM9DS1_OUT_Y_H_G                       0x1b /* Gyroscope roll (Y) high byte */
-#define LSM9DS1_OUT_Z_L_G                       0x1c /* Gyroscope yaw (Z) low byte */
-#define LSM9DS1_OUT_Z_H_G                       0x1d /* Gyroscope yaw (Z) high byte */
-#define LSM9DS1_CTRL_REG4                       0x1e /* Control register 4 */
-#define LSM9DS1_CTRL_REG5_XL                    0x1f /* Accelerometer control register 5 */
-#define LSM9DS1_CTRL_REG6_XL                    0x20 /* Accelerometer control register 6 */
-#define LSM9DS1_CTRL_REG7_XL                    0x21 /* Accelerometer control register 7 */
-#define LSM9DS1_CTRL_REG8                       0x22 /* Control register 8 */
-#define LSM9DS1_CTRL_REG9                       0x23 /* Control register 9 */
-#define LSM9DS1_CTRL_REG10                      0x24 /* Control register 10 */
-#define LSM9DS1_INT_GEN_SRC_XL                  0x26 /* Accelerometer interrupt source */
-#define LSM9DS1_STATUS_REG2                     0x27 /* Status register 2 */
-#define LSM9DS1_OUT_X_L_XL                      0x28 /* Accelerometer X low byte */
-#define LSM9DS1_OUT_X_H_XL                      0x29 /* Accelerometer X high byte */
-#define LSM9DS1_OUT_Y_L_XL                      0x2a /* Accelerometer Y low byte */
-#define LSM9DS1_OUT_Y_H_XL                      0x2b /* Accelerometer Y high byte */
-#define LSM9DS1_OUT_Z_L_XL                      0x2c /* Accelerometer Z low byte */
-#define LSM9DS1_OUT_Z_H_XL                      0x2d /* Accelerometer Z high byte */
-#define LSM9DS1_FIFO_CTRL                       0x2e /* FIFO control register */
-#define LSM9DS1_FIFO_SRC                        0x2f /* FIFO status control register */
-#define LSM9DS1_INT_GEN_CFG_G                   0x30 /* Gyroscope interrupt configuration */
-#define LSM9DS1_INT_GEN_THS_XH_G                0x31 /* Gyroscope pitch (X) interrupt threshold high byte */
-#define LSM9DS1_INT_GEN_THS_XL_G                0x32 /* Gyroscope pitch (X) interrupt threshold low byte */
-#define LSM9DS1_INT_GEN_THS_YH_G                0x33 /* Gyroscope roll (Y) interrupt threshold high byte */
-#define LSM9DS1_INT_GEN_THS_YL_G                0x34 /* Gyroscope roll (Y) interrupt threshold low byte */
-#define LSM9DS1_INT_GEN_THS_ZH_G                0x35 /* Gyroscope yaw (Z) interrupt threshold high byte */
-#define LSM9DS1_INT_GEN_THS_ZL_G                0x36 /* Gyroscope yaw (Z) interrupt threshold low byte */
-#define LSM9DS1_INT_GEN_DUR_G                   0x37 /* Gyroscope interrupt duration */
-
-/* Magnetometer registers */
-
-#define LSM9DS1_OFFSET_X_REG_L_M                0x05 /* X low byte offset */
-#define LSM9DS1_OFFSET_X_REG_H_M                0x06 /* X high byte offset */
-#define LSM9DS1_OFFSET_Y_REG_L_M                0x07 /* Y low byte offset */
-#define LSM9DS1_OFFSET_Y_REG_H_M                0x08 /* Y high byte offset */
-#define LSM9DS1_OFFSET_Z_REG_L_M                0x09 /* Z low byte offset */
-#define LSM9DS1_OFFSET_Z_REG_H_M                0x0a /* Z high byte offset */
-#define LSM9DS1_WHO_AM_I_M                      0x0f /* Device identification */
-#define LSM9DS1_CTRL_REG1_M                     0x20 /* Control register 1 */
-#define LSM9DS1_CTRL_REG2_M                     0x21 /* Control register 2 */
-#define LSM9DS1_CTRL_REG3_M                     0x22 /* Control register 3 */
-#define LSM9DS1_CTRL_REG4_M                     0x23 /* Control register 4 */
-#define LSM9DS1_CTRL_REG5_M                     0x24 /* Control register 5 */
-#define LSM9DS1_STATUS_REG_M                    0x27 /* Status register */
-#define LSM9DS1_OUT_X_L_M                       0x28 /* X low byte */
-#define LSM9DS1_OUT_X_H_M                       0x29 /* X high byte */
-#define LSM9DS1_OUT_Y_L_M                       0x2a /* Y low byte */
-#define LSM9DS1_OUT_Y_H_M                       0x2b /* Y high byte */
-#define LSM9DS1_OUT_Z_L_M                       0x2c /* Z low byte */
-#define LSM9DS1_OUT_Z_H_M                       0x2d /* Z high byte */
-#define LSM9DS1_INT_CFG_M                       0x30 /* Interrupt configuration */
-#define LSM9DS1_INT_SRC_M                       0x31 /* Interrupt source */
-#define LSM9DS1_INT_THS_L_M                     0x32 /* Interrupt threshold low byte */
-#define LSM9DS1_INT_THS_H_M                     0x33 /* Interrupt threshold high byte */
-
-/* Register Bit Definitions *************************************************/
-
-/* Inactivity threshold register */
-
-#define LSM9DS1_ACT_THS_ACT_THS_SHIFT           0 /* Inactivity threshold */
-#define LSM9DS1_ACT_THS_ACT_THS_MASK            (127 << LSM9DS1_ACT_THS_ACT_THS_SHIFT)
-#define LSM9DS1_ACT_THS_SLEEP_ON_INACT_EN       (1 << 7) /* Gyroscope operating mode during inactivity */
-
-/* Accelerometer interrupt configuration register */
-
-#define LSM9DS1_INT_GEN_CFG_XL_XLIE_XL          (1 << 0) /* X-axis low byte interrupt enable */
-#define LSM9DS1_INT_GEN_CFG_XL_XHIE_XL          (1 << 1) /* X-axis high byte interrupt enable */
-#define LSM9DS1_INT_GEN_CFG_XL_YLIE_XL          (1 << 2) /* Y-axis low byte interrupt enable */
-#define LSM9DS1_INT_GEN_CFG_XL_YHIE_XL          (1 << 3) /* Y-axis high byte interrupt enable */
-#define LSM9DS1_INT_GEN_CFG_XL_ZLIE_XL          (1 << 4) /* Z-axis low byte interrupt enable */
-#define LSM9DS1_INT_GEN_CFG_XL_ZHIE_XL          (1 << 5) /* Z-axis high byte interrupt enable */
-#define LSM9DS1_INT_GEN_CFG_XL_6D               (1 << 6) /* 6-direction detection function for interrupt */
-#define LSM9DS1_INT_GEN_CFG_XL_AOI_XL           (1 << 7) /* AND/OR combination of interrupt events */
-
-/* Accelerometer interrupt duration register */
-
-#define LSM9DS1_INT_GEN_DUR_XL_DUR_XL_SHIFT     0 /* Enter/exit interrupt duration */
-#define LSM9DS1_INT_GEN_DUR_XL_DUR_XL_MASK      (127 << LSM9DS1_INT_GEN_DUR_XL_DUR_XL_SHIFT)
-#define LSM9DS1_INT_GEN_DUR_XL_WAIT_XL          (1 << 7) /* Wait function enabled on duration counter */
-
-/* INT1_A/G pin control register */
-
-#define LSM9DS1_INT1_CTRL_INT1_DRDY_XL          (1 << 0) /* Accelerometer data ready */
-#define LSM9DS1_INT1_CTRL_INT1_DRDY_G           (1 << 1) /* Gyroscope data ready */
-#define LSM9DS1_INT1_CTRL_INT1_BOOT             (1 << 2) /* Boot status available */
-#define LSM9DS1_INT1_CTRL_INT1_FTH              (1 << 3) /* FIFO threshold interrupt */
-#define LSM9DS1_INT1_CTRL_INT1_OVR              (1 << 4) /* Overrun interrupt */
-#define LSM9DS1_INT1_CTRL_INT1_FSS5             (1 << 5) /* FSS5 interrupt */
-#define LSM9DS1_INT1_CTRL_INT1_IG_XL            (1 << 6) /* Accelerometer interrupt enable */
-#define LSM9DS1_INT1_CTRL_INT1_IG_G             (1 << 7) /* Gyroscope interrupt enable */
-
-/* INT2_A/G pin control register */
-
-#define LSM9DS1_INT2_CTRL_INT2_DRDY_XL          (1 << 0) /* Accelerometer data ready */
-#define LSM9DS1_INT2_CTRL_INT2_DRDY_G           (1 << 1) /* Gyroscope data ready */
-#define LSM9DS1_INT2_CTRL_INT2_DRDY_TEMP        (1 << 2) /* Temperature data ready */
-#define LSM9DS1_INT2_CTRL_INT2_FTH              (1 << 3) /* FIFO threshold interrupt */
-#define LSM9DS1_INT2_CTRL_INT2_OVR              (1 << 4) /* Overrun interrupt */
-#define LSM9DS1_INT2_CTRL_INT2_FSS5             (1 << 5) /* FSS5 interrupt */
-#define LSM9DS1_INT2_CTRL_INT2_INACT            (1 << 7) /* Inactivity interrupt output signal */
-
-/* Device identification register */
-
-#define LSM9DS1_WHO_AM_I_VALUE                  0x68
-
-/* Gyroscope control register 1 */
-
-#define LSM9DS1_CTRL_REG1_G_BW_G_SHIFT          0 /* Gyroscope bandwidth selection */
-#define LSM9DS1_CTRL_REG1_G_BW_G_MASK           (3 << LSM9DS1_CTRL_REG1_G_BW_G_SHIFT)
-#define LSM9DS1_CTRL_REG1_G_FS_G_SHIFT          3 /* Gyroscope full-scale selection */
-#define LSM9DS1_CTRL_REG1_G_FS_G_MASK           (3 << LSM9DS1_CTRL_REG1_G_FS_G_SHIFT)
-#  define LSM9DS1_CTRL_REG1_G_FS_G_245DPS       (0 << LSM9DS1_CTRL_REG1_G_FS_G_SHIFT) /* 245 dps */
-#  define LSM9DS1_CTRL_REG1_G_FS_G_500DPS       (1 << LSM9DS1_CTRL_REG1_G_FS_G_SHIFT) /* 500 dps */
-#  define LSM9DS1_CTRL_REG1_G_FS_G_2000DPS      (3 << LSM9DS1_CTRL_REG1_G_FS_G_SHIFT) /* 2000 dps */
-
-#define LSM9DS1_CTRL_REG1_G_ODR_G_SHIFT         5 /* Gyroscope bandwidth selection */
-#define LSM9DS1_CTRL_REG1_G_ODR_G_MASK          (7 << LSM9DS1_CTRL_REG1_G_ODR_G_SHIFT)
-#  define LSM9DS1_CTRL_REG1_G_ODR_G_POWERDOWN   (0 << LSM9DS1_CTRL_REG1_G_ODR_G_SHIFT) /* Power-down mode */
-#  define LSM9DS1_CTRL_REG1_G_ODR_G_14p9HZ      (1 << LSM9DS1_CTRL_REG1_G_ODR_G_SHIFT) /* 14.9 Hz */
-#  define LSM9DS1_CTRL_REG1_G_ODR_G_59p5HZ      (2 << LSM9DS1_CTRL_REG1_G_ODR_G_SHIFT) /* 59.5 Hz */
-#  define LSM9DS1_CTRL_REG1_G_ODR_G_119HZ       (3 << LSM9DS1_CTRL_REG1_G_ODR_G_SHIFT) /* 119 Hz */
-#  define LSM9DS1_CTRL_REG1_G_ODR_G_238HZ       (4 << LSM9DS1_CTRL_REG1_G_ODR_G_SHIFT) /* 238 Hz */
-#  define LSM9DS1_CTRL_REG1_G_ODR_G_476HZ       (5 << LSM9DS1_CTRL_REG1_G_ODR_G_SHIFT) /* 476 Hz */
-#  define LSM9DS1_CTRL_REG1_G_ODR_G_952HZ       (6 << LSM9DS1_CTRL_REG1_G_ODR_G_SHIFT) /* 952 Hz */
-
-/* Gyroscope control register 2 */
-
-#define LSM9DS1_CTRL_REG2_G_OUT_SEL_SHIFT       0 /* Out selection configuration */
-#define LSM9DS1_CTRL_REG2_G_OUT_SEL_MASK        (3 << LSM9DS1_CTRL_REG2_G_OUT_SEL_SHIFT)
-#define LSM9DS1_CTRL_REG2_G_INT_SEL_SHIFT       2 /* INT selection configuration */
-#define LSM9DS1_CTRL_REG2_G_INT_SEL_MASK        (3 << LSM9DS1_CTRL_REG2_G_INT_SEL_SHIFT)
-
-/* Gyroscope control register 3 */
-
-#define LSM9DS1_CTRL_REG3_G_HPCF_G_SHIFT        0 /* Gyroscope high-pass filter cutoff frequency selection */
-#define LSM9DS1_CTRL_REG3_G_HPCF_G_MASK         (15 << LSM9DS1_CTRL_REG3_G_HPCF_G_SHIFT)
-#define LSM9DS1_CTRL_REG3_G_HP_EN               (1 << 6) /* High-pass filter enable */
-#define LSM9DS1_CTRL_REG3_G_LP_MODE             (1 << 7) /* Low-power mode enable */
-
-/* Gyroscope sign and orientation register */
-
-#define LSM9DS1_ORIENT_CFG_G_ORIENT_SHIFT       0 /* Directional user orientation selection */
-#define LSM9DS1_ORIENT_CFG_G_ORIENT_MASK        (3 << LSM9DS1_ORIENT_CFG_G_ORIENT_SHIFT)
-#define LSM9DS1_ORIENT_CFG_G_SIGNZ_G            (1 << 3) /* Yaw axis (Z) angular rate sign */
-#define LSM9DS1_ORIENT_CFG_G_SIGNY_G            (1 << 4) /* Roll axis (Y) angular rate sign */
-#define LSM9DS1_ORIENT_CFG_G_SIGNX_G            (1 << 5) /* Pitch axis (X) angular rate sign */
-
-/* Gyroscope interrupt source register */
-
-#define LSM9DS1_INT_GEN_SRC_G_XL_G              (1 << 0) /* Pitch (X) low */
-#define LSM9DS1_INT_GEN_SRC_G_XH_G              (1 << 1) /* Pitch (X) high */
-#define LSM9DS1_INT_GEN_SRC_G_YL_G              (1 << 2) /* Roll (Y) low */
-#define LSM9DS1_INT_GEN_SRC_G_YH_G              (1 << 3) /* Roll (Y) high */
-#define LSM9DS1_INT_GEN_SRC_G_ZL_G              (1 << 4) /* Yaw (Z) low */
-#define LSM9DS1_INT_GEN_SRC_G_ZH_G              (1 << 5) /* Yaw (Z) high */
-#define LSM9DS1_INT_GEN_SRC_G_IA_G              (1 << 6) /* Interrupt active */
-
-/* Status register */
-
-#define LSM9DS1_STATUS_REG_XLDA                 (1 << 0) /* Accelerometer new data available */
-#define LSM9DS1_STATUS_REG_GDA                  (1 << 1) /* Gyroscope new data available */
-#define LSM9DS1_STATUS_REG_TDA                  (1 << 2) /* Temperature sensor new data available */
-#define LSM9DS1_STATUS_REG_BOOT_STATUS          (1 << 3) /* Boot running flag signal */
-#define LSM9DS1_STATUS_REG_INACT                (1 << 4) /* Inactivity interrupt output signal */
-#define LSM9DS1_STATUS_REG_IG_G                 (1 << 5) /* Gyroscope interrupt output signal */
-#define LSM9DS1_STATUS_REG_IG_XL                (1 << 6) /* Accelerometer interrupt output signal */
-
-/* Control register 4 */
-
-#define LSM9DS1_CTRL_REG4_4D_XL1                (1 << 0) /* 4D option enabled on interrupt */
-#define LSM9DS1_CTRL_REG4_LIR_XL1               (1 << 1) /* Latched interrupt */
-#define LSM9DS1_CTRL_REG4_XEN_G                 (1 << 3) /* Gyroscope's pitch axis (X) output enable */
-#define LSM9DS1_CTRL_REG4_YEN_G                 (1 << 4) /* Gyroscope's roll axis (Y) output enable */
-#define LSM9DS1_CTRL_REG4_ZEN_G                 (1 << 5) /* Gyroscope's yaw axis (Z) output enable */
-
-/* Accelerometer control register 5 */
-
-#define LSM9DS1_CTRL_REG5_XL_XEN_XL             (1 << 3) /* Accelerometer's X-axis output enable */
-#define LSM9DS1_CTRL_REG5_XL_YEN_XL             (1 << 4) /* Accelerometer's Y-axis output enable */
-#define LSM9DS1_CTRL_REG5_XL_ZEN_XL             (1 << 5) /* Accelerometer's Z-axis output enable */
-
-#define LSM9DS1_CTRL_REG5_XL_DEC_SHIFT          6 /* Decimation of acceleration data on OUT REG and FIFO  */
-#define LSM9DS1_CTRL_REG5_XL_DEC_MASK           (3 << LSM9DS1_CTRL_REG5_XL_DEC_SHIFT)
-#  define LSM9DS1_CTRL_REG5_XL_DEC_NODEC        (0 << LSM9DS1_CTRL_REG5_XL_DEC_SHIFT) /* No decimation */
-#  define LSM9DS1_CTRL_REG5_XL_DEC_2SAMPLES     (1 << LSM9DS1_CTRL_REG5_XL_DEC_SHIFT) /* Update every 2 samples */
-#  define LSM9DS1_CTRL_REG5_XL_DEC_4SAMPLES     (2 << LSM9DS1_CTRL_REG5_XL_DEC_SHIFT) /* Update every 4 samples */
-#  define LSM9DS1_CTRL_REG5_XL_DEC_8SAMPLES     (3 << LSM9DS1_CTRL_REG5_XL_DEC_SHIFT) /* Update every 8 samples */
-
-/* Accelerometer control register 6 */
-
-#define LSM9DS1_CTRL_REG6_XL_BW_XL_SHIFT        0 /* Anti-aliasing filter bandwidth selection */
-#define LSM9DS1_CTRL_REG6_XL_BW_XL_MASK         (3 << LSM9DS1_CTRL_REG6_XL_BW_XL_SHIFT)
-#  define LSM9DS1_CTRL_REG6_XL_BW_XL_408HZ      (0 << LSM9DS1_CTRL_REG6_XL_BW_XL_SHIFT) /* 408 Hz */
-#  define LSM9DS1_CTRL_REG6_XL_BW_XL_211HZ      (1 << LSM9DS1_CTRL_REG6_XL_BW_XL_SHIFT) /* 211 Hz */
-#  define LSM9DS1_CTRL_REG6_XL_BW_XL_105HZ      (2 << LSM9DS1_CTRL_REG6_XL_BW_XL_SHIFT) /* 105 Hz */
-#  define LSM9DS1_CTRL_REG6_XL_BW_XL_50HZ       (3 << LSM9DS1_CTRL_REG6_XL_BW_XL_SHIFT) /* 50 Hz */
-
-#define LSM9DS1_CTRL_REG6_XL_BW_SCAL_ODR        (1 << 2) /* Bandwidth selection */
-
-#define LSM9DS1_CTRL_REG6_XL_FS_XL_SHIFT        3 /* Accelerometer full-scale selection */
-#define LSM9DS1_CTRL_REG6_XL_FS_XL_MASK         (3 << LSM9DS1_CTRL_REG6_XL_FS_XL_SHIFT)
-#  define LSM9DS1_CTRL_REG6_XL_FS_XL_2G         (0 << LSM9DS1_CTRL_REG6_XL_FS_XL_SHIFT) /* +/- 2 g */
-#  define LSM9DS1_CTRL_REG6_XL_FS_XL_16G        (1 << LSM9DS1_CTRL_REG6_XL_FS_XL_SHIFT) /* +/- 16 g */
-#  define LSM9DS1_CTRL_REG6_XL_FS_XL_4G         (2 << LSM9DS1_CTRL_REG6_XL_FS_XL_SHIFT) /* +/- 4 g */
-#  define LSM9DS1_CTRL_REG6_XL_FS_XL_8G         (3 << LSM9DS1_CTRL_REG6_XL_FS_XL_SHIFT) /* +/- 8 g */
-
-#define LSM9DS1_CTRL_REG6_XL_ODR_XL_SHIFT       5 /* Output data rate and power mode selection */
-#define LSM9DS1_CTRL_REG6_XL_ODR_XL_MASK        (7 << LSM9DS1_CTRL_REG6_XL_ODR_XL_SHIFT)
-#  define LSM9DS1_CTRL_REG6_XL_ODR_XL_POWERDOWN (0 << LSM9DS1_CTRL_REG6_XL_ODR_XL_SHIFT) /* Power-down mode */
-#  define LSM9DS1_CTRL_REG6_XL_ODR_XL_10HZ      (1 << LSM9DS1_CTRL_REG6_XL_ODR_XL_SHIFT) /* 10 Hz */
-#  define LSM9DS1_CTRL_REG6_XL_ODR_XL_50HZ      (2 << LSM9DS1_CTRL_REG6_XL_ODR_XL_SHIFT) /* 50 Hz */
-#  define LSM9DS1_CTRL_REG6_XL_ODR_XL_119HZ     (3 << LSM9DS1_CTRL_REG6_XL_ODR_XL_SHIFT) /* 119 Hz */
-#  define LSM9DS1_CTRL_REG6_XL_ODR_XL_238HZ     (4 << LSM9DS1_CTRL_REG6_XL_ODR_XL_SHIFT) /* 238 Hz */
-#  define LSM9DS1_CTRL_REG6_XL_ODR_XL_476HZ     (5 << LSM9DS1_CTRL_REG6_XL_ODR_XL_SHIFT) /* 476 Hz */
-#  define LSM9DS1_CTRL_REG6_XL_ODR_XL_952HZ     (6 << LSM9DS1_CTRL_REG6_XL_ODR_XL_SHIFT) /* 952 Hz */
-
-/* Accelerometer control register 7 */
-
-#define LSM9DS1_CTRL_REG7_XL_HPIS1              (1 << 0) /* High-pass filter enabled */
-#define LSM9DS1_CTRL_REG7_XL_FDS                (1 << 2) /* Filtered data selection */
-
-#define LSM9DS1_CTRL_REG7_XL_DCF_SHIFT          5 /* Accelerometer digital filter cutoff frequency selection */
-#define LSM9DS1_CTRL_REG7_XL_DCF_MASK           (3 << LSM9DS1_CTRL_REG7_XL_DCF_SHIFT)
-#  define LSM9DS1_CTRL_REG7_XL_DCF_ODR_DIV50    (0 << LSM9DS1_CTRL_REG7_XL_DCF_SHIFT)
-#  define LSM9DS1_CTRL_REG7_XL_DCF_ODR_DIV100   (1 << LSM9DS1_CTRL_REG7_XL_DCF_SHIFT)
-#  define LSM9DS1_CTRL_REG7_XL_DCF_ODR_DIV9     (2 << LSM9DS1_CTRL_REG7_XL_DCF_SHIFT)
-#  define LSM9DS1_CTRL_REG7_XL_DCF_ODR_DIV400   (3 << LSM9DS1_CTRL_REG7_XL_DCF_SHIFT)
-#define LSM9DS1_CTRL_REG7_XL_HR                 (1 << 7) /* High resolution mode enable */
-
-/* Control register 8 */
-
-#define LSM9DS1_CTRL_REG8_SW_RESET              (1 << 0) /* Software reset */
-#define LSM9DS1_CTRL_REG8_BLE                   (1 << 1) /* Big/little endian data selection */
-#define LSM9DS1_CTRL_REG8_IF_ADD_INC            (1 << 2) /* Register address automatically incremented during a multibyte access */
-#define LSM9DS1_CTRL_REG8_SIM                   (1 << 3) /* SPI serial interface mode selection */
-#define LSM9DS1_CTRL_REG8_PP_OD                 (1 << 4) /* Push-pull/open-drain selection on the INT1_A/G and INT2_A/G pins */
-#define LSM9DS1_CTRL_REG8_H_LACTIVE             (1 << 5) /* Interrupt activation level */
-#define LSM9DS1_CTRL_REG8_BDU                   (1 << 6) /* Block data update */
-#define LSM9DS1_CTRL_REG8_BOOT                  (1 << 7) /* Reboot memory content */
-
-/* Control register 9 */
-
-#define LSM9DS1_CTRL_REG9_STOP_ON_FTH           (1 << 0) /* Enable FIFO threshold level use */
-#define LSM9DS1_CTRL_REG9_FIFO_EN               (1 << 1) /* FIFO memory enable */
-#define LSM9DS1_CTRL_REG9_I2C_DISABLE           (1 << 2) /* Disable I2C interface */
-#define LSM9DS1_CTRL_REG9_DRDY_MASK_BIT         (1 << 3) /* Data available enable bit */
-#define LSM9DS1_CTRL_REG9_FIFO_TEMP_EN          (1 << 4) /* Temperature data storage in FIFO enable */
-#define LSM9DS1_CTRL_REG9_SLEEP_G               (1 << 6) /* Gyroscope sleep mode enable */
-
-/* Control register 10 */
-
-#define LSM9DS1_CTRL_REG10_ST_XL                (1 << 0) /* Linear acceleration sensor self-test enable */
-#define LSM9DS1_CTRL_REG10_ST_G                 (1 << 2) /* Angular rate sensor self-test enable */
-
-/* Accelerometer interrupt source register */
-
-#define LSM9DS1_INT_GEN_SRC_XL_XL_XL            (1 << 0) /* Accelerometer's X low event */
-#define LSM9DS1_INT_GEN_SRC_XL_XH_XL            (1 << 1) /* Accelerometer's X high event */
-#define LSM9DS1_INT_GEN_SRC_XL_YL_XL            (1 << 2) /* Accelerometer's Y low event */
-#define LSM9DS1_INT_GEN_SRC_XL_YH_XL            (1 << 3) /* Accelerometer's Y high event */
-#define LSM9DS1_INT_GEN_SRC_XL_ZL_XL            (1 << 4) /* Accelerometer's Z low event */
-#define LSM9DS1_INT_GEN_SRC_XL_ZH_XL            (1 << 5) /* Accelerometer's Z high event */
-#define LSM9DS1_INT_GEN_SRC_XL_IA_XL            (1 << 6) /* Interrupt active */
-
-/* Status register 2 */
-
-#define LSM9DS1_STATUS_REG2_XLDA                (1 << 0) /* Accelerometer new data available */
-#define LSM9DS1_STATUS_REG2_GDA                 (1 << 1) /* Gyroscope new data available */
-#define LSM9DS1_STATUS_REG2_TDA                 (1 << 2) /* Temperature sensor new data available */
-#define LSM9DS1_STATUS_REG2_BOOT_STATUS         (1 << 3) /* Boot running flag signal */
-#define LSM9DS1_STATUS_REG2_INACT               (1 << 4) /* Inactivity interrupt output signal */
-#define LSM9DS1_STATUS_REG2_IG_G                (1 << 5) /* Gyroscope interrupt output signal */
-#define LSM9DS1_STATUS_REG2_IG_XL               (1 << 6) /* Accelerometer interrupt output signal */
-
-/* FIFO control register */
-
-#define LSM9DS1_FIFO_CTRL_FTH_SHIFT             0 /* FIFO threshold level setting */
-#define LSM9DS1_FIFO_CTRL_FTH_MASK              (31 << LSM9DS1_FIFO_CTRL_FTH_SHIFT)
-#define LSM9DS1_FIFO_CTRL_FMODE_SHIFT           5 /* FIFO mode selection bits */
-#define LSM9DS1_FIFO_CTRL_FMODE_MASK            (7 << LSM9DS1_FIFO_CTRL_FMODE_SHIFT)
-#  define LSM9DS1_FIFO_CTRL_FMODE_BYPASS        (0 << LSM9DS1_FIFO_CTRL_FMODE_SHIFT) /* Bypass mode */
-#  define LSM9DS1_FIFO_CTRL_FMODE_FIFO          (1 << LSM9DS1_FIFO_CTRL_FMODE_SHIFT) /* FIFO mode */
-#  define LSM9DS1_FIFO_CTRL_FMODE_CONT_FIFO     (3 << LSM9DS1_FIFO_CTRL_FMODE_SHIFT) /* Continuous-to-FIFO mode */
-#  define LSM9DS1_FIFO_CTRL_FMODE_BYPASS_CONT   (4 << LSM9DS1_FIFO_CTRL_FMODE_SHIFT) /* Bypass-to-continuous mode */
-#  define LSM9DS1_FIFO_CTRL_FMODE_CONT          (5 << LSM9DS1_FIFO_CTRL_FMODE_SHIFT) /* Continuous mode */
-
-/* FIFO status control register */
-
-#define LSM9DS1_FIFO_SRC_FSS_SHIFT              0 /* Number of unread samples stored into FIFO */
-#define LSM9DS1_FIFO_SRC_FSS_MASK               (63 << LSM9DS1_FIFO_SRC_FSS_SHIFT)
-#define LSM9DS1_FIFO_SRC_OVRN                   (1 << 6) /* FIFO overrun status */
-#define LSM9DS1_FIFO_SRC_FTH                    (1 << 7) /* FIFO threshold status */
-
-/* Gyroscope interrupt configuration register */
-
-#define LSM9DS1_INT_GEN_CFG_G_XLIE_G            (1 << 0) /* Pitch (X) axis low event interrupt enable */
-#define LSM9DS1_INT_GEN_CFG_G_XHIE_G            (1 << 1) /* Pitch (X) axis high event interrupt enable */
-#define LSM9DS1_INT_GEN_CFG_G_YLIE_G            (1 << 2) /* Roll (Y) axis low event interrupt enable */
-#define LSM9DS1_INT_GEN_CFG_G_YHIE_G            (1 << 3) /* Roll (Y) axis high event interrupt enable */
-#define LSM9DS1_INT_GEN_CFG_G_ZLIE_G            (1 << 4) /* Yaw (Z) axis low event interrupt enable */
-#define LSM9DS1_INT_GEN_CFG_G_ZHIE_G            (1 << 5) /* Yaw (Z) axis high event interrupt enable */
-#define LSM9DS1_INT_GEN_CFG_G_LIR_G             (1 << 6) /* Latch interrupt request */
-#define LSM9DS1_INT_GEN_CFG_G_AOI_G             (1 << 7) /* AND/OR combination of interrupt events */
-
-/* Gyroscope interrupt threshold registers */
-
-#define LSM9DS1_INT_GEN_THS_XH_G_THS_XH_G_SHIFT 0 /* X interrupt threshold high byte */
-#define LSM9DS1_INT_GEN_THS_XH_G_THS_XH_G_MASK  (127 << LSM9DS1_INT_GEN_THS_XH_G_THS_XH_G_SHIFT)
-#define LSM9DS1_INT_GEN_THS_XH_G_DCRM_G         (1 << 7) /* Decrement or reset counter mode selection */
-
-/* Gyroscope interrupt duration register */
-
-#define LSM9DS1_INT_GEN_DUR_G_DUR_G_SHIFT       0 /* Enter/exit interrupt duration */
-#define LSM9DS1_INT_GEN_DUR_G_DUR_G_MASK        (127 << LSM9DS1_INT_GEN_DUR_G_DUR_G_SHIFT)
-#define LSM9DS1_INT_GEN_DUR_G_WAIT_G            (1 << 7) /* Exit from interrupt wait function enable */
-
-/* Device identification register */
-
-#define LSM9DS1_WHO_AM_I_M_VALUE                0x3d
-
-/* Magnetometer control register 1 */
-
-#define LSM9DS1_CTRL_REG1_M_ST                  (1 << 0) /* Self-test enable */
-#define LSM9DS1_CTRL_REG1_M_FAST_ODR            (1 << 1) /* Enable data rates higher than 80 Hz */
-
-#define LSM9DS1_CTRL_REG1_M_DO_SHIFT            2 /* Output data rate selection */
-#define LSM9DS1_CTRL_REG1_M_DO_MASK             (7 << LSM9DS1_CTRL_REG1_M_DO_SHIFT)
-#  define LSM9DS1_CTRL_REG1_M_DO_0p625HZ        (0 << LSM9DS1_CTRL_REG1_M_DO_SHIFT) /* 0.625 Hz */
-#  define LSM9DS1_CTRL_REG1_M_DO_1p25HZ         (1 << LSM9DS1_CTRL_REG1_M_DO_SHIFT) /* 1.25 Hz */
-#  define LSM9DS1_CTRL_REG1_M_DO_2p5HZ          (2 << LSM9DS1_CTRL_REG1_M_DO_SHIFT) /* 2.5 Hz */
-#  define LSM9DS1_CTRL_REG1_M_DO_5HZ            (3 << LSM9DS1_CTRL_REG1_M_DO_SHIFT) /* 5 Hz */
-#  define LSM9DS1_CTRL_REG1_M_DO_10HZ           (4 << LSM9DS1_CTRL_REG1_M_DO_SHIFT) /* 10 Hz */
-#  define LSM9DS1_CTRL_REG1_M_DO_20HZ           (5 << LSM9DS1_CTRL_REG1_M_DO_SHIFT) /* 20 Hz */
-#  define LSM9DS1_CTRL_REG1_M_DO_40HZ           (6 << LSM9DS1_CTRL_REG1_M_DO_SHIFT) /* 40 Hz */
-#  define LSM9DS1_CTRL_REG1_M_DO_80HZ           (7 << LSM9DS1_CTRL_REG1_M_DO_SHIFT) /* 80 Hz */
-
-#define LSM9DS1_CTRL_REG1_M_OM_SHIFT            5 /* X and Y axes operative mode selection */
-#define LSM9DS1_CTRL_REG1_M_OM_MASK             (3 << LSM9DS1_CTRL_REG1_M_OM_SHIFT)
-#  define LSM9DS1_CTRL_REG1_M_OM_LOW            (0 << LSM9DS1_CTRL_REG1_M_OM_SHIFT) /* Low-power mode */
-#  define LSM9DS1_CTRL_REG1_M_OM_MEDIUM         (1 << LSM9DS1_CTRL_REG1_M_OM_SHIFT) /* Medium-performance mode */
-#  define LSM9DS1_CTRL_REG1_M_OM_HIGH           (2 << LSM9DS1_CTRL_REG1_M_OM_SHIFT) /* High-performance mode */
-#  define LSM9DS1_CTRL_REG1_M_OM_ULTRAHIGH      (3 << LSM9DS1_CTRL_REG1_M_OM_SHIFT) /* Ultra-high performance mode */
-
-#define LSM9DS1_CTRL_REG1_M_TEMP_COMP           (1 << 7) /* Temperature compensation enable */
-
-/* Magnetometer control register 2 */
-
-#define LSM9DS1_CTRL_REG2_M_SOFT_RST            (1 << 2) /* Configuration register and user register reset */
-#define LSM9DS1_CTRL_REG2_M_REBOOT              (1 << 3) /* Reboot memory content */
-
-#define LSM9DS1_CTRL_REG2_M_FS_SHIFT            5 /* Full-scale configuration */
-#define LSM9DS1_CTRL_REG2_M_FS_MASK             (3 << LSM9DS1_CTRL_REG2_M_FS_SHIFT)
-#  define LSM9DS1_CTRL_REG2_M_FS_4GAUSS         (0 << LSM9DS1_CTRL_REG2_M_FS_SHIFT) /* +/- 4 gauss */
-#  define LSM9DS1_CTRL_REG2_M_FS_8GAUSS         (1 << LSM9DS1_CTRL_REG2_M_FS_SHIFT) /* +/- 8 gauss */
-#  define LSM9DS1_CTRL_REG2_M_FS_12GAUSS        (2 << LSM9DS1_CTRL_REG2_M_FS_SHIFT) /* +/- 12 gauss */
-#  define LSM9DS1_CTRL_REG2_M_FS_16GAUSS        (3 << LSM9DS1_CTRL_REG2_M_FS_SHIFT) /* +/- 16 gauss */
-
-/* Magnetometer control register 3 */
-
-#define LSM9DS1_CTRL_REG3_M_MD_SHIFT            0 /* Operating mode selection */
-#define LSM9DS1_CTRL_REG3_M_MD_MASK             (3 << LSM9DS1_CTRL_REG3_M_MD_SHIFT)
-#  define LSM9DS1_CTRL_REG3_M_MD_CONT           (0 << LSM9DS1_CTRL_REG3_M_MD_SHIFT) /* Continuous-conversion mode */
-#  define LSM9DS1_CTRL_REG3_M_MD_SINGLE         (1 << LSM9DS1_CTRL_REG3_M_MD_SHIFT) /* Single-conversion mode */
-#  define LSM9DS1_CTRL_REG3_M_MD_POWERDOWN      (2 << LSM9DS1_CTRL_REG3_M_MD_SHIFT) /* Power-down mode */
-#  define LSM9DS1_CTRL_REG3_M_MD_POWERDOWN2     (3 << LSM9DS1_CTRL_REG3_M_MD_SHIFT) /* Power-down mode */
-
-#define LSM9DS1_CTRL_REG3_M_SIM                 (1 << 2) /* SPI serial interface mode selection */
-#define LSM9DS1_CTRL_REG3_M_LP                  (1 << 5) /* Low-power mode configuration */
-#define LSM9DS1_CTRL_REG3_M_I2C_DISABLE         (1 << 7) /* Disable I2C interface */
-
-/* Magnetometer control register 4 */
-
-#define LSM9DS1_CTRL_REG4_M_BLE                 (1 << 1) /* Big/little endian data selection */
-
-#define LSM9DS1_CTRL_REG4_M_OMZ_SHIFT           2 /* Z-axis operative mode selection */
-#define LSM9DS1_CTRL_REG4_M_OMZ_MASK            (3 << LSM9DS1_CTRL_REG4_M_OMZ_SHIFT)
-#  define LSM9DS1_CTRL_REG4_M_OMZ_LOW           (0 << LSM9DS1_CTRL_REG4_M_OMZ_SHIFT) /* Low-power mode */
-#  define LSM9DS1_CTRL_REG4_M_OMZ_MEDIUM        (1 << LSM9DS1_CTRL_REG4_M_OMZ_SHIFT) /* Medium-performance mode */
-#  define LSM9DS1_CTRL_REG4_M_OMZ_HIGH          (2 << LSM9DS1_CTRL_REG4_M_OMZ_SHIFT) /* High-performance mode */
-#  define LSM9DS1_CTRL_REG4_M_OMZ_ULTRAHIGH     (3 << LSM9DS1_CTRL_REG4_M_OMZ_SHIFT) /* Ultra-high performance mode */
-
-/* Magnetometer control register 5 */
-
-#define LSM9DS1_CTRL_REG5_M_BDU                 (1 << 6) /* Block data update */
-#define LSM9DS1_CTRL_REG5_M_FAST_READ           (1 << 7) /* Fast read enable */
-
-/* Magnetometer status register */
-
-#define LSM9DS1_STATUS_REG_M_XDA                (1 << 0) /* X-axis new data available */
-#define LSM9DS1_STATUS_REG_M_YDA                (1 << 1) /* Y-axis new data available */
-#define LSM9DS1_STATUS_REG_M_ZDA                (1 << 2) /* Z-axis new data available */
-#define LSM9DS1_STATUS_REG_M_ZYXDA              (1 << 3) /* X, Y and Z-axis new data available */
-#define LSM9DS1_STATUS_REG_M_XOR                (1 << 4) /* X-axis data overrun */
-#define LSM9DS1_STATUS_REG_M_YOR                (1 << 5) /* Y-axis data overrun */
-#define LSM9DS1_STATUS_REG_M_ZOR                (1 << 6) /* Z-axis data overrun */
-#define LSM9DS1_STATUS_REG_M_ZYXOR              (1 << 7) /* X, Y and Z-axis data overrun */
-
-/* Magnetometer interrupt configuration register */
-
-#define LSM9DS1_INT_CFG_M_IEN                   (1 << 0) /* Interrupt enable on the INT_M pin */
-#define LSM9DS1_INT_CFG_M_IEL                   (1 << 1) /* Latch interrupt request */
-#define LSM9DS1_INT_CFG_M_IEA                   (1 << 2) /* Interrupt active configuration on INT_MAG */
-#define LSM9DS1_INT_CFG_M_ZIEN                  (1 << 5) /* Z-axis interrupt enable */
-#define LSM9DS1_INT_CFG_M_YIEN                  (1 << 6) /* Y-axis interrupt enable */
-#define LSM9DS1_INT_CFG_M_XIEN                  (1 << 7) /* X-axis interrupt enable */
-
-/* Magnetometer interrupt source register */
-
-#define LSM9DS1_INT_SRC_M_INT                   (1 << 0) /* Interrupt occurred */
-#define LSM9DS1_INT_SRC_M_MROI                  (1 << 1) /* Internal measurement range overflow */
-#define LSM9DS1_INT_SRC_M_NTH_Z                 (1 << 2) /* Value on Z-axis exceeds threshold on negative side */
-#define LSM9DS1_INT_SRC_M_NTH_Y                 (1 << 3) /* Value on Y-axis exceeds threshold on negative side */
-#define LSM9DS1_INT_SRC_M_NTH_X                 (1 << 4) /* Value on X-axis exceeds threshold on negative side */
-#define LSM9DS1_INT_SRC_M_PTH_Z                 (1 << 5) /* Value on Z-axis exceeds threshold on positive side */
-#define LSM9DS1_INT_SRC_M_PTH_Y                 (1 << 6) /* Value on Y-axis exceeds threshold on positive side */
-#define LSM9DS1_INT_SRC_M_PTH_X                 (1 << 7) /* Value on X-axis exceeds threshold on positive side */
-
-/****************************************************************************
- * Private Types
- ****************************************************************************/
-
-struct lsm9ds1_dev_s;
-struct lsm9ds1_ops_s
-{
-  CODE int (*config)(FAR struct lsm9ds1_dev_s *priv);
-  CODE int (*start)(FAR struct lsm9ds1_dev_s *priv);
-  CODE int (*stop)(FAR struct lsm9ds1_dev_s *priv);
-  CODE int (*setsamplerate)(FAR struct lsm9ds1_dev_s *priv,
-                            uint32_t samplerate);
-  CODE int (*setfullscale)(FAR struct lsm9ds1_dev_s *priv,
-                           uint32_t fullscale);
-};
-
-struct lsm9ds1_dev_s
-{
-  FAR struct i2c_master_s        *i2c;        /* I2C interface */
-  uint8_t                         addr;       /* I2C address */
-
-  FAR const struct lsm9ds1_ops_s *ops;
-
-  uint32_t                        samplerate; /* Output data rate */
-  uint8_t                         datareg;    /* Output data register of X low byte */
-};
-
 /****************************************************************************
  * Private Function Prototypes
  ****************************************************************************/
 
-/* I2C Helpers */
-
-static int lsm9ds1_readreg8(FAR struct lsm9ds1_dev_s *priv, uint8_t regaddr,
-                            FAR uint8_t *regval);
-static int lsm9ds1_writereg8(FAR struct lsm9ds1_dev_s *priv, uint8_t regaddr,
-                             uint8_t regval);
-static int lsm9ds1_modifyreg8(FAR struct lsm9ds1_dev_s *priv,
-                              uint8_t regaddr, uint8_t clearbits,
-                              uint8_t setbits);
-
-/* Other Helpers */
-
-static uint32_t lsm9ds1_midpoint(uint32_t a, uint32_t b);
-
-/* Accelerometer Operations */
-
-static int lsm9ds1accelgyro_config(FAR struct lsm9ds1_dev_s *priv);
-static int lsm9ds1accel_start(FAR struct lsm9ds1_dev_s *priv);
-static int lsm9ds1accel_stop(FAR struct lsm9ds1_dev_s *priv);
-static int lsm9ds1accelgyro_setsamplerate(FAR struct lsm9ds1_dev_s *priv,
-                                          uint32_t samplerate);
-static int lsm9ds1accel_setfullscale(FAR struct lsm9ds1_dev_s *priv,
-                                     uint32_t fullscale);
-
-/* Gyroscope Operations */
-
-static int lsm9ds1gyro_start(FAR struct lsm9ds1_dev_s *priv);
-static int lsm9ds1gyro_stop(FAR struct lsm9ds1_dev_s *priv);
-static int lsm9ds1gyro_setfullscale(FAR struct lsm9ds1_dev_s *priv,
-                                    uint32_t fullscale);
-
-/* Magnetometer Operations */
-
-static int lsm9ds1mag_config(FAR struct lsm9ds1_dev_s *priv);
-static int lsm9ds1mag_start(FAR struct lsm9ds1_dev_s *priv);
-static int lsm9ds1mag_stop(FAR struct lsm9ds1_dev_s *priv);
-static int lsm9ds1mag_setfullscale(FAR struct lsm9ds1_dev_s *priv,
-                                   uint32_t fullscale);
-static int lsm9ds1mag_setsamplerate(FAR struct lsm9ds1_dev_s *priv,
-                                    uint32_t samplerate);
-
 /* Character Driver Methods */
 
 static ssize_t lsm9ds1_read(FAR struct file *filep, FAR char *buffer,
@@ -590,605 +62,10 @@ static const struct file_operations g_fops =
   lsm9ds1_ioctl,   /* ioctl */
 };
 
-static const struct lsm9ds1_ops_s g_lsm9ds1accel_ops =
-{
-  lsm9ds1accelgyro_config,
-  lsm9ds1accel_start,
-  lsm9ds1accel_stop,
-  lsm9ds1accelgyro_setsamplerate,
-  lsm9ds1accel_setfullscale,
-};
-
-static const struct lsm9ds1_ops_s g_lsm9ds1gyro_ops =
-{
-  lsm9ds1accelgyro_config,
-  lsm9ds1gyro_start,
-  lsm9ds1gyro_stop,
-  lsm9ds1accelgyro_setsamplerate,
-  lsm9ds1gyro_setfullscale,
-};
-
-static const struct lsm9ds1_ops_s g_lsm9ds1mag_ops =
-{
-  lsm9ds1mag_config,
-  lsm9ds1mag_start,
-  lsm9ds1mag_stop,
-  lsm9ds1mag_setsamplerate,
-  lsm9ds1mag_setfullscale,
-};
-
 /****************************************************************************
  * Private Functions
  ****************************************************************************/
 
-/****************************************************************************
- * Name: lsm9ds1_readreg8
- *
- * Description:
- *   Read from an 8-bit register.
- *
- ****************************************************************************/
-
-static int lsm9ds1_readreg8(FAR struct lsm9ds1_dev_s *priv, uint8_t regaddr,
-                            FAR uint8_t *regval)
-{
-  struct i2c_config_s config;
-  int ret;
-
-  /* Sanity check */
-
-  DEBUGASSERT(priv != NULL);
-  DEBUGASSERT(regval != NULL);
-
-  /* Set up the I2C configuration */
-
-  config.frequency = CONFIG_LSM9DS1_I2C_FREQUENCY;
-  config.address   = priv->addr;
-  config.addrlen   = 7;
-
-  /* Write the register address */
-
-  ret = i2c_write(priv->i2c, &config, &regaddr, sizeof(regaddr));
-  if (ret < 0)
-    {
-      snerr("ERROR: i2c_write failed: %d\n", ret);
-      return ret;
-    }
-
-  /* Restart and read 8 bits from the register */
-
-  ret = i2c_read(priv->i2c, &config, regval, sizeof(*regval));
-  if (ret < 0)
-    {
-      snerr("ERROR: i2c_read failed: %d\n", ret);
-      return ret;
-    }
-
-  sninfo("addr: %02x value: %02x\n", regaddr, *regval);
-  return OK;
-}
-
-/****************************************************************************
- * Name: lsm9ds1_writereg8
- *
- * Description:
- *   Write to an 8-bit register.
- *
- ****************************************************************************/
-
-static int lsm9ds1_writereg8(FAR struct lsm9ds1_dev_s *priv, uint8_t regaddr,
-                             uint8_t regval)
-{
-  struct i2c_config_s config;
-  uint8_t buffer[2];
-  int ret;
-
-  /* Sanity check */
-
-  DEBUGASSERT(priv != NULL);
-
-  /* Set up a 2-byte message to send */
-
-  buffer[0] = regaddr;
-  buffer[1] = regval;
-
-  /* Set up the I2C configuration */
-
-  config.frequency = CONFIG_LSM9DS1_I2C_FREQUENCY;
-  config.address   = priv->addr;
-  config.addrlen   = 7;
-
-  /* Write the register address followed by the data (no RESTART) */
-
-  ret = i2c_write(priv->i2c, &config, buffer, sizeof(buffer));
-  if (ret < 0)
-    {
-      snerr("ERROR: i2c_write failed: %d\n", ret);
-      return ret;
-    }
-
-  sninfo("addr: %02x value: %02x\n", regaddr, regval);
-  return OK;
-}
-
-/****************************************************************************
- * Name: lsm9ds1_modifyreg8
- *
- * Description:
- *   Modify an 8-bit register.
- *
- ****************************************************************************/
-
-static int lsm9ds1_modifyreg8(FAR struct lsm9ds1_dev_s *priv,
-                              uint8_t regaddr,
-                              uint8_t clearbits,
-                              uint8_t setbits)
-{
-  int ret;
-  uint8_t regval;
-
-  /* Sanity check */
-
-  DEBUGASSERT(priv != NULL);
-
-  ret = lsm9ds1_readreg8(priv, regaddr, &regval);
-  if (ret < 0)
-    {
-      snerr("ERROR: lsm9ds1_readreg8 failed: %d\n", ret);
-      return ret;
-    }
-
-  regval &= ~clearbits;
-  regval |= setbits;
-
-  ret = lsm9ds1_writereg8(priv, regaddr, regval);
-  if (ret < 0)
-    {
-      snerr("ERROR: lsm9ds1_writereg8 failed: %d\n", ret);
-      return ret;
-    }
-
-  return OK;
-}
-
-/****************************************************************************
- * Name: lsm9ds1_midpoint
- *
- * Description:
- *   Find the midpoint between two numbers.
- *
- ****************************************************************************/
-
-static uint32_t lsm9ds1_midpoint(uint32_t a, uint32_t b)
-{
-  return (uint32_t)(((uint64_t)a +
-         (uint64_t)b + (uint64_t)1) / (uint64_t)2);
-}
-
-/****************************************************************************
- * Name: lsm9ds1accelgyro_config
- *
- * Description:
- *   Configure the accelerometer and gyroscope.
- *
- ****************************************************************************/
-
-static int lsm9ds1accelgyro_config(FAR struct lsm9ds1_dev_s *priv)
-{
-  int ret;
-  uint8_t regval;
-
-  /* Sanity check */
-
-  DEBUGASSERT(priv != NULL);
-
-  /* Get the device identification */
-
-  ret = lsm9ds1_readreg8(priv, LSM9DS1_WHO_AM_I, &regval);
-  if (ret < 0)
-    {
-      snerr("ERROR: lsm9ds1_readreg8 failed: %d\n", ret);
-      return ret;
-    }
-
-  if (regval != LSM9DS1_WHO_AM_I_VALUE)
-    {
-      snerr("ERROR: Invalid device identification %02x\n", regval);
-      return -ENODEV;
-    }
-
-  return OK;
-}
-
-/****************************************************************************
- * Name: lsm9ds1accel_start
- *
- * Description:
- *   Start the accelerometer.
- *
- ****************************************************************************/
-
-static int lsm9ds1accel_start(FAR struct lsm9ds1_dev_s *priv)
-{
-  uint8_t setbits;
-
-  /* Sanity check */
-
-  DEBUGASSERT(priv != NULL);
-
-  if (priv->samplerate < lsm9ds1_midpoint(10, 50))
-    {
-      setbits = LSM9DS1_CTRL_REG6_XL_ODR_XL_10HZ;
-    }
-  else if (priv->samplerate < lsm9ds1_midpoint(50, 119))
-    {
-      setbits = LSM9DS1_CTRL_REG6_XL_ODR_XL_50HZ;
-    }
-  else if (priv->samplerate < lsm9ds1_midpoint(119, 238))
-    {
-      setbits = LSM9DS1_CTRL_REG6_XL_ODR_XL_119HZ;
-    }
-  else if (priv->samplerate < lsm9ds1_midpoint(238, 476))
-    {
-      setbits = LSM9DS1_CTRL_REG6_XL_ODR_XL_238HZ;
-    }
-  else if (priv->samplerate < lsm9ds1_midpoint(476, 952))
-    {
-      setbits = LSM9DS1_CTRL_REG6_XL_ODR_XL_476HZ;
-    }
-  else
-    {
-      setbits = LSM9DS1_CTRL_REG6_XL_ODR_XL_952HZ;
-    }
-
-  return lsm9ds1_modifyreg8(priv, LSM9DS1_CTRL_REG6_XL,
-                            LSM9DS1_CTRL_REG6_XL_ODR_XL_MASK, setbits);
-}
-
-/****************************************************************************
- * Name: lsm9ds1accel_stop
- *
- * Description:
- *   Stop the accelerometer.
- *
- ****************************************************************************/
-
-static int lsm9ds1accel_stop(FAR struct lsm9ds1_dev_s *priv)
-{
-  /* Sanity check */
-
-  DEBUGASSERT(priv != NULL);
-
-  return lsm9ds1_modifyreg8(priv, LSM9DS1_CTRL_REG6_XL,
-                            LSM9DS1_CTRL_REG6_XL_ODR_XL_MASK,
-                            LSM9DS1_CTRL_REG6_XL_ODR_XL_POWERDOWN);
-}
-
-/****************************************************************************
- * Name: lsm9ds1accelgyro_setsamplerate
- *
- * Description:
- *   Set the accelerometer or gyroscope's sample rate.
- *
- ****************************************************************************/
-
-static int lsm9ds1accelgyro_setsamplerate(FAR struct lsm9ds1_dev_s *priv,
-                                          uint32_t samplerate)
-{
-  /* Sanity check */
-
-  DEBUGASSERT(priv != NULL);
-
-  priv->samplerate = samplerate;
-  return OK;
-}
-
-/****************************************************************************
- * Name: lsm9ds1accel_setfullscale
- *
- * Description:
- *   Set the accelerometer's full-scale range.
- *
- ****************************************************************************/
-
-static int lsm9ds1accel_setfullscale(FAR struct lsm9ds1_dev_s *priv,
-                                     uint32_t fullscale)
-{
-  uint8_t setbits;
-
-  /* Sanity check */
-
-  DEBUGASSERT(priv != NULL);
-
-  if (fullscale < lsm9ds1_midpoint(2, 4))
-    {
-      setbits = LSM9DS1_CTRL_REG6_XL_FS_XL_2G;
-    }
-  else if (fullscale < lsm9ds1_midpoint(4, 8))
-    {
-      setbits = LSM9DS1_CTRL_REG6_XL_FS_XL_4G;
-    }
-  else if (fullscale < lsm9ds1_midpoint(8, 16))
-    {
-      setbits = LSM9DS1_CTRL_REG6_XL_FS_XL_8G;
-    }
-  else
-    {
-      setbits = LSM9DS1_CTRL_REG6_XL_FS_XL_16G;
-    }
-
-  return lsm9ds1_modifyreg8(priv, LSM9DS1_CTRL_REG6_XL,
-                            LSM9DS1_CTRL_REG6_XL_FS_XL_MASK, setbits);
-}
-
-/****************************************************************************
- * Name: lsm9ds1gyro_start
- *
- * Description:
- *   Start the gyroscope.
- *
- ****************************************************************************/
-
-static int lsm9ds1gyro_start(FAR struct lsm9ds1_dev_s *priv)
-{
-  uint8_t setbits;
-
-  /* Sanity check */
-
-  DEBUGASSERT(priv != NULL);
-
-  if (priv->samplerate < lsm9ds1_midpoint(14, 59))
-    {
-      setbits = LSM9DS1_CTRL_REG1_G_ODR_G_14p9HZ;
-    }
-  else if (priv->samplerate < lsm9ds1_midpoint(59, 119))
-    {
-      setbits = LSM9DS1_CTRL_REG1_G_ODR_G_59p5HZ;
-    }
-  else if (priv->samplerate < lsm9ds1_midpoint(119, 238))
-    {
-      setbits = LSM9DS1_CTRL_REG1_G_ODR_G_119HZ;
-    }
-  else if (priv->samplerate < lsm9ds1_midpoint(238, 476))
-    {
-      setbits = LSM9DS1_CTRL_REG1_G_ODR_G_238HZ;
-    }
-  else if (priv->samplerate < lsm9ds1_midpoint(476, 952))
-    {
-      setbits = LSM9DS1_CTRL_REG1_G_ODR_G_476HZ;
-    }
-  else
-    {
-      setbits = LSM9DS1_CTRL_REG1_G_ODR_G_952HZ;
-    }
-
-  return lsm9ds1_modifyreg8(priv, LSM9DS1_CTRL_REG1_G,
-                            LSM9DS1_CTRL_REG1_G_ODR_G_MASK, setbits);
-}
-
-/****************************************************************************
- * Name: lsm9ds1gyro_stop
- *
- * Description:
- *   Stop the gyroscope.
- *
- ****************************************************************************/
-
-static int lsm9ds1gyro_stop(FAR struct lsm9ds1_dev_s *priv)
-{
-  /* Sanity check */
-
-  DEBUGASSERT(priv != NULL);
-
-  return lsm9ds1_modifyreg8(priv, LSM9DS1_CTRL_REG1_G,
-                            LSM9DS1_CTRL_REG1_G_ODR_G_MASK,
-                            LSM9DS1_CTRL_REG1_G_ODR_G_POWERDOWN);
-}
-
-/****************************************************************************
- * Name: lsm9ds1gyro_setfullscale
- *
- * Description:
- *   Set the gyroscope's full-scale range.
- *
- ****************************************************************************/
-
-static int lsm9ds1gyro_setfullscale(FAR struct lsm9ds1_dev_s *priv,
-                                    uint32_t fullscale)
-{
-  uint8_t setbits;
-
-  /* Sanity check */
-
-  DEBUGASSERT(priv != NULL);
-
-  if (fullscale < lsm9ds1_midpoint(245, 500))
-    {
-      setbits = LSM9DS1_CTRL_REG1_G_FS_G_245DPS;
-    }
-  else if (fullscale < lsm9ds1_midpoint(500, 2000))
-    {
-      setbits = LSM9DS1_CTRL_REG1_G_FS_G_500DPS;
-    }
-  else
-    {
-      setbits = LSM9DS1_CTRL_REG1_G_FS_G_2000DPS;
-    }
-
-  return lsm9ds1_modifyreg8(priv, LSM9DS1_CTRL_REG1_G,
-                            LSM9DS1_CTRL_REG1_G_FS_G_MASK, setbits);
-}
-
-/****************************************************************************
- * Name: lsm9ds1mag_config
- *
- * Description:
- *   Configure the magnetometer.
- *
- ****************************************************************************/
-
-static int lsm9ds1mag_config(FAR struct lsm9ds1_dev_s *priv)
-{
-  int ret;
-  uint8_t regval;
-
-  /* Sanity check */
-
-  DEBUGASSERT(priv != NULL);
-
-  /* Get the device identification */
-
-  ret = lsm9ds1_readreg8(priv, LSM9DS1_WHO_AM_I_M, &regval);
-  if (ret < 0)
-    {
-      snerr("ERROR: lsm9ds1_readreg8 failed: %d\n", ret);
-      return ret;
-    }
-
-  if (regval != LSM9DS1_WHO_AM_I_M_VALUE)
-    {
-      snerr("ERROR: Invalid device identification %02x\n", regval);
-      return -ENODEV;
-    }
-
-  return OK;
-}
-
-/****************************************************************************
- * Name: lsm9ds1mag_start
- *
- * Description:
- *   Start the magnetometer.
- *
- ****************************************************************************/
-
-static int lsm9ds1mag_start(FAR struct lsm9ds1_dev_s *priv)
-{
-  /* Sanity check */
-
-  DEBUGASSERT(priv != NULL);
-
-  return lsm9ds1_modifyreg8(priv, LSM9DS1_CTRL_REG3_M,
-                            LSM9DS1_CTRL_REG3_M_MD_MASK,
-                            LSM9DS1_CTRL_REG3_M_MD_CONT);
-}
-
-/****************************************************************************
- * Name: lsm9ds1mag_stop
- *
- * Description:
- *   Stop the magnetometer.
- *
- ****************************************************************************/
-
-static int lsm9ds1mag_stop(FAR struct lsm9ds1_dev_s *priv)
-{
-  /* Sanity check */
-
-  DEBUGASSERT(priv != NULL);
-
-  return lsm9ds1_modifyreg8(priv, LSM9DS1_CTRL_REG3_M,
-                            LSM9DS1_CTRL_REG3_M_MD_MASK,
-                            LSM9DS1_CTRL_REG3_M_MD_POWERDOWN2);
-}
-
-/****************************************************************************
- * Name: lsm9ds1mag_setfullscale
- *
- * Description:
- *   Set the magnetometer's full-scale range.
- *
- ****************************************************************************/
-
-static int lsm9ds1mag_setfullscale(FAR struct lsm9ds1_dev_s *priv,
-                                   uint32_t fullscale)
-{
-  uint8_t setbits;
-
-  /* Sanity check */
-
-  DEBUGASSERT(priv != NULL);
-
-  if (fullscale < lsm9ds1_midpoint(4, 8))
-    {
-      setbits = LSM9DS1_CTRL_REG2_M_FS_4GAUSS;
-    }
-  else if (fullscale < lsm9ds1_midpoint(8, 12))
-    {
-      setbits = LSM9DS1_CTRL_REG2_M_FS_8GAUSS;
-    }
-  else if (fullscale < lsm9ds1_midpoint(12, 16))
-    {
-      setbits = LSM9DS1_CTRL_REG2_M_FS_12GAUSS;
-    }
-  else
-    {
-      setbits = LSM9DS1_CTRL_REG2_M_FS_16GAUSS;
-    }
-
-  return lsm9ds1_modifyreg8(priv, LSM9DS1_CTRL_REG2_M,
-                            LSM9DS1_CTRL_REG2_M_FS_MASK, setbits);
-}
-
-/****************************************************************************
- * Name: lsm9ds1mag_setsamplerate
- *
- * Description:
- *   Set the magnetometer's sample rate.
- *
- ****************************************************************************/
-
-static int lsm9ds1mag_setsamplerate(FAR struct lsm9ds1_dev_s *priv,
-                                    uint32_t samplerate)
-{
-  uint8_t setbits;
-
-  /* Sanity check */
-
-  DEBUGASSERT(priv != NULL);
-
-  /* The magnetometer can change its sample rate without exiting
-   * power-down mode, so we don't need to save the value for later,
-   * unlike the accelerometer and gyroscope.
-   */
-
-  if (samplerate < lsm9ds1_midpoint(0, 1))
-    {
-      setbits = LSM9DS1_CTRL_REG1_M_DO_0p625HZ;
-    }
-  else if (samplerate < lsm9ds1_midpoint(1, 2))
-    {
-      setbits = LSM9DS1_CTRL_REG1_M_DO_1p25HZ;
-    }
-  else if (samplerate < lsm9ds1_midpoint(2, 5))
-    {
-      setbits = LSM9DS1_CTRL_REG1_M_DO_2p5HZ;
-    }
-  else if (samplerate < lsm9ds1_midpoint(5, 10))
-    {
-      setbits = LSM9DS1_CTRL_REG1_M_DO_5HZ;
-    }
-  else if (samplerate < lsm9ds1_midpoint(10, 20))
-    {
-      setbits = LSM9DS1_CTRL_REG1_M_DO_10HZ;
-    }
-  else if (samplerate < lsm9ds1_midpoint(20, 40))
-    {
-      setbits = LSM9DS1_CTRL_REG1_M_DO_20HZ;
-    }
-  else if (samplerate < lsm9ds1_midpoint(40, 80))
-    {
-      setbits = LSM9DS1_CTRL_REG1_M_DO_40HZ;
-    }
-  else
-    {
-      setbits = LSM9DS1_CTRL_REG1_M_DO_80HZ;
-    }
-
-  return lsm9ds1_modifyreg8(priv, LSM9DS1_CTRL_REG1_M,
-                            LSM9DS1_CTRL_REG1_M_DO_MASK, setbits);
-}
-
 /****************************************************************************
  * Name: lsm9ds1_read
  *
diff --git a/drivers/sensors/lsm9ds1_base.c b/drivers/sensors/lsm9ds1_base.c
new file mode 100644
index 0000000000..43ce757a96
--- /dev/null
+++ b/drivers/sensors/lsm9ds1_base.c
@@ -0,0 +1,717 @@
+/****************************************************************************
+ * drivers/sensors/lsm9ds1_base.c
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.  The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include "lsm9ds1_base.h"
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Function Prototypes
+ ****************************************************************************/
+
+/* Accelerometer Operations */
+
+static int lsm9ds1accelgyro_config(FAR struct lsm9ds1_dev_s *priv);
+static int lsm9ds1accel_start(FAR struct lsm9ds1_dev_s *priv);
+static int lsm9ds1accel_stop(FAR struct lsm9ds1_dev_s *priv);
+static int lsm9ds1accelgyro_setsamplerate(FAR struct lsm9ds1_dev_s *priv,
+                                          uint32_t samplerate);
+static int lsm9ds1accel_setfullscale(FAR struct lsm9ds1_dev_s *priv,
+                                     uint32_t fullscale);
+
+/* Gyroscope Operations */
+
+static int lsm9ds1gyro_start(FAR struct lsm9ds1_dev_s *priv);
+static int lsm9ds1gyro_stop(FAR struct lsm9ds1_dev_s *priv);
+static int lsm9ds1gyro_setfullscale(FAR struct lsm9ds1_dev_s *priv,
+                                    uint32_t fullscale);
+
+/* Magnetometer Operations */
+
+static int lsm9ds1mag_config(FAR struct lsm9ds1_dev_s *priv);
+static int lsm9ds1mag_start(FAR struct lsm9ds1_dev_s *priv);
+static int lsm9ds1mag_stop(FAR struct lsm9ds1_dev_s *priv);
+static int lsm9ds1mag_setfullscale(FAR struct lsm9ds1_dev_s *priv,
+                                   uint32_t fullscale);
+static int lsm9ds1mag_setsamplerate(FAR struct lsm9ds1_dev_s *priv,
+                                    uint32_t samplerate);
+
+/****************************************************************************
+ * Private Types
+ ****************************************************************************/
+
+const struct lsm9ds1_ops_s g_lsm9ds1accel_ops =
+{
+  lsm9ds1accelgyro_config,
+  lsm9ds1accel_start,
+  lsm9ds1accel_stop,
+  lsm9ds1accelgyro_setsamplerate,
+  lsm9ds1accel_setfullscale,
+};
+
+const struct lsm9ds1_ops_s g_lsm9ds1gyro_ops =
+{
+  lsm9ds1accelgyro_config,
+  lsm9ds1gyro_start,
+  lsm9ds1gyro_stop,
+  lsm9ds1accelgyro_setsamplerate,
+  lsm9ds1gyro_setfullscale,
+};
+
+const struct lsm9ds1_ops_s g_lsm9ds1mag_ops =
+{
+  lsm9ds1mag_config,
+  lsm9ds1mag_start,
+  lsm9ds1mag_stop,
+  lsm9ds1mag_setsamplerate,
+  lsm9ds1mag_setfullscale,
+};
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: lsm9ds1accelgyro_config
+ *
+ * Description:
+ *   Configure the accelerometer and gyroscope.
+ *
+ ****************************************************************************/
+
+static int lsm9ds1accelgyro_config(FAR struct lsm9ds1_dev_s *priv)
+{
+  uint8_t regval;
+  int     ret;
+
+  /* Sanity check */
+
+  DEBUGASSERT(priv != NULL);
+
+  /* Get the device identification */
+
+  ret = lsm9ds1_readreg8(priv, LSM9DS1_WHO_AM_I, &regval);
+  if (ret < 0)
+    {
+      snerr("ERROR: lsm9ds1_readreg8 failed: %d\n", ret);
+      return ret;
+    }
+
+  if (regval != LSM9DS1_WHO_AM_I_VALUE)
+    {
+      snerr("ERROR: Invalid device identification %02x\n", regval);
+      return -ENODEV;
+    }
+
+  return OK;
+}
+
+/****************************************************************************
+ * Name: lsm9ds1accel_start
+ *
+ * Description:
+ *   Start the accelerometer.
+ *
+ ****************************************************************************/
+
+static int lsm9ds1accel_start(FAR struct lsm9ds1_dev_s *priv)
+{
+  uint8_t setbits;
+
+  /* Sanity check */
+
+  DEBUGASSERT(priv != NULL);
+
+  if (priv->samplerate < lsm9ds1_midpoint(10, 50))
+    {
+      setbits = LSM9DS1_CTRL_REG6_XL_ODR_XL_10HZ;
+    }
+  else if (priv->samplerate < lsm9ds1_midpoint(50, 119))
+    {
+      setbits = LSM9DS1_CTRL_REG6_XL_ODR_XL_50HZ;
+    }
+  else if (priv->samplerate < lsm9ds1_midpoint(119, 238))
+    {
+      setbits = LSM9DS1_CTRL_REG6_XL_ODR_XL_119HZ;
+    }
+  else if (priv->samplerate < lsm9ds1_midpoint(238, 476))
+    {
+      setbits = LSM9DS1_CTRL_REG6_XL_ODR_XL_238HZ;
+    }
+  else if (priv->samplerate < lsm9ds1_midpoint(476, 952))
+    {
+      setbits = LSM9DS1_CTRL_REG6_XL_ODR_XL_476HZ;
+    }
+  else
+    {
+      setbits = LSM9DS1_CTRL_REG6_XL_ODR_XL_952HZ;
+    }
+
+  return lsm9ds1_modifyreg8(priv, LSM9DS1_CTRL_REG6_XL,
+                            LSM9DS1_CTRL_REG6_XL_ODR_XL_MASK, setbits);
+}
+
+/****************************************************************************
+ * Name: lsm9ds1accel_stop
+ *
+ * Description:
+ *   Stop the accelerometer.
+ *
+ ****************************************************************************/
+
+static int lsm9ds1accel_stop(FAR struct lsm9ds1_dev_s *priv)
+{
+  /* Sanity check */
+
+  DEBUGASSERT(priv != NULL);
+
+  return lsm9ds1_modifyreg8(priv, LSM9DS1_CTRL_REG6_XL,
+                            LSM9DS1_CTRL_REG6_XL_ODR_XL_MASK,
+                            LSM9DS1_CTRL_REG6_XL_ODR_XL_POWERDOWN);
+}
+
+/****************************************************************************
+ * Name: lsm9ds1accelgyro_setsamplerate
+ *
+ * Description:
+ *   Set the accelerometer or gyroscope's sample rate.
+ *
+ ****************************************************************************/
+
+static int lsm9ds1accelgyro_setsamplerate(FAR struct lsm9ds1_dev_s *priv,
+                                          uint32_t samplerate)
+{
+  /* Sanity check */
+
+  DEBUGASSERT(priv != NULL);
+
+  priv->samplerate = samplerate;
+  return OK;
+}
+
+/****************************************************************************
+ * Name: lsm9ds1accel_setfullscale
+ *
+ * Description:
+ *   Set the accelerometer's full-scale range.
+ *
+ ****************************************************************************/
+
+static int lsm9ds1accel_setfullscale(FAR struct lsm9ds1_dev_s *priv,
+                                     uint32_t fullscale)
+{
+  uint8_t setbits;
+
+  /* Sanity check */
+
+  DEBUGASSERT(priv != NULL);
+
+  if (fullscale < lsm9ds1_midpoint(2, 4))
+    {
+      setbits = LSM9DS1_CTRL_REG6_XL_FS_XL_2G;
+    }
+  else if (fullscale < lsm9ds1_midpoint(4, 8))
+    {
+      setbits = LSM9DS1_CTRL_REG6_XL_FS_XL_4G;
+    }
+  else if (fullscale < lsm9ds1_midpoint(8, 16))
+    {
+      setbits = LSM9DS1_CTRL_REG6_XL_FS_XL_8G;
+    }
+  else
+    {
+      setbits = LSM9DS1_CTRL_REG6_XL_FS_XL_16G;
+    }
+
+  return lsm9ds1_modifyreg8(priv, LSM9DS1_CTRL_REG6_XL,
+                            LSM9DS1_CTRL_REG6_XL_FS_XL_MASK, setbits);
+}
+
+/****************************************************************************
+ * Name: lsm9ds1gyro_start
+ *
+ * Description:
+ *   Start the gyroscope.
+ *
+ ****************************************************************************/
+
+static int lsm9ds1gyro_start(FAR struct lsm9ds1_dev_s *priv)
+{
+  uint8_t setbits;
+
+  /* Sanity check */
+
+  DEBUGASSERT(priv != NULL);
+
+  if (priv->samplerate < lsm9ds1_midpoint(14, 59))
+    {
+      setbits = LSM9DS1_CTRL_REG1_G_ODR_G_14p9HZ;
+    }
+  else if (priv->samplerate < lsm9ds1_midpoint(59, 119))
+    {
+      setbits = LSM9DS1_CTRL_REG1_G_ODR_G_59p5HZ;
+    }
+  else if (priv->samplerate < lsm9ds1_midpoint(119, 238))
+    {
+      setbits = LSM9DS1_CTRL_REG1_G_ODR_G_119HZ;
+    }
+  else if (priv->samplerate < lsm9ds1_midpoint(238, 476))
+    {
+      setbits = LSM9DS1_CTRL_REG1_G_ODR_G_238HZ;
+    }
+  else if (priv->samplerate < lsm9ds1_midpoint(476, 952))
+    {
+      setbits = LSM9DS1_CTRL_REG1_G_ODR_G_476HZ;
+    }
+  else
+    {
+      setbits = LSM9DS1_CTRL_REG1_G_ODR_G_952HZ;
+    }
+
+  return lsm9ds1_modifyreg8(priv, LSM9DS1_CTRL_REG1_G,
+                            LSM9DS1_CTRL_REG1_G_ODR_G_MASK, setbits);
+}
+
+/****************************************************************************
+ * Name: lsm9ds1gyro_stop
+ *
+ * Description:
+ *   Stop the gyroscope.
+ *
+ ****************************************************************************/
+
+static int lsm9ds1gyro_stop(FAR struct lsm9ds1_dev_s *priv)
+{
+  /* Sanity check */
+
+  DEBUGASSERT(priv != NULL);
+
+  return lsm9ds1_modifyreg8(priv, LSM9DS1_CTRL_REG1_G,
+                            LSM9DS1_CTRL_REG1_G_ODR_G_MASK,
+                            LSM9DS1_CTRL_REG1_G_ODR_G_POWERDOWN);
+}
+
+/****************************************************************************
+ * Name: lsm9ds1gyro_setfullscale
+ *
+ * Description:
+ *   Set the gyroscope's full-scale range.
+ *
+ ****************************************************************************/
+
+static int lsm9ds1gyro_setfullscale(FAR struct lsm9ds1_dev_s *priv,
+                                    uint32_t fullscale)
+{
+  uint8_t setbits;
+
+  /* Sanity check */
+
+  DEBUGASSERT(priv != NULL);
+
+  if (fullscale < lsm9ds1_midpoint(245, 500))
+    {
+      setbits = LSM9DS1_CTRL_REG1_G_FS_G_245DPS;
+    }
+  else if (fullscale < lsm9ds1_midpoint(500, 2000))
+    {
+      setbits = LSM9DS1_CTRL_REG1_G_FS_G_500DPS;
+    }
+  else
+    {
+      setbits = LSM9DS1_CTRL_REG1_G_FS_G_2000DPS;
+    }
+
+  return lsm9ds1_modifyreg8(priv, LSM9DS1_CTRL_REG1_G,
+                            LSM9DS1_CTRL_REG1_G_FS_G_MASK, setbits);
+}
+
+/****************************************************************************
+ * Name: lsm9ds1mag_config
+ *
+ * Description:
+ *   Configure the magnetometer.
+ *
+ ****************************************************************************/
+
+static int lsm9ds1mag_config(FAR struct lsm9ds1_dev_s *priv)
+{
+  uint8_t regval;
+  int     ret;
+
+  /* Sanity check */
+
+  DEBUGASSERT(priv != NULL);
+
+  /* Get the device identification */
+
+  ret = lsm9ds1_readreg8(priv, LSM9DS1_WHO_AM_I_M, &regval);
+  if (ret < 0)
+    {
+      snerr("ERROR: lsm9ds1_readreg8 failed: %d\n", ret);
+      return ret;
+    }
+
+  if (regval != LSM9DS1_WHO_AM_I_M_VALUE)
+    {
+      snerr("ERROR: Invalid device identification %02x\n", regval);
+      return -ENODEV;
+    }
+
+  return OK;
+}
+
+/****************************************************************************
+ * Name: lsm9ds1mag_start
+ *
+ * Description:
+ *   Start the magnetometer.
+ *
+ ****************************************************************************/
+
+static int lsm9ds1mag_start(FAR struct lsm9ds1_dev_s *priv)
+{
+  /* Sanity check */
+
+  DEBUGASSERT(priv != NULL);
+
+  return lsm9ds1_modifyreg8(priv, LSM9DS1_CTRL_REG3_M,
+                            LSM9DS1_CTRL_REG3_M_MD_MASK,
+                            LSM9DS1_CTRL_REG3_M_MD_CONT);
+}
+
+/****************************************************************************
+ * Name: lsm9ds1mag_stop
+ *
+ * Description:
+ *   Stop the magnetometer.
+ *
+ ****************************************************************************/
+
+static int lsm9ds1mag_stop(FAR struct lsm9ds1_dev_s *priv)
+{
+  /* Sanity check */
+
+  DEBUGASSERT(priv != NULL);
+
+  return lsm9ds1_modifyreg8(priv, LSM9DS1_CTRL_REG3_M,
+                            LSM9DS1_CTRL_REG3_M_MD_MASK,
+                            LSM9DS1_CTRL_REG3_M_MD_POWERDOWN2);
+}
+
+/****************************************************************************
+ * Name: lsm9ds1mag_setfullscale
+ *
+ * Description:
+ *   Set the magnetometer's full-scale range.
+ *
+ ****************************************************************************/
+
+static int lsm9ds1mag_setfullscale(FAR struct lsm9ds1_dev_s *priv,
+                                   uint32_t fullscale)
+{
+  uint8_t setbits;
+
+  /* Sanity check */
+
+  DEBUGASSERT(priv != NULL);
+
+  if (fullscale < lsm9ds1_midpoint(4, 8))
+    {
+      setbits = LSM9DS1_CTRL_REG2_M_FS_4GAUSS;
+    }
+  else if (fullscale < lsm9ds1_midpoint(8, 12))
+    {
+      setbits = LSM9DS1_CTRL_REG2_M_FS_8GAUSS;
+    }
+  else if (fullscale < lsm9ds1_midpoint(12, 16))
+    {
+      setbits = LSM9DS1_CTRL_REG2_M_FS_12GAUSS;
+    }
+  else
+    {
+      setbits = LSM9DS1_CTRL_REG2_M_FS_16GAUSS;
+    }
+
+  return lsm9ds1_modifyreg8(priv, LSM9DS1_CTRL_REG2_M,
+                            LSM9DS1_CTRL_REG2_M_FS_MASK, setbits);
+}
+
+/****************************************************************************
+ * Name: lsm9ds1mag_setsamplerate
+ *
+ * Description:
+ *   Set the magnetometer's sample rate.
+ *
+ ****************************************************************************/
+
+static int lsm9ds1mag_setsamplerate(FAR struct lsm9ds1_dev_s *priv,
+                                    uint32_t samplerate)
+{
+  uint8_t setbits;
+
+  /* Sanity check */
+
+  DEBUGASSERT(priv != NULL);
+
+  /* The magnetometer can change its sample rate without exiting
+   * power-down mode, so we don't need to save the value for later,
+   * unlike the accelerometer and gyroscope.
+   */
+
+  if (samplerate < lsm9ds1_midpoint(0, 1))
+    {
+      setbits = LSM9DS1_CTRL_REG1_M_DO_0p625HZ;
+    }
+  else if (samplerate < lsm9ds1_midpoint(1, 2))
+    {
+      setbits = LSM9DS1_CTRL_REG1_M_DO_1p25HZ;
+    }
+  else if (samplerate < lsm9ds1_midpoint(2, 5))
+    {
+      setbits = LSM9DS1_CTRL_REG1_M_DO_2p5HZ;
+    }
+  else if (samplerate < lsm9ds1_midpoint(5, 10))
+    {
+      setbits = LSM9DS1_CTRL_REG1_M_DO_5HZ;
+    }
+  else if (samplerate < lsm9ds1_midpoint(10, 20))
+    {
+      setbits = LSM9DS1_CTRL_REG1_M_DO_10HZ;
+    }
+  else if (samplerate < lsm9ds1_midpoint(20, 40))
+    {
+      setbits = LSM9DS1_CTRL_REG1_M_DO_20HZ;
+    }
+  else if (samplerate < lsm9ds1_midpoint(40, 80))
+    {
+      setbits = LSM9DS1_CTRL_REG1_M_DO_40HZ;
+    }
+  else
+    {
+      setbits = LSM9DS1_CTRL_REG1_M_DO_80HZ;
+    }
+
+  return lsm9ds1_modifyreg8(priv, LSM9DS1_CTRL_REG1_M,
+                            LSM9DS1_CTRL_REG1_M_DO_MASK, setbits);
+}
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: lsm9ds1_readreg8
+ *
+ * Description:
+ *   Read from an 8-bit register.
+ *
+ ****************************************************************************/
+
+int lsm9ds1_readreg8(FAR struct lsm9ds1_dev_s *priv,
+                     uint8_t regaddr, FAR uint8_t *regval)
+{
+  struct i2c_config_s config;
+  int                 ret;
+
+  /* Sanity check */
+
+  DEBUGASSERT(priv != NULL);
+  DEBUGASSERT(regval != NULL);
+
+  /* Set up the I2C configuration */
+
+  config.frequency = CONFIG_LSM9DS1_I2C_FREQUENCY;
+  config.address   = priv->addr;
+  config.addrlen   = 7;
+
+  /* Write the register address */
+
+  ret = i2c_write(priv->i2c, &config, &regaddr, sizeof(regaddr));
+  if (ret < 0)
+    {
+      snerr("ERROR: i2c_write failed: %d\n", ret);
+      return ret;
+    }
+
+  /* Restart and read 8 bits from the register */
+
+  ret = i2c_read(priv->i2c, &config, regval, sizeof(*regval));
+  if (ret < 0)
+    {
+      snerr("ERROR: i2c_read failed: %d\n", ret);
+      return ret;
+    }
+
+  sninfo("addr: %02x value: %02x\n", regaddr, *regval);
+  return OK;
+}
+
+/****************************************************************************
+ * Name: lsm9ds1_readreg
+ *
+ * Description:
+ *   Read bytes from registers
+ *
+ ****************************************************************************/
+
+int lsm9ds1_readreg(FAR struct lsm9ds1_dev_s *priv,
+                    uint8_t regaddr, FAR uint8_t *regval, uint8_t len)
+{
+  struct i2c_config_s config;
+  int                 ret;
+
+  /* Sanity check */
+
+  DEBUGASSERT(priv != NULL);
+  DEBUGASSERT(regval != NULL);
+
+  /* Set up the I2C configuration */
+
+  config.frequency = CONFIG_LSM9DS1_I2C_FREQUENCY;
+  config.address   = priv->addr;
+  config.addrlen   = 7;
+
+  /* Write the register address */
+
+  ret = i2c_write(priv->i2c, &config, &regaddr, sizeof(regaddr));
+  if (ret < 0)
+    {
+      snerr("ERROR: i2c_write failed: %d\n", ret);
+      return ret;
+    }
+
+  /* Restart and read 8 bits from the register */
+
+  ret = i2c_read(priv->i2c, &config, regval, sizeof(*regval) * len);
+  if (ret < 0)
+    {
+      snerr("ERROR: i2c_read failed: %d\n", ret);
+      return ret;
+    }
+
+  return OK;
+}
+
+/****************************************************************************
+ * Name: lsm9ds1_writereg8
+ *
+ * Description:
+ *   Write to an 8-bit register.
+ *
+ ****************************************************************************/
+
+int lsm9ds1_writereg8(FAR struct lsm9ds1_dev_s *priv,
+                      uint8_t regaddr, uint8_t regval)
+{
+  struct i2c_config_s config;
+  uint8_t             buffer[2];
+  int                 ret;
+
+  /* Sanity check */
+
+  DEBUGASSERT(priv != NULL);
+
+  /* Set up a 2-byte message to send */
+
+  buffer[0] = regaddr;
+  buffer[1] = regval;
+
+  /* Set up the I2C configuration */
+
+  config.frequency = CONFIG_LSM9DS1_I2C_FREQUENCY;
+  config.address   = priv->addr;
+  config.addrlen   = 7;
+
+  /* Write the register address followed by the data (no RESTART) */
+
+  ret = i2c_write(priv->i2c, &config, buffer, sizeof(buffer));
+  if (ret < 0)
+    {
+      snerr("ERROR: i2c_write failed: %d\n", ret);
+      return ret;
+    }
+
+  sninfo("addr: %02x value: %02x\n", regaddr, regval);
+  return OK;
+}
+
+/****************************************************************************
+ * Name: lsm9ds1_modifyreg8
+ *
+ * Description:
+ *   Modify an 8-bit register.
+ *
+ ****************************************************************************/
+
+int lsm9ds1_modifyreg8(FAR struct lsm9ds1_dev_s *priv,
+                       uint8_t regaddr, uint8_t clearbits,
+                       uint8_t setbits)
+{
+  uint8_t regval;
+  int     ret;
+
+  /* Sanity check */
+
+  DEBUGASSERT(priv != NULL);
+
+  ret = lsm9ds1_readreg8(priv, regaddr, &regval);
+  if (ret < 0)
+    {
+      snerr("ERROR: lsm9ds1_readreg8 failed: %d\n", ret);
+      return ret;
+    }
+
+  regval &= ~clearbits;
+  regval |= setbits;
+
+  ret = lsm9ds1_writereg8(priv, regaddr, regval);
+  if (ret < 0)
+    {
+      snerr("ERROR: lsm9ds1_writereg8 failed: %d\n", ret);
+      return ret;
+    }
+
+  return OK;
+}
+
+/****************************************************************************
+ * Name: lsm9ds1_midpoint
+ *
+ * Description:
+ *   Find the midpoint between two numbers.
+ *
+ ****************************************************************************/
+
+uint32_t lsm9ds1_midpoint(uint32_t a, uint32_t b)
+{
+  return (uint32_t)(((uint64_t)a +
+                     (uint64_t)b + (uint64_t)1) / (uint64_t)2);
+}
+
diff --git a/drivers/sensors/lsm9ds1.c b/drivers/sensors/lsm9ds1_base.h
similarity index 54%
copy from drivers/sensors/lsm9ds1.c
copy to drivers/sensors/lsm9ds1_base.h
index 23e578d4d1..e972d65670 100644
--- a/drivers/sensors/lsm9ds1.c
+++ b/drivers/sensors/lsm9ds1_base.h
@@ -1,5 +1,5 @@
 /****************************************************************************
- * drivers/sensors/lsm9ds1.c
+ * drivers/sensors/lsm9ds1_base.h
  *
  * Licensed to the Apache Software Foundation (ASF) under one or more
  * contributor license agreements.  See the NOTICE file distributed with
@@ -18,6 +18,9 @@
  *
  ****************************************************************************/
 
+#ifndef __INCLUDE_NUTTX_SENSORS_LSM9DS1_COMMOM_H
+#define __INCLUDE_NUTTX_SENSORS_LSM9DS1_COMMOM_H
+
 /****************************************************************************
  * Included Files
  ****************************************************************************/
@@ -32,19 +35,14 @@
 #include <nuttx/kmalloc.h>
 #include <nuttx/random.h>
 #include <nuttx/fs/fs.h>
+
 #include <nuttx/i2c/i2c_master.h>
 #include <nuttx/sensors/lsm9ds1.h>
 
-#if defined(CONFIG_I2C) && defined(CONFIG_SENSORS_LSM9DS1)
-
 /****************************************************************************
  * Pre-processor Definitions
  ****************************************************************************/
 
-#ifndef CONFIG_LSM9DS1_I2C_FREQUENCY
-#  define CONFIG_LSM9DS1_I2C_FREQUENCY 400000
-#endif
-
 /* Register Addresses *******************************************************/
 
 /* Accelerometer and gyroscope registers */
@@ -489,7 +487,7 @@
 #define LSM9DS1_INT_SRC_M_PTH_X                 (1 << 7) /* Value on X-axis exceeds threshold on positive side */
 
 /****************************************************************************
- * Private Types
+ * Public Types
  ****************************************************************************/
 
 struct lsm9ds1_dev_s;
@@ -507,1045 +505,33 @@ struct lsm9ds1_ops_s
 struct lsm9ds1_dev_s
 {
   FAR struct i2c_master_s        *i2c;        /* I2C interface */
+  FAR const struct lsm9ds1_ops_s *ops;        /* Ops */
   uint8_t                         addr;       /* I2C address */
-
-  FAR const struct lsm9ds1_ops_s *ops;
-
   uint32_t                        samplerate; /* Output data rate */
   uint8_t                         datareg;    /* Output data register of X low byte */
 };
 
 /****************************************************************************
- * Private Function Prototypes
- ****************************************************************************/
-
-/* I2C Helpers */
-
-static int lsm9ds1_readreg8(FAR struct lsm9ds1_dev_s *priv, uint8_t regaddr,
-                            FAR uint8_t *regval);
-static int lsm9ds1_writereg8(FAR struct lsm9ds1_dev_s *priv, uint8_t regaddr,
-                             uint8_t regval);
-static int lsm9ds1_modifyreg8(FAR struct lsm9ds1_dev_s *priv,
-                              uint8_t regaddr, uint8_t clearbits,
-                              uint8_t setbits);
-
-/* Other Helpers */
-
-static uint32_t lsm9ds1_midpoint(uint32_t a, uint32_t b);
-
-/* Accelerometer Operations */
-
-static int lsm9ds1accelgyro_config(FAR struct lsm9ds1_dev_s *priv);
-static int lsm9ds1accel_start(FAR struct lsm9ds1_dev_s *priv);
-static int lsm9ds1accel_stop(FAR struct lsm9ds1_dev_s *priv);
-static int lsm9ds1accelgyro_setsamplerate(FAR struct lsm9ds1_dev_s *priv,
-                                          uint32_t samplerate);
-static int lsm9ds1accel_setfullscale(FAR struct lsm9ds1_dev_s *priv,
-                                     uint32_t fullscale);
-
-/* Gyroscope Operations */
-
-static int lsm9ds1gyro_start(FAR struct lsm9ds1_dev_s *priv);
-static int lsm9ds1gyro_stop(FAR struct lsm9ds1_dev_s *priv);
-static int lsm9ds1gyro_setfullscale(FAR struct lsm9ds1_dev_s *priv,
-                                    uint32_t fullscale);
-
-/* Magnetometer Operations */
-
-static int lsm9ds1mag_config(FAR struct lsm9ds1_dev_s *priv);
-static int lsm9ds1mag_start(FAR struct lsm9ds1_dev_s *priv);
-static int lsm9ds1mag_stop(FAR struct lsm9ds1_dev_s *priv);
-static int lsm9ds1mag_setfullscale(FAR struct lsm9ds1_dev_s *priv,
-                                   uint32_t fullscale);
-static int lsm9ds1mag_setsamplerate(FAR struct lsm9ds1_dev_s *priv,
-                                    uint32_t samplerate);
-
-/* Character Driver Methods */
-
-static ssize_t lsm9ds1_read(FAR struct file *filep, FAR char *buffer,
-                            size_t buflen);
-static ssize_t lsm9ds1_write(FAR struct file *filep, FAR const char *buffer,
-                             size_t buflen);
-static int     lsm9ds1_ioctl(FAR struct file *filep, int cmd,
-                             unsigned long arg);
-
-/* Common Register Function */
-
-static int lsm9ds1_register(FAR const char *devpath,
-                            FAR struct i2c_master_s *i2c, uint8_t addr,
-                            FAR const struct lsm9ds1_ops_s *ops,
-                            uint8_t datareg);
-
-/****************************************************************************
- * Private Data
- ****************************************************************************/
-
-static const struct file_operations g_fops =
-{
-  NULL,            /* open */
-  NULL,            /* close */
-  lsm9ds1_read,    /* read */
-  lsm9ds1_write,   /* write */
-  NULL,            /* seek */
-  lsm9ds1_ioctl,   /* ioctl */
-};
-
-static const struct lsm9ds1_ops_s g_lsm9ds1accel_ops =
-{
-  lsm9ds1accelgyro_config,
-  lsm9ds1accel_start,
-  lsm9ds1accel_stop,
-  lsm9ds1accelgyro_setsamplerate,
-  lsm9ds1accel_setfullscale,
-};
-
-static const struct lsm9ds1_ops_s g_lsm9ds1gyro_ops =
-{
-  lsm9ds1accelgyro_config,
-  lsm9ds1gyro_start,
-  lsm9ds1gyro_stop,
-  lsm9ds1accelgyro_setsamplerate,
-  lsm9ds1gyro_setfullscale,
-};
-
-static const struct lsm9ds1_ops_s g_lsm9ds1mag_ops =
-{
-  lsm9ds1mag_config,
-  lsm9ds1mag_start,
-  lsm9ds1mag_stop,
-  lsm9ds1mag_setsamplerate,
-  lsm9ds1mag_setfullscale,
-};
-
-/****************************************************************************
- * Private Functions
- ****************************************************************************/
-
-/****************************************************************************
- * Name: lsm9ds1_readreg8
- *
- * Description:
- *   Read from an 8-bit register.
- *
- ****************************************************************************/
-
-static int lsm9ds1_readreg8(FAR struct lsm9ds1_dev_s *priv, uint8_t regaddr,
-                            FAR uint8_t *regval)
-{
-  struct i2c_config_s config;
-  int ret;
-
-  /* Sanity check */
-
-  DEBUGASSERT(priv != NULL);
-  DEBUGASSERT(regval != NULL);
-
-  /* Set up the I2C configuration */
-
-  config.frequency = CONFIG_LSM9DS1_I2C_FREQUENCY;
-  config.address   = priv->addr;
-  config.addrlen   = 7;
-
-  /* Write the register address */
-
-  ret = i2c_write(priv->i2c, &config, &regaddr, sizeof(regaddr));
-  if (ret < 0)
-    {
-      snerr("ERROR: i2c_write failed: %d\n", ret);
-      return ret;
-    }
-
-  /* Restart and read 8 bits from the register */
-
-  ret = i2c_read(priv->i2c, &config, regval, sizeof(*regval));
-  if (ret < 0)
-    {
-      snerr("ERROR: i2c_read failed: %d\n", ret);
-      return ret;
-    }
-
-  sninfo("addr: %02x value: %02x\n", regaddr, *regval);
-  return OK;
-}
-
-/****************************************************************************
- * Name: lsm9ds1_writereg8
- *
- * Description:
- *   Write to an 8-bit register.
- *
- ****************************************************************************/
-
-static int lsm9ds1_writereg8(FAR struct lsm9ds1_dev_s *priv, uint8_t regaddr,
-                             uint8_t regval)
-{
-  struct i2c_config_s config;
-  uint8_t buffer[2];
-  int ret;
-
-  /* Sanity check */
-
-  DEBUGASSERT(priv != NULL);
-
-  /* Set up a 2-byte message to send */
-
-  buffer[0] = regaddr;
-  buffer[1] = regval;
-
-  /* Set up the I2C configuration */
-
-  config.frequency = CONFIG_LSM9DS1_I2C_FREQUENCY;
-  config.address   = priv->addr;
-  config.addrlen   = 7;
-
-  /* Write the register address followed by the data (no RESTART) */
-
-  ret = i2c_write(priv->i2c, &config, buffer, sizeof(buffer));
-  if (ret < 0)
-    {
-      snerr("ERROR: i2c_write failed: %d\n", ret);
-      return ret;
-    }
-
-  sninfo("addr: %02x value: %02x\n", regaddr, regval);
-  return OK;
-}
-
-/****************************************************************************
- * Name: lsm9ds1_modifyreg8
- *
- * Description:
- *   Modify an 8-bit register.
- *
- ****************************************************************************/
-
-static int lsm9ds1_modifyreg8(FAR struct lsm9ds1_dev_s *priv,
-                              uint8_t regaddr,
-                              uint8_t clearbits,
-                              uint8_t setbits)
-{
-  int ret;
-  uint8_t regval;
-
-  /* Sanity check */
-
-  DEBUGASSERT(priv != NULL);
-
-  ret = lsm9ds1_readreg8(priv, regaddr, &regval);
-  if (ret < 0)
-    {
-      snerr("ERROR: lsm9ds1_readreg8 failed: %d\n", ret);
-      return ret;
-    }
-
-  regval &= ~clearbits;
-  regval |= setbits;
-
-  ret = lsm9ds1_writereg8(priv, regaddr, regval);
-  if (ret < 0)
-    {
-      snerr("ERROR: lsm9ds1_writereg8 failed: %d\n", ret);
-      return ret;
-    }
-
-  return OK;
-}
-
-/****************************************************************************
- * Name: lsm9ds1_midpoint
- *
- * Description:
- *   Find the midpoint between two numbers.
- *
- ****************************************************************************/
-
-static uint32_t lsm9ds1_midpoint(uint32_t a, uint32_t b)
-{
-  return (uint32_t)(((uint64_t)a +
-         (uint64_t)b + (uint64_t)1) / (uint64_t)2);
-}
-
-/****************************************************************************
- * Name: lsm9ds1accelgyro_config
- *
- * Description:
- *   Configure the accelerometer and gyroscope.
- *
- ****************************************************************************/
-
-static int lsm9ds1accelgyro_config(FAR struct lsm9ds1_dev_s *priv)
-{
-  int ret;
-  uint8_t regval;
-
-  /* Sanity check */
-
-  DEBUGASSERT(priv != NULL);
-
-  /* Get the device identification */
-
-  ret = lsm9ds1_readreg8(priv, LSM9DS1_WHO_AM_I, &regval);
-  if (ret < 0)
-    {
-      snerr("ERROR: lsm9ds1_readreg8 failed: %d\n", ret);
-      return ret;
-    }
-
-  if (regval != LSM9DS1_WHO_AM_I_VALUE)
-    {
-      snerr("ERROR: Invalid device identification %02x\n", regval);
-      return -ENODEV;
-    }
-
-  return OK;
-}
-
-/****************************************************************************
- * Name: lsm9ds1accel_start
- *
- * Description:
- *   Start the accelerometer.
- *
- ****************************************************************************/
-
-static int lsm9ds1accel_start(FAR struct lsm9ds1_dev_s *priv)
-{
-  uint8_t setbits;
-
-  /* Sanity check */
-
-  DEBUGASSERT(priv != NULL);
-
-  if (priv->samplerate < lsm9ds1_midpoint(10, 50))
-    {
-      setbits = LSM9DS1_CTRL_REG6_XL_ODR_XL_10HZ;
-    }
-  else if (priv->samplerate < lsm9ds1_midpoint(50, 119))
-    {
-      setbits = LSM9DS1_CTRL_REG6_XL_ODR_XL_50HZ;
-    }
-  else if (priv->samplerate < lsm9ds1_midpoint(119, 238))
-    {
-      setbits = LSM9DS1_CTRL_REG6_XL_ODR_XL_119HZ;
-    }
-  else if (priv->samplerate < lsm9ds1_midpoint(238, 476))
-    {
-      setbits = LSM9DS1_CTRL_REG6_XL_ODR_XL_238HZ;
-    }
-  else if (priv->samplerate < lsm9ds1_midpoint(476, 952))
-    {
-      setbits = LSM9DS1_CTRL_REG6_XL_ODR_XL_476HZ;
-    }
-  else
-    {
-      setbits = LSM9DS1_CTRL_REG6_XL_ODR_XL_952HZ;
-    }
-
-  return lsm9ds1_modifyreg8(priv, LSM9DS1_CTRL_REG6_XL,
-                            LSM9DS1_CTRL_REG6_XL_ODR_XL_MASK, setbits);
-}
-
-/****************************************************************************
- * Name: lsm9ds1accel_stop
- *
- * Description:
- *   Stop the accelerometer.
- *
- ****************************************************************************/
-
-static int lsm9ds1accel_stop(FAR struct lsm9ds1_dev_s *priv)
-{
-  /* Sanity check */
-
-  DEBUGASSERT(priv != NULL);
-
-  return lsm9ds1_modifyreg8(priv, LSM9DS1_CTRL_REG6_XL,
-                            LSM9DS1_CTRL_REG6_XL_ODR_XL_MASK,
-                            LSM9DS1_CTRL_REG6_XL_ODR_XL_POWERDOWN);
-}
-
-/****************************************************************************
- * Name: lsm9ds1accelgyro_setsamplerate
- *
- * Description:
- *   Set the accelerometer or gyroscope's sample rate.
- *
- ****************************************************************************/
-
-static int lsm9ds1accelgyro_setsamplerate(FAR struct lsm9ds1_dev_s *priv,
-                                          uint32_t samplerate)
-{
-  /* Sanity check */
-
-  DEBUGASSERT(priv != NULL);
-
-  priv->samplerate = samplerate;
-  return OK;
-}
-
-/****************************************************************************
- * Name: lsm9ds1accel_setfullscale
- *
- * Description:
- *   Set the accelerometer's full-scale range.
- *
+ * Public data
  ****************************************************************************/
 
-static int lsm9ds1accel_setfullscale(FAR struct lsm9ds1_dev_s *priv,
-                                     uint32_t fullscale)
-{
-  uint8_t setbits;
-
-  /* Sanity check */
-
-  DEBUGASSERT(priv != NULL);
-
-  if (fullscale < lsm9ds1_midpoint(2, 4))
-    {
-      setbits = LSM9DS1_CTRL_REG6_XL_FS_XL_2G;
-    }
-  else if (fullscale < lsm9ds1_midpoint(4, 8))
-    {
-      setbits = LSM9DS1_CTRL_REG6_XL_FS_XL_4G;
-    }
-  else if (fullscale < lsm9ds1_midpoint(8, 16))
-    {
-      setbits = LSM9DS1_CTRL_REG6_XL_FS_XL_8G;
-    }
-  else
-    {
-      setbits = LSM9DS1_CTRL_REG6_XL_FS_XL_16G;
-    }
-
-  return lsm9ds1_modifyreg8(priv, LSM9DS1_CTRL_REG6_XL,
-                            LSM9DS1_CTRL_REG6_XL_FS_XL_MASK, setbits);
-}
+extern const struct lsm9ds1_ops_s g_lsm9ds1accel_ops;
+extern const struct lsm9ds1_ops_s g_lsm9ds1gyro_ops;
+extern const struct lsm9ds1_ops_s g_lsm9ds1mag_ops;
 
 /****************************************************************************
- * Name: lsm9ds1gyro_start
- *
- * Description:
- *   Start the gyroscope.
- *
+ * Public Function Prototypes
  ****************************************************************************/
 
-static int lsm9ds1gyro_start(FAR struct lsm9ds1_dev_s *priv)
-{
-  uint8_t setbits;
-
-  /* Sanity check */
-
-  DEBUGASSERT(priv != NULL);
-
-  if (priv->samplerate < lsm9ds1_midpoint(14, 59))
-    {
-      setbits = LSM9DS1_CTRL_REG1_G_ODR_G_14p9HZ;
-    }
-  else if (priv->samplerate < lsm9ds1_midpoint(59, 119))
-    {
-      setbits = LSM9DS1_CTRL_REG1_G_ODR_G_59p5HZ;
-    }
-  else if (priv->samplerate < lsm9ds1_midpoint(119, 238))
-    {
-      setbits = LSM9DS1_CTRL_REG1_G_ODR_G_119HZ;
-    }
-  else if (priv->samplerate < lsm9ds1_midpoint(238, 476))
-    {
-      setbits = LSM9DS1_CTRL_REG1_G_ODR_G_238HZ;
-    }
-  else if (priv->samplerate < lsm9ds1_midpoint(476, 952))
-    {
-      setbits = LSM9DS1_CTRL_REG1_G_ODR_G_476HZ;
-    }
-  else
-    {
-      setbits = LSM9DS1_CTRL_REG1_G_ODR_G_952HZ;
-    }
-
-  return lsm9ds1_modifyreg8(priv, LSM9DS1_CTRL_REG1_G,
-                            LSM9DS1_CTRL_REG1_G_ODR_G_MASK, setbits);
-}
-
-/****************************************************************************
- * Name: lsm9ds1gyro_stop
- *
- * Description:
- *   Stop the gyroscope.
- *
- ****************************************************************************/
-
-static int lsm9ds1gyro_stop(FAR struct lsm9ds1_dev_s *priv)
-{
-  /* Sanity check */
-
-  DEBUGASSERT(priv != NULL);
-
-  return lsm9ds1_modifyreg8(priv, LSM9DS1_CTRL_REG1_G,
-                            LSM9DS1_CTRL_REG1_G_ODR_G_MASK,
-                            LSM9DS1_CTRL_REG1_G_ODR_G_POWERDOWN);
-}
-
-/****************************************************************************
- * Name: lsm9ds1gyro_setfullscale
- *
- * Description:
- *   Set the gyroscope's full-scale range.
- *
- ****************************************************************************/
-
-static int lsm9ds1gyro_setfullscale(FAR struct lsm9ds1_dev_s *priv,
-                                    uint32_t fullscale)
-{
-  uint8_t setbits;
-
-  /* Sanity check */
-
-  DEBUGASSERT(priv != NULL);
-
-  if (fullscale < lsm9ds1_midpoint(245, 500))
-    {
-      setbits = LSM9DS1_CTRL_REG1_G_FS_G_245DPS;
-    }
-  else if (fullscale < lsm9ds1_midpoint(500, 2000))
-    {
-      setbits = LSM9DS1_CTRL_REG1_G_FS_G_500DPS;
-    }
-  else
-    {
-      setbits = LSM9DS1_CTRL_REG1_G_FS_G_2000DPS;
-    }
-
-  return lsm9ds1_modifyreg8(priv, LSM9DS1_CTRL_REG1_G,
-                            LSM9DS1_CTRL_REG1_G_FS_G_MASK, setbits);
-}
-
-/****************************************************************************
- * Name: lsm9ds1mag_config
- *
- * Description:
- *   Configure the magnetometer.
- *
- ****************************************************************************/
-
-static int lsm9ds1mag_config(FAR struct lsm9ds1_dev_s *priv)
-{
-  int ret;
-  uint8_t regval;
-
-  /* Sanity check */
-
-  DEBUGASSERT(priv != NULL);
-
-  /* Get the device identification */
-
-  ret = lsm9ds1_readreg8(priv, LSM9DS1_WHO_AM_I_M, &regval);
-  if (ret < 0)
-    {
-      snerr("ERROR: lsm9ds1_readreg8 failed: %d\n", ret);
-      return ret;
-    }
-
-  if (regval != LSM9DS1_WHO_AM_I_M_VALUE)
-    {
-      snerr("ERROR: Invalid device identification %02x\n", regval);
-      return -ENODEV;
-    }
-
-  return OK;
-}
-
-/****************************************************************************
- * Name: lsm9ds1mag_start
- *
- * Description:
- *   Start the magnetometer.
- *
- ****************************************************************************/
-
-static int lsm9ds1mag_start(FAR struct lsm9ds1_dev_s *priv)
-{
-  /* Sanity check */
-
-  DEBUGASSERT(priv != NULL);
-
-  return lsm9ds1_modifyreg8(priv, LSM9DS1_CTRL_REG3_M,
-                            LSM9DS1_CTRL_REG3_M_MD_MASK,
-                            LSM9DS1_CTRL_REG3_M_MD_CONT);
-}
-
-/****************************************************************************
- * Name: lsm9ds1mag_stop
- *
- * Description:
- *   Stop the magnetometer.
- *
- ****************************************************************************/
-
-static int lsm9ds1mag_stop(FAR struct lsm9ds1_dev_s *priv)
-{
-  /* Sanity check */
-
-  DEBUGASSERT(priv != NULL);
-
-  return lsm9ds1_modifyreg8(priv, LSM9DS1_CTRL_REG3_M,
-                            LSM9DS1_CTRL_REG3_M_MD_MASK,
-                            LSM9DS1_CTRL_REG3_M_MD_POWERDOWN2);
-}
-
-/****************************************************************************
- * Name: lsm9ds1mag_setfullscale
- *
- * Description:
- *   Set the magnetometer's full-scale range.
- *
- ****************************************************************************/
-
-static int lsm9ds1mag_setfullscale(FAR struct lsm9ds1_dev_s *priv,
-                                   uint32_t fullscale)
-{
-  uint8_t setbits;
-
-  /* Sanity check */
-
-  DEBUGASSERT(priv != NULL);
-
-  if (fullscale < lsm9ds1_midpoint(4, 8))
-    {
-      setbits = LSM9DS1_CTRL_REG2_M_FS_4GAUSS;
-    }
-  else if (fullscale < lsm9ds1_midpoint(8, 12))
-    {
-      setbits = LSM9DS1_CTRL_REG2_M_FS_8GAUSS;
-    }
-  else if (fullscale < lsm9ds1_midpoint(12, 16))
-    {
-      setbits = LSM9DS1_CTRL_REG2_M_FS_12GAUSS;
-    }
-  else
-    {
-      setbits = LSM9DS1_CTRL_REG2_M_FS_16GAUSS;
-    }
-
-  return lsm9ds1_modifyreg8(priv, LSM9DS1_CTRL_REG2_M,
-                            LSM9DS1_CTRL_REG2_M_FS_MASK, setbits);
-}
-
-/****************************************************************************
- * Name: lsm9ds1mag_setsamplerate
- *
- * Description:
- *   Set the magnetometer's sample rate.
- *
- ****************************************************************************/
-
-static int lsm9ds1mag_setsamplerate(FAR struct lsm9ds1_dev_s *priv,
-                                    uint32_t samplerate)
-{
-  uint8_t setbits;
-
-  /* Sanity check */
-
-  DEBUGASSERT(priv != NULL);
-
-  /* The magnetometer can change its sample rate without exiting
-   * power-down mode, so we don't need to save the value for later,
-   * unlike the accelerometer and gyroscope.
-   */
-
-  if (samplerate < lsm9ds1_midpoint(0, 1))
-    {
-      setbits = LSM9DS1_CTRL_REG1_M_DO_0p625HZ;
-    }
-  else if (samplerate < lsm9ds1_midpoint(1, 2))
-    {
-      setbits = LSM9DS1_CTRL_REG1_M_DO_1p25HZ;
-    }
-  else if (samplerate < lsm9ds1_midpoint(2, 5))
-    {
-      setbits = LSM9DS1_CTRL_REG1_M_DO_2p5HZ;
-    }
-  else if (samplerate < lsm9ds1_midpoint(5, 10))
-    {
-      setbits = LSM9DS1_CTRL_REG1_M_DO_5HZ;
-    }
-  else if (samplerate < lsm9ds1_midpoint(10, 20))
-    {
-      setbits = LSM9DS1_CTRL_REG1_M_DO_10HZ;
-    }
-  else if (samplerate < lsm9ds1_midpoint(20, 40))
-    {
-      setbits = LSM9DS1_CTRL_REG1_M_DO_20HZ;
-    }
-  else if (samplerate < lsm9ds1_midpoint(40, 80))
-    {
-      setbits = LSM9DS1_CTRL_REG1_M_DO_40HZ;
-    }
-  else
-    {
-      setbits = LSM9DS1_CTRL_REG1_M_DO_80HZ;
-    }
-
-  return lsm9ds1_modifyreg8(priv, LSM9DS1_CTRL_REG1_M,
-                            LSM9DS1_CTRL_REG1_M_DO_MASK, setbits);
-}
-
-/****************************************************************************
- * Name: lsm9ds1_read
- *
- * Description:
- *   The standard read method.
- *
- ****************************************************************************/
-
-static ssize_t lsm9ds1_read(FAR struct file *filep, FAR char *buffer,
-                            size_t buflen)
-{
-  FAR struct inode         *inode;
-  FAR struct lsm9ds1_dev_s *priv;
-  int                       ret;
-  size_t                    i;
-  size_t                    j;
-  size_t                    samplesize;
-  size_t                    nsamples;
-  uint16_t                  data;
-  FAR int16_t              *ptr;
-  uint8_t                   regaddr;
-  uint8_t                   lo;
-  uint8_t                   hi;
-  uint32_t                  merge = 0;
-
-  /* Sanity check */
-
-  inode = filep->f_inode;
-
-  priv = inode->i_private;
-
-  DEBUGASSERT(priv != NULL);
-  DEBUGASSERT(priv->datareg == LSM9DS1_OUT_X_L_G ||
-              priv->datareg == LSM9DS1_OUT_X_L_XL ||
-              priv->datareg == LSM9DS1_OUT_X_L_M);
-  DEBUGASSERT(buffer != NULL);
-
-  samplesize = 3 * sizeof(*ptr);
-  nsamples   = buflen / samplesize;
-  ptr        = (FAR int16_t *)buffer;
-
-  /* Get the requested number of samples */
-
-  for (i = 0; i < nsamples; i++)
-    {
-      /* Reset the register address to the X low byte register */
-
-      regaddr = priv->datareg;
-
-      /* Read the X, Y and Z data */
-
-      for (j = 0; j < 3; j++)
-        {
-          /* Read the low byte */
-
-          ret = lsm9ds1_readreg8(priv, regaddr, &lo);
-          if (ret < 0)
-            {
-              snerr("ERROR: lsm9ds1_readreg8 failed: %d\n", ret);
-              return (ssize_t)ret;
-            }
-
-          regaddr++;
-
-          /* Read the high byte */
-
-          ret = lsm9ds1_readreg8(priv, regaddr, &hi);
-          if (ret < 0)
-            {
-              snerr("ERROR: lsm9ds1_readreg8 failed: %d\n", ret);
-              return (ssize_t)ret;
-            }
-
-          regaddr++;
-
-          /* The data is 16 bits in two's complement representation */
-
-          data = ((uint16_t)hi << 8) | (uint16_t)lo;
-
-          /* Collect entropy */
-
-          merge += data ^ (merge >> 16);
-
-          /* The value is positive */
-
-          if (data < 0x8000)
-            {
-              ptr[j] = (int16_t)data;
-            }
-
-          /* The value is negative, so find its absolute value by taking the
-           * two's complement
-           */
-
-          else if (data > 0x8000)
-            {
-              data = ~data + 1;
-              ptr[j] = -(int16_t)data;
-            }
-
-          /* The value is negative and can't be represented as a positive
-           * int16_t value
-           */
-
-          else
-            {
-              ptr[j] = (int16_t)(-32768);
-            }
-        }
-    }
-
-  /* Feed sensor data to entropy pool */
-
-  add_sensor_randomness(merge);
-
-  return nsamples * samplesize;
-}
-
-/****************************************************************************
- * Name: lsm9ds1_write
- *
- * Description:
- *   A dummy write method.
- *
- ****************************************************************************/
-
-static ssize_t lsm9ds1_write(FAR struct file *filep, FAR const char *buffer,
-                             size_t buflen)
-{
-  return -ENOSYS;
-}
-
-/****************************************************************************
- * Name: lsm9ds1_ioctl
- *
- * Description:
- *   The standard ioctl method.
- *
- ****************************************************************************/
-
-static int lsm9ds1_ioctl(FAR struct file *filep, int cmd, unsigned long arg)
-{
-  FAR struct inode         *inode;
-  FAR struct lsm9ds1_dev_s *priv;
-  int                       ret;
-
-  /* Sanity check */
-
-  inode = filep->f_inode;
-
-  priv = inode->i_private;
-
-  DEBUGASSERT(priv != NULL);
-
-  /* Handle ioctl commands */
-
-  switch (cmd)
-    {
-      /* Start converting. Arg: None. */
-
-      case SNIOC_START:
-        ret = priv->ops->start(priv);
-        break;
-
-      /* Stop converting. Arg: None. */
-
-      case SNIOC_STOP:
-        ret = priv->ops->stop(priv);
-        break;
-
-      /* Set the sample rate. Arg: uint32_t value. */
-
-      case SNIOC_SETSAMPLERATE:
-        ret = priv->ops->setsamplerate(priv, (uint32_t)arg);
-        sninfo("sample rate: %08" PRId32 " ret: %d\n",
-               (uint32_t)arg, ret);
-        break;
-
-      /* Set the full-scale range. Arg: uint32_t value. */
-
-      case SNIOC_SETFULLSCALE:
-        ret = priv->ops->setfullscale(priv, (uint32_t)arg);
-        sninfo("full-scale range: %08" PRId32 " ret: %d\n",
-               (uint32_t)arg, ret);
-        break;
-
-      /* Unrecognized commands */
-
-      default:
-        snerr("ERROR: Unrecognized cmd: %d arg: %lu\n", cmd, arg);
-        ret = -ENOTTY;
-        break;
-    }
-
-  return ret;
-}
-
-/****************************************************************************
- * Name: lsm9ds1_register
- *
- * Description:
- *   Register the LSM9DS1 accelerometer, gyroscope or magnetometer character
- *   device as 'devpath'.
- *
- * Input Parameters:
- *   devpath - The full path to the driver to register, e.g., "/dev/accel0",
- *             "/dev/gyro0" or "/dev/mag0".
- *   i2c     - An I2C driver instance.
- *   addr    - The I2C address of the LSM9DS1 accelerometer, gyroscope or
- *             magnetometer.
- *   ops     - The device operations structure.
- *   datareg - The register address of the low byte of the X-coordinate data.
- *
- * Returned Value:
- *   Zero (OK) on success; a negated errno value on failure.
- *
- ****************************************************************************/
-
-static int lsm9ds1_register(FAR const char *devpath,
-                            FAR struct i2c_master_s *i2c, uint8_t addr,
-                            FAR const struct lsm9ds1_ops_s *ops,
-                            uint8_t datareg)
-{
-  FAR struct lsm9ds1_dev_s *priv;
-  int ret;
-
-  /* Sanity check */
-
-  DEBUGASSERT(devpath != NULL);
-  DEBUGASSERT(i2c != NULL);
-  DEBUGASSERT(datareg == LSM9DS1_OUT_X_L_XL ||
-              datareg == LSM9DS1_OUT_X_L_G ||
-              datareg == LSM9DS1_OUT_X_L_M);
-
-  /* Initialize the device's structure */
-
-  priv = kmm_malloc(sizeof(*priv));
-  if (priv == NULL)
-    {
-      snerr("ERROR: Failed to allocate instance\n");
-      return -ENOMEM;
-    }
-
-  priv->i2c        = i2c;
-  priv->addr       = addr;
-  priv->ops        = ops;
-  priv->samplerate = 0;
-  priv->datareg    = datareg;
-
-  /* Configure the device */
-
-  ret = priv->ops->config(priv);
-  if (ret < 0)
-    {
-      snerr("ERROR: Failed to configure device: %d\n", ret);
-      kmm_free(priv);
-      return ret;
-    }
-
-  /* Register the character driver */
-
-  ret = register_driver(devpath, &g_fops, 0666, priv);
-  if (ret < 0)
-    {
-      snerr("ERROR: Failed to register driver: %d\n", ret);
-      kmm_free(priv);
-      return ret;
-    }
-
-  return OK;
-}
-
-/****************************************************************************
- * Public Functions
- ****************************************************************************/
-
-/****************************************************************************
- * Name: lsm9ds1accel_register
- *
- * Description:
- *   Register the LSM9DS1 accelerometer character device as 'devpath'.
- *
- * Input Parameters:
- *   devpath - The full path to the driver to register, e.g., "/dev/accel0".
- *   i2c     - An I2C driver instance.
- *   addr    - The I2C address of the LSM9DS1 accelerometer.
- *
- * Returned Value:
- *   Zero (OK) on success; a negated errno value on failure.
- *
- ****************************************************************************/
-
-int lsm9ds1accel_register(FAR const char *devpath,
-                          FAR struct i2c_master_s *i2c,
-                          uint8_t addr)
-{
-  /* Sanity check */
-
-  DEBUGASSERT(addr == LSM9DS1ACCEL_ADDR0 || addr == LSM9DS1ACCEL_ADDR1);
-
-  return lsm9ds1_register(devpath, i2c, addr, &g_lsm9ds1accel_ops,
-                          LSM9DS1_OUT_X_L_XL);
-}
-
-/****************************************************************************
- * Name: lsm9ds1gyro_register
- *
- * Description:
- *   Register the LSM9DS1 gyroscope character device as 'devpath'.
- *
- * Input Parameters:
- *   devpath - The full path to the driver to register, e.g., "/dev/gyro0".
- *   i2c     - An I2C driver instance.
- *   addr    - The I2C address of the LSM9DS1 gyroscope.
- *
- * Returned Value:
- *   Zero (OK) on success; a negated errno value on failure.
- *
- ****************************************************************************/
-
-int lsm9ds1gyro_register(FAR const char *devpath,
-                         FAR struct i2c_master_s *i2c,
-                         uint8_t addr)
-{
-  /* Sanity check */
-
-  DEBUGASSERT(addr == LSM9DS1GYRO_ADDR0 || addr == LSM9DS1GYRO_ADDR1);
-
-  return lsm9ds1_register(devpath, i2c, addr, &g_lsm9ds1gyro_ops,
-                          LSM9DS1_OUT_X_L_G);
-}
-
-/****************************************************************************
- * Name: lsm9ds1mag_register
- *
- * Description:
- *   Register the LSM9DS1 magnetometer character device as 'devpath'.
- *
- * Input Parameters:
- *   devpath - The full path to the driver to register, e.g., "/dev/mag0".
- *   i2c     - An I2C driver instance.
- *   addr    - The I2C address of the LSM9DS1 magnetometer.
- *
- * Returned Value:
- *   Zero (OK) on success; a negated errno value on failure.
- *
- ****************************************************************************/
-
-int lsm9ds1mag_register(FAR const char *devpath,
-                        FAR struct i2c_master_s *i2c,
-                        uint8_t addr)
-{
-  /* Sanity check */
-
-  DEBUGASSERT(addr == LSM9DS1MAG_ADDR0 || addr == LSM9DS1MAG_ADDR1);
+int lsm9ds1_readreg8(FAR struct lsm9ds1_dev_s *priv,
+                     uint8_t regaddr, FAR uint8_t *regval);
+int lsm9ds1_readreg(FAR struct lsm9ds1_dev_s *priv,
+                    uint8_t regaddr, FAR uint8_t *regval, uint8_t len);
+int lsm9ds1_writereg8(FAR struct lsm9ds1_dev_s *priv,
+                      uint8_t regaddr, uint8_t regval);
+int lsm9ds1_modifyreg8(FAR struct lsm9ds1_dev_s *priv,
+                       uint8_t regaddr, uint8_t clearbits,
+                       uint8_t setbits);
+uint32_t lsm9ds1_midpoint(uint32_t a, uint32_t b);
 
-  return lsm9ds1_register(devpath, i2c, addr, &g_lsm9ds1mag_ops,
-                          LSM9DS1_OUT_X_L_M);
-}
-#endif /* CONFIG_I2C && CONFIG_SENSORS_LSM9DS1 */
+#endif /* __INCLUDE_NUTTX_SENSORS_LSM9DS1_COMMOM_H */
diff --git a/drivers/sensors/lsm9ds1_uorb.c b/drivers/sensors/lsm9ds1_uorb.c
new file mode 100644
index 0000000000..6875d5b583
--- /dev/null
+++ b/drivers/sensors/lsm9ds1_uorb.c
@@ -0,0 +1,803 @@
+/****************************************************************************
+ * drivers/sensors/lsm9ds1_uorb.c
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.  The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <math.h>
+#include <stdio.h>
+#include <string.h>
+#include <limits.h>
+#include <fcntl.h>
+#include <inttypes.h>
+#include <sys/param.h>
+
+#include <nuttx/mutex.h>
+#include <nuttx/signal.h>
+#include <nuttx/compiler.h>
+#include <nuttx/nuttx.h>
+#include <nuttx/kthread.h>
+
+#include <nuttx/sensors/sensor.h>
+#include <nuttx/sensors/ioctl.h>
+
+#include "lsm9ds1_base.h"
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+#define CONSTANTS_ONE_G 9.8f
+
+/****************************************************************************
+ * Private Types
+ ****************************************************************************/
+
+enum lsm9ds1_idx_e
+{
+  LSM9DS1_ACCEL_IDX = 0,
+  LSM9DS1_GYRO_IDX,
+  LSM9DS1_MAG_IDX,
+  LSM9DS1_MAX_IDX
+};
+
+struct lsm9ds1_sensor_s
+{
+  struct sensor_lowerhalf_s  lower;
+  uint64_t                   last_update;
+  float                      scale;
+  FAR void                  *dev;
+#ifdef CONFIG_SENSORS_LSM9DS1_POLL
+  bool                       enabled;
+  unsigned long              interval;
+#endif
+  struct lsm9ds1_dev_s       base;
+};
+
+struct lsm9ds1_sensor_dev_s
+{
+  struct lsm9ds1_sensor_s priv[3];
+  mutex_t                 lock;
+#ifdef CONFIG_SENSORS_LSM9DS1_POLL
+  sem_t                   run;
+#endif
+};
+
+/****************************************************************************
+ * Private Function Prototypes
+ ****************************************************************************/
+
+/* Sensor methods */
+
+static int lsm9ds1_activate(FAR struct sensor_lowerhalf_s *lower,
+                           FAR struct file *filep,
+                           bool enable);
+static int lsm9ds1_set_interval(FAR struct sensor_lowerhalf_s *lower,
+                                FAR struct file *filep,
+                                FAR unsigned long *period_us);
+#ifndef CONFIG_SENSORS_LSM9DS1_POLL
+static int lsm9ds1_fetch(FAR struct sensor_lowerhalf_s *lower,
+                         FAR struct file *filep,
+                         FAR char *buffer, size_t buflen);
+#endif
+static int lsm9ds1_control(FAR struct sensor_lowerhalf_s *lower,
+                           FAR struct file *filep,
+                           int cmd, unsigned long arg);
+
+/* Helpers */
+
+static int lsm9ds1_mag_scale(FAR struct lsm9ds1_sensor_s *priv,
+                             uint8_t scale);
+static int lsm9ds1_accel_scale(FAR struct lsm9ds1_sensor_s *priv,
+                               uint8_t scale);
+static int lsm9ds1_gyro_scale(FAR struct lsm9ds1_sensor_s *priv,
+                              uint8_t scale);
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+static const struct sensor_ops_s g_sensor_ops =
+{
+  NULL,                 /* open */
+  NULL,                 /* close */
+  .activate     = lsm9ds1_activate,
+  .set_interval = lsm9ds1_set_interval,
+  NULL,                 /* batch */
+#ifdef CONFIG_SENSORS_LSM9DS1_POLL
+  NULL,                 /* fetch */
+#else
+  .fetch        = lsm9ds1_fetch,
+#endif
+  NULL,                 /* selftest */
+  NULL,                 /* set_calibvalue */
+  NULL,                 /* calibrate */
+  .control      = lsm9ds1_control
+};
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: lsm9ds1_activate
+ ****************************************************************************/
+
+static int lsm9ds1_activate(FAR struct sensor_lowerhalf_s *lower,
+                            FAR struct file *filep, bool enable)
+{
+#ifdef CONFIG_SENSORS_LSM9DS1_POLL
+  FAR struct lsm9ds1_sensor_s     *priv         = NULL;
+  FAR struct lsm9ds1_sensor_dev_s *dev          = NULL;
+  bool                             start_thread = false;
+  int                              ret          = OK;
+
+  priv = container_of(lower, struct lsm9ds1_sensor_s, lower);
+  dev = priv->dev;
+
+  if (enable)
+    {
+      if (!priv->enabled)
+        {
+          start_thread      = true;
+          priv->last_update = sensor_get_timestamp();
+        }
+
+      ret = priv->base.ops->start(&priv->base);
+    }
+  else
+    {
+      ret = priv->base.ops->stop(&priv->base);
+    }
+
+  priv->enabled = enable;
+
+  if (start_thread)
+    {
+      /* Wake up the thread */
+
+      nxsem_post(&dev->run);
+    }
+
+  return ret;
+#else
+  return OK;
+#endif
+}
+
+/****************************************************************************
+ * Name: lsm9ds1_set_interval
+ ****************************************************************************/
+
+static int lsm9ds1_set_interval(FAR struct sensor_lowerhalf_s *lower,
+                                FAR struct file *filep,
+                                FAR unsigned long *interval)
+{
+#ifdef CONFIG_SENSORS_LSM9DS1_POLL
+  FAR struct lsm9ds1_sensor_s *priv = NULL;
+
+  priv = container_of(lower, struct lsm9ds1_sensor_s, lower);
+
+  priv->interval = *interval;
+#endif
+
+  return OK;
+}
+
+/****************************************************************************
+ * Name: lsm9ds1_data
+ ****************************************************************************/
+
+static int16_t lsm9ds1_data(int16_t data)
+{
+  /* The value is positive */
+
+  if (data < 0x8000)
+    {
+      data = data;
+    }
+
+  /* The value is negative, so find its absolute value by taking the
+   * two's complement
+   */
+
+  else if (data > 0x8000)
+    {
+      data = -(~data + 1);
+    }
+
+  /* The value is negative and can't be represented as a positive
+   * int16_t value
+   */
+
+  else
+    {
+      data = -32768;
+    }
+
+  return data;
+}
+
+#ifndef CONFIG_SENSORS_LSM9DS1_POLL
+/****************************************************************************
+ * Name: lsm9ds1_set_interval
+ ****************************************************************************/
+
+static int lsm9ds1_fetch(FAR struct sensor_lowerhalf_s *lower,
+                         FAR struct file *filep, FAR char *buffer,
+                         size_t buflen)
+{
+  FAR struct lsm9ds1_sensor_s *priv = NULL;
+  int16_t                      data[3];
+  int                          ret  = OK;
+
+  priv = container_of(lower, struct lsm9ds1_sensor_s, lower);
+
+  switch (lower->type)
+    {
+      case SENSOR_TYPE_ACCELEROMETER:
+        {
+          struct sensor_accel accel;
+
+          ret = lsm9ds1_readreg(&priv->base, LSM9DS1_OUT_X_L_XL,
+                                (FAR uint8_t *)data, 6);
+
+          accel.timestamp = sensor_get_timestamp();
+          accel.x         = (int16_t)lsm9ds1_data(data[0]) * priv->scale;
+          accel.y         = (int16_t)lsm9ds1_data(data[1]) * priv->scale;
+          accel.z         = (int16_t)lsm9ds1_data(data[2]) * priv->scale;
+
+          memcpy(buffer, &accel, sizeof(accel));
+
+          break;
+        }
+
+      case SENSOR_TYPE_GYROSCOPE:
+        {
+          struct sensor_gyro gyro;
+
+          ret = lsm9ds1_readreg(&priv->base, LSM9DS1_OUT_X_L_G,
+                                (FAR uint8_t *)data, 6);
+
+          gyro.timestamp = sensor_get_timestamp();
+          gyro.x         = (int16_t)lsm9ds1_data(data[0]) * priv->scale;
+          gyro.y         = (int16_t)lsm9ds1_data(data[1]) * priv->scale;
+          gyro.z         = (int16_t)lsm9ds1_data(data[2]) * priv->scale;
+
+          memcpy(buffer, &gyro, sizeof(gyro));
+
+          break;
+        }
+
+      case SENSOR_TYPE_MAGNETIC_FIELD:
+        {
+          struct sensor_mag mag;
+
+          ret = lsm9ds1_readreg(&priv->base, LSM9DS1_OUT_X_L_M,
+                                (FAR uint8_t *)data, 6);
+
+          mag.timestamp = sensor_get_timestamp();
+          mag.x         = (int16_t)lsm9ds1_data(data[0]) * priv->scale;
+          mag.y         = (int16_t)lsm9ds1_data(data[1]) * priv->scale;
+          mag.z         = (int16_t)lsm9ds1_data(data[2]) * priv->scale;
+
+          memcpy(buffer, &mag, sizeof(mag));
+
+          break;
+        }
+
+      default:
+        {
+          ret = -EINVAL;
+          break;
+        }
+    }
+
+  return ret;
+}
+#endif
+
+/****************************************************************************
+ * Name: lsm9ds1_cotrol
+ ****************************************************************************/
+
+static int lsm9ds1_control(FAR struct sensor_lowerhalf_s *lower,
+                           FAR struct file *filep, int cmd,
+                           unsigned long arg)
+{
+  FAR struct lsm9ds1_sensor_s *priv = NULL;
+  int                          ret  = OK;
+
+  priv = container_of(lower, struct lsm9ds1_sensor_s, lower);
+
+  switch (cmd)
+    {
+        /* Set full scale command */
+
+      case SNIOC_SET_SCALE_XL:
+        {
+          if (priv->lower.type == SENSOR_TYPE_GYROSCOPE)
+            {
+              ret = lsm9ds1_gyro_scale(priv, arg);
+            }
+          else if (priv->lower.type == SENSOR_TYPE_ACCELEROMETER)
+            {
+              ret = lsm9ds1_accel_scale(priv, arg);
+            }
+          else if (priv->lower.type == SENSOR_TYPE_MAGNETIC_FIELD)
+            {
+              ret = lsm9ds1_mag_scale(priv, arg);
+            }
+
+          break;
+        }
+
+      default:
+        {
+          snerr("ERROR: Unrecognized cmd: %d\n", cmd);
+          ret = -ENOTTY;
+          break;
+        }
+    }
+
+  return ret;
+}
+
+/****************************************************************************
+ * Name: lsm9ds1_mag_scale
+ ****************************************************************************/
+
+static int lsm9ds1_mag_scale(FAR struct lsm9ds1_sensor_s *priv,
+                             uint8_t scale)
+{
+  int ret = OK;
+
+  ret = priv->base.ops->setfullscale(&priv->base, scale);
+  if (ret < 0)
+    {
+      return ret;
+    }
+
+  if (scale < lsm9ds1_midpoint(4, 8))
+    {
+      priv->scale = 8.f / 65536.f;
+    }
+  else if (scale < lsm9ds1_midpoint(8, 12))
+    {
+      priv->scale = 16.f / 65536.f;
+    }
+  else if (scale < lsm9ds1_midpoint(12, 16))
+    {
+      priv->scale = 24.f / 65536.f;
+    }
+  else
+    {
+      priv->scale = 32.f / 65536.f;
+    }
+
+  return ret;
+}
+
+/****************************************************************************
+ * Name: lsm9ds1_accel_scale
+ ****************************************************************************/
+
+static int lsm9ds1_accel_scale(FAR struct lsm9ds1_sensor_s *priv,
+                               uint8_t scale)
+{
+  int ret = OK;
+
+  ret = priv->base.ops->setfullscale(&priv->base, scale);
+  if (ret < 0)
+    {
+      return ret;
+    }
+
+  if (scale < lsm9ds1_midpoint(2, 4))
+    {
+      priv->scale = CONSTANTS_ONE_G / 16384.f;
+    }
+  else if (scale < lsm9ds1_midpoint(4, 8))
+    {
+      priv->scale = CONSTANTS_ONE_G / 8192.f;
+    }
+  else if (scale < lsm9ds1_midpoint(8, 16))
+    {
+      priv->scale = CONSTANTS_ONE_G / 4096.f;
+    }
+  else
+    {
+      priv->scale = CONSTANTS_ONE_G / 2048.f;
+    }
+
+  return ret;
+}
+
+/****************************************************************************
+ * Name: lsm9ds1_gyro_scale
+ ****************************************************************************/
+
+static int lsm9ds1_gyro_scale(FAR struct lsm9ds1_sensor_s *priv,
+                              uint8_t scale)
+{
+  int ret = OK;
+
+  ret = priv->base.ops->setfullscale(&priv->base, scale);
+  if (ret < 0)
+    {
+      return ret;
+    }
+
+  if (scale < lsm9ds1_midpoint(245, 500))
+    {
+      priv->scale = (M_PI / 180.0f) * 245.f / 32768.f;
+    }
+  else if (scale < lsm9ds1_midpoint(500, 2000))
+    {
+      priv->scale = (M_PI / 180.0f) * 500.f / 32768.f;
+    }
+  else
+    {
+      priv->scale = (M_PI / 180.0f) * 2000.f / 32768.f;
+    }
+
+  return ret;
+}
+
+#ifdef CONFIG_SENSORS_LSM9DS1_POLL
+/****************************************************************************
+ * Name: lsm9ds1_accel_data
+ *
+ * Description: get and push accel data from struct sensor_data_s
+ *
+ * Parameter:
+ *   priv  - Internal private lower half driver instance
+ *   buf  - Point to data
+ *
+ * Return:
+ *   OK - on success
+ *
+ ****************************************************************************/
+
+static void lsm9ds1_accel_data(FAR struct lsm9ds1_sensor_s *priv,
+                               FAR int16_t *buf)
+{
+  FAR struct sensor_lowerhalf_s *lower = &priv->lower;
+  struct sensor_accel accel;
+  uint64_t now                         = sensor_get_timestamp();
+
+  if (!priv->enabled || now - priv->last_update < priv->interval)
+    {
+      return;
+    }
+
+  priv->last_update = now;
+
+  accel.timestamp   = now;
+  accel.x           = (int16_t)lsm9ds1_data(buf[0]) * priv->scale;
+  accel.y           = (int16_t)lsm9ds1_data(buf[1]) * priv->scale;
+  accel.z           = (int16_t)lsm9ds1_data(buf[2]) * priv->scale;
+  accel.temperature = 0;
+
+  lower->push_event(lower->priv, &accel, sizeof(accel));
+}
+
+/****************************************************************************
+ * Name: lsm9ds1_gyro_data
+ *
+ * Description: get and push gyro data from struct sensor_data_s
+ *
+ * Parameter:
+ *   priv  - Internal private lower half driver instance
+ *   buf  - Point to data
+ *
+ * Return:
+ *   OK - on success
+ *
+ ****************************************************************************/
+
+static void lsm9ds1_gyro_data(FAR struct lsm9ds1_sensor_s *priv,
+                              FAR int16_t *buf)
+{
+  FAR struct sensor_lowerhalf_s *lower = &priv->lower;
+  struct sensor_gyro             gyro;
+  uint64_t                       now   = sensor_get_timestamp();
+
+  if (!priv->enabled || now - priv->last_update < priv->interval)
+    {
+      return;
+    }
+
+  priv->last_update = now;
+
+  gyro.timestamp   = now;
+  gyro.x           = (int16_t)lsm9ds1_data(buf[0]) * priv->scale;
+  gyro.y           = (int16_t)lsm9ds1_data(buf[1]) * priv->scale;
+  gyro.z           = (int16_t)lsm9ds1_data(buf[2]) * priv->scale;
+  gyro.temperature = 0;
+
+  lower->push_event(lower->priv, &gyro, sizeof(gyro));
+}
+
+/****************************************************************************
+ * Name: lsm9ds1_mag_data
+ *
+ * Description: get and push magnetometer data from struct sensor_data_s
+ *
+ * Parameter:
+ *   priv  - Internal private lower half driver instance
+ *   buf  - Point to data
+ *
+ * Return:
+ *   OK - on success
+ *
+ ****************************************************************************/
+
+static void lsm9ds1_mag_data(FAR struct lsm9ds1_sensor_s *priv,
+                             FAR int16_t *buf)
+{
+  FAR struct sensor_lowerhalf_s *lower = &priv->lower;
+  struct sensor_mag              mag;
+  uint64_t                       now   = sensor_get_timestamp();
+
+  if (!priv->enabled || now - priv->last_update < priv->interval)
+    {
+      return;
+    }
+
+  priv->last_update = now;
+
+  mag.timestamp   = now;
+  mag.x           = (int16_t)lsm9ds1_data(buf[0]) * priv->scale;
+  mag.y           = (int16_t)lsm9ds1_data(buf[1]) * priv->scale;
+  mag.z           = (int16_t)lsm9ds1_data(buf[2]) * priv->scale;
+  mag.temperature = 0;
+
+  lower->push_event(lower->priv, &mag, sizeof(mag));
+}
+
+/****************************************************************************
+ * Name: lsm9ds1_thread
+ *
+ * Description: Thread for performing interval measurement cycle and data
+ *              read.
+ *
+ * Parameter:
+ *   argc - Number opf arguments
+ *   argv - Pointer to argument list
+ *
+ ****************************************************************************/
+
+static int lsm9ds1_thread(int argc, FAR char **argv)
+{
+  FAR struct lsm9ds1_sensor_dev_s *dev
+      = (FAR struct lsm9ds1_sensor_dev_s *)((uintptr_t)strtoul(argv[1], NULL,
+                                                               16));
+  FAR struct lsm9ds1_sensor_s *accel = &dev->priv[LSM9DS1_ACCEL_IDX];
+  FAR struct lsm9ds1_sensor_s *gyro  = &dev->priv[LSM9DS1_GYRO_IDX];
+  FAR struct lsm9ds1_sensor_s *mag   = &dev->priv[LSM9DS1_MAG_IDX];
+  unsigned long                min_interval;
+  int16_t                      adata[3];
+  int16_t                      gdata[3];
+  int16_t                      mdata[3];
+  int                          ret;
+
+  while (true)
+    {
+      if ((!accel->enabled) && (!gyro->enabled) && (!mag->enabled))
+        {
+          /* Waiting to be woken up */
+
+          ret = nxsem_wait(&dev->run);
+          if (ret < 0)
+            {
+              continue;
+            }
+        }
+
+      /* Read accel */
+
+      if (accel->enabled)
+        {
+          ret = lsm9ds1_readreg(&accel->base,
+                                LSM9DS1_OUT_X_L_XL, (uint8_t *)adata, 6);
+          lsm9ds1_accel_data(accel, adata);
+        }
+
+      /* Read gyro */
+
+      if (gyro->enabled)
+        {
+          ret = lsm9ds1_readreg(&gyro->base,
+                                LSM9DS1_OUT_X_L_G, (uint8_t *)gdata, 6);
+          lsm9ds1_gyro_data(gyro, gdata);
+        }
+
+      /* Read mag */
+
+      if (mag->enabled)
+        {
+          ret = lsm9ds1_readreg(&mag->base,
+                                LSM9DS1_OUT_X_L_M, (uint8_t *)mdata, 6);
+          lsm9ds1_mag_data(mag, mdata);
+        }
+
+      /* Sleeping thread before fetching the next sensor data */
+
+      min_interval = MIN(accel->interval, gyro->interval);
+      min_interval = MIN(min_interval, mag->interval);
+      nxsig_usleep(min_interval);
+    }
+
+  return OK;
+}
+#endif
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: lsm9ds1_register_uorb
+ *
+ * Description:
+ *   Register the LSM9DS1 IMU as sensor device
+ *
+ * Input Parameters:
+ *   devno   - Instance number for driver
+ *   config  - configuratio
+ *
+ * Returned Value:
+ *   Zero (OK) on success; a negated errno value on failure.
+ *
+ ****************************************************************************/
+
+int lsm9ds1_register_uorb(int devno, FAR struct lsm9ds1_config_s *config)
+{
+  FAR struct lsm9ds1_sensor_dev_s *dev = NULL;
+  FAR struct lsm9ds1_sensor_s     *tmp = NULL;
+#ifdef CONFIG_SENSORS_LSM9DS1_POLL
+  FAR char                        *argv[2];
+  char                             arg1[32];
+#endif
+  int                              ret = OK;
+
+  /* Initialize the device structure. */
+
+  dev = (FAR struct lsm9ds1_sensor_dev_s *)kmm_malloc(sizeof(*dev));
+  if (dev == NULL)
+    {
+      snerr("ERROR: Failed to allocate instance\n");
+      return -ENOMEM;
+    }
+
+  memset(dev, 0, sizeof(*dev));
+  nxmutex_init(&dev->lock);
+#ifdef CONFIG_SENSORS_LSM9DS1_POLL
+  nxsem_init(&dev->run, 0, 0);
+#endif
+
+  /* Accelerometer register */
+
+  tmp                = &dev->priv[LSM9DS1_ACCEL_IDX];
+  tmp->dev           = dev;
+  tmp->base.ops      = &g_lsm9ds1accel_ops;
+  tmp->base.i2c      = config->i2c;
+  tmp->base.addr     = config->addr_acc;
+  tmp->lower.ops     = &g_sensor_ops;
+  tmp->lower.type    = SENSOR_TYPE_ACCELEROMETER;
+  tmp->lower.nbuffer = 1;
+#ifdef CONFIG_SENSORS_LSM9DS1_POLL
+  tmp->enabled       = false;
+  tmp->interval      = CONFIG_SENSORS_LSM9DS1_POLL_INTERVAL;
+#endif
+
+  ret = sensor_register(&tmp->lower, devno);
+  if (ret < 0)
+    {
+      snerr("sensor_register failed: %d\n", ret);
+      goto gyro_err;
+    }
+
+  lsm9ds1_accel_scale(tmp, 2);
+
+  /* Gyroscope register */
+
+  tmp                = &dev->priv[LSM9DS1_GYRO_IDX];
+  tmp->dev           = dev;
+  tmp->base.ops      = &g_lsm9ds1gyro_ops;
+  tmp->base.i2c      = config->i2c;
+  tmp->base.addr     = config->addr_gyro;
+  tmp->lower.ops     = &g_sensor_ops;
+  tmp->lower.type    = SENSOR_TYPE_GYROSCOPE;
+  tmp->lower.nbuffer = 1;
+#ifdef CONFIG_SENSORS_LSM9DS1_POLL
+  tmp->enabled       = false;
+  tmp->interval      = CONFIG_SENSORS_LSM9DS1_POLL_INTERVAL;
+#endif
+
+  ret = sensor_register(&tmp->lower, devno);
+  if (ret < 0)
+    {
+      snerr("sensor_register failed: %d\n", ret);
+      goto gyro_err;
+    }
+
+  lsm9ds1_gyro_scale(tmp, 245);
+
+  /* Magnetic register */
+
+  tmp                = &dev->priv[LSM9DS1_MAG_IDX];
+  tmp->dev           = dev;
+  tmp->base.ops      = &g_lsm9ds1mag_ops;
+  tmp->base.i2c      = config->i2c;
+  tmp->base.addr     = config->addr_mag;
+  tmp->lower.ops     = &g_sensor_ops;
+  tmp->lower.type    = SENSOR_TYPE_MAGNETIC_FIELD;
+  tmp->lower.nbuffer = 1;
+#ifdef CONFIG_SENSORS_LSM9DS1_POLL
+  tmp->enabled       = false;
+  tmp->interval      = CONFIG_SENSORS_LSM9DS1_POLL_INTERVAL;
+#endif
+
+  ret = sensor_register(&tmp->lower, devno);
+  if (ret < 0)
+    {
+      snerr("sensor_register failed: %d\n", ret);
+      goto mag_err;
+    }
+
+  lsm9ds1_mag_scale(tmp, 4);
+
+#ifdef CONFIG_SENSORS_LSM9DS1_POLL
+  /* Create thread for polling sensor data */
+
+  snprintf(arg1, 16, "%p", dev);
+  argv[0] = arg1;
+  argv[1] = NULL;
+
+  ret = kthread_create("lsm9ds1_thread", SCHED_PRIORITY_DEFAULT,
+                       CONFIG_SENSORS_LSM9DS1_THREAD_STACKSIZE,
+                       lsm9ds1_thread,
+                       argv);
+  if (ret < 0)
+    {
+      goto thr_err;
+    }
+#endif
+
+  return ret;
+
+#ifdef CONFIG_SENSORS_LSM9DS1_POLL
+thr_err:
+#endif
+  sensor_unregister(&dev->priv[LSM9DS1_MAG_IDX].lower, devno);
+mag_err:
+  sensor_unregister(&dev->priv[LSM9DS1_GYRO_IDX].lower, devno);
+gyro_err:
+  sensor_unregister(&dev->priv[LSM9DS1_ACCEL_IDX].lower, devno);
+
+  kmm_free(dev);
+
+  return ret;
+}
diff --git a/include/nuttx/sensors/lsm9ds1.h b/include/nuttx/sensors/lsm9ds1.h
index a5cd2c6c35..44ae703ca2 100644
--- a/include/nuttx/sensors/lsm9ds1.h
+++ b/include/nuttx/sensors/lsm9ds1.h
@@ -57,6 +57,14 @@
 
 struct i2c_master_s;
 
+struct lsm9ds1_config_s
+{
+  FAR struct i2c_master_s *i2c;
+  int                      addr_acc;
+  int                      addr_gyro;
+  int                      addr_mag;
+};
+
 /****************************************************************************
  * Public Function Prototypes
  ****************************************************************************/
@@ -66,6 +74,8 @@ extern "C"
 {
 #endif
 
+#ifndef CONFIG_SENSORS_LSM9DS1_UORB
+
 /****************************************************************************
  * Name: lsm9ds1accel_register
  *
@@ -126,6 +136,26 @@ int lsm9ds1mag_register(FAR const char *devpath,
                         FAR struct i2c_master_s *i2c,
                         uint8_t addr);
 
+#else
+
+/****************************************************************************
+ * Name: lsm9ds1_register_uorb
+ *
+ * Description:
+ *   Register the LSM9DS1 IMU as sensor device
+ *
+ * Input Parameters:
+ *   devno   - Instance number for driver
+ *   config  - configuratio
+ *
+ * Returned Value:
+ *   Zero (OK) on success; a negated errno value on failure.
+ *
+ ****************************************************************************/
+
+int lsm9ds1_register_uorb(int devno, FAR struct lsm9ds1_config_s *config);
+#endif
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/include/nuttx/sensors/sensor.h b/include/nuttx/sensors/sensor.h
index 3aa577a94c..4fd0f385e9 100644
--- a/include/nuttx/sensors/sensor.h
+++ b/include/nuttx/sensors/sensor.h
@@ -966,7 +966,7 @@ struct sensor_ops_s
                              FAR struct file *filep,
                              unsigned long arg);
 
-/****************************************************************************
+  /**************************************************************************
    * Name: calibrate
    *
    * This operation can trigger the calibration operation, and if the


(nuttx) 02/02: nrf52/common: support for lsm9ds1 uorb

Posted by xi...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

xiaoxiang pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/nuttx.git

commit b7db53b6e1b1aa4b8774799f5aaa233289769c29
Author: raiden00pl <ra...@railab.me>
AuthorDate: Fri Mar 8 13:30:21 2024 +0100

    nrf52/common: support for lsm9ds1 uorb
---
 boards/arm/nrf52/common/src/nrf52_lsm9ds1.c | 36 ++++++++++++++++++++++++++++-
 1 file changed, 35 insertions(+), 1 deletion(-)

diff --git a/boards/arm/nrf52/common/src/nrf52_lsm9ds1.c b/boards/arm/nrf52/common/src/nrf52_lsm9ds1.c
index af6ba01b3d..df22f74b23 100644
--- a/boards/arm/nrf52/common/src/nrf52_lsm9ds1.c
+++ b/boards/arm/nrf52/common/src/nrf52_lsm9ds1.c
@@ -54,6 +54,39 @@
 
 int nrf52_lsm9ds1_initialize(int bus)
 {
+#ifdef CONFIG_SENSORS_LSM9DS1_UORB
+  struct lsm9ds1_config_s  config;
+  struct i2c_master_s     *i2c;
+  int                      ret = OK;
+
+  sninfo("Initializing LMS6DSL!\n");
+
+  i2c = nrf52_i2cbus_initialize(bus);
+  if (i2c == NULL)
+    {
+      return -ENODEV;
+    }
+
+  sninfo("INFO: Initializing LMS9DS1 9DoF sensor over I2C%d\n", bus);
+
+  config.i2c       = i2c;
+  config.addr_acc  = LSM9DS1ACCEL_ADDR1;
+  config.addr_gyro = LSM9DS1GYRO_ADDR1;
+  config.addr_mag  = LSM9DS1MAG_ADDR1;
+
+  /* Register sensor as uorb devices */
+
+  ret = lsm9ds1_register_uorb(0, &config);
+  if (ret < 0)
+    {
+      snerr("ERROR: Failed to initialize LMS9DS1 mag driver\n");
+      return -ENODEV;
+    }
+
+  sninfo("INFO: LMS9DS1 sensor has been initialized successfully\n");
+
+  return ret;
+#else
   struct i2c_master_s *i2c;
   int ret = OK;
 
@@ -67,7 +100,7 @@ int nrf52_lsm9ds1_initialize(int bus)
 
   sninfo("INFO: Initializing LMS9DS1 9DoF sensor over I2C%d\n", bus);
 
-  /* Register snesors as character devices */
+  /* Register sensor as character devices */
 
   ret = lsm9ds1mag_register(LSM9DS1MAG_DEVPATH, i2c, LSM9DS1MAG_ADDR1);
   if (ret < 0)
@@ -94,4 +127,5 @@ int nrf52_lsm9ds1_initialize(int bus)
     }
 
   return ret;
+#endif
 }