Skip to content

Commit 0943456

Browse files
trentp-igormbolivar-nordic
authored andcommitted
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 <[email protected]>
1 parent 5edd422 commit 0943456

File tree

5 files changed

+42
-9
lines changed

5 files changed

+42
-9
lines changed

drivers/sensor/lsm6dso/lsm6dso.c

Lines changed: 19 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -51,21 +51,28 @@ static int lsm6dso_odr_to_freq_val(uint16_t odr)
5151
}
5252

5353
static const uint16_t lsm6dso_accel_fs_map[] = {2, 16, 4, 8};
54-
static const uint16_t lsm6dso_accel_fs_sens[] = {1, 8, 2, 4};
5554

56-
static int lsm6dso_accel_range_to_fs_val(int32_t range)
55+
static int lsm6dso_accel_range_to_fs_val(int32_t range, bool double_range)
5756
{
5857
size_t i;
5958

6059
for (i = 0; i < ARRAY_SIZE(lsm6dso_accel_fs_map); i++) {
61-
if (range == lsm6dso_accel_fs_map[i]) {
60+
if (range == (lsm6dso_accel_fs_map[i] << double_range)) {
6261
return i;
6362
}
6463
}
6564

6665
return -EINVAL;
6766
}
6867

68+
static int lsm6dso_accel_fs_val_to_gain(int fs, bool double_range)
69+
{
70+
/* Range of ±2G has a LSB of GAIN_UNIT_XL, thus divide by 2 */
71+
return double_range ?
72+
lsm6dso_accel_fs_map[fs] * GAIN_UNIT_XL :
73+
lsm6dso_accel_fs_map[fs] * GAIN_UNIT_XL / 2;
74+
}
75+
6976
static const uint16_t lsm6dso_gyro_fs_map[] = {250, 125, 500, 0, 1000, 0, 2000};
7077
static const uint16_t lsm6dso_gyro_fs_sens[] = {2, 1, 4, 0, 8, 0, 16};
7178

@@ -172,8 +179,10 @@ static int lsm6dso_accel_range_set(const struct device *dev, int32_t range)
172179
{
173180
int fs;
174181
struct lsm6dso_data *data = dev->data;
182+
const struct lsm6dso_config *cfg = dev->config;
183+
bool range_double = !!(cfg->accel_range & ACCEL_RANGE_DOUBLE);
175184

176-
fs = lsm6dso_accel_range_to_fs_val(range);
185+
fs = lsm6dso_accel_range_to_fs_val(range, range_double);
177186
if (fs < 0) {
178187
return fs;
179188
}
@@ -183,7 +192,7 @@ static int lsm6dso_accel_range_set(const struct device *dev, int32_t range)
183192
return -EIO;
184193
}
185194

186-
data->acc_gain = (lsm6dso_accel_fs_sens[fs] * GAIN_UNIT_XL);
195+
data->acc_gain = lsm6dso_accel_fs_val_to_gain(fs, range_double);
187196
return 0;
188197
}
189198

@@ -746,13 +755,13 @@ static int lsm6dso_init_chip(const struct device *dev)
746755
break;
747756
}
748757

749-
fs = cfg->accel_range;
758+
fs = cfg->accel_range & ACCEL_RANGE_MASK;
750759
LOG_DBG("accel range is %d", fs);
751760
if (lsm6dso_accel_set_fs_raw(dev, fs) < 0) {
752761
LOG_ERR("failed to set accelerometer range %d", fs);
753762
return -EIO;
754763
}
755-
lsm6dso->acc_gain = lsm6dso_accel_fs_sens[fs] * GAIN_UNIT_XL;
764+
lsm6dso->acc_gain = lsm6dso_accel_fs_val_to_gain(fs, cfg->accel_range & ACCEL_RANGE_DOUBLE);
756765

757766
odr = cfg->accel_odr;
758767
LOG_DBG("accel odr is %d", odr);
@@ -879,7 +888,9 @@ static int lsm6dso_init(const struct device *dev)
879888
#define LSM6DSO_CONFIG_COMMON(inst) \
880889
.accel_pm = DT_INST_PROP(inst, accel_pm), \
881890
.accel_odr = DT_INST_PROP(inst, accel_odr), \
882-
.accel_range = DT_INST_PROP(inst, accel_range), \
891+
.accel_range = DT_INST_PROP(inst, accel_range) | \
892+
(DT_NODE_HAS_COMPAT(DT_DRV_INST(inst), st_lsm6dso32) ? \
893+
ACCEL_RANGE_DOUBLE : 0), \
883894
.gyro_pm = DT_INST_PROP(inst, gyro_pm), \
884895
.gyro_odr = DT_INST_PROP(inst, gyro_odr), \
885896
.gyro_range = DT_INST_PROP(inst, gyro_range), \

drivers/sensor/lsm6dso/lsm6dso.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,8 @@ struct lsm6dso_config {
5252
} stmemsc_cfg;
5353
uint8_t accel_pm;
5454
uint8_t accel_odr;
55+
#define ACCEL_RANGE_DOUBLE BIT(7)
56+
#define ACCEL_RANGE_MASK BIT_MASK(6)
5557
uint8_t accel_range;
5658
uint8_t gyro_pm;
5759
uint8_t gyro_odr;

dts/bindings/sensor/st,lsm6dso-common.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ properties:
4646
description: |
4747
Range in g. Default is power-up configuration.
4848
enum:
49-
- 0 # 2g (0.061 mg/LSB)
49+
- 0 # 2g (0.061 mg/LSB) (LSM6DSO32 will be double these values)
5050
- 1 # 16g (0.488 mg/LSB)
5151
- 2 # 4g (0.122 mg/LSB)
5252
- 3 # 8g (0.244 mg/LSB)
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
# Copyright (c) 2019 STMicroelectronics
2+
# SPDX-License-Identifier: Apache-2.0
3+
4+
description: |
5+
STMicroelectronics LSM6DSO32 6-axis IMU (Inertial Measurement Unit) sensor
6+
accessed through I2C bus
7+
8+
compatible: "st,lsm6dso32"
9+
10+
include: ["i2c-device.yaml", "st,lsm6dso-common.yaml"]
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
# Copyright (c) 2019 STMicroelectronics
2+
# SPDX-License-Identifier: Apache-2.0
3+
4+
description: |
5+
STMicroelectronics LSM6DSO32 6-axis IMU (Inertial Measurement Unit) sensor
6+
accessed through SPI bus
7+
8+
compatible: "st,lsm6dso32"
9+
10+
include: ["spi-device.yaml", "st,lsm6dso-common.yaml"]

0 commit comments

Comments
 (0)