You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mynewt.apache.org by GitBox <gi...@apache.org> on 2018/03/15 23:10:09 UTC

[GitHub] vrahane commented on a change in pull request #926: Add Driver for LIS2DW12

vrahane commented on a change in pull request #926: Add Driver for LIS2DW12
URL: https://github.com/apache/mynewt-core/pull/926#discussion_r174959140
 
 

 ##########
 File path: hw/drivers/sensors/lis2dw12/src/lis2dw12.c
 ##########
 @@ -0,0 +1,1664 @@
+/*
+ * 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
+ * resarding 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.
+ */
+
+#include <assert.h>
+#include <stdio.h>
+#include <errno.h>
+#include <string.h>
+
+#include "sysinit/sysinit.h"
+#include "defs/error.h"
+#include "os/os.h"
+#include "hal/hal_spi.h"
+#include "hal/hal_i2c.h"
+#include "sensor/sensor.h"
+#include "sensor/accel.h"
+#include "lis2dw12/lis2dw12.h"
+#include "lis2dw12_priv.h"
+#include "hal/hal_gpio.h"
+#include "log/log.h"
+#include "stats/stats.h"
+
+static struct hal_spi_settings spi_lis2dw12_settings = {
+    .data_order = HAL_SPI_MSB_FIRST,
+    .data_mode  = HAL_SPI_MODE3,
+    .baudrate   = 4000,
+    .word_size  = HAL_SPI_WORD_SIZE_8BIT,
+};
+
+/* Define the stats section and records */
+STATS_SECT_START(lis2dw12_stat_section)
+    STATS_SECT_ENTRY(write_errors)
+    STATS_SECT_ENTRY(read_errors)
+STATS_SECT_END
+
+/* Define stat names for querying */
+STATS_NAME_START(lis2dw12_stat_section)
+    STATS_NAME(lis2dw12_stat_section, write_errors)
+    STATS_NAME(lis2dw12_stat_section, read_errors)
+STATS_NAME_END(lis2dw12_stat_section)
+
+/* Global variable used to hold stats data */
+STATS_SECT_DECL(lis2dw12_stat_section) g_lis2dw12stats;
+
+#define LOG_MODULE_LIS2DW12    (212)
+#define LIS2DW12_INFO(...)     LOG_INFO(&_log, LOG_MODULE_LIS2DW12, __VA_ARGS__)
+#define LIS2DW12_ERR(...)      LOG_ERROR(&_log, LOG_MODULE_LIS2DW12, __VA_ARGS__)
+static struct log _log;
+
+#define LIS2DW12_NOTIFY_MASK 0x01
+
+/* Exports for the sensor API */
+static int lis2dw12_sensor_read(struct sensor *, sensor_type_t,
+        sensor_data_func_t, void *, uint32_t);
+static int lis2dw12_sensor_get_config(struct sensor *, sensor_type_t,
+        struct sensor_cfg *);
+static int lis2dw12_sensor_set_notification(struct sensor *,
+                                            sensor_event_type_t);
+static int lis2dw12_sensor_unset_notification(struct sensor *,
+                                              sensor_event_type_t);
+static int lis2dw12_sensor_handle_interrupt(struct sensor *);
+
+static const struct sensor_driver g_lis2dw12_sensor_driver = {
+    .sd_read = lis2dw12_sensor_read,
+    .sd_get_config = lis2dw12_sensor_get_config,
+    .sd_set_notification = lis2dw12_sensor_set_notification,
+    .sd_unset_notification = lis2dw12_sensor_unset_notification,
+    .sd_handle_interrupt = lis2dw12_sensor_handle_interrupt
+
+};
+
+/**
+ * Writes a single byte to the specified register using i2c
+ *
+ * @param The sensor interface
+ * @param The register address to write to
+ * @param The value to write
+ *
+ * @return 0 on success, non-zero error on failure.
+ */
+int
+lis2dw12_i2c_write8(struct sensor_itf *itf, uint8_t reg, uint8_t value)
+{
+    int rc;
+    uint8_t payload[2] = { reg, value };
+    
+    struct hal_i2c_master_data data_struct = {
+        .address = itf->si_addr,
+        .len = 2,
+        .buffer = payload
+    };
+
+    rc = hal_i2c_master_write(itf->si_num, &data_struct,
+                              OS_TICKS_PER_SEC / 10, 1);
+
+    if (rc) {
+        LIS2DW12_ERR("Failed to write to 0x%02X:0x%02X with value 0x%02X\n",
+                    itf->si_addr, reg, value);
+        STATS_INC(g_lis2dw12stats, read_errors);
+    }
+
+    return rc;
+}
+
+/**
+ * Read multiple bytes starting from specified register over i2c
+ *    
+ * @param The sensor interface
+ * @param The register address start reading from
+ * @param Pointer to where the register value should be written
+ * @param Number of bytes to read
+ *
+ * @return 0 on success, non-zero error on failure.
+ */
+int
+lis2dw12_i2c_readlen(struct sensor_itf *itf, uint8_t reg, uint8_t *buffer, uint8_t len)
+{
+    int rc;
+
+    struct hal_i2c_master_data data_struct = {
+        .address = itf->si_addr,
+        .len = 1,
+        .buffer = &reg
+    };
+
+    /* Register write */
+    rc = hal_i2c_master_write(itf->si_num, &data_struct,
+                              OS_TICKS_PER_SEC / 10, 1);
+    if (rc) {
+        LIS2DW12_ERR("I2C access failed at address 0x%02X\n", itf->si_addr);
+        STATS_INC(g_lis2dw12stats, write_errors);
+        return rc;
+    }
+
+    /* Read data */
+    data_struct.len = len;
+    data_struct.buffer = buffer;
+    rc = hal_i2c_master_read(itf->si_num, &data_struct,
+                             OS_TICKS_PER_SEC / 10, 1);
+
+    if (rc) {
+        LIS2DW12_ERR("Failed to read from 0x%02X:0x%02X\n", itf->si_addr, reg);
+        STATS_INC(g_lis2dw12stats, read_errors);
+    }
+
+    return rc;
+}
+
+/**
+ * Writes a single byte to the specified register using SPI
+ *
+ * @param The sensor interface
+ * @param The register address to write to
+ * @param The value to write
+ *
+ * @return 0 on success, non-zero error on failure.
+ */
+int
+lis2dw12_spi_write8(struct sensor_itf *itf, uint8_t reg, uint8_t value)
+{
+    int rc;
+
+    /* Select the device */
+    hal_gpio_write(itf->si_cs_pin, 0);
+
+    /* Send the address */
+    rc = hal_spi_tx_val(itf->si_num, reg & ~LIS2DW12_SPI_READ_CMD_BIT);
+    if (rc == 0xFFFF) {
+        rc = SYS_EINVAL;
+        LIS2DW12_ERR("SPI_%u register write failed addr:0x%02X\n",
+                   itf->si_num, reg);
+        STATS_INC(g_lis2dw12stats, write_errors);
+        goto err;
+    }
+
+    /* Read data */
+    rc = hal_spi_tx_val(itf->si_num, value);
+    if (rc == 0xFFFF) {
+        rc = SYS_EINVAL;
+        LIS2DW12_ERR("SPI_%u write failed addr:0x%02X:0x%02X\n",
+                   itf->si_num, reg);
+        STATS_INC(g_lis2dw12stats, write_errors);
+        goto err;
+    }
+
+    rc = 0;
+
+err:
+    /* De-select the device */
+    hal_gpio_write(itf->si_cs_pin, 1);
+
+    return rc;
+}
+
+/**
+ * Read multiple bytes starting from specified register over SPI
+ *
+ * @param The sensor interface
+ * @param The register address start reading from
+ * @param Pointer to where the register value should be written
+ * @param Number of bytes to read
+ *
+ * @return 0 on success, non-zero on failure
+ */
+int
+lis2dw12_spi_readlen(struct sensor_itf *itf, uint8_t reg, uint8_t *buffer,
+                    uint8_t len)
+{
+    int i;
+    uint16_t retval;
+    int rc = 0;
+
+    /* Select the device */
+    hal_gpio_write(itf->si_cs_pin, 0);
+
+    /* Send the address */
+    retval = hal_spi_tx_val(itf->si_num, reg | LIS2DW12_SPI_READ_CMD_BIT);
+    
+    if (retval == 0xFFFF) {
+        rc = SYS_EINVAL;
+        LIS2DW12_ERR("SPI_%u register write failed addr:0x%02X\n",
+                   itf->si_num, reg);
+        STATS_INC(g_lis2dw12stats, read_errors);
+        goto err;
+    }
+
+    for (i = 0; i < len; i++) {
+        /* Read data */
+        retval = hal_spi_tx_val(itf->si_num, 0);
+        if (retval == 0xFFFF) {
+            rc = SYS_EINVAL;
+            LIS2DW12_ERR("SPI_%u read failed addr:0x%02X\n",
+                       itf->si_num, reg);
+            STATS_INC(g_lis2dw12stats, read_errors);
+            goto err;
+        }
+        buffer[i] = retval;
+    }
+
+err:
+    /* De-select the device */
+    hal_gpio_write(itf->si_cs_pin, 1);
+
+    return rc;
+}
+
+
+/**
+ * Write byte to sensor over different interfaces
+ *
+ * @param The sensor interface
+ * @param The register address to write to
+ * @param The value to write
+ *
+ * @return 0 on success, non-zero on failure
+ */
+int
+lis2dw12_write8(struct sensor_itf *itf, uint8_t reg, uint8_t value)
+{
+    int rc;
+
+    if (itf->si_type == SENSOR_ITF_I2C) {
+        rc = lis2dw12_i2c_write8(itf, reg, value);
+    } else {
+        rc = lis2dw12_spi_write8(itf, reg, value);
+    }
+
+    return rc;
+}
+
+/**
+ * Read byte data from sensor over different interfaces
+ *
+ * @param The sensor interface
+ * @param The register address to read from
+ * @param Pointer to where the register value should be written
+ *
+ * @return 0 on success, non-zero on failure
+ */
+int
+lis2dw12_read8(struct sensor_itf *itf, uint8_t reg, uint8_t *value)
+{
+    int rc;
+
+    if (itf->si_type == SENSOR_ITF_I2C) {
+        rc = lis2dw12_i2c_readlen(itf, reg, value, 1);
+    } else {
+        rc = lis2dw12_spi_readlen(itf, reg, value, 1);
+    }
+
+    return rc;
+}
+
+/**
+ * Read multiple bytes starting from specified register over different interfaces
+ *
+ * @param The sensor interface
+ * @param The register address start reading from
+ * @param Pointer to where the register value should be written
+ * @param Number of bytes to read
+ *
+ * @return 0 on success, non-zero on failure
+ */
+int
+lis2dw12_readlen(struct sensor_itf *itf, uint8_t reg, uint8_t *buffer,
+                uint8_t len)
+{
+    int rc;
+
+    if (itf->si_type == SENSOR_ITF_I2C) {
+        rc = lis2dw12_i2c_readlen(itf, reg, buffer, len);
+    } else {
+        rc = lis2dw12_spi_readlen(itf, reg, buffer, len);
+    }
+
+    return rc;
+}
+
+/**
+ * Calculates the acceleration in m/s^2 from mg
+ *
+ * @param acc value in mg
+ * @param float ptr to return calculated value in ms2
+ */
+void
+lis2dw12_calc_acc_ms2(int16_t acc_mg, float *acc_ms2)
+{
+    *acc_ms2 = (acc_mg * STANDARD_ACCEL_GRAVITY)/1000;
+}
+
+/**
+ * Calculates the acceleration in mg from m/s^2
+ *
+ * @param acc value in m/s^2
+ * @param int16 ptr to return calculated value in mg
+ */
+void
+lis2dw12_calc_acc_mg(float acc_ms2, int16_t *acc_mg)
+{
+    *acc_mg = (acc_ms2 * 1000)/STANDARD_ACCEL_GRAVITY;
+}
+
+/**
+ * Reset lis2dw12
+ *
+ * @param The sensor interface
+ * @return 0 on success, non-zero on failure
+ */
+int
+lis2dw12_reset(struct sensor_itf *itf)
+{
+    int rc;
+    uint8_t reg;
+
+    rc = lis2dw12_read8(itf, LIS2DW12_REG_CTRL_REG2, &reg);
+    if (rc) {
+        goto err;
+    }
+
+    reg |= LIS2DW12_CTRL_REG2_SOFT_RESET | LIS2DW12_CTRL_REG2_BOOT;
+
+    rc = lis2dw12_write8(itf, LIS2DW12_REG_CTRL_REG2, reg);
+    if (rc) {
+        goto err;
+    }
+
+    os_time_delay((OS_TICKS_PER_SEC * 6/1000) + 1);
+
+err:
+    return rc;
+}
+
+/**
+ * Get chip ID
+ *
+ * @param sensor interface
+ * @param ptr to chip id to be filled up
+ */
+int
+lis2dw12_get_chip_id(struct sensor_itf *itf, uint8_t *chip_id)
+{
+    uint8_t reg;
+    int rc;
+
+    rc = lis2dw12_read8(itf, LIS2DW12_REG_WHO_AM_I, &reg);
+
+    if (rc) {
+        goto err;
+    }
+
+    *chip_id = reg;
+
+err:
+    return rc;
+}
+
+/**
+ * Sets the full scale selection
+ *
+ * @param The sensor interface
+ * @param The fs setting
+ *
+ * @return 0 on success, non-zero on failure
+ */
+int
+lis2dw12_set_full_scale(struct sensor_itf *itf, uint8_t fs)
+{
+    int rc;
+    uint8_t reg;
+
+    if (fs > LIS2DW12_FS_16G) {
+        LIS2DW12_ERR("Invalid full scale value\n");
+        rc = SYS_EINVAL;
+        goto err;
+    }
+
+    rc = lis2dw12_read8(itf, LIS2DW12_REG_CTRL_REG6, &reg);
+    if (rc) {
+        goto err;
+    }
+
+    reg = (reg & ~LIS2DW12_CTRL_REG6_FS) | fs;
+
+    rc = lis2dw12_write8(itf, LIS2DW12_REG_CTRL_REG6, reg);
+    if (rc) {
+        goto err;
+    }
+
+    return 0;
+err:
+    return rc;
+}
+
+/**
+ * Gets the full scale selection
+ *
+ * @param The sensor interface
+ * @param ptr to fs
+ *
+ * @return 0 on success, non-zero on failure
+ */
+int
+lis2dw12_get_full_scale(struct sensor_itf *itf, uint8_t *fs)
+{
+    int rc;
+    uint8_t reg;
+
+    rc = lis2dw12_read8(itf, LIS2DW12_REG_CTRL_REG6, &reg);
+    if (rc) {
+        goto err;
+    }
+
+    *fs = reg & LIS2DW12_CTRL_REG6_FS;
+
+    return 0;
+err:
+    return rc;
+}
+
+/**
+ * Sets the rate
+ *
+ * @param The sensor interface
+ * @param The rate
+ *
+ * @return 0 on success, non-zero on failure
+ */
+int
+lis2dw12_set_rate(struct sensor_itf *itf, uint8_t rate)
+{
+    int rc;
+    uint8_t reg;
+
+    if (rate > LIS2DW12_DATA_RATE_1600HZ) {
+        LIS2DW12_ERR("Invalid rate value\n");
+        rc = SYS_EINVAL;
+        goto err;
+    }
+
+    rc = lis2dw12_read8(itf, LIS2DW12_REG_CTRL_REG1, &reg);
+    if (rc) {
+        goto err;
+    }
+
+    reg = (reg & ~LIS2DW12_CTRL_REG1_ODR) | rate;
+
+    rc = lis2dw12_write8(itf, LIS2DW12_REG_CTRL_REG1, reg);
+    if (rc) {
+        goto err;
+    }
+
+    return 0;
+err:
+    return rc;
+}
+
+/**
+ * Gets the rate
+ *
+ * @param The sensor ineterface
+ * @param ptr to the rate
+ * @return 0 on success, non-zero on failure
+ */
+int
+lis2dw12_get_rate(struct sensor_itf *itf, uint8_t *rate)
+{
+    int rc;
+    uint8_t reg;
+
+    rc = lis2dw12_read8(itf, LIS2DW12_REG_CTRL_REG1, &reg);
+    if (rc) {
+        goto err;
+    }
+
+    *rate = reg & LIS2DW12_CTRL_REG1_ODR;
+
+    return 0;
+err:
+    return rc;
+}
+
+/**
+ * Sets the low noise enable
+ *
+ * @param The sensor interface
+ * @param low noise enabled
+ *
+ * @return 0 on success, non-zero on failure
+ */
+int
+lis2dw12_set_low_noise(struct sensor_itf *itf, uint8_t en)
+{
+    int rc;
+    uint8_t reg;
+
+    rc = lis2dw12_read8(itf, LIS2DW12_REG_CTRL_REG6, &reg);
+    if (rc) {
+        goto err;
+    }
+
+    if (en) {
+        reg |= LIS2DW12_CTRL_REG6_LOW_NOISE;
+    } else {
+        reg &= ~LIS2DW12_CTRL_REG6_LOW_NOISE;
+    }
+
+    rc = lis2dw12_write8(itf, LIS2DW12_REG_CTRL_REG6, reg);
+    if (rc) {
+        goto err;
+    }
+
+    return 0;
+err:
+    return rc;
+}
+
+/**
+ * Gets whether low noise is enabled
+ *
+ * @param The sensor interface
+ * @param ptr to low noise settings read from sensor
+ *
+ * @return 0 on success, non-zero on failure
+ */
+int
+lis2dw12_get_low_noise(struct sensor_itf *itf, uint8_t *en)
+{
+    int rc;
+    uint8_t reg;
+
+    rc = lis2dw12_read8(itf, LIS2DW12_REG_CTRL_REG6, &reg);
+    if (rc) {
+        goto err;
+    }
+
+    *en = (reg & LIS2DW12_CTRL_REG6_LOW_NOISE) > 0;
+
+    return 0;
+err:
+    return rc;
+}
+
+/**
+ * Sets the power mode of the sensor
+ *
+ * @param The sensor interface
+ * @param power mode
+ *
+ * @return 0 on success, non-zero on failure
+ */
+int
+lis2dw12_set_power_mode(struct sensor_itf *itf, uint8_t mode)
+{
+    int rc;
+    uint8_t reg;
+
+    rc = lis2dw12_read8(itf, LIS2DW12_REG_CTRL_REG1, &reg);
+    if (rc) {
+        goto err;
+    }
+
+    reg &= ~LIS2DW12_CTRL_REG1_MODE;
+    reg &= ~LIS2DW12_CTRL_REG1_LP_MODE;
+    reg |= mode;
+    
+    rc = lis2dw12_write8(itf, LIS2DW12_REG_CTRL_REG1, reg);
+    if (rc) {
+        goto err;
+    }
+
+    return 0;
+err:
+    return rc;
+}
+
+/**
+ * Gets the power mode of the sensor
+ *
+ * @param The sensor interface
+ * @param ptr to power mode setting read from sensor
+ *
+ * @return 0 on success, non-zero on failure
+ */
+int
+lis2dw12_get_power_mode(struct sensor_itf *itf, uint8_t *mode)
+{
+    int rc;
+    uint8_t reg;
+
+    rc = lis2dw12_read8(itf, LIS2DW12_REG_CTRL_REG1, &reg);
+    if (rc) {
+        goto err;
+    }
+
+    *mode = reg & (LIS2DW12_CTRL_REG1_MODE | LIS2DW12_CTRL_REG1_LP_MODE);
+
+    return 0;
+err:
+    return rc;
+}
+
+/**
+ * Sets the self test mode of the sensor
+ *
+ * @param The sensor interface
+ * @param self test mode
+ *
+ * @return 0 on success, non-zero on failure
+ */
+int
+lis2dw12_set_self_test(struct sensor_itf *itf, uint8_t mode)
+{
+    int rc;
+    uint8_t reg;
+
+    rc = lis2dw12_read8(itf, LIS2DW12_REG_CTRL_REG3, &reg);
+    if (rc) {
+        goto err;
+    }
+
+    reg &= ~LIS2DW12_CTRL_REG3_ST_MODE;
+    reg |= (mode & LIS2DW12_CTRL_REG3_ST_MODE);
+    
+    rc = lis2dw12_write8(itf, LIS2DW12_REG_CTRL_REG3, reg);
+    if (rc) {
+        goto err;
+    }
+
+    return 0;
+err:
+    return rc;
+}
+
+/**
+ * Gets the self test mode of the sensor
+ *
+ * @param The sensor interface
+ * @param ptr to self test mode read from sensor
+ *
+ * @return 0 on success, non-zero on failure
+ */
+int
+lis2dw12_get_self_test(struct sensor_itf *itf, uint8_t *mode)
+{
+    int rc;
+    uint8_t reg;
+
+    rc = lis2dw12_read8(itf, LIS2DW12_REG_CTRL_REG3, &reg);
+    if (rc) {
+        goto err;
+    }
+
+    *mode = reg & LIS2DW12_CTRL_REG3_ST_MODE;
+
+    return 0;
+err:
+    return rc;
+}
+
+/**
+ * Set filter config
+ *
+ * @param the sensor interface
+ * @param the filter bandwidth
+ * @param filter type (1 = high pass, 0 = low pass)
+ * @return 0 on success, non-zero on failure
+ */
+int
+lis2dw12_set_filter_cfg(struct sensor_itf *itf, uint8_t bw, uint8_t type)
+{
+    int rc;
+    uint8_t reg;
+
+    rc = lis2dw12_read8(itf, LIS2DW12_REG_CTRL_REG6, &reg);
+    if (rc) {
+        goto err;
+    }
+
+    reg &= ~LIS2DW12_CTRL_REG6_BW_FILT;
+    reg &= ~LIS2DW12_CTRL_REG6_FDS;
+    reg |= (bw & LIS2DW12_CTRL_REG6_BW_FILT);
+    if (type) {
+        reg |= LIS2DW12_CTRL_REG6_FDS;
+    }
+    
+    rc = lis2dw12_write8(itf, LIS2DW12_REG_CTRL_REG6, reg);
+    if (rc) {
+        goto err;
+    }
+
+    return 0;
+err:
+    return rc;
+
+}
+
+/**
+ * Get filter config
+ *
+ * @param the sensor interface
+ * @param ptr to the filter bandwidth
+ * @param ptr to filter type (1 = high pass, 0 = low pass)
+ * @return 0 on success, non-zero on failure
+ */
+int
+lis2dw12_get_filter_cfg(struct sensor_itf *itf, uint8_t *bw, uint8_t *type)
+{
+    int rc;
+    uint8_t reg;
+
+    rc = lis2dw12_read8(itf, LIS2DW12_REG_CTRL_REG6, &reg);
+    if (rc) {
+        goto err;
+    }
+
+    *bw = reg & LIS2DW12_CTRL_REG6_BW_FILT;
+    *type = (reg & LIS2DW12_CTRL_REG6_FDS) > 0;
+
+    return 0;
+err:
+    return rc;
+}
+
+/**
+ * Sets new offsets in sensor
+ *
+ * @param The sensor interface
+ * @param X offset
+ * @param Y offset
+ * @param Z offset
+ *
+ * @return 0 on success, non-zero error on failure.
+ */
+int
+lis2dw12_set_offsets(struct sensor_itf *itf, int8_t offset_x,
+                    int8_t offset_y, int8_t offset_z)
+{
+    int rc;
+  
+    rc = lis2dw12_write8(itf, LIS2DW12_REG_X_OFS, offset_x);
+    if (rc){
+        return rc;
+    }
+
+    rc = lis2dw12_write8(itf, LIS2DW12_REG_Y_OFS, offset_y);
+    if (rc){
+        return rc;
+    }
+
+    return lis2dw12_write8(itf, LIS2DW12_REG_Z_OFS, offset_z);
+}
+
+/**
+ * Gets the offsets currently set
+ *
+ * @param The sensor interface
+ * @param Pointer to location to store X offset
+ * @param Pointer to location to store Y offset
+ * @param Pointer to location to store Z offset
+ *
+ * @return 0 on success, non-zero error on failure.
+ */
+int
+lis2dw12_get_offsets(struct sensor_itf *itf, int8_t *offset_x,
+                    int8_t *offset_y, int8_t *offset_z)
+{
+
+    int rc;
+  
+    rc = lis2dw12_read8(itf, LIS2DW12_REG_X_OFS, (uint8_t *)offset_x);
+    if (rc){
+        return rc;
+    }
+
+    rc = lis2dw12_read8(itf, LIS2DW12_REG_Y_OFS, (uint8_t *)offset_y);
+    if (rc){
+        return rc;
+    }
+
+    return lis2dw12_read8(itf, LIS2DW12_REG_Z_OFS, (uint8_t *)offset_z);
+}
+
+/**
+ * Set tap detection configuration
+ *
+ * @param the sensor interface
+ * @param the tap settings
+ * @return 0 on success, non-zero on failure
+ */
+int lis2dw12_set_tap_cfg(struct sensor_itf *itf, struct lis2dw12_tap_settings cfg)
+{
+    int rc;
+    uint8_t reg;
+
+    reg = cfg.en_4d ? LIS2DW12_TAP_THS_X_4D_EN : 0;
+    reg |= (cfg.ths_6d & 0x3) << 5;
+    reg |= cfg.tap_ths_x & LIS2DW12_TAP_THS_X_THS;
+
+    rc = lis2dw12_write8(itf, LIS2DW12_REG_TAP_THS_X, reg);
+    if (rc) {
+        return rc;
+    }
+
+    reg = 0;
+    reg |= (cfg.tap_priority & 0x7) << 5;
+    reg |= cfg.tap_ths_y & LIS2DW12_TAP_THS_Y_THS;
+
+    rc = lis2dw12_write8(itf, LIS2DW12_REG_TAP_THS_Y, reg);
+    if (rc) {
+        return rc;
+    }
+
+    reg = 0;
+    reg |= cfg.en_x ? LIS2DW12_TAP_THS_Z_X_EN : 0;
+    reg |= cfg.en_y ? LIS2DW12_TAP_THS_Z_Y_EN : 0;
+    reg |= cfg.en_z ? LIS2DW12_TAP_THS_Z_Z_EN : 0;
+    reg |= cfg.tap_ths_z & LIS2DW12_REG_TAP_THS_Z;
+    
+    rc = lis2dw12_write8(itf, LIS2DW12_REG_TAP_THS_Z, reg);
+    if (rc) {
+        return rc;
+    }
+
+    reg = 0;
+    reg |= (cfg.latency & LIS2DW12_INT_DUR_LATENCY) << 4;
+    reg |= (cfg.quiet & LIS2DW12_INT_DUR_QUIET) << 2;
+    reg |= cfg.shock & LIS2DW12_INT_DUR_SHOCK;
+
+    return 0;
+}
+
+/**
+ * Get tap detection config
+ *
+ * @param the sensor interface
+ * @param ptr to the tap settings
+ * @return 0 on success, non-zero on failure
+ */
+int lis2dw12_get_tap_cfg(struct sensor_itf *itf, struct lis2dw12_tap_settings *cfg)
+{
+    int rc;
+    uint8_t reg;
+
+    rc = lis2dw12_read8(itf, LIS2DW12_REG_TAP_THS_X, &reg);
+    if (rc) {
+        return rc;
+    }
+
+    cfg->en_4d = (reg & LIS2DW12_TAP_THS_X_4D_EN) > 0;
+    cfg->ths_6d = (reg & LIS2DW12_TAP_THS_X_6D_THS) >> 5;
+    cfg->tap_ths_x = reg & LIS2DW12_TAP_THS_X_THS;
+
+    rc = lis2dw12_read8(itf, LIS2DW12_REG_TAP_THS_Y, &reg);
+    if (rc) {
+        return rc;
+    }
+
+    cfg->tap_priority = (reg & LIS2DW12_TAP_THS_Y_PRIOR) >> 5;
+    cfg->tap_ths_y = reg & LIS2DW12_TAP_THS_Y_THS;
+
+    rc = lis2dw12_read8(itf, LIS2DW12_REG_TAP_THS_Z, &reg);
+    if (rc) {
+        return rc;
+    }
+
+    cfg->en_x = (reg & LIS2DW12_TAP_THS_Z_X_EN) > 0;
+    cfg->en_y = (reg & LIS2DW12_TAP_THS_Z_Y_EN) > 0;
+    cfg->en_z = (reg & LIS2DW12_TAP_THS_Z_Z_EN) > 0;
+    cfg->tap_ths_z = reg & LIS2DW12_TAP_THS_Z_THS;
+
+    rc = lis2dw12_read8(itf, LIS2DW12_REG_INT_DUR, &reg);
+    if (rc) {
+        return rc;
+    }
+
+    cfg->latency = (reg & LIS2DW12_INT_DUR_LATENCY) >> 4;
+    cfg->quiet = (reg & LIS2DW12_INT_DUR_QUIET) >> 2;
+    cfg->shock = reg & LIS2DW12_INT_DUR_SHOCK;
+    
+    return 0;
+}
+
+/**
+ * Set freefall detection configuration
+ *
+ * @param the sensor interface
+ * @param freefall duration (5 bits LSB = 1/ODR)
+ * @param freefall threshold (3 bits)
+ * @return 0 on success, non-zero on failure
+ */
+int lis2dw12_set_freefall(struct sensor_itf *itf, uint8_t dur, uint8_t ths)
+{
+    uint8_t reg;
+
+    reg = 0;
+    reg |= (dur & 0x1F) << 3;
+    reg |= ths & LIS2DW12_FREEFALL_THS;
+
+    return lis2dw12_write8(itf, LIS2DW12_REG_FREEFALL, reg);
+}
+
+/**
+ * Get freefall detection config
+ *
+ * @param the sensor interface
+ * @param ptr to freefall duration
+ * @param ptr to freefall threshold
+ * @return 0 on success, non-zero on failure
+ */
+int lis2dw12_get_freefall(struct sensor_itf *itf, uint8_t *dur, uint8_t *ths)
+{
+    int rc;
+    uint8_t reg;
+    
+    rc = lis2dw12_read8(itf, LIS2DW12_REG_FREEFALL, &reg);
+    if (rc) {
+        return rc;
+    }
+
+    *dur = (reg & LIS2DW12_FREEFALL_DUR) >> 3;
+    *ths = reg & LIS2DW12_FREEFALL_THS;
+
+    return 0;
+}
+
+
+/**
+ * Set interrupt pin configuration for interrupt 1
+ *
+ * @param the sensor interface
+ * @param config
+ * @return 0 on success, non-zero on failure
+ */
+int
+lis2dw12_set_int1_pin_cfg(struct sensor_itf *itf, uint8_t cfg)
+{
+    return lis2dw12_write8(itf, LIS2DW12_REG_CTRL_REG4, cfg);
+}
+
+/**
+ * Set interrupt pin configuration for interrupt 2
+ *
+ * @param the sensor interface
+ * @param config
+ * @return 0 on success, non-zero on failure
+ */
+int
+lis2dw12_set_int2_pin_cfg(struct sensor_itf *itf, uint8_t cfg)
+{
+    return lis2dw12_write8(itf, LIS2DW12_REG_CTRL_REG5, cfg);
+}
+
+/**
+ * Clear interrupt 1
+ *
+ * @param the sensor interface
+ */
+int
+lis2dw12_clear_int(struct sensor_itf *itf, uint8_t *src)
+{
+    return lis2dw12_read8(itf, LIS2DW12_REG_INT_SRC, src);  
+}
+
+/**
+ * Run Self test on sensor
+ *
+ * @param the sensor interface
+ * @param pointer to return test result in (0 on pass, non-zero on failure)
+ *
+ * @return 0 on sucess, non-zero on failure
+ */
+int lis2dw12_run_self_test(struct sensor_itf *itf, int *result)
+{
+    int rc;
+    int16_t base[3], pos[3];
+    int i;
+    int16_t change;
+    
+    /* ensure self test mode is disabled */
+    rc = lis2dw12_set_self_test(itf, LIS2DW12_ST_MODE_DISABLE);
+    if (rc) {
+        return rc;
+    }
+    
+    os_time_delay(OS_TICKS_PER_SEC / 10);
+    
+    /* take base reading */
+    rc = lis2dw12_get_data(itf, &(base[0]), &(base[1]), &(base[2]));
+    if (rc) {
+        return rc;
+    }
+
+    /* set self test mode to positive self test */
+    rc = lis2dw12_set_self_test(itf, LIS2DW12_ST_MODE_MODE1);
+    if (rc) {
+        return rc;
+    }
+
+    os_time_delay(OS_TICKS_PER_SEC / 10);
+
+    /* take self test reading */
+    rc = lis2dw12_get_data(itf, &(pos[0]), &(pos[1]), &(pos[2]));
+    if (rc) {
+        return rc;
+    }
+
+    /* disable self test mod */
+    rc = lis2dw12_set_self_test(itf, LIS2DW12_ST_MODE_DISABLE);
+    if (rc) {
+        return rc;
+    }
+
+    /* calculate accel data difference */
+    change = 0;
+    for(i = 0; i < 3; i++) {
+        change += pos[i] - base[i];
+    }
+
+    if ((change > 70) && (change < 1500)) {
+        *result = 0;
+    } else {
+        *result = -1;
+    }
+
+    return 0;
+}
+
+
+/**
+ * IRQ handler for interrupts for high/low threshold
+ *
+ * @param arg
+ */
+static void
+lis2dw12_int_irq_handler(void *arg)
+{
+    struct sensor *sensor = arg;
+    sensor_mgr_put_interrupt_evt(sensor);
+}
+
+static int
+init_intpin(struct lis2dw12 * lis2dw12, hal_gpio_irq_handler_t handler,
+            void * arg)
+{
+    struct lis2dw12_private_driver_data *pdd = &lis2dw12->pdd;
+    hal_gpio_irq_trig_t trig;
+    int pin = -1;
+    int rc;
+    int i;
+
+    for (i = 0; i < MYNEWT_VAL(SENSOR_MAX_INTERRUPTS_PINS); i++){
+        pin = lis2dw12->sensor.s_itf.si_ints[i].host_pin;
+        if (pin >= 0) {
+            break;
+        }
+    }
+
+    if (pin < 0) {
+        LIS2DW12_ERR("Interrupt pin not configured\n");
+        return SYS_EINVAL;
+    }
+
+    pdd->int_num = i;
+    if (lis2dw12->sensor.s_itf.si_ints[pdd->int_num].active) {
+        trig = HAL_GPIO_TRIG_RISING;
+    } else {
+        trig = HAL_GPIO_TRIG_FALLING;
+    }
+  
+    rc = hal_gpio_irq_init(pin,
+                           handler,
+                           arg,
+                           trig,
+                           HAL_GPIO_PULL_NONE);
+    if (rc != 0) {
+        LIS2DW12_ERR("Failed to initialise interrupt pin %d\n", pin);
+        return rc;
+    } 
+
+    return 0;
+}
+
+static int
+enable_interrupt(struct sensor * sensor, uint8_t int_cfg)
+{
+    struct lis2dw12 *lis2dw12;
+    struct sensor_itf *itf;
+    uint8_t reg;
+    int rc;
+
+    lis2dw12 = (struct lis2dw12 *)SENSOR_GET_DEVICE(sensor);
+    itf = SENSOR_GET_ITF(sensor);
+ 
+    /* enable int pin */
+    hal_gpio_irq_enable(lis2dw12->sensor.s_itf.si_ints[lis2dw12->pdd.int_num]
+                        .host_pin);
+
+    /* enable interrupt in device */
+    rc = lis2dw12_set_int1_pin_cfg(itf, int_cfg);
+    if (rc) {
+        return rc;
+    }
+
+    return lis2dw12_clear_int(itf, &reg);
+    
+}
+
+static int
+disable_interrupt(struct sensor * sensor, uint8_t int_cfg)
+{
+    struct lis2dw12 *lis2dw12;
+    struct sensor_itf *itf;
+
+    lis2dw12 = (struct lis2dw12 *)SENSOR_GET_DEVICE(sensor);
+    itf = SENSOR_GET_ITF(sensor);
+    
+    /* disable int pin */
+    hal_gpio_irq_disable(lis2dw12->sensor.s_itf.si_ints[lis2dw12->pdd.int_num]
+                         .host_pin);
+    
+    /* update interrupt setup in device */
+    return lis2dw12_set_int1_pin_cfg(itf, int_cfg);
+}
+
+/**
+ * Gets a new data sample from the sensor.
+ *
+ * @param The sensor interface
+ * @param x axis data
+ * @param y axis data
+ * @param z axis data
+ *
+ * @return 0 on success, non-zero on failure
+ */
+int
+lis2dw12_get_data(struct sensor_itf *itf, int16_t *x, int16_t *y, int16_t *z)
+{
+    int rc;
+    uint8_t payload[6] = {0};
+    uint8_t fs;
+
+    *x = *y = *z = 0;
+
+    rc = lis2dw12_readlen(itf, LIS2DW12_REG_OUT_X_L, payload, 6);
+    if (rc) {
+        goto err;
+    }
+
+    *x = payload[0] | (payload[1] << 8);
+    *y = payload[2] | (payload[3] << 8);
+    *z = payload[4] | (payload[5] << 8);
+
+    rc = lis2dw12_get_full_scale(itf, &fs);
+    if (rc) {
+        goto err;
+    }
+
+    if (fs == LIS2DW12_FS_2G) {
+        fs = 2;
+    } else if (fs == LIS2DW12_FS_4G) {
+        fs = 4;
+    } else if (fs == LIS2DW12_FS_8G) {
+        fs = 8;
+    } else if (fs == LIS2DW12_FS_16G) {
+        fs = 16;
+    } else {
+        rc = SYS_EINVAL;
+        goto err;
+    }
+
+    /*
+     * Since full scale is +/-(fs)g,
+     * fs should be multiplied by 2 to account for full scale.
+     * To calculate mg from g we use the 1000 multiple.
+     * Since the full scale is represented by 16 bit value,
+     * we use that as a divisor.
+     */
+    *x = (fs * 2 * 1000 * *x)/UINT16_MAX;
+    *y = (fs * 2 * 1000 * *y)/UINT16_MAX;
+    *z = (fs * 2 * 1000 * *z)/UINT16_MAX;
+
+    return 0;
+err:
+    return rc;
+}
+
+static int
+lis2dw12_sensor_read(struct sensor *sensor, sensor_type_t type,
+        sensor_data_func_t data_func, void *data_arg, uint32_t timeout)
+{
+    struct sensor_accel_data sad;
+    struct sensor_itf *itf;
+    int16_t x, y ,z;
+    float fx, fy ,fz;
+    int rc;
+
+    /* If the read isn't looking for accel or mag data, don't do anything. */
+    if (!(type & SENSOR_TYPE_ACCELEROMETER)) {
+        rc = SYS_EINVAL;
+        goto err;
+    }
+
+    itf = SENSOR_GET_ITF(sensor);
+
+    x = y = z = 0;
+
+    if (itf->si_type == SENSOR_ITF_SPI) {
+
+        rc = hal_spi_disable(sensor->s_itf.si_num);
+        if (rc) {
+            goto err;
+        }
+
+        rc = hal_spi_config(sensor->s_itf.si_num, &spi_lis2dw12_settings);
+        if (rc == EINVAL) {
+            /* If spi is already enabled, for nrf52, it returns -1, We should not
+             * fail if the spi is already enabled
+             */
+            goto err;
+        }
+
+        rc = hal_spi_enable(sensor->s_itf.si_num);
+        if (rc) {
+            goto err;
+        }
+    }
+
+    rc = lis2dw12_get_data(itf, &x, &y, &z);
+    if (rc) {
+        goto err;
+    }
+
+    /* converting values from mg to ms^2 */
+    lis2dw12_calc_acc_ms2(x, &fx);
+    lis2dw12_calc_acc_ms2(y, &fy);
+    lis2dw12_calc_acc_ms2(z, &fz);
+
+    sad.sad_x = fx;
+    sad.sad_y = fy;
+    sad.sad_z = fz;
+
+    sad.sad_x_is_valid = 1;
+    sad.sad_y_is_valid = 1;
+    sad.sad_z_is_valid = 1;
+
+    /* Call data function */
+    rc = data_func(sensor, data_arg, &sad, SENSOR_TYPE_ACCELEROMETER);
+    if (rc != 0) {
+        goto err;
+    }
+
+    return 0;
+err:
+    return rc;
+}
+
+static int
+lis2dw12_sensor_set_notification(struct sensor *sensor, sensor_event_type_t type)
+{
+    struct lis2dw12 * lis2dw12;
+    uint8_t int_cfg = 0;
+    struct lis2dw12_private_driver_data *pdd;
+    int rc;
+
+    if ((type & ~(SENSOR_EVENT_TYPE_DOUBLE_TAP |
+                  SENSOR_EVENT_TYPE_SINGLE_TAP)) != 0) {
+        return SYS_EINVAL;
+    }
+
+    /*XXX for now we do not support registering for both events */
+    if (type == (SENSOR_EVENT_TYPE_DOUBLE_TAP |
+                 SENSOR_EVENT_TYPE_SINGLE_TAP)) {
+        return SYS_EINVAL;
+    }
+
+    lis2dw12 = (struct lis2dw12 *)SENSOR_GET_DEVICE(sensor);
+    pdd = &lis2dw12->pdd;
+
+    if (pdd->registered_mask & LIS2DW12_NOTIFY_MASK) {
+        return SYS_EBUSY;
+    }
+
+    /* Enable tap interrupt */
+    if(type == SENSOR_EVENT_TYPE_DOUBLE_TAP) {
+        int_cfg |= LIS2DW12_INT1_CFG_DOUBLE_TAP;
+    }
+    if(type == SENSOR_EVENT_TYPE_SINGLE_TAP) {
+        int_cfg |= LIS2DW12_INT1_CFG_SINGLE_TAP;
+    }
+
+    rc = enable_interrupt(sensor, int_cfg);
+    if (rc) {
+        return rc;
+    }
+
+    pdd->notify_ctx.snec_evtype |= type;
+    pdd->registered_mask |= LIS2DW12_NOTIFY_MASK;
+
+    return 0;
+}
+
+static int
+lis2dw12_sensor_unset_notification(struct sensor *sensor, sensor_event_type_t type)
+{
+    struct lis2dw12 * lis2dw12;
+    
+    if ((type & ~(SENSOR_EVENT_TYPE_DOUBLE_TAP |
+                  SENSOR_EVENT_TYPE_SINGLE_TAP)) != 0) {
+        return SYS_EINVAL;
+    }
+    
+    /*XXX for now we do not support registering for both events */
+    if (type == (SENSOR_EVENT_TYPE_DOUBLE_TAP |
+                 SENSOR_EVENT_TYPE_SINGLE_TAP)) {
+        return SYS_EINVAL;
+    }
+    
+    lis2dw12 = (struct lis2dw12 *)SENSOR_GET_DEVICE(sensor);
+    
+    lis2dw12->pdd.notify_ctx.snec_evtype &= ~type;
+    lis2dw12->pdd.registered_mask &= ~LIS2DW12_NOTIFY_MASK;
+    
+    return disable_interrupt(sensor, 0);
+}
+
+static int
+lis2dw12_sensor_handle_interrupt(struct sensor * sensor)
+{
+    struct lis2dw12 * lis2dw12;
+    struct lis2dw12_private_driver_data *pdd;
+    struct sensor_itf *itf;
+    uint8_t int_src;
+    
+    int rc;
+
+    lis2dw12 = (struct lis2dw12 *)SENSOR_GET_DEVICE(sensor);
+    itf = SENSOR_GET_ITF(sensor);
+
+    pdd = &lis2dw12->pdd;
+
+    rc = lis2dw12_clear_int(itf, &int_src);
+    if (rc) {
+        LIS2DW12_ERR("Cound not read int status err=0x%02x\n", rc);
+        return rc;
+    }
+
+    if ((pdd->registered_mask & LIS2DW12_NOTIFY_MASK) &&
+        ((int_src & LIS2DW12_INT_SRC_STAP) ||
+         (int_src & LIS2DW12_INT_SRC_DTAP))) {
+        sensor_mgr_put_notify_evt(&pdd->notify_ctx);
+    }
+
+    return 0;
+}
+
+static int
+lis2dw12_sensor_get_config(struct sensor *sensor, sensor_type_t type,
+        struct sensor_cfg *cfg)
+{
+    int rc;
+
+    if (type != SENSOR_TYPE_ACCELEROMETER) {
+        rc = SYS_EINVAL;
+        goto err;
+    }
+
+    cfg->sc_valtype = SENSOR_VALUE_TYPE_FLOAT_TRIPLET;
+
+    return 0;
+err:
+    return rc;
+}
+
+/**
+ * Expects to be called back through os_dev_create().
+ *
+ * @param The device object associated with this accelerometer
+ * @param Argument passed to OS device init, unused
+ *
+ * @return 0 on success, non-zero error on failure.
+ */
+int
+lis2dw12_init(struct os_dev *dev, void *arg)
+{
+    struct lis2dw12 *lis2dw12;
+    struct sensor *sensor;
+    int rc;
+
+    if (!arg || !dev) {
+        rc = SYS_ENODEV;
+        goto err;
+    }
+
+    lis2dw12 = (struct lis2dw12 *) dev;
+
+    lis2dw12->cfg.mask = SENSOR_TYPE_ALL;
+
+    log_register(dev->od_name, &_log, &log_console_handler, NULL, LOG_SYSLEVEL);
+
+    sensor = &lis2dw12->sensor;
+
+    /* Initialise the stats entry */
+    rc = stats_init(
+        STATS_HDR(g_lis2dw12stats),
+        STATS_SIZE_INIT_PARMS(g_lis2dw12stats, STATS_SIZE_32),
+        STATS_NAME_INIT_PARMS(lis2dw12_stat_section));
+    SYSINIT_PANIC_ASSERT(rc == 0);
+    /* Register the entry with the stats registry */
+    rc = stats_register(dev->od_name, STATS_HDR(g_lis2dw12stats));
+    SYSINIT_PANIC_ASSERT(rc == 0);
+
+    rc = sensor_init(sensor, dev);
+    if (rc) {
+        goto err;
+    }
+
+    /* Add the light driver */
+    rc = sensor_set_driver(sensor, SENSOR_TYPE_ACCELEROMETER,
+            (struct sensor_driver *) &g_lis2dw12_sensor_driver);
+    if (rc) {
+        goto err;
+    }
+
+    /* Set the interface */
+    rc = sensor_set_interface(sensor, arg);
+    if (rc) {
+        goto err;
+    }
+
+    rc = sensor_mgr_register(sensor);
+    if (rc) {
+        goto err;
+    }
+
+    if (sensor->s_itf.si_type == SENSOR_ITF_SPI) {
+
+        rc = hal_spi_disable(sensor->s_itf.si_num);
+        if (rc) {
+            goto err;
+        }
+
+        rc = hal_spi_config(sensor->s_itf.si_num, &spi_lis2dw12_settings);
+        if (rc == EINVAL) {
+            /* If spi is already enabled, for nrf52, it returns -1, We should not
+             * fail if the spi is already enabled
+             */
+            goto err;
+        }
+
+        rc = hal_spi_enable(sensor->s_itf.si_num);
+        if (rc) {
+            goto err;
+        }
+
+        rc = hal_gpio_init_out(sensor->s_itf.si_cs_pin, 1);
+        if (rc) {
+            goto err;
+        }
+    }
+
+    lis2dw12->pdd.notify_ctx.snec_sensor = sensor;
+    lis2dw12->pdd.registered_mask = 0;
+
+    rc = init_intpin(lis2dw12, lis2dw12_int_irq_handler, sensor);
+    if (rc) {
+        return rc;
+    }
+
+    return 0;
+err:
+    return rc;
+
+}
+
+/**
+ * Configure the sensor
+ *
+ * @param ptr to sensor driver
+ * @param ptr to sensor driver config
+ */
+int
+lis2dw12_config(struct lis2dw12 *lis2dw12, struct lis2dw12_cfg *cfg)
+{
+    int rc;
+    struct sensor_itf *itf;
+    uint8_t chip_id;
+    struct sensor *sensor;
+
+    itf = SENSOR_GET_ITF(&(lis2dw12->sensor));
+    sensor = &(lis2dw12->sensor);
+
+    if (itf->si_type == SENSOR_ITF_SPI) {
+
+        rc = hal_spi_disable(sensor->s_itf.si_num);
+        if (rc) {
+            goto err;
+        }
+
+        rc = hal_spi_config(sensor->s_itf.si_num, &spi_lis2dw12_settings);
+        if (rc == EINVAL) {
+            /* If spi is already enabled, for nrf52, it returns -1, We should not
+             * fail if the spi is already enabled
+             */
+            goto err;
+        }
+
+        rc = hal_spi_enable(sensor->s_itf.si_num);
+        if (rc) {
+            goto err;
+        }
+    }
+
+    rc = lis2dw12_get_chip_id(itf, &chip_id);
+    if (rc) {
+        goto err;
+    }
+
+    if (chip_id != LIS2DW12_ID) {
+        rc = SYS_EINVAL;
+        goto err;
+    }
+
+    rc = lis2dw12_reset(itf);
+    if (rc) {
+        goto err;
+    }
+
+    rc = lis2dw12_write8(itf, LIS2DW12_REG_CTRL_REG2, 0x40);
+    if (rc) {
+        goto err;
+    }
+
+    rc = lis2dw12_write8(itf, LIS2DW12_REG_CTRL_REG3, 0x10);
+    if (rc) {
+        goto err;
+    }
+
+    
+    rc = lis2dw12_set_offsets(itf, cfg->offset_x, cfg->offset_y, cfg->offset_z);
+    if (rc) {
+        goto err;
+    }
+    
+    rc = lis2dw12_set_filter_cfg(itf, LIS2DW12_FILTER_BW_ODR_DIV_2, 0);
+    if (rc) {
+        goto err;
+    }
+
+    rc = lis2dw12_set_full_scale(itf, cfg->fs);
+    if (rc) {
+        goto err;
+    }
+
+    lis2dw12->cfg.fs = cfg->fs;
+
+    rc = lis2dw12_set_rate(itf, cfg->rate);
+    if (rc) {
+        goto err;
+    }
+
+    lis2dw12->cfg.rate = cfg->rate;
+
+    rc = lis2dw12_set_self_test(itf, LIS2DW12_ST_MODE_DISABLE);
+    if (rc) {
+        goto err;
+    }
+
+    rc = lis2dw12_set_power_mode(itf, LIS2DW12_PM_HIGH_PERF);
+    if (rc) {
+        goto err;
+    }
+
+    rc = lis2dw12_set_low_noise(itf, 1);
+    if (rc) {
+        goto err;
+    }
+
+    rc = lis2dw12_write8(itf, LIS2DW12_REG_CTRL_REG7, 0x30);
+    if (rc) {
+        goto err;
+    }
+
+    rc = lis2dw12_set_int1_pin_cfg(itf, 0);
+    if (rc) {
+        goto err;
+    }
+
+    rc = lis2dw12_set_int2_pin_cfg(itf, 0);
 
 Review comment:
   I think the configuration for the interrupts should come from the lis2dw12_cfg which is not the case. I agree that none of it should be enabled at init time but everytime a change to the config is made, you want to be able to change interrupt config settings, which should not be 0 here.

----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on GitHub and use the
URL above to go to the specific comment.
 
For queries about this service, please contact Infrastructure at:
users@infra.apache.org


With regards,
Apache Git Services