#ifndef INV_ICM45600_H_
#define INV_ICM45600_H_
#include <linux/bits.h>
#include <linux/limits.h>
#include <linux/mutex.h>
#include <linux/regmap.h>
#include <linux/regulator/consumer.h>
#include <linux/sizes.h>
#include <linux/types.h>
#include <linux/iio/common/inv_sensors_timestamp.h>
#include <linux/iio/iio.h>
#include "inv_icm45600_buffer.h"
#define INV_ICM45600_REG_BANK_MASK GENMASK(15, 8)
#define INV_ICM45600_REG_ADDR_MASK GENMASK(7, 0)
enum inv_icm45600_sensor_mode {
INV_ICM45600_SENSOR_MODE_OFF,
INV_ICM45600_SENSOR_MODE_STANDBY,
INV_ICM45600_SENSOR_MODE_LOW_POWER,
INV_ICM45600_SENSOR_MODE_LOW_NOISE,
INV_ICM45600_SENSOR_MODE_MAX
};
enum inv_icm45600_gyro_fs {
INV_ICM45600_GYRO_FS_2000DPS,
INV_ICM45600_GYRO_FS_1000DPS,
INV_ICM45600_GYRO_FS_500DPS,
INV_ICM45600_GYRO_FS_250DPS,
INV_ICM45600_GYRO_FS_125DPS,
INV_ICM45600_GYRO_FS_62_5DPS,
INV_ICM45600_GYRO_FS_31_25DPS,
INV_ICM45600_GYRO_FS_15_625DPS,
INV_ICM45600_GYRO_FS_MAX
};
enum inv_icm45686_gyro_fs {
INV_ICM45686_GYRO_FS_4000DPS,
INV_ICM45686_GYRO_FS_2000DPS,
INV_ICM45686_GYRO_FS_1000DPS,
INV_ICM45686_GYRO_FS_500DPS,
INV_ICM45686_GYRO_FS_250DPS,
INV_ICM45686_GYRO_FS_125DPS,
INV_ICM45686_GYRO_FS_62_5DPS,
INV_ICM45686_GYRO_FS_31_25DPS,
INV_ICM45686_GYRO_FS_15_625DPS,
INV_ICM45686_GYRO_FS_MAX
};
enum inv_icm45600_accel_fs {
INV_ICM45600_ACCEL_FS_16G,
INV_ICM45600_ACCEL_FS_8G,
INV_ICM45600_ACCEL_FS_4G,
INV_ICM45600_ACCEL_FS_2G,
INV_ICM45600_ACCEL_FS_MAX
};
enum inv_icm45686_accel_fs {
INV_ICM45686_ACCEL_FS_32G,
INV_ICM45686_ACCEL_FS_16G,
INV_ICM45686_ACCEL_FS_8G,
INV_ICM45686_ACCEL_FS_4G,
INV_ICM45686_ACCEL_FS_2G,
INV_ICM45686_ACCEL_FS_MAX
};
enum inv_icm45600_odr {
INV_ICM45600_ODR_6400HZ_LN = 0x03,
INV_ICM45600_ODR_3200HZ_LN,
INV_ICM45600_ODR_1600HZ_LN,
INV_ICM45600_ODR_800HZ_LN,
INV_ICM45600_ODR_400HZ,
INV_ICM45600_ODR_200HZ,
INV_ICM45600_ODR_100HZ,
INV_ICM45600_ODR_50HZ,
INV_ICM45600_ODR_25HZ,
INV_ICM45600_ODR_12_5HZ,
INV_ICM45600_ODR_6_25HZ_LP,
INV_ICM45600_ODR_3_125HZ_LP,
INV_ICM45600_ODR_1_5625HZ_LP,
INV_ICM45600_ODR_MAX
};
struct inv_icm45600_sensor_conf {
u8 mode;
u8 fs;
u8 odr;
u8 filter;
};
#define INV_ICM45600_SENSOR_CONF_KEEP_VALUES { U8_MAX, U8_MAX, U8_MAX, U8_MAX }
struct inv_icm45600_conf {
struct inv_icm45600_sensor_conf gyro;
struct inv_icm45600_sensor_conf accel;
};
struct inv_icm45600_suspended {
enum inv_icm45600_sensor_mode gyro;
enum inv_icm45600_sensor_mode accel;
};
struct inv_icm45600_chip_info {
u8 whoami;
const char *name;
const struct inv_icm45600_conf *conf;
const int *accel_scales;
const int accel_scales_len;
const int *gyro_scales;
const int gyro_scales_len;
};
extern const struct inv_icm45600_chip_info inv_icm45605_chip_info;
extern const struct inv_icm45600_chip_info inv_icm45606_chip_info;
extern const struct inv_icm45600_chip_info inv_icm45608_chip_info;
extern const struct inv_icm45600_chip_info inv_icm45634_chip_info;
extern const struct inv_icm45600_chip_info inv_icm45686_chip_info;
extern const struct inv_icm45600_chip_info inv_icm45687_chip_info;
extern const struct inv_icm45600_chip_info inv_icm45688p_chip_info;
extern const struct inv_icm45600_chip_info inv_icm45689_chip_info;
extern const int inv_icm45600_accel_scale[][2];
extern const int inv_icm45686_accel_scale[][2];
extern const int inv_icm45600_gyro_scale[][2];
extern const int inv_icm45686_gyro_scale[][2];
struct inv_icm45600_state {
struct mutex lock;
struct regmap *map;
struct regulator *vddio_supply;
struct iio_mount_matrix orientation;
struct inv_icm45600_conf conf;
struct inv_icm45600_suspended suspended;
struct iio_dev *indio_gyro;
struct iio_dev *indio_accel;
const struct inv_icm45600_chip_info *chip_info;
struct {
s64 gyro;
s64 accel;
} timestamp;
struct inv_icm45600_fifo fifo;
union {
u8 buff[2];
__le16 u16;
u8 ireg[3];
} buffer __aligned(IIO_DMA_MINALIGN);
};
struct inv_icm45600_sensor_state {
const int *scales;
size_t scales_len;
enum inv_icm45600_sensor_mode power_mode;
struct inv_sensors_timestamp ts;
};
#define INV_ICM45600_REG_IREG_ADDR 0x7C
#define INV_ICM45600_REG_IREG_DATA 0x7E
#define INV_ICM45600_REG_MISC2 0x007F
#define INV_ICM45600_MISC2_SOFT_RESET BIT(1)
#define INV_ICM45600_REG_DRIVE_CONFIG0 0x0032
#define INV_ICM45600_DRIVE_CONFIG0_SPI_MASK GENMASK(3, 1)
#define INV_ICM45600_SPI_SLEW_RATE_0_5NS 6
#define INV_ICM45600_SPI_SLEW_RATE_4NS 5
#define INV_ICM45600_SPI_SLEW_RATE_5NS 4
#define INV_ICM45600_SPI_SLEW_RATE_7NS 3
#define INV_ICM45600_SPI_SLEW_RATE_10NS 2
#define INV_ICM45600_SPI_SLEW_RATE_14NS 1
#define INV_ICM45600_SPI_SLEW_RATE_38NS 0
#define INV_ICM45600_REG_INT1_CONFIG2 0x0018
#define INV_ICM45600_INT1_CONFIG2_OPEN_DRAIN BIT(2)
#define INV_ICM45600_INT1_CONFIG2_LATCHED BIT(1)
#define INV_ICM45600_INT1_CONFIG2_ACTIVE_HIGH BIT(0)
#define INV_ICM45600_INT1_CONFIG2_ACTIVE_LOW 0x00
#define INV_ICM45600_REG_FIFO_CONFIG0 0x001D
#define INV_ICM45600_FIFO_CONFIG0_MODE_MASK GENMASK(7, 6)
#define INV_ICM45600_FIFO_CONFIG0_MODE_BYPASS 0
#define INV_ICM45600_FIFO_CONFIG0_MODE_STREAM 1
#define INV_ICM45600_FIFO_CONFIG0_MODE_STOP_ON_FULL 2
#define INV_ICM45600_FIFO_CONFIG0_FIFO_DEPTH_MASK GENMASK(5, 0)
#define INV_ICM45600_FIFO_CONFIG0_FIFO_DEPTH_MAX 0x1F
#define INV_ICM45600_REG_FIFO_CONFIG2 0x0020
#define INV_ICM45600_REG_FIFO_CONFIG2_FIFO_FLUSH BIT(7)
#define INV_ICM45600_REG_FIFO_CONFIG2_WM_GT_TH BIT(3)
#define INV_ICM45600_REG_FIFO_CONFIG3 0x0021
#define INV_ICM45600_FIFO_CONFIG3_ES1_EN BIT(5)
#define INV_ICM45600_FIFO_CONFIG3_ES0_EN BIT(4)
#define INV_ICM45600_FIFO_CONFIG3_HIRES_EN BIT(3)
#define INV_ICM45600_FIFO_CONFIG3_GYRO_EN BIT(2)
#define INV_ICM45600_FIFO_CONFIG3_ACCEL_EN BIT(1)
#define INV_ICM45600_FIFO_CONFIG3_IF_EN BIT(0)
#define INV_ICM45600_REG_FIFO_CONFIG4 0x0022
#define INV_ICM45600_FIFO_CONFIG4_COMP_EN BIT(2)
#define INV_ICM45600_FIFO_CONFIG4_TMST_FSYNC_EN BIT(1)
#define INV_ICM45600_FIFO_CONFIG4_ES0_9B BIT(0)
#define INV_ICM45600_REG_TEMP_DATA 0x000C
#define INV_ICM45600_REG_ACCEL_DATA_X 0x0000
#define INV_ICM45600_REG_ACCEL_DATA_Y 0x0002
#define INV_ICM45600_REG_ACCEL_DATA_Z 0x0004
#define INV_ICM45600_REG_GYRO_DATA_X 0x0006
#define INV_ICM45600_REG_GYRO_DATA_Y 0x0008
#define INV_ICM45600_REG_GYRO_DATA_Z 0x000A
#define INV_ICM45600_REG_INT_STATUS 0x0019
#define INV_ICM45600_INT_STATUS_RESET_DONE BIT(7)
#define INV_ICM45600_INT_STATUS_AUX1_AGC_RDY BIT(6)
#define INV_ICM45600_INT_STATUS_AP_AGC_RDY BIT(5)
#define INV_ICM45600_INT_STATUS_AP_FSYNC BIT(4)
#define INV_ICM45600_INT_STATUS_AUX1_DRDY BIT(3)
#define INV_ICM45600_INT_STATUS_DATA_RDY BIT(2)
#define INV_ICM45600_INT_STATUS_FIFO_THS BIT(1)
#define INV_ICM45600_INT_STATUS_FIFO_FULL BIT(0)
#define INV_ICM45600_REG_FIFO_COUNT 0x0012
#define INV_ICM45600_REG_FIFO_DATA 0x0014
#define INV_ICM45600_REG_PWR_MGMT0 0x0010
#define INV_ICM45600_PWR_MGMT0_GYRO_MODE_MASK GENMASK(3, 2)
#define INV_ICM45600_PWR_MGMT0_ACCEL_MODE_MASK GENMASK(1, 0)
#define INV_ICM45600_REG_ACCEL_CONFIG0 0x001B
#define INV_ICM45600_ACCEL_CONFIG0_FS_MASK GENMASK(6, 4)
#define INV_ICM45600_ACCEL_CONFIG0_ODR_MASK GENMASK(3, 0)
#define INV_ICM45600_REG_GYRO_CONFIG0 0x001C
#define INV_ICM45600_GYRO_CONFIG0_FS_MASK GENMASK(7, 4)
#define INV_ICM45600_GYRO_CONFIG0_ODR_MASK GENMASK(3, 0)
#define INV_ICM45600_REG_SMC_CONTROL_0 0xA258
#define INV_ICM45600_SMC_CONTROL_0_ACCEL_LP_CLK_SEL BIT(4)
#define INV_ICM45600_SMC_CONTROL_0_TMST_EN BIT(0)
#define INV_ICM45600_REG_FIFO_WATERMARK 0x001E
#define INV_ICM45600_FIFO_SIZE_MAX SZ_8K
#define INV_ICM45600_REG_INT1_CONFIG0 0x0016
#define INV_ICM45600_INT1_CONFIG0_RESET_DONE_EN BIT(7)
#define INV_ICM45600_INT1_CONFIG0_AUX1_AGC_RDY_EN BIT(6)
#define INV_ICM45600_INT1_CONFIG0_AP_AGC_RDY_EN BIT(5)
#define INV_ICM45600_INT1_CONFIG0_AP_FSYNC_EN BIT(4)
#define INV_ICM45600_INT1_CONFIG0_AUX1_DRDY_EN BIT(3)
#define INV_ICM45600_INT1_CONFIG0_DRDY_EN BIT(2)
#define INV_ICM45600_INT1_CONFIG0_FIFO_THS_EN BIT(1)
#define INV_ICM45600_INT1_CONFIG0_FIFO_FULL_EN BIT(0)
#define INV_ICM45600_REG_WHOAMI 0x0072
#define INV_ICM45600_WHOAMI_ICM45605 0xE5
#define INV_ICM45600_WHOAMI_ICM45686 0xE9
#define INV_ICM45600_WHOAMI_ICM45688P 0xE7
#define INV_ICM45600_WHOAMI_ICM45608 0x81
#define INV_ICM45600_WHOAMI_ICM45634 0x82
#define INV_ICM45600_WHOAMI_ICM45689 0x83
#define INV_ICM45600_WHOAMI_ICM45606 0x84
#define INV_ICM45600_WHOAMI_ICM45687 0x85
#define INV_ICM45600_IPREG_SYS1_REG_42 0xA42A
#define INV_ICM45600_IPREG_SYS1_REG_56 0xA438
#define INV_ICM45600_IPREG_SYS1_REG_70 0xA446
#define INV_ICM45600_GYRO_OFFUSER_MASK GENMASK(13, 0)
#define INV_ICM45600_IPREG_SYS1_REG_170 0xA4AA
#define INV_ICM45600_IPREG_SYS1_170_GYRO_LP_AVG_MASK GENMASK(4, 1)
#define INV_ICM45600_GYRO_LP_AVG_SEL_8X 5
#define INV_ICM45600_GYRO_LP_AVG_SEL_2X 1
#define INV_ICM45600_IPREG_SYS2_REG_24 0xA518
#define INV_ICM45600_IPREG_SYS2_REG_32 0xA520
#define INV_ICM45600_IPREG_SYS2_REG_40 0xA528
#define INV_ICM45600_ACCEL_OFFUSER_MASK GENMASK(13, 0)
#define INV_ICM45600_IPREG_SYS2_REG_129 0xA581
#define INV_ICM45600_ACCEL_LP_AVG_SEL_1X 0x0000
#define INV_ICM45600_ACCEL_LP_AVG_SEL_4X 0x0002
#define INV_ICM45600_ACCEL_STARTUP_TIME_MS 60
#define INV_ICM45600_GYRO_STARTUP_TIME_MS 60
#define INV_ICM45600_GYRO_STOP_TIME_MS 150
#define INV_ICM45600_IREG_DELAY_US 4
typedef int (*inv_icm45600_bus_setup)(struct inv_icm45600_state *);
extern const struct dev_pm_ops inv_icm45600_pm_ops;
const struct iio_mount_matrix *
inv_icm45600_get_mount_matrix(const struct iio_dev *indio_dev,
const struct iio_chan_spec *chan);
#define INV_ICM45600_TEMP_CHAN(_index) \
{ \
.type = IIO_TEMP, \
.info_mask_separate = \
BIT(IIO_CHAN_INFO_RAW) | \
BIT(IIO_CHAN_INFO_OFFSET) | \
BIT(IIO_CHAN_INFO_SCALE), \
.scan_index = _index, \
.scan_type = { \
.sign = 's', \
.realbits = 16, \
.storagebits = 16, \
.endianness = IIO_LE, \
}, \
}
int inv_icm45600_temp_read_raw(struct iio_dev *indio_dev,
struct iio_chan_spec const *chan,
int *val, int *val2, long mask);
u32 inv_icm45600_odr_to_period(enum inv_icm45600_odr odr);
int inv_icm45600_set_accel_conf(struct inv_icm45600_state *st,
struct inv_icm45600_sensor_conf *conf,
unsigned int *sleep_ms);
int inv_icm45600_set_gyro_conf(struct inv_icm45600_state *st,
struct inv_icm45600_sensor_conf *conf,
unsigned int *sleep_ms);
int inv_icm45600_debugfs_reg(struct iio_dev *indio_dev, unsigned int reg,
unsigned int writeval, unsigned int *readval);
int inv_icm45600_core_probe(struct regmap *regmap,
const struct inv_icm45600_chip_info *chip_info,
bool reset, inv_icm45600_bus_setup bus_setup);
struct iio_dev *inv_icm45600_gyro_init(struct inv_icm45600_state *st);
int inv_icm45600_gyro_parse_fifo(struct iio_dev *indio_dev);
struct iio_dev *inv_icm45600_accel_init(struct inv_icm45600_state *st);
int inv_icm45600_accel_parse_fifo(struct iio_dev *indio_dev);
#endif