aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c')
-rw-r--r--drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c622
1 files changed, 511 insertions, 111 deletions
diff --git a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c
index a6702a74570e..2d3495560136 100644
--- a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c
+++ b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c
@@ -10,6 +10,8 @@
* +-125/+-245/+-500/+-1000/+-2000 dps
* LSM6DSx series has an integrated First-In-First-Out (FIFO) buffer
* allowing dynamic batching of sensor data.
+ * LSM9DSx series is similar but includes an additional magnetometer, handled
+ * by a different driver.
*
* Supported sensors:
* - LSM6DS3:
@@ -18,18 +20,25 @@
* - Gyroscope supported full-scale [dps]: +-125/+-245/+-500/+-1000/+-2000
* - FIFO size: 8KB
*
- * - LSM6DS3H/LSM6DSL/LSM6DSM/ISM330DLC:
+ * - LSM6DS3H/LSM6DSL/LSM6DSM/ISM330DLC/LSM6DS3TR-C:
* - Accelerometer/Gyroscope supported ODR [Hz]: 13, 26, 52, 104, 208, 416
* - Accelerometer supported full-scale [g]: +-2/+-4/+-8/+-16
* - Gyroscope supported full-scale [dps]: +-125/+-245/+-500/+-1000/+-2000
* - FIFO size: 4KB
*
- * - LSM6DSO/LSM6DSOX/ASM330LHH/LSM6DSR
+ * - LSM6DSO/LSM6DSOX/ASM330LHH/LSM6DSR/ISM330DHCX:
* - Accelerometer/Gyroscope supported ODR [Hz]: 13, 26, 52, 104, 208, 416
* - Accelerometer supported full-scale [g]: +-2/+-4/+-8/+-16
* - Gyroscope supported full-scale [dps]: +-125/+-245/+-500/+-1000/+-2000
* - FIFO size: 3KB
*
+ * - LSM9DS1:
+ * - Accelerometer supported ODR [Hz]: 10, 50, 119, 238, 476, 952
+ * - Accelerometer supported full-scale [g]: +-2/+-4/+-8/+-16
+ * - Gyroscope supported ODR [Hz]: 15, 60, 119, 238, 476, 952
+ * - Gyroscope supported full-scale [dps]: +-245/+-500/+-2000
+ * - FIFO size: 32
+ *
* Copyright 2016 STMicroelectronics Inc.
*
* Lorenzo Bianconi <lorenzo.bianconi@st.com>
@@ -49,79 +58,110 @@
#include "st_lsm6dsx.h"
-#define ST_LSM6DSX_REG_INT1_ADDR 0x0d
-#define ST_LSM6DSX_REG_INT2_ADDR 0x0e
#define ST_LSM6DSX_REG_FIFO_FTH_IRQ_MASK BIT(3)
#define ST_LSM6DSX_REG_WHOAMI_ADDR 0x0f
-#define ST_LSM6DSX_REG_RESET_ADDR 0x12
#define ST_LSM6DSX_REG_RESET_MASK BIT(0)
#define ST_LSM6DSX_REG_BOOT_MASK BIT(7)
#define ST_LSM6DSX_REG_BDU_ADDR 0x12
#define ST_LSM6DSX_REG_BDU_MASK BIT(6)
-#define ST_LSM6DSX_REG_INT2_ON_INT1_ADDR 0x13
-#define ST_LSM6DSX_REG_INT2_ON_INT1_MASK BIT(5)
-
-#define ST_LSM6DSX_REG_ACC_OUT_X_L_ADDR 0x28
-#define ST_LSM6DSX_REG_ACC_OUT_Y_L_ADDR 0x2a
-#define ST_LSM6DSX_REG_ACC_OUT_Z_L_ADDR 0x2c
-
-#define ST_LSM6DSX_REG_GYRO_OUT_X_L_ADDR 0x22
-#define ST_LSM6DSX_REG_GYRO_OUT_Y_L_ADDR 0x24
-#define ST_LSM6DSX_REG_GYRO_OUT_Z_L_ADDR 0x26
-
-static const struct st_lsm6dsx_odr_table_entry st_lsm6dsx_odr_table[] = {
- [ST_LSM6DSX_ID_ACC] = {
- .reg = {
- .addr = 0x10,
- .mask = GENMASK(7, 4),
- },
- .odr_avl[0] = { 13, 0x01 },
- .odr_avl[1] = { 26, 0x02 },
- .odr_avl[2] = { 52, 0x03 },
- .odr_avl[3] = { 104, 0x04 },
- .odr_avl[4] = { 208, 0x05 },
- .odr_avl[5] = { 416, 0x06 },
- },
- [ST_LSM6DSX_ID_GYRO] = {
- .reg = {
- .addr = 0x11,
- .mask = GENMASK(7, 4),
- },
- .odr_avl[0] = { 13, 0x01 },
- .odr_avl[1] = { 26, 0x02 },
- .odr_avl[2] = { 52, 0x03 },
- .odr_avl[3] = { 104, 0x04 },
- .odr_avl[4] = { 208, 0x05 },
- .odr_avl[5] = { 416, 0x06 },
- }
+
+static const struct iio_chan_spec st_lsm6dsx_acc_channels[] = {
+ ST_LSM6DSX_CHANNEL(IIO_ACCEL, 0x28, IIO_MOD_X, 0),
+ ST_LSM6DSX_CHANNEL(IIO_ACCEL, 0x2a, IIO_MOD_Y, 1),
+ ST_LSM6DSX_CHANNEL(IIO_ACCEL, 0x2c, IIO_MOD_Z, 2),
+ IIO_CHAN_SOFT_TIMESTAMP(3),
};
-static const struct st_lsm6dsx_fs_table_entry st_lsm6dsx_fs_table[] = {
- [ST_LSM6DSX_ID_ACC] = {
- .reg = {
- .addr = 0x10,
- .mask = GENMASK(3, 2),
- },
- .fs_avl[0] = { IIO_G_TO_M_S_2(61), 0x0 },
- .fs_avl[1] = { IIO_G_TO_M_S_2(122), 0x2 },
- .fs_avl[2] = { IIO_G_TO_M_S_2(244), 0x3 },
- .fs_avl[3] = { IIO_G_TO_M_S_2(488), 0x1 },
- },
- [ST_LSM6DSX_ID_GYRO] = {
- .reg = {
- .addr = 0x11,
- .mask = GENMASK(3, 2),
- },
- .fs_avl[0] = { IIO_DEGREE_TO_RAD(8750), 0x0 },
- .fs_avl[1] = { IIO_DEGREE_TO_RAD(17500), 0x1 },
- .fs_avl[2] = { IIO_DEGREE_TO_RAD(35000), 0x2 },
- .fs_avl[3] = { IIO_DEGREE_TO_RAD(70000), 0x3 },
- }
+static const struct iio_chan_spec st_lsm6dsx_gyro_channels[] = {
+ ST_LSM6DSX_CHANNEL(IIO_ANGL_VEL, 0x22, IIO_MOD_X, 0),
+ ST_LSM6DSX_CHANNEL(IIO_ANGL_VEL, 0x24, IIO_MOD_Y, 1),
+ ST_LSM6DSX_CHANNEL(IIO_ANGL_VEL, 0x26, IIO_MOD_Z, 2),
+ IIO_CHAN_SOFT_TIMESTAMP(3),
+};
+
+static const struct iio_chan_spec st_lsm6ds0_gyro_channels[] = {
+ ST_LSM6DSX_CHANNEL(IIO_ANGL_VEL, 0x18, IIO_MOD_X, 0),
+ ST_LSM6DSX_CHANNEL(IIO_ANGL_VEL, 0x1a, IIO_MOD_Y, 1),
+ ST_LSM6DSX_CHANNEL(IIO_ANGL_VEL, 0x1c, IIO_MOD_Z, 2),
+ IIO_CHAN_SOFT_TIMESTAMP(3),
};
static const struct st_lsm6dsx_settings st_lsm6dsx_sensor_settings[] = {
{
+ .wai = 0x68,
+ .int1_addr = 0x0c,
+ .int2_addr = 0x0d,
+ .reset_addr = 0x22,
+ .max_fifo_size = 32,
+ .id = {
+ {
+ .hw_id = ST_LSM9DS1_ID,
+ .name = ST_LSM9DS1_DEV_NAME,
+ },
+ },
+ .channels = {
+ [ST_LSM6DSX_ID_ACC] = {
+ .chan = st_lsm6dsx_acc_channels,
+ .len = ARRAY_SIZE(st_lsm6dsx_acc_channels),
+ },
+ [ST_LSM6DSX_ID_GYRO] = {
+ .chan = st_lsm6ds0_gyro_channels,
+ .len = ARRAY_SIZE(st_lsm6ds0_gyro_channels),
+ },
+ },
+ .odr_table = {
+ [ST_LSM6DSX_ID_ACC] = {
+ .reg = {
+ .addr = 0x20,
+ .mask = GENMASK(7, 5),
+ },
+ .odr_avl[0] = { 10, 0x01 },
+ .odr_avl[1] = { 50, 0x02 },
+ .odr_avl[2] = { 119, 0x03 },
+ .odr_avl[3] = { 238, 0x04 },
+ .odr_avl[4] = { 476, 0x05 },
+ .odr_avl[5] = { 952, 0x06 },
+ },
+ [ST_LSM6DSX_ID_GYRO] = {
+ .reg = {
+ .addr = 0x10,
+ .mask = GENMASK(7, 5),
+ },
+ .odr_avl[0] = { 15, 0x01 },
+ .odr_avl[1] = { 60, 0x02 },
+ .odr_avl[2] = { 119, 0x03 },
+ .odr_avl[3] = { 238, 0x04 },
+ .odr_avl[4] = { 476, 0x05 },
+ .odr_avl[5] = { 952, 0x06 },
+ },
+ },
+ .fs_table = {
+ [ST_LSM6DSX_ID_ACC] = {
+ .reg = {
+ .addr = 0x20,
+ .mask = GENMASK(4, 3),
+ },
+ .fs_avl[0] = { IIO_G_TO_M_S_2(61), 0x0 },
+ .fs_avl[1] = { IIO_G_TO_M_S_2(122), 0x2 },
+ .fs_avl[2] = { IIO_G_TO_M_S_2(244), 0x3 },
+ .fs_avl[3] = { IIO_G_TO_M_S_2(732), 0x1 },
+ },
+ [ST_LSM6DSX_ID_GYRO] = {
+ .reg = {
+ .addr = 0x10,
+ .mask = GENMASK(4, 3),
+ },
+ .fs_avl[0] = { IIO_DEGREE_TO_RAD(245), 0x0 },
+ .fs_avl[1] = { IIO_DEGREE_TO_RAD(500), 0x1 },
+ .fs_avl[2] = { IIO_DEGREE_TO_RAD(2000), 0x3 },
+ },
+ },
+ },
+ {
.wai = 0x69,
+ .int1_addr = 0x0d,
+ .int2_addr = 0x0e,
+ .reset_addr = 0x12,
.max_fifo_size = 1365,
.id = {
{
@@ -129,6 +169,64 @@ static const struct st_lsm6dsx_settings st_lsm6dsx_sensor_settings[] = {
.name = ST_LSM6DS3_DEV_NAME,
},
},
+ .channels = {
+ [ST_LSM6DSX_ID_ACC] = {
+ .chan = st_lsm6dsx_acc_channels,
+ .len = ARRAY_SIZE(st_lsm6dsx_acc_channels),
+ },
+ [ST_LSM6DSX_ID_GYRO] = {
+ .chan = st_lsm6dsx_gyro_channels,
+ .len = ARRAY_SIZE(st_lsm6dsx_gyro_channels),
+ },
+ },
+ .odr_table = {
+ [ST_LSM6DSX_ID_ACC] = {
+ .reg = {
+ .addr = 0x10,
+ .mask = GENMASK(7, 4),
+ },
+ .odr_avl[0] = { 13, 0x01 },
+ .odr_avl[1] = { 26, 0x02 },
+ .odr_avl[2] = { 52, 0x03 },
+ .odr_avl[3] = { 104, 0x04 },
+ .odr_avl[4] = { 208, 0x05 },
+ .odr_avl[5] = { 416, 0x06 },
+ },
+ [ST_LSM6DSX_ID_GYRO] = {
+ .reg = {
+ .addr = 0x11,
+ .mask = GENMASK(7, 4),
+ },
+ .odr_avl[0] = { 13, 0x01 },
+ .odr_avl[1] = { 26, 0x02 },
+ .odr_avl[2] = { 52, 0x03 },
+ .odr_avl[3] = { 104, 0x04 },
+ .odr_avl[4] = { 208, 0x05 },
+ .odr_avl[5] = { 416, 0x06 },
+ },
+ },
+ .fs_table = {
+ [ST_LSM6DSX_ID_ACC] = {
+ .reg = {
+ .addr = 0x10,
+ .mask = GENMASK(3, 2),
+ },
+ .fs_avl[0] = { IIO_G_TO_M_S_2(61), 0x0 },
+ .fs_avl[1] = { IIO_G_TO_M_S_2(122), 0x2 },
+ .fs_avl[2] = { IIO_G_TO_M_S_2(244), 0x3 },
+ .fs_avl[3] = { IIO_G_TO_M_S_2(488), 0x1 },
+ },
+ [ST_LSM6DSX_ID_GYRO] = {
+ .reg = {
+ .addr = 0x11,
+ .mask = GENMASK(3, 2),
+ },
+ .fs_avl[0] = { IIO_DEGREE_TO_RAD(8750), 0x0 },
+ .fs_avl[1] = { IIO_DEGREE_TO_RAD(17500), 0x1 },
+ .fs_avl[2] = { IIO_DEGREE_TO_RAD(35000), 0x2 },
+ .fs_avl[3] = { IIO_DEGREE_TO_RAD(70000), 0x3 },
+ },
+ },
.decimator = {
[ST_LSM6DSX_ID_ACC] = {
.addr = 0x08,
@@ -140,6 +238,7 @@ static const struct st_lsm6dsx_settings st_lsm6dsx_sensor_settings[] = {
},
},
.fifo_ops = {
+ .update_fifo = st_lsm6dsx_update_fifo,
.read_fifo = st_lsm6dsx_read_fifo,
.fifo_th = {
.addr = 0x06,
@@ -172,6 +271,9 @@ static const struct st_lsm6dsx_settings st_lsm6dsx_sensor_settings[] = {
},
{
.wai = 0x69,
+ .int1_addr = 0x0d,
+ .int2_addr = 0x0e,
+ .reset_addr = 0x12,
.max_fifo_size = 682,
.id = {
{
@@ -179,6 +281,64 @@ static const struct st_lsm6dsx_settings st_lsm6dsx_sensor_settings[] = {
.name = ST_LSM6DS3H_DEV_NAME,
},
},
+ .channels = {
+ [ST_LSM6DSX_ID_ACC] = {
+ .chan = st_lsm6dsx_acc_channels,
+ .len = ARRAY_SIZE(st_lsm6dsx_acc_channels),
+ },
+ [ST_LSM6DSX_ID_GYRO] = {
+ .chan = st_lsm6dsx_gyro_channels,
+ .len = ARRAY_SIZE(st_lsm6dsx_gyro_channels),
+ },
+ },
+ .odr_table = {
+ [ST_LSM6DSX_ID_ACC] = {
+ .reg = {
+ .addr = 0x10,
+ .mask = GENMASK(7, 4),
+ },
+ .odr_avl[0] = { 13, 0x01 },
+ .odr_avl[1] = { 26, 0x02 },
+ .odr_avl[2] = { 52, 0x03 },
+ .odr_avl[3] = { 104, 0x04 },
+ .odr_avl[4] = { 208, 0x05 },
+ .odr_avl[5] = { 416, 0x06 },
+ },
+ [ST_LSM6DSX_ID_GYRO] = {
+ .reg = {
+ .addr = 0x11,
+ .mask = GENMASK(7, 4),
+ },
+ .odr_avl[0] = { 13, 0x01 },
+ .odr_avl[1] = { 26, 0x02 },
+ .odr_avl[2] = { 52, 0x03 },
+ .odr_avl[3] = { 104, 0x04 },
+ .odr_avl[4] = { 208, 0x05 },
+ .odr_avl[5] = { 416, 0x06 },
+ },
+ },
+ .fs_table = {
+ [ST_LSM6DSX_ID_ACC] = {
+ .reg = {
+ .addr = 0x10,
+ .mask = GENMASK(3, 2),
+ },
+ .fs_avl[0] = { IIO_G_TO_M_S_2(61), 0x0 },
+ .fs_avl[1] = { IIO_G_TO_M_S_2(122), 0x2 },
+ .fs_avl[2] = { IIO_G_TO_M_S_2(244), 0x3 },
+ .fs_avl[3] = { IIO_G_TO_M_S_2(488), 0x1 },
+ },
+ [ST_LSM6DSX_ID_GYRO] = {
+ .reg = {
+ .addr = 0x11,
+ .mask = GENMASK(3, 2),
+ },
+ .fs_avl[0] = { IIO_DEGREE_TO_RAD(8750), 0x0 },
+ .fs_avl[1] = { IIO_DEGREE_TO_RAD(17500), 0x1 },
+ .fs_avl[2] = { IIO_DEGREE_TO_RAD(35000), 0x2 },
+ .fs_avl[3] = { IIO_DEGREE_TO_RAD(70000), 0x3 },
+ },
+ },
.decimator = {
[ST_LSM6DSX_ID_ACC] = {
.addr = 0x08,
@@ -190,6 +350,7 @@ static const struct st_lsm6dsx_settings st_lsm6dsx_sensor_settings[] = {
},
},
.fifo_ops = {
+ .update_fifo = st_lsm6dsx_update_fifo,
.read_fifo = st_lsm6dsx_read_fifo,
.fifo_th = {
.addr = 0x06,
@@ -222,6 +383,9 @@ static const struct st_lsm6dsx_settings st_lsm6dsx_sensor_settings[] = {
},
{
.wai = 0x6a,
+ .int1_addr = 0x0d,
+ .int2_addr = 0x0e,
+ .reset_addr = 0x12,
.max_fifo_size = 682,
.id = {
{
@@ -233,6 +397,67 @@ static const struct st_lsm6dsx_settings st_lsm6dsx_sensor_settings[] = {
}, {
.hw_id = ST_ISM330DLC_ID,
.name = ST_ISM330DLC_DEV_NAME,
+ }, {
+ .hw_id = ST_LSM6DS3TRC_ID,
+ .name = ST_LSM6DS3TRC_DEV_NAME,
+ },
+ },
+ .channels = {
+ [ST_LSM6DSX_ID_ACC] = {
+ .chan = st_lsm6dsx_acc_channels,
+ .len = ARRAY_SIZE(st_lsm6dsx_acc_channels),
+ },
+ [ST_LSM6DSX_ID_GYRO] = {
+ .chan = st_lsm6dsx_gyro_channels,
+ .len = ARRAY_SIZE(st_lsm6dsx_gyro_channels),
+ },
+ },
+ .odr_table = {
+ [ST_LSM6DSX_ID_ACC] = {
+ .reg = {
+ .addr = 0x10,
+ .mask = GENMASK(7, 4),
+ },
+ .odr_avl[0] = { 13, 0x01 },
+ .odr_avl[1] = { 26, 0x02 },
+ .odr_avl[2] = { 52, 0x03 },
+ .odr_avl[3] = { 104, 0x04 },
+ .odr_avl[4] = { 208, 0x05 },
+ .odr_avl[5] = { 416, 0x06 },
+ },
+ [ST_LSM6DSX_ID_GYRO] = {
+ .reg = {
+ .addr = 0x11,
+ .mask = GENMASK(7, 4),
+ },
+ .odr_avl[0] = { 13, 0x01 },
+ .odr_avl[1] = { 26, 0x02 },
+ .odr_avl[2] = { 52, 0x03 },
+ .odr_avl[3] = { 104, 0x04 },
+ .odr_avl[4] = { 208, 0x05 },
+ .odr_avl[5] = { 416, 0x06 },
+ },
+ },
+ .fs_table = {
+ [ST_LSM6DSX_ID_ACC] = {
+ .reg = {
+ .addr = 0x10,
+ .mask = GENMASK(3, 2),
+ },
+ .fs_avl[0] = { IIO_G_TO_M_S_2(61), 0x0 },
+ .fs_avl[1] = { IIO_G_TO_M_S_2(122), 0x2 },
+ .fs_avl[2] = { IIO_G_TO_M_S_2(244), 0x3 },
+ .fs_avl[3] = { IIO_G_TO_M_S_2(488), 0x1 },
+ },
+ [ST_LSM6DSX_ID_GYRO] = {
+ .reg = {
+ .addr = 0x11,
+ .mask = GENMASK(3, 2),
+ },
+ .fs_avl[0] = { IIO_DEGREE_TO_RAD(8750), 0x0 },
+ .fs_avl[1] = { IIO_DEGREE_TO_RAD(17500), 0x1 },
+ .fs_avl[2] = { IIO_DEGREE_TO_RAD(35000), 0x2 },
+ .fs_avl[3] = { IIO_DEGREE_TO_RAD(70000), 0x3 },
},
},
.decimator = {
@@ -246,6 +471,7 @@ static const struct st_lsm6dsx_settings st_lsm6dsx_sensor_settings[] = {
},
},
.fifo_ops = {
+ .update_fifo = st_lsm6dsx_update_fifo,
.read_fifo = st_lsm6dsx_read_fifo,
.fifo_th = {
.addr = 0x06,
@@ -278,6 +504,9 @@ static const struct st_lsm6dsx_settings st_lsm6dsx_sensor_settings[] = {
},
{
.wai = 0x6c,
+ .int1_addr = 0x0d,
+ .int2_addr = 0x0e,
+ .reset_addr = 0x12,
.max_fifo_size = 512,
.id = {
{
@@ -288,6 +517,64 @@ static const struct st_lsm6dsx_settings st_lsm6dsx_sensor_settings[] = {
.name = ST_LSM6DSOX_DEV_NAME,
},
},
+ .channels = {
+ [ST_LSM6DSX_ID_ACC] = {
+ .chan = st_lsm6dsx_acc_channels,
+ .len = ARRAY_SIZE(st_lsm6dsx_acc_channels),
+ },
+ [ST_LSM6DSX_ID_GYRO] = {
+ .chan = st_lsm6dsx_gyro_channels,
+ .len = ARRAY_SIZE(st_lsm6dsx_gyro_channels),
+ },
+ },
+ .odr_table = {
+ [ST_LSM6DSX_ID_ACC] = {
+ .reg = {
+ .addr = 0x10,
+ .mask = GENMASK(7, 4),
+ },
+ .odr_avl[0] = { 13, 0x01 },
+ .odr_avl[1] = { 26, 0x02 },
+ .odr_avl[2] = { 52, 0x03 },
+ .odr_avl[3] = { 104, 0x04 },
+ .odr_avl[4] = { 208, 0x05 },
+ .odr_avl[5] = { 416, 0x06 },
+ },
+ [ST_LSM6DSX_ID_GYRO] = {
+ .reg = {
+ .addr = 0x11,
+ .mask = GENMASK(7, 4),
+ },
+ .odr_avl[0] = { 13, 0x01 },
+ .odr_avl[1] = { 26, 0x02 },
+ .odr_avl[2] = { 52, 0x03 },
+ .odr_avl[3] = { 104, 0x04 },
+ .odr_avl[4] = { 208, 0x05 },
+ .odr_avl[5] = { 416, 0x06 },
+ },
+ },
+ .fs_table = {
+ [ST_LSM6DSX_ID_ACC] = {
+ .reg = {
+ .addr = 0x10,
+ .mask = GENMASK(3, 2),
+ },
+ .fs_avl[0] = { IIO_G_TO_M_S_2(61), 0x0 },
+ .fs_avl[1] = { IIO_G_TO_M_S_2(122), 0x2 },
+ .fs_avl[2] = { IIO_G_TO_M_S_2(244), 0x3 },
+ .fs_avl[3] = { IIO_G_TO_M_S_2(488), 0x1 },
+ },
+ [ST_LSM6DSX_ID_GYRO] = {
+ .reg = {
+ .addr = 0x11,
+ .mask = GENMASK(3, 2),
+ },
+ .fs_avl[0] = { IIO_DEGREE_TO_RAD(8750), 0x0 },
+ .fs_avl[1] = { IIO_DEGREE_TO_RAD(17500), 0x1 },
+ .fs_avl[2] = { IIO_DEGREE_TO_RAD(35000), 0x2 },
+ .fs_avl[3] = { IIO_DEGREE_TO_RAD(70000), 0x3 },
+ },
+ },
.batch = {
[ST_LSM6DSX_ID_ACC] = {
.addr = 0x09,
@@ -299,6 +586,7 @@ static const struct st_lsm6dsx_settings st_lsm6dsx_sensor_settings[] = {
},
},
.fifo_ops = {
+ .update_fifo = st_lsm6dsx_update_fifo,
.read_fifo = st_lsm6dsx_read_tagged_fifo,
.fifo_th = {
.addr = 0x07,
@@ -306,7 +594,7 @@ static const struct st_lsm6dsx_settings st_lsm6dsx_sensor_settings[] = {
},
.fifo_diff = {
.addr = 0x3a,
- .mask = GENMASK(8, 0),
+ .mask = GENMASK(9, 0),
},
.th_wl = 1,
},
@@ -349,6 +637,9 @@ static const struct st_lsm6dsx_settings st_lsm6dsx_sensor_settings[] = {
},
{
.wai = 0x6b,
+ .int1_addr = 0x0d,
+ .int2_addr = 0x0e,
+ .reset_addr = 0x12,
.max_fifo_size = 512,
.id = {
{
@@ -356,6 +647,64 @@ static const struct st_lsm6dsx_settings st_lsm6dsx_sensor_settings[] = {
.name = ST_ASM330LHH_DEV_NAME,
},
},
+ .channels = {
+ [ST_LSM6DSX_ID_ACC] = {
+ .chan = st_lsm6dsx_acc_channels,
+ .len = ARRAY_SIZE(st_lsm6dsx_acc_channels),
+ },
+ [ST_LSM6DSX_ID_GYRO] = {
+ .chan = st_lsm6dsx_gyro_channels,
+ .len = ARRAY_SIZE(st_lsm6dsx_gyro_channels),
+ },
+ },
+ .odr_table = {
+ [ST_LSM6DSX_ID_ACC] = {
+ .reg = {
+ .addr = 0x10,
+ .mask = GENMASK(7, 4),
+ },
+ .odr_avl[0] = { 13, 0x01 },
+ .odr_avl[1] = { 26, 0x02 },
+ .odr_avl[2] = { 52, 0x03 },
+ .odr_avl[3] = { 104, 0x04 },
+ .odr_avl[4] = { 208, 0x05 },
+ .odr_avl[5] = { 416, 0x06 },
+ },
+ [ST_LSM6DSX_ID_GYRO] = {
+ .reg = {
+ .addr = 0x11,
+ .mask = GENMASK(7, 4),
+ },
+ .odr_avl[0] = { 13, 0x01 },
+ .odr_avl[1] = { 26, 0x02 },
+ .odr_avl[2] = { 52, 0x03 },
+ .odr_avl[3] = { 104, 0x04 },
+ .odr_avl[4] = { 208, 0x05 },
+ .odr_avl[5] = { 416, 0x06 },
+ },
+ },
+ .fs_table = {
+ [ST_LSM6DSX_ID_ACC] = {
+ .reg = {
+ .addr = 0x10,
+ .mask = GENMASK(3, 2),
+ },
+ .fs_avl[0] = { IIO_G_TO_M_S_2(61), 0x0 },
+ .fs_avl[1] = { IIO_G_TO_M_S_2(122), 0x2 },
+ .fs_avl[2] = { IIO_G_TO_M_S_2(244), 0x3 },
+ .fs_avl[3] = { IIO_G_TO_M_S_2(488), 0x1 },
+ },
+ [ST_LSM6DSX_ID_GYRO] = {
+ .reg = {
+ .addr = 0x11,
+ .mask = GENMASK(3, 2),
+ },
+ .fs_avl[0] = { IIO_DEGREE_TO_RAD(8750), 0x0 },
+ .fs_avl[1] = { IIO_DEGREE_TO_RAD(17500), 0x1 },
+ .fs_avl[2] = { IIO_DEGREE_TO_RAD(35000), 0x2 },
+ .fs_avl[3] = { IIO_DEGREE_TO_RAD(70000), 0x3 },
+ },
+ },
.batch = {
[ST_LSM6DSX_ID_ACC] = {
.addr = 0x09,
@@ -367,6 +716,7 @@ static const struct st_lsm6dsx_settings st_lsm6dsx_sensor_settings[] = {
},
},
.fifo_ops = {
+ .update_fifo = st_lsm6dsx_update_fifo,
.read_fifo = st_lsm6dsx_read_tagged_fifo,
.fifo_th = {
.addr = 0x07,
@@ -374,7 +724,7 @@ static const struct st_lsm6dsx_settings st_lsm6dsx_sensor_settings[] = {
},
.fifo_diff = {
.addr = 0x3a,
- .mask = GENMASK(8, 0),
+ .mask = GENMASK(9, 0),
},
.th_wl = 1,
},
@@ -391,11 +741,75 @@ static const struct st_lsm6dsx_settings st_lsm6dsx_sensor_settings[] = {
},
{
.wai = 0x6b,
+ .int1_addr = 0x0d,
+ .int2_addr = 0x0e,
+ .reset_addr = 0x12,
.max_fifo_size = 512,
.id = {
{
.hw_id = ST_LSM6DSR_ID,
.name = ST_LSM6DSR_DEV_NAME,
+ }, {
+ .hw_id = ST_ISM330DHCX_ID,
+ .name = ST_ISM330DHCX_DEV_NAME,
+ },
+ },
+ .channels = {
+ [ST_LSM6DSX_ID_ACC] = {
+ .chan = st_lsm6dsx_acc_channels,
+ .len = ARRAY_SIZE(st_lsm6dsx_acc_channels),
+ },
+ [ST_LSM6DSX_ID_GYRO] = {
+ .chan = st_lsm6dsx_gyro_channels,
+ .len = ARRAY_SIZE(st_lsm6dsx_gyro_channels),
+ },
+ },
+ .odr_table = {
+ [ST_LSM6DSX_ID_ACC] = {
+ .reg = {
+ .addr = 0x10,
+ .mask = GENMASK(7, 4),
+ },
+ .odr_avl[0] = { 13, 0x01 },
+ .odr_avl[1] = { 26, 0x02 },
+ .odr_avl[2] = { 52, 0x03 },
+ .odr_avl[3] = { 104, 0x04 },
+ .odr_avl[4] = { 208, 0x05 },
+ .odr_avl[5] = { 416, 0x06 },
+ },
+ [ST_LSM6DSX_ID_GYRO] = {
+ .reg = {
+ .addr = 0x11,
+ .mask = GENMASK(7, 4),
+ },
+ .odr_avl[0] = { 13, 0x01 },
+ .odr_avl[1] = { 26, 0x02 },
+ .odr_avl[2] = { 52, 0x03 },
+ .odr_avl[3] = { 104, 0x04 },
+ .odr_avl[4] = { 208, 0x05 },
+ .odr_avl[5] = { 416, 0x06 },
+ },
+ },
+ .fs_table = {
+ [ST_LSM6DSX_ID_ACC] = {
+ .reg = {
+ .addr = 0x10,
+ .mask = GENMASK(3, 2),
+ },
+ .fs_avl[0] = { IIO_G_TO_M_S_2(61), 0x0 },
+ .fs_avl[1] = { IIO_G_TO_M_S_2(122), 0x2 },
+ .fs_avl[2] = { IIO_G_TO_M_S_2(244), 0x3 },
+ .fs_avl[3] = { IIO_G_TO_M_S_2(488), 0x1 },
+ },
+ [ST_LSM6DSX_ID_GYRO] = {
+ .reg = {
+ .addr = 0x11,
+ .mask = GENMASK(3, 2),
+ },
+ .fs_avl[0] = { IIO_DEGREE_TO_RAD(8750), 0x0 },
+ .fs_avl[1] = { IIO_DEGREE_TO_RAD(17500), 0x1 },
+ .fs_avl[2] = { IIO_DEGREE_TO_RAD(35000), 0x2 },
+ .fs_avl[3] = { IIO_DEGREE_TO_RAD(70000), 0x3 },
},
},
.batch = {
@@ -409,6 +823,7 @@ static const struct st_lsm6dsx_settings st_lsm6dsx_sensor_settings[] = {
},
},
.fifo_ops = {
+ .update_fifo = st_lsm6dsx_update_fifo,
.read_fifo = st_lsm6dsx_read_tagged_fifo,
.fifo_th = {
.addr = 0x07,
@@ -416,7 +831,7 @@ static const struct st_lsm6dsx_settings st_lsm6dsx_sensor_settings[] = {
},
.fifo_diff = {
.addr = 0x3a,
- .mask = GENMASK(8, 0),
+ .mask = GENMASK(9, 0),
},
.th_wl = 1,
},
@@ -459,26 +874,6 @@ static const struct st_lsm6dsx_settings st_lsm6dsx_sensor_settings[] = {
},
};
-static const struct iio_chan_spec st_lsm6dsx_acc_channels[] = {
- ST_LSM6DSX_CHANNEL(IIO_ACCEL, ST_LSM6DSX_REG_ACC_OUT_X_L_ADDR,
- IIO_MOD_X, 0),
- ST_LSM6DSX_CHANNEL(IIO_ACCEL, ST_LSM6DSX_REG_ACC_OUT_Y_L_ADDR,
- IIO_MOD_Y, 1),
- ST_LSM6DSX_CHANNEL(IIO_ACCEL, ST_LSM6DSX_REG_ACC_OUT_Z_L_ADDR,
- IIO_MOD_Z, 2),
- IIO_CHAN_SOFT_TIMESTAMP(3),
-};
-
-static const struct iio_chan_spec st_lsm6dsx_gyro_channels[] = {
- ST_LSM6DSX_CHANNEL(IIO_ANGL_VEL, ST_LSM6DSX_REG_GYRO_OUT_X_L_ADDR,
- IIO_MOD_X, 0),
- ST_LSM6DSX_CHANNEL(IIO_ANGL_VEL, ST_LSM6DSX_REG_GYRO_OUT_Y_L_ADDR,
- IIO_MOD_Y, 1),
- ST_LSM6DSX_CHANNEL(IIO_ANGL_VEL, ST_LSM6DSX_REG_GYRO_OUT_Z_L_ADDR,
- IIO_MOD_Z, 2),
- IIO_CHAN_SOFT_TIMESTAMP(3),
-};
-
int st_lsm6dsx_set_page(struct st_lsm6dsx_hw *hw, bool enable)
{
const struct st_lsm6dsx_shub_settings *hub_settings;
@@ -533,23 +928,22 @@ static int st_lsm6dsx_check_whoami(struct st_lsm6dsx_hw *hw, int id,
static int st_lsm6dsx_set_full_scale(struct st_lsm6dsx_sensor *sensor,
u32 gain)
{
- struct st_lsm6dsx_hw *hw = sensor->hw;
- const struct st_lsm6dsx_reg *reg;
+ const struct st_lsm6dsx_fs_table_entry *fs_table;
unsigned int data;
int i, err;
- u8 val;
+ fs_table = &sensor->hw->settings->fs_table[sensor->id];
for (i = 0; i < ST_LSM6DSX_FS_LIST_SIZE; i++)
- if (st_lsm6dsx_fs_table[sensor->id].fs_avl[i].gain == gain)
+ if (fs_table->fs_avl[i].gain == gain)
break;
if (i == ST_LSM6DSX_FS_LIST_SIZE)
return -EINVAL;
- val = st_lsm6dsx_fs_table[sensor->id].fs_avl[i].val;
- reg = &st_lsm6dsx_fs_table[sensor->id].reg;
- data = ST_LSM6DSX_SHIFT_VAL(val, reg->mask);
- err = st_lsm6dsx_update_bits_locked(hw, reg->addr, reg->mask, data);
+ data = ST_LSM6DSX_SHIFT_VAL(fs_table->fs_avl[i].val,
+ fs_table->reg.mask);
+ err = st_lsm6dsx_update_bits_locked(sensor->hw, fs_table->reg.addr,
+ fs_table->reg.mask, data);
if (err < 0)
return err;
@@ -560,20 +954,22 @@ static int st_lsm6dsx_set_full_scale(struct st_lsm6dsx_sensor *sensor,
int st_lsm6dsx_check_odr(struct st_lsm6dsx_sensor *sensor, u16 odr, u8 *val)
{
+ const struct st_lsm6dsx_odr_table_entry *odr_table;
int i;
+ odr_table = &sensor->hw->settings->odr_table[sensor->id];
for (i = 0; i < ST_LSM6DSX_ODR_LIST_SIZE; i++)
/*
* ext devices can run at different odr respect to
* accel sensor
*/
- if (st_lsm6dsx_odr_table[sensor->id].odr_avl[i].hz >= odr)
+ if (odr_table->odr_avl[i].hz >= odr)
break;
if (i == ST_LSM6DSX_ODR_LIST_SIZE)
return -EINVAL;
- *val = st_lsm6dsx_odr_table[sensor->id].odr_avl[i].val;
+ *val = odr_table->odr_avl[i].val;
return 0;
}
@@ -638,7 +1034,7 @@ static int st_lsm6dsx_set_odr(struct st_lsm6dsx_sensor *sensor, u16 req_odr)
return err;
}
- reg = &st_lsm6dsx_odr_table[ref_sensor->id].reg;
+ reg = &hw->settings->odr_table[ref_sensor->id].reg;
data = ST_LSM6DSX_SHIFT_VAL(val, reg->mask);
return st_lsm6dsx_update_bits_locked(hw, reg->addr, reg->mask, data);
}
@@ -783,11 +1179,12 @@ st_lsm6dsx_sysfs_sampling_frequency_avail(struct device *dev,
{
struct st_lsm6dsx_sensor *sensor = iio_priv(dev_get_drvdata(dev));
enum st_lsm6dsx_sensor_id id = sensor->id;
+ struct st_lsm6dsx_hw *hw = sensor->hw;
int i, len = 0;
for (i = 0; i < ST_LSM6DSX_ODR_LIST_SIZE; i++)
len += scnprintf(buf + len, PAGE_SIZE - len, "%d ",
- st_lsm6dsx_odr_table[id].odr_avl[i].hz);
+ hw->settings->odr_table[id].odr_avl[i].hz);
buf[len - 1] = '\n';
return len;
@@ -798,12 +1195,19 @@ static ssize_t st_lsm6dsx_sysfs_scale_avail(struct device *dev,
char *buf)
{
struct st_lsm6dsx_sensor *sensor = iio_priv(dev_get_drvdata(dev));
+ const struct st_lsm6dsx_fs_table_entry *fs_table;
enum st_lsm6dsx_sensor_id id = sensor->id;
+ struct st_lsm6dsx_hw *hw = sensor->hw;
int i, len = 0;
- for (i = 0; i < ST_LSM6DSX_FS_LIST_SIZE; i++)
+ fs_table = &hw->settings->fs_table[id];
+ for (i = 0; i < ST_LSM6DSX_FS_LIST_SIZE; i++) {
+ if (!fs_table->fs_avl[i].gain)
+ break;
+
len += scnprintf(buf + len, PAGE_SIZE - len, "0.%06u ",
- st_lsm6dsx_fs_table[id].fs_avl[i].gain);
+ fs_table->fs_avl[i].gain);
+ }
buf[len - 1] = '\n';
return len;
@@ -873,10 +1277,10 @@ static int st_lsm6dsx_get_drdy_reg(struct st_lsm6dsx_hw *hw, u8 *drdy_reg)
switch (drdy_pin) {
case 1:
- *drdy_reg = ST_LSM6DSX_REG_INT1_ADDR;
+ *drdy_reg = hw->settings->int1_addr;
break;
case 2:
- *drdy_reg = ST_LSM6DSX_REG_INT2_ADDR;
+ *drdy_reg = hw->settings->int2_addr;
break;
default:
dev_err(hw->dev, "unsupported data ready pin\n");
@@ -976,7 +1380,7 @@ static int st_lsm6dsx_init_device(struct st_lsm6dsx_hw *hw)
int err;
/* device sw reset */
- err = regmap_update_bits(hw->regmap, ST_LSM6DSX_REG_RESET_ADDR,
+ err = regmap_update_bits(hw->regmap, hw->settings->reset_addr,
ST_LSM6DSX_REG_RESET_MASK,
FIELD_PREP(ST_LSM6DSX_REG_RESET_MASK, 1));
if (err < 0)
@@ -985,7 +1389,7 @@ static int st_lsm6dsx_init_device(struct st_lsm6dsx_hw *hw)
msleep(50);
/* reload trimming parameter */
- err = regmap_update_bits(hw->regmap, ST_LSM6DSX_REG_RESET_ADDR,
+ err = regmap_update_bits(hw->regmap, hw->settings->reset_addr,
ST_LSM6DSX_REG_BOOT_MASK,
FIELD_PREP(ST_LSM6DSX_REG_BOOT_MASK, 1));
if (err < 0)
@@ -1033,28 +1437,24 @@ static struct iio_dev *st_lsm6dsx_alloc_iiodev(struct st_lsm6dsx_hw *hw,
iio_dev->modes = INDIO_DIRECT_MODE;
iio_dev->dev.parent = hw->dev;
iio_dev->available_scan_masks = st_lsm6dsx_available_scan_masks;
+ iio_dev->channels = hw->settings->channels[id].chan;
+ iio_dev->num_channels = hw->settings->channels[id].len;
sensor = iio_priv(iio_dev);
sensor->id = id;
sensor->hw = hw;
- sensor->odr = st_lsm6dsx_odr_table[id].odr_avl[0].hz;
- sensor->gain = st_lsm6dsx_fs_table[id].fs_avl[0].gain;
+ sensor->odr = hw->settings->odr_table[id].odr_avl[0].hz;
+ sensor->gain = hw->settings->fs_table[id].fs_avl[0].gain;
sensor->watermark = 1;
switch (id) {
case ST_LSM6DSX_ID_ACC:
- iio_dev->channels = st_lsm6dsx_acc_channels;
- iio_dev->num_channels = ARRAY_SIZE(st_lsm6dsx_acc_channels);
iio_dev->info = &st_lsm6dsx_acc_info;
-
scnprintf(sensor->name, sizeof(sensor->name), "%s_accel",
name);
break;
case ST_LSM6DSX_ID_GYRO:
- iio_dev->channels = st_lsm6dsx_gyro_channels;
- iio_dev->num_channels = ARRAY_SIZE(st_lsm6dsx_gyro_channels);
iio_dev->info = &st_lsm6dsx_gyro_info;
-
scnprintf(sensor->name, sizeof(sensor->name), "%s_gyro",
name);
break;