summaryrefslogtreecommitdiff
path: root/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx.h
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/iio/imu/st_lsm6dsx/st_lsm6dsx.h')
-rw-r--r--drivers/iio/imu/st_lsm6dsx/st_lsm6dsx.h114
1 files changed, 92 insertions, 22 deletions
diff --git a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx.h b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx.h
index b56df409ed0f..6405a5367d76 100644
--- a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx.h
+++ b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx.h
@@ -13,6 +13,7 @@
#include <linux/device.h>
#include <linux/iio/iio.h>
+#include <linux/regulator/consumer.h>
#define ST_LSM6DS3_DEV_NAME "lsm6ds3"
#define ST_LSM6DS3H_DEV_NAME "lsm6ds3h"
@@ -28,9 +29,19 @@
#define ST_LSM9DS1_DEV_NAME "lsm9ds1-imu"
#define ST_LSM6DS0_DEV_NAME "lsm6ds0"
#define ST_LSM6DSRX_DEV_NAME "lsm6dsrx"
+#define ST_LSM6DST_DEV_NAME "lsm6dst"
+#define ST_LSM6DSOP_DEV_NAME "lsm6dsop"
+#define ST_ASM330LHHX_DEV_NAME "asm330lhhx"
+#define ST_LSM6DSTX_DEV_NAME "lsm6dstx"
+#define ST_LSM6DSV_DEV_NAME "lsm6dsv"
+#define ST_LSM6DSV16X_DEV_NAME "lsm6dsv16x"
+#define ST_LSM6DSO16IS_DEV_NAME "lsm6dso16is"
+#define ST_ISM330IS_DEV_NAME "ism330is"
+#define ST_ASM330LHB_DEV_NAME "asm330lhb"
+#define ST_ASM330LHHXG1_DEV_NAME "asm330lhhxg1"
enum st_lsm6dsx_hw_id {
- ST_LSM6DS3_ID,
+ ST_LSM6DS3_ID = 1,
ST_LSM6DS3H_ID,
ST_LSM6DSL_ID,
ST_LSM6DSM_ID,
@@ -44,6 +55,16 @@ enum st_lsm6dsx_hw_id {
ST_LSM9DS1_ID,
ST_LSM6DS0_ID,
ST_LSM6DSRX_ID,
+ ST_LSM6DST_ID,
+ ST_LSM6DSOP_ID,
+ ST_ASM330LHHX_ID,
+ ST_LSM6DSTX_ID,
+ ST_LSM6DSV_ID,
+ ST_LSM6DSV16X_ID,
+ ST_LSM6DSO16IS_ID,
+ ST_ISM330IS_ID,
+ ST_ASM330LHB_ID,
+ ST_ASM330LHHXG1_ID,
ST_LSM6DSX_MAX_ID,
};
@@ -76,7 +97,7 @@ enum st_lsm6dsx_hw_id {
.endianness = IIO_LE, \
}, \
.event_spec = &st_lsm6dsx_event, \
- .ext_info = st_lsm6dsx_accel_ext_info, \
+ .ext_info = st_lsm6dsx_ext_info, \
.num_event_specs = 1, \
}
@@ -96,6 +117,7 @@ enum st_lsm6dsx_hw_id {
.storagebits = 16, \
.endianness = IIO_LE, \
}, \
+ .ext_info = st_lsm6dsx_ext_info, \
}
struct st_lsm6dsx_reg {
@@ -119,6 +141,13 @@ struct st_lsm6dsx_odr_table_entry {
int odr_len;
};
+struct st_lsm6dsx_samples_to_discard {
+ struct {
+ u32 milli_hz;
+ u16 samples;
+ } val[ST_LSM6DSX_ODR_LIST_SIZE];
+};
+
struct st_lsm6dsx_fs {
u32 gain;
u8 val;
@@ -138,6 +167,7 @@ struct st_lsm6dsx_fs_table_entry {
* @read_fifo: Read FIFO callback.
* @fifo_th: FIFO threshold register info (addr + mask).
* @fifo_diff: FIFO diff status register info (addr + mask).
+ * @max_size: Sensor max fifo length in FIFO words.
* @th_wl: FIFO threshold word length.
*/
struct st_lsm6dsx_fifo_ops {
@@ -151,6 +181,7 @@ struct st_lsm6dsx_fifo_ops {
u8 addr;
u16 mask;
} fifo_diff;
+ u16 max_size;
u8 th_wl;
};
@@ -161,6 +192,22 @@ struct st_lsm6dsx_fifo_ops {
* @fifo_en: Hw timer FIFO enable register info (addr + mask).
* @decimator: Hw timer FIFO decimator register info (addr + mask).
* @freq_fine: Difference in % of ODR with respect to the typical.
+ * @ts_sensitivity: Nominal timestamp sensitivity.
+ * @ts_trim_coeff: Coefficient for calculating the calibrated timestamp gain.
+ * This coefficient comes into play when linearizing the formula
+ * used to calculate the calibrated timestamp (please see the
+ * relevant formula in the AN for the specific IMU).
+ * For example, in the case of LSM6DSO we have:
+ *
+ * 1 / (1 + x) ~= 1 - x (Taylor’s Series)
+ * ttrim[s] = 1 / (40000 * (1 + 0.0015 * val)) (from AN5192)
+ * ttrim[ns] ~= 25000 - 37.5 * val
+ * ttrim[ns] ~= 25000 - (37500 * val) / 1000
+ *
+ * so, replacing ts_sensitivity = 25000 and
+ * ts_trim_coeff = 37500
+ *
+ * ttrim[ns] ~= ts_sensitivity - (ts_trim_coeff * val) / 1000
*/
struct st_lsm6dsx_hw_ts_settings {
struct st_lsm6dsx_reg timer_en;
@@ -168,6 +215,8 @@ struct st_lsm6dsx_hw_ts_settings {
struct st_lsm6dsx_reg fifo_en;
struct st_lsm6dsx_reg decimator;
u8 freq_fine;
+ u16 ts_sensitivity;
+ u16 ts_trim_coeff;
};
/**
@@ -221,6 +270,15 @@ struct st_lsm6dsx_event_settings {
u8 wakeup_src_x_mask;
};
+enum st_lsm6dsx_sensor_id {
+ ST_LSM6DSX_ID_GYRO,
+ ST_LSM6DSX_ID_ACC,
+ ST_LSM6DSX_ID_EXT0,
+ ST_LSM6DSX_ID_EXT1,
+ ST_LSM6DSX_ID_EXT2,
+ ST_LSM6DSX_ID_MAX
+};
+
enum st_lsm6dsx_ext_sensor_id {
ST_LSM6DSX_ID_MAGN,
};
@@ -263,16 +321,15 @@ struct st_lsm6dsx_ext_dev_settings {
/**
* struct st_lsm6dsx_settings - ST IMU sensor settings
- * @wai: Sensor WhoAmI default value.
* @reset: register address for reset.
* @boot: register address for boot.
* @bdu: register address for Block Data Update.
- * @max_fifo_size: Sensor max fifo length in FIFO words.
* @id: List of hw id/device name supported by the driver configuration.
* @channels: IIO channels supported by the device.
* @irq_config: interrupts related registers.
* @drdy_mask: register info for data-ready mask (addr + mask).
* @odr_table: Hw sensors odr table (Hz + val).
+ * @samples_to_discard: Number of samples to discard for filters settling time.
* @fs_table: Hw sensors gain table (gain + val).
* @decimator: List of decimator register info (addr + mask).
* @batch: List of FIFO batching register info (addr + mask).
@@ -281,14 +338,13 @@ struct st_lsm6dsx_ext_dev_settings {
* @shub_settings: i2c controller related settings.
*/
struct st_lsm6dsx_settings {
- u8 wai;
struct st_lsm6dsx_reg reset;
struct st_lsm6dsx_reg boot;
struct st_lsm6dsx_reg bdu;
- u16 max_fifo_size;
struct {
enum st_lsm6dsx_hw_id hw_id;
const char *name;
+ u8 wai;
} id[ST_LSM6DSX_MAX_ID];
struct {
const struct iio_chan_spec *chan;
@@ -306,24 +362,16 @@ struct st_lsm6dsx_settings {
} irq_config;
struct st_lsm6dsx_reg drdy_mask;
struct st_lsm6dsx_odr_table_entry odr_table[2];
+ struct st_lsm6dsx_samples_to_discard samples_to_discard[2];
struct st_lsm6dsx_fs_table_entry fs_table[2];
- struct st_lsm6dsx_reg decimator[ST_LSM6DSX_MAX_ID];
- struct st_lsm6dsx_reg batch[ST_LSM6DSX_MAX_ID];
+ struct st_lsm6dsx_reg decimator[ST_LSM6DSX_ID_MAX];
+ struct st_lsm6dsx_reg batch[2];
struct st_lsm6dsx_fifo_ops fifo_ops;
struct st_lsm6dsx_hw_ts_settings ts_settings;
struct st_lsm6dsx_shub_settings shub_settings;
struct st_lsm6dsx_event_settings event_settings;
};
-enum st_lsm6dsx_sensor_id {
- ST_LSM6DSX_ID_GYRO,
- ST_LSM6DSX_ID_ACC,
- ST_LSM6DSX_ID_EXT0,
- ST_LSM6DSX_ID_EXT1,
- ST_LSM6DSX_ID_EXT2,
- ST_LSM6DSX_ID_MAX,
-};
-
enum st_lsm6dsx_fifo_mode {
ST_LSM6DSX_FIFO_BYPASS = 0x0,
ST_LSM6DSX_FIFO_CONT = 0x6,
@@ -335,7 +383,9 @@ enum st_lsm6dsx_fifo_mode {
* @id: Sensor identifier.
* @hw: Pointer to instance of struct st_lsm6dsx_hw.
* @gain: Configured sensor sensitivity.
- * @odr: Output data rate of the sensor [Hz].
+ * @odr: Output data rate of the sensor [mHz].
+ * hwfifo_odr_mHz: Batch data rate for hardware FIFO [mHz]
+ * @samples_to_discard: Number of samples to discard for filters settling time.
* @watermark: Sensor watermark level.
* @decimator: Sensor decimation factor.
* @sip: Number of samples in a given pattern.
@@ -349,7 +399,9 @@ struct st_lsm6dsx_sensor {
u32 gain;
u32 odr;
+ u32 hwfifo_odr_mHz;
+ u16 samples_to_discard;
u16 watermark;
u8 decimator;
u8 sip;
@@ -383,6 +435,7 @@ struct st_lsm6dsx_sensor {
* @iio_devs: Pointers to acc/gyro iio_dev instances.
* @settings: Pointer to the specific sensor settings in use.
* @orientation: sensor chip orientation relative to main hardware.
+ * @scan: Temporary buffers used to align data before iio_push_to_buffers()
*/
struct st_lsm6dsx_hw {
struct device *dev;
@@ -411,6 +464,11 @@ struct st_lsm6dsx_hw {
const struct st_lsm6dsx_settings *settings;
struct iio_mount_matrix orientation;
+ /* Ensure natural alignment of buffer elements */
+ struct {
+ __le16 channels[3];
+ aligned_s64 ts;
+ } scan[ST_LSM6DSX_ID_MAX];
};
static __maybe_unused const struct iio_event_spec st_lsm6dsx_event = {
@@ -436,13 +494,13 @@ int st_lsm6dsx_update_watermark(struct st_lsm6dsx_sensor *sensor,
u16 watermark);
int st_lsm6dsx_update_fifo(struct st_lsm6dsx_sensor *sensor, bool enable);
int st_lsm6dsx_flush_fifo(struct st_lsm6dsx_hw *hw);
-int st_lsm6dsx_set_fifo_mode(struct st_lsm6dsx_hw *hw,
- enum st_lsm6dsx_fifo_mode fifo_mode);
+int st_lsm6dsx_resume_fifo(struct st_lsm6dsx_hw *hw);
int st_lsm6dsx_read_fifo(struct st_lsm6dsx_hw *hw);
int st_lsm6dsx_read_tagged_fifo(struct st_lsm6dsx_hw *hw);
int st_lsm6dsx_check_odr(struct st_lsm6dsx_sensor *sensor, u32 odr, u8 *val);
int st_lsm6dsx_shub_probe(struct st_lsm6dsx_hw *hw, const char *name);
int st_lsm6dsx_shub_set_enable(struct st_lsm6dsx_sensor *sensor, bool enable);
+int st_lsm6dsx_shub_read_output(struct st_lsm6dsx_hw *hw, u8 *data, int len);
int st_lsm6dsx_set_page(struct st_lsm6dsx_hw *hw, bool enable);
static inline int
@@ -484,7 +542,7 @@ st_lsm6dsx_write_locked(struct st_lsm6dsx_hw *hw, unsigned int addr,
return err;
}
-static const inline struct iio_mount_matrix *
+static inline const struct iio_mount_matrix *
st_lsm6dsx_get_mount_matrix(const struct iio_dev *iio_dev,
const struct iio_chan_spec *chan)
{
@@ -494,7 +552,19 @@ st_lsm6dsx_get_mount_matrix(const struct iio_dev *iio_dev,
return &hw->orientation;
}
-static const struct iio_chan_spec_ext_info st_lsm6dsx_accel_ext_info[] = {
+static inline int
+st_lsm6dsx_device_set_enable(struct st_lsm6dsx_sensor *sensor, bool enable)
+{
+ if (sensor->id == ST_LSM6DSX_ID_EXT0 ||
+ sensor->id == ST_LSM6DSX_ID_EXT1 ||
+ sensor->id == ST_LSM6DSX_ID_EXT2)
+ return st_lsm6dsx_shub_set_enable(sensor, enable);
+
+ return st_lsm6dsx_sensor_set_enable(sensor, enable);
+}
+
+static const
+struct iio_chan_spec_ext_info __maybe_unused st_lsm6dsx_ext_info[] = {
IIO_MOUNT_MATRIX(IIO_SHARED_BY_ALL, st_lsm6dsx_get_mount_matrix),
{ }
};