diff --git a/drivers/sensor/lsm6dso/lsm6dso.c b/drivers/sensor/lsm6dso/lsm6dso.c index ba19e7b6679..693220d8c11 100644 --- a/drivers/sensor/lsm6dso/lsm6dso.c +++ b/drivers/sensor/lsm6dso/lsm6dso.c @@ -51,14 +51,13 @@ static int lsm6dso_odr_to_freq_val(uint16_t odr) } static const uint16_t lsm6dso_accel_fs_map[] = {2, 16, 4, 8}; -static const uint16_t lsm6dso_accel_fs_sens[] = {1, 8, 2, 4}; -static int lsm6dso_accel_range_to_fs_val(int32_t range) +static int lsm6dso_accel_range_to_fs_val(int32_t range, bool double_range) { size_t i; for (i = 0; i < ARRAY_SIZE(lsm6dso_accel_fs_map); i++) { - if (range == lsm6dso_accel_fs_map[i]) { + if (range == (lsm6dso_accel_fs_map[i] << double_range)) { return i; } } @@ -66,6 +65,14 @@ static int lsm6dso_accel_range_to_fs_val(int32_t range) return -EINVAL; } +static int lsm6dso_accel_fs_val_to_gain(int fs, bool double_range) +{ + /* Range of ±2G has a LSB of GAIN_UNIT_XL, thus divide by 2 */ + return double_range ? + lsm6dso_accel_fs_map[fs] * GAIN_UNIT_XL : + lsm6dso_accel_fs_map[fs] * GAIN_UNIT_XL / 2; +} + static const uint16_t lsm6dso_gyro_fs_map[] = {250, 125, 500, 0, 1000, 0, 2000}; static const uint16_t lsm6dso_gyro_fs_sens[] = {2, 1, 4, 0, 8, 0, 16}; @@ -172,8 +179,10 @@ static int lsm6dso_accel_range_set(const struct device *dev, int32_t range) { int fs; struct lsm6dso_data *data = dev->data; + const struct lsm6dso_config *cfg = dev->config; + bool range_double = !!(cfg->accel_range & ACCEL_RANGE_DOUBLE); - fs = lsm6dso_accel_range_to_fs_val(range); + fs = lsm6dso_accel_range_to_fs_val(range, range_double); if (fs < 0) { return fs; } @@ -183,7 +192,7 @@ static int lsm6dso_accel_range_set(const struct device *dev, int32_t range) return -EIO; } - data->acc_gain = (lsm6dso_accel_fs_sens[fs] * GAIN_UNIT_XL); + data->acc_gain = lsm6dso_accel_fs_val_to_gain(fs, range_double); return 0; } @@ -746,13 +755,13 @@ static int lsm6dso_init_chip(const struct device *dev) break; } - fs = cfg->accel_range; + fs = cfg->accel_range & ACCEL_RANGE_MASK; LOG_DBG("accel range is %d", fs); if (lsm6dso_accel_set_fs_raw(dev, fs) < 0) { LOG_ERR("failed to set accelerometer range %d", fs); return -EIO; } - lsm6dso->acc_gain = lsm6dso_accel_fs_sens[fs] * GAIN_UNIT_XL; + lsm6dso->acc_gain = lsm6dso_accel_fs_val_to_gain(fs, cfg->accel_range & ACCEL_RANGE_DOUBLE); odr = cfg->accel_odr; LOG_DBG("accel odr is %d", odr); @@ -879,7 +888,9 @@ static int lsm6dso_init(const struct device *dev) #define LSM6DSO_CONFIG_COMMON(inst) \ .accel_pm = DT_INST_PROP(inst, accel_pm), \ .accel_odr = DT_INST_PROP(inst, accel_odr), \ - .accel_range = DT_INST_PROP(inst, accel_range), \ + .accel_range = DT_INST_PROP(inst, accel_range) | \ + (DT_NODE_HAS_COMPAT(DT_DRV_INST(inst), st_lsm6dso32) ? \ + ACCEL_RANGE_DOUBLE : 0), \ .gyro_pm = DT_INST_PROP(inst, gyro_pm), \ .gyro_odr = DT_INST_PROP(inst, gyro_odr), \ .gyro_range = DT_INST_PROP(inst, gyro_range), \ diff --git a/drivers/sensor/lsm6dso/lsm6dso.h b/drivers/sensor/lsm6dso/lsm6dso.h index 336ebcdd475..8c1c1fac1f6 100644 --- a/drivers/sensor/lsm6dso/lsm6dso.h +++ b/drivers/sensor/lsm6dso/lsm6dso.h @@ -52,6 +52,8 @@ struct lsm6dso_config { } stmemsc_cfg; uint8_t accel_pm; uint8_t accel_odr; +#define ACCEL_RANGE_DOUBLE BIT(7) +#define ACCEL_RANGE_MASK BIT_MASK(6) uint8_t accel_range; uint8_t gyro_pm; uint8_t gyro_odr; diff --git a/dts/bindings/sensor/st,lsm6dso-common.yaml b/dts/bindings/sensor/st,lsm6dso-common.yaml index 29216e1d153..7f7606cefa9 100644 --- a/dts/bindings/sensor/st,lsm6dso-common.yaml +++ b/dts/bindings/sensor/st,lsm6dso-common.yaml @@ -46,7 +46,7 @@ properties: description: | Range in g. Default is power-up configuration. enum: - - 0 # 2g (0.061 mg/LSB) + - 0 # 2g (0.061 mg/LSB) (LSM6DSO32 will be double these values) - 1 # 16g (0.488 mg/LSB) - 2 # 4g (0.122 mg/LSB) - 3 # 8g (0.244 mg/LSB) diff --git a/dts/bindings/sensor/st,lsm6dso32-i2c.yaml b/dts/bindings/sensor/st,lsm6dso32-i2c.yaml new file mode 100644 index 00000000000..76b952aaa31 --- /dev/null +++ b/dts/bindings/sensor/st,lsm6dso32-i2c.yaml @@ -0,0 +1,10 @@ +# Copyright (c) 2019 STMicroelectronics +# SPDX-License-Identifier: Apache-2.0 + +description: | + STMicroelectronics LSM6DSO32 6-axis IMU (Inertial Measurement Unit) sensor + accessed through I2C bus + +compatible: "st,lsm6dso32" + +include: ["i2c-device.yaml", "st,lsm6dso-common.yaml"] diff --git a/dts/bindings/sensor/st,lsm6dso32-spi.yaml b/dts/bindings/sensor/st,lsm6dso32-spi.yaml new file mode 100644 index 00000000000..715ca7052e9 --- /dev/null +++ b/dts/bindings/sensor/st,lsm6dso32-spi.yaml @@ -0,0 +1,10 @@ +# Copyright (c) 2019 STMicroelectronics +# SPDX-License-Identifier: Apache-2.0 + +description: | + STMicroelectronics LSM6DSO32 6-axis IMU (Inertial Measurement Unit) sensor + accessed through SPI bus + +compatible: "st,lsm6dso32" + +include: ["spi-device.yaml", "st,lsm6dso-common.yaml"]