drivers/sensor: lsm6dso: Add support for lsm6dso32

This sensor is virtually identical to the lsm6dso.  The only difference
is the accelerometer ranges are double those of the lsm6dso.

Use the same driver.  The difference is detected by using "st,lsm6dso32"
as the first compatible entry, followed by "st,lsm6dso".

An bit flag in the existing accel_range config field is used to check if
the chip is the doubled range or not.

Signed-off-by: Trent Piepho <trent.piepho@igorinstitute.com>
This commit is contained in:
Trent Piepho 2022-05-03 22:05:20 -07:00 committed by Marti Bolivar
commit 094345629b
5 changed files with 42 additions and 9 deletions

View file

@ -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), \

View file

@ -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;

View file

@ -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)

View file

@ -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"]

View file

@ -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"]