Files
cubelinux-kernel/drivers/iio/imu/inv_icm45600/inv_icm45600.h
T
Greg Kroah-Hartman 598cf27219 Linux 6.19.3
Link: https://lore.kernel.org/r/20260217200002.683975158@linuxfoundation.org
Tested-by: Florian Fainelli <florian.fainelli@broadcom.com>
Tested-by: Takeshi Ogasawara <takeshi.ogasawara@futuring-girl.com>
Tested-by: Peter Schneider <pschneider1968@googlemail.com>
Tested-by: Jon Hunter <jonathanh@nvidia.com>
Tested-by: Salvatore Bonaccorso <carnil@debian.org>
Tested-by: Brett A C Sheffield <bacs@librecast.net>
Tested-by: Mark Brown <broonie@kernel.org>
Tested-by: Luna Jernberg <droidbittin@gmail.com>
Tested-by: Ronald Warsow <rwarsow@gmx.de>
Tested-by: Justin M. Forbes <jforbes@fedoraproject.org>
Tested-by: Ron Economos <re@w6rz.net>
Tested-by: Miguel Ojeda <ojeda@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2026-02-19 16:33:27 +01:00

386 lines
12 KiB
C

/* SPDX-License-Identifier: GPL-2.0-or-later */
/* Copyright (C) 2025 Invensense, Inc. */
#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
};
/* gyroscope fullscale values */
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
};
/* accelerometer fullscale values */
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
};
/* ODR suffixed by LN or LP are Low-Noise or Low-Power mode only */
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 - driver state variables
* @lock: lock for serializing multiple registers access.
* @map: regmap pointer.
* @vddio_supply: I/O voltage regulator for the chip.
* @orientation: sensor chip orientation relative to main hardware.
* @conf: chip sensors configurations.
* @suspended: suspended sensors configuration.
* @indio_gyro: gyroscope IIO device.
* @indio_accel: accelerometer IIO device.
* @chip_info: chip driver data.
* @timestamp: interrupt timestamps.
* @fifo: FIFO management structure.
* @buffer: data transfer buffer aligned for DMA.
*/
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 - sensor state variables
* @scales: table of scales.
* @scales_len: length (nb of items) of the scales table.
* @power_mode: sensor requested power mode (for common frequencies)
* @ts: timestamp module states.
*/
struct inv_icm45600_sensor_state {
const int *scales;
size_t scales_len;
enum inv_icm45600_sensor_mode power_mode;
struct inv_sensors_timestamp ts;
};
/* Virtual register addresses: @bank on MSB (16 bits), @address on LSB */
/* Indirect register access */
#define INV_ICM45600_REG_IREG_ADDR 0x7C
#define INV_ICM45600_REG_IREG_DATA 0x7E
/* Direct acces registers */
#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_PUSH_PULL 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)
/* all sensor data are 16 bits (2 registers wide) in big-endian */
#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)
/*
* FIFO access registers
* FIFO count is 16 bits (2 registers)
* FIFO data is a continuous read register to read FIFO content
*/
#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)
/* FIFO watermark is 16 bits (2 registers wide) in little-endian */
#define INV_ICM45600_REG_FIFO_WATERMARK 0x001E
/* FIFO is configured for 8kb */
#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
/* Gyro USER offset */
#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)
/* Gyro Averaging filter */
#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
/* Accel USER offset */
#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)
/* Accel averaging filter */
#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
/* Sleep times required by the driver */
#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