drivers:iio:stm:imu:st_lsm6dsox: Extend support to WAI 6C
LSM6DSOX driver now support all devices included in the following list: - LSM6DSO - LSM6DSOX - LSM6DSO32 - LSM6DSO32X Select device using the device tree compatible string Signed-off-by: Mario Tesi <mario.tesi@st.com> Change-Id: Ib5f9f292a671f744843646a3c24f042e1b8e3dd5 Reviewed-on: https://sczcxd1104.scz.st.com/gerrit/c/linux/stm-ldd-iio/+/420 Reviewed-by: Denis CIOCCA <denis.ciocca@st.com> Tested-by: CI STM MSD <aosp-ger@st.com>
This commit is contained in:
parent
9c104992b5
commit
9c1ca8655c
@ -9,8 +9,8 @@ config IIO_ST_LSM6DSOX
|
||||
select IIO_ST_LSM6DSOX_SPI if (SPI_MASTER)
|
||||
select IIO_ST_LSM6DSOX_I3C if (I3C)
|
||||
help
|
||||
Say yes here to build support for STMicroelectronics LSM6DSOX imu
|
||||
sensor.
|
||||
Say yes here to build support for STMicroelectronics
|
||||
LSM6DSO/LSM6DSOX/LSM6DSO32/LSM6DSO32X imu sensors.
|
||||
|
||||
To compile this driver as a module, choose M here: the module
|
||||
will be called st_lsm6dsox.
|
||||
@ -30,27 +30,6 @@ config IIO_ST_LSM6DSOX_I3C
|
||||
depends on IIO_ST_LSM6DSOX
|
||||
select REGMAP_I3C
|
||||
|
||||
config IIO_ST_LSM6DSOX_MLC
|
||||
bool "Enable machine learning core"
|
||||
depends on IIO_ST_LSM6DSOX
|
||||
help
|
||||
Enable support to loading MLC binary for internal hw machine learning
|
||||
core. The configuration code is loaded via the firmware support upload
|
||||
the file st_lsm6dsox_mlc.bin in / etc / firmware
|
||||
|
||||
The binary configuration code must be generated using the ST UNICO tool
|
||||
application
|
||||
|
||||
config IIO_ST_LSM6DSOX_MLC_PRELOAD
|
||||
bool "Preload some examples on MLC/FSM core"
|
||||
depends on IIO_ST_LSM6DSOX_MLC
|
||||
help
|
||||
Select yes if you want to preload some examples on machine learning core
|
||||
and finite state machine.
|
||||
|
||||
The examples code is a 6D position recognition and is hardcoded in the
|
||||
driver in the mlcdata structure.
|
||||
|
||||
config IIO_ST_LSM6DSOX_MAY_WAKEUP
|
||||
bool "Enable wake-up irq"
|
||||
depends on IIO_ST_LSM6DSOX
|
||||
|
@ -18,7 +18,11 @@
|
||||
|
||||
#define ST_LSM6DSOX_ODR_EXPAND(odr, uodr) (((odr) * 1000000) + (uodr))
|
||||
|
||||
#define ST_LSM6DSO_DEV_NAME "lsm6dso"
|
||||
#define ST_LSM6DSOX_DEV_NAME "lsm6dsox"
|
||||
#define ST_LSM6DSO32_DEV_NAME "lsm6dso32"
|
||||
#define ST_LSM6DSO32X_DEV_NAME "lsm6dso32x"
|
||||
|
||||
#define ST_LSM6DSOX_DRV_VERSION "1.2"
|
||||
|
||||
#define ST_LSM6DSOX_REG_FUNC_CFG_ACCESS_ADDR 0x01
|
||||
@ -206,6 +210,14 @@
|
||||
ST_LSM6DSOX_TAG_SIZE)
|
||||
#define ST_LSM6DSOX_MAX_FIFO_DEPTH 416
|
||||
|
||||
enum st_lsm6dsox_hw_id {
|
||||
ST_LSM6DSO_ID,
|
||||
ST_LSM6DSOX_ID,
|
||||
ST_LSM6DSO32_ID,
|
||||
ST_LSM6DSO32X_ID,
|
||||
ST_LSM6DSOX_MAX_ID,
|
||||
};
|
||||
|
||||
#define ST_LSM6DSOX_DATA_CHANNEL(chan_type, addr, mod, ch2, scan_idx, \
|
||||
rb, sb, sg, ext_inf) \
|
||||
{ \
|
||||
@ -261,9 +273,8 @@ enum st_lsm6dsox_fsm_mlc_enable_id {
|
||||
ST_LSM6DSOX_FSM_ENABLED = BIT(1),
|
||||
};
|
||||
|
||||
#ifdef CONFIG_IIO_ST_LSM6DSOX_MLC
|
||||
/**
|
||||
* struct mlc_config_t -
|
||||
* struct mlc_config_t - MLC/FSM data register structure
|
||||
* @mlc_int_addr: interrupt register address.
|
||||
* @mlc_int_mask: interrupt register mask.
|
||||
* @fsm_int_addr: interrupt register address.
|
||||
@ -285,10 +296,11 @@ struct st_lsm6dsox_mlc_config_t {
|
||||
uint16_t requested_odr;
|
||||
enum st_lsm6dsox_fsm_mlc_enable_id status;
|
||||
};
|
||||
#endif /* CONFIG_IIO_ST_LSM6DSOX_MLC */
|
||||
|
||||
/**
|
||||
* struct st_lsm6dsox_reg - Generic sensor register description (addr + mask)
|
||||
* struct st_lsm6dsox_reg - Generic sensor register
|
||||
* description (addr + mask)
|
||||
*
|
||||
* @addr: Address of register.
|
||||
* @mask: Bitmask register for proper usage.
|
||||
*/
|
||||
@ -381,25 +393,28 @@ struct st_lsm6dsox_odr_table_entry {
|
||||
};
|
||||
|
||||
/**
|
||||
* struct st_lsm6dsox_fs - Full Scale sensor table entry
|
||||
* @reg: Register description for FS settings.
|
||||
* @gain: Sensor sensitivity (mdps/LSB, mg/LSB and uC/LSB).
|
||||
* @val: FS register value.
|
||||
* struct st_lsm6dsox_fs
|
||||
* brief Full scale entry
|
||||
*
|
||||
* @gain: The gain to obtain data value from raw data (LSB).
|
||||
* @val: Register value.
|
||||
*/
|
||||
struct st_lsm6dsox_fs {
|
||||
struct st_lsm6dsox_reg reg;
|
||||
u32 gain;
|
||||
u8 val;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct st_lsm6dsox_fs_table_entry - Full Scale sensor table
|
||||
* @size: Full Scale sensor table size.
|
||||
* @reg: st_lsm6dsox_reg struct.
|
||||
* @fs_avl: Full Scale list entries.
|
||||
* @fs_len: Real size of fs_avl array.
|
||||
*/
|
||||
#define ST_LSM6DSOX_FS_LIST_SIZE 4
|
||||
struct st_lsm6dsox_fs_table_entry {
|
||||
u8 size;
|
||||
struct st_lsm6dsox_fs fs_avl[5];
|
||||
struct st_lsm6dsox_reg reg;
|
||||
struct st_lsm6dsox_fs fs_avl[ST_LSM6DSOX_FS_LIST_SIZE];
|
||||
int fs_len;
|
||||
};
|
||||
|
||||
enum st_lsm6dsox_sensor_id {
|
||||
@ -412,7 +427,6 @@ enum st_lsm6dsox_sensor_id {
|
||||
ST_LSM6DSOX_ID_STEP_DETECTOR,
|
||||
ST_LSM6DSOX_ID_SIGN_MOTION,
|
||||
ST_LSM6DSOX_ID_TILT,
|
||||
#ifdef CONFIG_IIO_ST_LSM6DSOX_MLC
|
||||
ST_LSM6DSOX_ID_MLC,
|
||||
ST_LSM6DSOX_ID_MLC_0,
|
||||
ST_LSM6DSOX_ID_MLC_1,
|
||||
@ -438,7 +452,6 @@ enum st_lsm6dsox_sensor_id {
|
||||
ST_LSM6DSOX_ID_FSM_13,
|
||||
ST_LSM6DSOX_ID_FSM_14,
|
||||
ST_LSM6DSOX_ID_FSM_15,
|
||||
#endif /* CONFIG_IIO_ST_LSM6DSOX_MLC */
|
||||
ST_LSM6DSOX_ID_MAX,
|
||||
};
|
||||
|
||||
@ -456,7 +469,6 @@ static const enum st_lsm6dsox_sensor_id st_lsm6dsox_main_sensor_list[] = {
|
||||
[6] = ST_LSM6DSOX_ID_TILT,
|
||||
};
|
||||
|
||||
#ifdef CONFIG_IIO_ST_LSM6DSOX_MLC
|
||||
static const enum st_lsm6dsox_sensor_id st_lsm6dsox_mlc_sensor_list[] = {
|
||||
[0] = ST_LSM6DSOX_ID_MLC_0,
|
||||
[1] = ST_LSM6DSOX_ID_MLC_1,
|
||||
@ -511,11 +523,8 @@ static const enum st_lsm6dsox_sensor_id st_lsm6dsox_fsm_sensor_list[] = {
|
||||
BIT(ST_LSM6DSOX_ID_FSM_13) | \
|
||||
BIT(ST_LSM6DSOX_ID_FSM_14) | \
|
||||
BIT(ST_LSM6DSOX_ID_FSM_15))
|
||||
#endif /* CONFIG_IIO_ST_LSM6DSOX_MLC */
|
||||
|
||||
/*
|
||||
* HW devices that can wakeup the target
|
||||
*/
|
||||
/* HW devices that can wakeup the target */
|
||||
#define ST_LSM6DSOX_WAKE_UP_SENSORS (BIT(ST_LSM6DSOX_ID_GYRO) | \
|
||||
BIT(ST_LSM6DSOX_ID_ACC))
|
||||
|
||||
@ -543,19 +552,23 @@ struct st_lsm6dsox_ext_dev_info {
|
||||
* @id: Sensor identifier.
|
||||
* @hw: Pointer to instance of struct st_lsm6dsox_hw.
|
||||
* @ext_dev_info: For sensor hub indicate device info struct.
|
||||
* @gain: Configured sensor sensitivity.
|
||||
* @odr: Output data rate of the sensor [Hz].
|
||||
* @uodr: Output data rate of the sensor [uHz].
|
||||
* @gain: Configured sensor sensitivity.
|
||||
* @offset: Sensor data offset.
|
||||
* decimator: Sensor decimator
|
||||
* dec_counter: Sensor decimator counter
|
||||
* @decimator: Sensor decimator
|
||||
* @dec_counter: Sensor decimator counter
|
||||
* @old_data: Used by Temperature sensor for data comtinuity.
|
||||
* @max_watermark: Max supported watermark level.
|
||||
* @watermark: Sensor watermark level.
|
||||
* @pm: sensor power mode (HP, LP).
|
||||
* @last_fifo_timestamp: Timestamp related to last sample in FIFO.
|
||||
* @selftest_status: Report last self test status.
|
||||
* @min_st: Min self test raw data value.
|
||||
* @max_st: Max self test raw data value.
|
||||
* @status_reg: Status register used by mlc/fsm.
|
||||
* @outreg_addr: Output data register used by mlc/fsm.
|
||||
* @status: Status of mlc/fsm algos.
|
||||
*/
|
||||
struct st_lsm6dsox_sensor {
|
||||
char name[32];
|
||||
@ -593,9 +606,11 @@ struct st_lsm6dsox_sensor {
|
||||
|
||||
/**
|
||||
* struct st_lsm6dsox_hw - ST IMU MEMS hw instance
|
||||
* @dev_name: STM device name.
|
||||
* @dev: Pointer to instance of struct device (I2C or SPI).
|
||||
* @irq: Device interrupt line (I2C or SPI).
|
||||
* @regmap: Register map of the device.
|
||||
* @page_lock: Mutex to prevent concurrent access to the page selector.
|
||||
* @fifo_lock: Mutex to prevent concurrent access to the hw FIFO.
|
||||
* @fifo_mode: FIFO operating mode supported by the device.
|
||||
* @state: hw operational state.
|
||||
@ -609,13 +624,18 @@ struct st_lsm6dsox_sensor {
|
||||
* @ts: Latest timestamp from irq handler.
|
||||
* @i2c_master_pu: I2C master line Pull Up configuration.
|
||||
* @orientation: Sensor orientation matrix.
|
||||
* @mlc_config:
|
||||
* @odr_table_entry: Sensors ODR table.
|
||||
* @vdd_supply: Voltage regulator for VDD.
|
||||
* @vddio_supply: Voltage regulator for VDDIIO.
|
||||
* @mlc_config: MLC/FSM data register structure.
|
||||
* @settings: ST IMU sensor settings.
|
||||
* @st_lsm6dsox_odr_table: Sensors ODR table.
|
||||
* @preload_mlc: MLC/FSM preload flag.
|
||||
* @iio_devs: Pointers to acc/gyro iio_dev instances.
|
||||
* @embfunc_irq_reg: Embedded function irq configuration register (other).
|
||||
* @embfunc_pg0_irq_reg: Embedded function irq configuration register (page 0).
|
||||
*/
|
||||
struct st_lsm6dsox_hw {
|
||||
char dev_name[16];
|
||||
struct device *dev;
|
||||
int irq;
|
||||
struct regmap *regmap;
|
||||
@ -637,7 +657,8 @@ struct st_lsm6dsox_hw {
|
||||
struct regulator *vddio_supply;
|
||||
|
||||
struct st_lsm6dsox_mlc_config_t *mlc_config;
|
||||
const struct st_lsm6dsox_odr_table_entry *odr_table_entry;
|
||||
const struct st_lsm6dsox_settings *settings;
|
||||
const struct st_lsm6dsox_odr_table_entry *st_lsm6dsox_odr_table;
|
||||
|
||||
bool preload_mlc;
|
||||
|
||||
@ -649,7 +670,26 @@ struct st_lsm6dsox_hw {
|
||||
|
||||
extern const struct dev_pm_ops st_lsm6dsox_pm_ops;
|
||||
|
||||
static inline bool st_lsm6dsox_is_fifo_enabled(struct st_lsm6dsox_hw *hw)
|
||||
/**
|
||||
* struct st_lsm6dsox_settings - ST IMU sensor settings
|
||||
*
|
||||
* @hw_id: Hw id supported by the driver configuration.
|
||||
* @name: Device name supported by the driver configuration.
|
||||
* @fs_table: Full scale table for a selected device.
|
||||
* @st_mlc_probe: MLC probe flag.
|
||||
*/
|
||||
struct st_lsm6dsox_settings {
|
||||
struct {
|
||||
enum st_lsm6dsox_hw_id hw_id;
|
||||
const char *name;
|
||||
} id[ST_LSM6DSOX_MAX_ID];
|
||||
struct st_lsm6dsox_fs_table_entry fs_table[ST_LSM6DSOX_ID_MAX];
|
||||
bool st_mlc_probe;
|
||||
};
|
||||
|
||||
|
||||
static inline bool
|
||||
st_lsm6dsox_is_fifo_enabled(struct st_lsm6dsox_hw *hw)
|
||||
{
|
||||
return hw->enable_mask & (BIT(ST_LSM6DSOX_ID_GYRO) |
|
||||
BIT(ST_LSM6DSOX_ID_STEP_COUNTER) |
|
||||
@ -683,10 +723,10 @@ st_lsm6dsox_update_bits_locked(struct st_lsm6dsox_hw *hw, unsigned int addr,
|
||||
}
|
||||
|
||||
/* use when mask is constant */
|
||||
static inline int st_lsm6dsox_write_with_mask_locked(struct st_lsm6dsox_hw *hw,
|
||||
unsigned int addr,
|
||||
unsigned int mask,
|
||||
unsigned int data)
|
||||
static inline int
|
||||
st_lsm6dsox_write_with_mask_locked(struct st_lsm6dsox_hw *hw,
|
||||
unsigned int addr, unsigned int mask,
|
||||
unsigned int data)
|
||||
{
|
||||
int err;
|
||||
unsigned int val = FIELD_PREP(mask, data);
|
||||
@ -729,18 +769,18 @@ static inline int st_lsm6dsox_set_page_access(struct st_lsm6dsox_hw *hw,
|
||||
unsigned int mask)
|
||||
{
|
||||
return regmap_update_bits(hw->regmap,
|
||||
ST_LSM6DSOX_REG_FUNC_CFG_ACCESS_ADDR,
|
||||
mask,
|
||||
ST_LSM6DSOX_SHIFT_VAL(val, mask));
|
||||
ST_LSM6DSOX_REG_FUNC_CFG_ACCESS_ADDR,
|
||||
mask,
|
||||
ST_LSM6DSOX_SHIFT_VAL(val, mask));
|
||||
}
|
||||
|
||||
int st_lsm6dsox_probe(struct device *dev, int irq,
|
||||
int st_lsm6dsox_probe(struct device *dev, int irq, int hw_id,
|
||||
struct regmap *regmap);
|
||||
int st_lsm6dsox_sensor_set_enable(struct st_lsm6dsox_sensor *sensor,
|
||||
bool enable);
|
||||
int st_lsm6dsox_buffers_setup(struct st_lsm6dsox_hw *hw);
|
||||
int st_lsm6dsox_get_batch_val(struct st_lsm6dsox_sensor *sensor, int odr,
|
||||
int uodr, u8 *val);
|
||||
int st_lsm6dsox_get_batch_val(struct st_lsm6dsox_sensor *sensor,
|
||||
int odr, int uodr, u8 *val);
|
||||
int st_lsm6dsox_update_watermark(struct st_lsm6dsox_sensor *sensor,
|
||||
u16 watermark);
|
||||
ssize_t st_lsm6dsox_flush_fifo(struct device *dev,
|
||||
@ -750,7 +790,8 @@ ssize_t st_lsm6dsox_get_max_watermark(struct device *dev,
|
||||
struct device_attribute *attr,
|
||||
char *buf);
|
||||
ssize_t st_lsm6dsox_get_watermark(struct device *dev,
|
||||
struct device_attribute *attr, char *buf);
|
||||
struct device_attribute *attr,
|
||||
char *buf);
|
||||
ssize_t st_lsm6dsox_set_watermark(struct device *dev,
|
||||
struct device_attribute *attr,
|
||||
const char *buf, size_t size);
|
||||
@ -763,12 +804,10 @@ int st_lsm6dsox_shub_probe(struct st_lsm6dsox_hw *hw);
|
||||
int st_lsm6dsox_shub_set_enable(struct st_lsm6dsox_sensor *sensor,
|
||||
bool enable);
|
||||
|
||||
#ifdef CONFIG_IIO_ST_LSM6DSOX_MLC
|
||||
int st_lsm6dsox_mlc_probe(struct st_lsm6dsox_hw *hw);
|
||||
int st_lsm6dsox_mlc_remove(struct device *dev);
|
||||
int st_lsm6dsox_mlc_check_status(struct st_lsm6dsox_hw *hw);
|
||||
int st_lsm6dsox_mlc_init_preload(struct st_lsm6dsox_hw *hw);
|
||||
#endif /* CONFIG_IIO_ST_LSM6DSOX_MLC */
|
||||
|
||||
int st_lsm6dsox_embfunc_sensor_set_enable(struct st_lsm6dsox_sensor *sensor,
|
||||
bool enable);
|
||||
|
@ -102,8 +102,8 @@ st_lsm6dsox_set_sensor_batching_odr(struct st_lsm6dsox_sensor *sensor,
|
||||
}
|
||||
|
||||
return st_lsm6dsox_update_bits_locked(hw,
|
||||
hw->odr_table_entry[id].batching_reg.addr,
|
||||
hw->odr_table_entry[id].batching_reg.mask,
|
||||
hw->st_lsm6dsox_odr_table[id].batching_reg.addr,
|
||||
hw->st_lsm6dsox_odr_table[id].batching_reg.mask,
|
||||
data);
|
||||
}
|
||||
|
||||
@ -447,8 +447,8 @@ static int st_lsm6dsox_update_fifo(struct iio_dev *iio_dev, bool enable)
|
||||
}
|
||||
|
||||
err = st_lsm6dsox_update_bits_locked(hw,
|
||||
hw->odr_table_entry[ST_LSM6DSOX_ID_ACC].batching_reg.addr,
|
||||
hw->odr_table_entry[ST_LSM6DSOX_ID_ACC].batching_reg.mask,
|
||||
hw->st_lsm6dsox_odr_table[ST_LSM6DSOX_ID_ACC].batching_reg.addr,
|
||||
hw->st_lsm6dsox_odr_table[ST_LSM6DSOX_ID_ACC].batching_reg.mask,
|
||||
data);
|
||||
if (err < 0)
|
||||
goto out;
|
||||
@ -497,9 +497,8 @@ static irqreturn_t st_lsm6dsox_handler_thread(int irq, void *private)
|
||||
{
|
||||
struct st_lsm6dsox_hw *hw = (struct st_lsm6dsox_hw *)private;
|
||||
|
||||
#ifdef CONFIG_IIO_ST_LSM6DSOX_MLC
|
||||
st_lsm6dsox_mlc_check_status(hw);
|
||||
#endif /* CONFIG_IIO_ST_LSM6DSOX_MLC */
|
||||
if (hw->settings->st_mlc_probe)
|
||||
st_lsm6dsox_mlc_check_status(hw);
|
||||
|
||||
mutex_lock(&hw->fifo_lock);
|
||||
st_lsm6dsox_read_fifo(hw);
|
||||
|
@ -230,83 +230,141 @@ static const struct st_lsm6dsox_odr_table_entry st_lsm6dsox_odr_table[] = {
|
||||
},
|
||||
};
|
||||
|
||||
static const struct st_lsm6dsox_fs_table_entry st_lsm6dsox_fs_table[] = {
|
||||
[ST_LSM6DSOX_ID_ACC] = {
|
||||
.size = 4,
|
||||
.fs_avl[0] = {
|
||||
.reg = {
|
||||
.addr = ST_LSM6DSOX_CTRL1_XL_ADDR,
|
||||
.mask = GENMASK(3, 2),
|
||||
/**
|
||||
* List of supported Full Scale Values
|
||||
*
|
||||
* The following table is complete list of supported Full Scale by Acc,
|
||||
* Gyro and Temp sensors.
|
||||
*/
|
||||
static const struct st_lsm6dsox_settings st_lsm6dsox_sensor_settings[] = {
|
||||
{
|
||||
.id = {
|
||||
{
|
||||
.hw_id = ST_LSM6DSO_ID,
|
||||
.name = ST_LSM6DSO_DEV_NAME,
|
||||
},
|
||||
.gain = IIO_G_TO_M_S_2(61),
|
||||
.val = 0x0,
|
||||
},
|
||||
.fs_avl[1] = {
|
||||
.reg = {
|
||||
.addr = ST_LSM6DSOX_CTRL1_XL_ADDR,
|
||||
.mask = GENMASK(3, 2),
|
||||
.fs_table = {
|
||||
[ST_LSM6DSOX_ID_ACC] = {
|
||||
.reg = {
|
||||
.addr = ST_LSM6DSOX_CTRL1_XL_ADDR,
|
||||
.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 },
|
||||
.fs_len = 4,
|
||||
},
|
||||
.gain = IIO_G_TO_M_S_2(122),
|
||||
.val = 0x2,
|
||||
},
|
||||
.fs_avl[2] = {
|
||||
.reg = {
|
||||
.addr = ST_LSM6DSOX_CTRL1_XL_ADDR,
|
||||
.mask = GENMASK(3, 2),
|
||||
[ST_LSM6DSOX_ID_GYRO] = {
|
||||
.reg = {
|
||||
.addr = ST_LSM6DSOX_CTRL2_G_ADDR,
|
||||
.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 },
|
||||
.fs_len = 4,
|
||||
},
|
||||
.gain = IIO_G_TO_M_S_2(244),
|
||||
.val = 0x3,
|
||||
},
|
||||
.fs_avl[3] = {
|
||||
.reg = {
|
||||
.addr = ST_LSM6DSOX_CTRL1_XL_ADDR,
|
||||
.mask = GENMASK(3, 2),
|
||||
},
|
||||
.gain = IIO_G_TO_M_S_2(488),
|
||||
.val = 0x1,
|
||||
},
|
||||
},
|
||||
[ST_LSM6DSOX_ID_GYRO] = {
|
||||
.size = 4,
|
||||
.fs_avl[0] = {
|
||||
.reg = {
|
||||
.addr = ST_LSM6DSOX_CTRL2_G_ADDR,
|
||||
.mask = GENMASK(3, 0),
|
||||
{
|
||||
.id = {
|
||||
{
|
||||
.hw_id = ST_LSM6DSOX_ID,
|
||||
.name = ST_LSM6DSOX_DEV_NAME,
|
||||
},
|
||||
.gain = IIO_DEGREE_TO_RAD(8750),
|
||||
.val = 0x0,
|
||||
},
|
||||
.fs_avl[1] = {
|
||||
.reg = {
|
||||
.addr = ST_LSM6DSOX_CTRL2_G_ADDR,
|
||||
.mask = GENMASK(3, 0),
|
||||
.st_mlc_probe = true,
|
||||
.fs_table = {
|
||||
[ST_LSM6DSOX_ID_ACC] = {
|
||||
.reg = {
|
||||
.addr = ST_LSM6DSOX_CTRL1_XL_ADDR,
|
||||
.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 },
|
||||
.fs_len = 4,
|
||||
},
|
||||
.gain = IIO_DEGREE_TO_RAD(17500),
|
||||
.val = 0x4,
|
||||
},
|
||||
.fs_avl[2] = {
|
||||
.reg = {
|
||||
.addr = ST_LSM6DSOX_CTRL2_G_ADDR,
|
||||
.mask = GENMASK(3, 0),
|
||||
[ST_LSM6DSOX_ID_GYRO] = {
|
||||
.reg = {
|
||||
.addr = ST_LSM6DSOX_CTRL2_G_ADDR,
|
||||
.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 },
|
||||
.fs_len = 4,
|
||||
},
|
||||
.gain = IIO_DEGREE_TO_RAD(35000),
|
||||
.val = 0x8,
|
||||
},
|
||||
.fs_avl[3] = {
|
||||
.reg = {
|
||||
.addr = ST_LSM6DSOX_CTRL2_G_ADDR,
|
||||
.mask = GENMASK(3, 0),
|
||||
},
|
||||
.gain = IIO_DEGREE_TO_RAD(70000),
|
||||
.val = 0x0C,
|
||||
},
|
||||
},
|
||||
[ST_LSM6DSOX_ID_TEMP] = {
|
||||
.size = 1,
|
||||
.fs_avl[0] = {
|
||||
.reg = { 0 },
|
||||
.gain = (1000000 / ST_LSM6DSOX_TEMP_GAIN),
|
||||
.val = 0x0
|
||||
{
|
||||
.id = {
|
||||
{
|
||||
.hw_id = ST_LSM6DSO32_ID,
|
||||
.name = ST_LSM6DSO32_DEV_NAME,
|
||||
},
|
||||
},
|
||||
.fs_table = {
|
||||
[ST_LSM6DSOX_ID_ACC] = {
|
||||
.reg = {
|
||||
.addr = ST_LSM6DSOX_CTRL1_XL_ADDR,
|
||||
.mask = GENMASK(3, 2),
|
||||
},
|
||||
.fs_avl[0] = { IIO_G_TO_M_S_2(122), 0x0 },
|
||||
.fs_avl[1] = { IIO_G_TO_M_S_2(244), 0x2 },
|
||||
.fs_avl[2] = { IIO_G_TO_M_S_2(488), 0x3 },
|
||||
.fs_avl[3] = { IIO_G_TO_M_S_2(976), 0x1 },
|
||||
.fs_len = 4,
|
||||
},
|
||||
[ST_LSM6DSOX_ID_GYRO] = {
|
||||
.reg = {
|
||||
.addr = ST_LSM6DSOX_CTRL2_G_ADDR,
|
||||
.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 },
|
||||
.fs_len = 4,
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
.id = {
|
||||
{
|
||||
.hw_id = ST_LSM6DSO32X_ID,
|
||||
.name = ST_LSM6DSO32X_DEV_NAME,
|
||||
},
|
||||
},
|
||||
.st_mlc_probe = true,
|
||||
.fs_table = {
|
||||
[ST_LSM6DSOX_ID_ACC] = {
|
||||
.reg = {
|
||||
.addr = ST_LSM6DSOX_CTRL1_XL_ADDR,
|
||||
.mask = GENMASK(3, 2),
|
||||
},
|
||||
.fs_avl[0] = { IIO_G_TO_M_S_2(122), 0x0 },
|
||||
.fs_avl[1] = { IIO_G_TO_M_S_2(244), 0x2 },
|
||||
.fs_avl[2] = { IIO_G_TO_M_S_2(488), 0x3 },
|
||||
.fs_avl[3] = { IIO_G_TO_M_S_2(976), 0x1 },
|
||||
.fs_len = 4,
|
||||
},
|
||||
[ST_LSM6DSOX_ID_GYRO] = {
|
||||
.reg = {
|
||||
.addr = ST_LSM6DSOX_CTRL2_G_ADDR,
|
||||
.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 },
|
||||
.fs_len = 4,
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
@ -456,22 +514,56 @@ static int st_lsm6dsox_set_page_0(struct st_lsm6dsox_hw *hw)
|
||||
ST_LSM6DSOX_REG_FUNC_CFG_ACCESS_ADDR, 0);
|
||||
}
|
||||
|
||||
static int st_lsm6dsox_check_whoami(struct st_lsm6dsox_hw *hw)
|
||||
/**
|
||||
* Detect device ID
|
||||
*
|
||||
* Check the value of the Device ID if valid
|
||||
*
|
||||
* @param hw: ST IMU MEMS hw instance.
|
||||
* @param id: ST IMU MEMS id index.
|
||||
* @param name: Store ST IMU sensor name.
|
||||
* @return 0 if OK, negative value for ERROR
|
||||
*/
|
||||
static int st_lsm6dsox_check_whoami(struct st_lsm6dsox_hw *hw, int id,
|
||||
const char **name)
|
||||
{
|
||||
int err;
|
||||
int data;
|
||||
int err, i, j, data;
|
||||
|
||||
err = regmap_read(hw->regmap, ST_LSM6DSOX_REG_WHOAMI_ADDR, &data);
|
||||
for (i = 0; i < ARRAY_SIZE(st_lsm6dsox_sensor_settings); i++) {
|
||||
for (j = 0; j < ST_LSM6DSOX_MAX_ID; j++) {
|
||||
if (st_lsm6dsox_sensor_settings[i].id[j].name &&
|
||||
st_lsm6dsox_sensor_settings[i].id[j].hw_id == id)
|
||||
break;
|
||||
}
|
||||
|
||||
if (j < ST_LSM6DSOX_MAX_ID)
|
||||
break;
|
||||
}
|
||||
|
||||
if (i == ARRAY_SIZE(st_lsm6dsox_sensor_settings)) {
|
||||
dev_err(hw->dev, "unsupported hw id [%02x]\n", id);
|
||||
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
err = regmap_read(hw->regmap, ST_LSM6DSOX_REG_WHOAMI_ADDR,
|
||||
&data);
|
||||
if (err < 0) {
|
||||
dev_err(hw->dev, "failed to read whoami register\n");
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
if (data != ST_LSM6DSOX_WHOAMI_VAL) {
|
||||
dev_err(hw->dev, "unsupported whoami [%02x]\n", data);
|
||||
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
*name = st_lsm6dsox_sensor_settings[i].id[j].name;
|
||||
hw->settings = &st_lsm6dsox_sensor_settings[i];
|
||||
hw->st_lsm6dsox_odr_table = st_lsm6dsox_odr_table;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -500,24 +592,26 @@ static int st_lsm6dsox_get_odr_calibration(struct st_lsm6dsox_hw *hw)
|
||||
static int st_lsm6dsox_set_full_scale(struct st_lsm6dsox_sensor *sensor,
|
||||
u32 gain)
|
||||
{
|
||||
const struct st_lsm6dsox_fs_table_entry *fs_table;
|
||||
enum st_lsm6dsox_sensor_id id = sensor->id;
|
||||
struct st_lsm6dsox_hw *hw = sensor->hw;
|
||||
int i, err;
|
||||
u8 val;
|
||||
|
||||
for (i = 0; i < st_lsm6dsox_fs_table[id].size; i++)
|
||||
if (st_lsm6dsox_fs_table[id].fs_avl[i].gain == gain)
|
||||
fs_table = &sensor->hw->settings->fs_table[id];
|
||||
|
||||
for (i = 0; i < fs_table->fs_len; i++)
|
||||
if (fs_table->fs_avl[i].gain == gain)
|
||||
break;
|
||||
|
||||
if (i == st_lsm6dsox_fs_table[id].size)
|
||||
if (i == fs_table->fs_len)
|
||||
return -EINVAL;
|
||||
|
||||
val = st_lsm6dsox_fs_table[id].fs_avl[i].val;
|
||||
val = fs_table->fs_avl[i].val;
|
||||
err = regmap_update_bits(hw->regmap,
|
||||
st_lsm6dsox_fs_table[id].fs_avl[i].reg.addr,
|
||||
st_lsm6dsox_fs_table[id].fs_avl[i].reg.mask,
|
||||
ST_LSM6DSOX_SHIFT_VAL(val,
|
||||
st_lsm6dsox_fs_table[id].fs_avl[i].reg.mask));
|
||||
fs_table->reg.addr,
|
||||
fs_table->reg.mask,
|
||||
ST_LSM6DSOX_SHIFT_VAL(val, fs_table->reg.mask));
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
@ -609,7 +703,6 @@ static int st_lsm6dsox_set_odr(struct st_lsm6dsox_sensor *sensor, int req_odr,
|
||||
case ST_LSM6DSOX_ID_STEP_DETECTOR:
|
||||
case ST_LSM6DSOX_ID_SIGN_MOTION:
|
||||
case ST_LSM6DSOX_ID_TILT:
|
||||
#ifdef CONFIG_IIO_ST_LSM6DSOX_MLC
|
||||
case ST_LSM6DSOX_ID_FSM_0:
|
||||
case ST_LSM6DSOX_ID_FSM_1:
|
||||
case ST_LSM6DSOX_ID_FSM_2:
|
||||
@ -634,7 +727,6 @@ static int st_lsm6dsox_set_odr(struct st_lsm6dsox_sensor *sensor, int req_odr,
|
||||
case ST_LSM6DSOX_ID_MLC_5:
|
||||
case ST_LSM6DSOX_ID_MLC_6:
|
||||
case ST_LSM6DSOX_ID_MLC_7:
|
||||
#endif /* CONFIG_IIO_ST_LSM6DSOX_MLC */
|
||||
case ST_LSM6DSOX_ID_ACC: {
|
||||
int odr;
|
||||
int i;
|
||||
@ -936,12 +1028,14 @@ static ssize_t st_lsm6dsox_sysfs_scale_avail(struct device *dev,
|
||||
char *buf)
|
||||
{
|
||||
struct st_lsm6dsox_sensor *sensor = iio_priv(dev_get_drvdata(dev));
|
||||
const struct st_lsm6dsox_fs_table_entry *fs_table;
|
||||
enum st_lsm6dsox_sensor_id id = sensor->id;
|
||||
int i, len = 0;
|
||||
|
||||
for (i = 0; i < st_lsm6dsox_fs_table[id].size; i++)
|
||||
fs_table = &sensor->hw->settings->fs_table[id];
|
||||
for (i = 0; i < fs_table->fs_len; i++)
|
||||
len += scnprintf(buf + len, PAGE_SIZE - len, "0.%06u ",
|
||||
st_lsm6dsox_fs_table[id].fs_avl[i].gain);
|
||||
fs_table->fs_avl[i].gain);
|
||||
buf[len - 1] = '\n';
|
||||
|
||||
return len;
|
||||
@ -1750,12 +1844,14 @@ static struct iio_dev *st_lsm6dsox_alloc_iiodev(struct st_lsm6dsox_hw *hw,
|
||||
case ST_LSM6DSOX_ID_ACC:
|
||||
iio_dev->channels = st_lsm6dsox_acc_channels;
|
||||
iio_dev->num_channels = ARRAY_SIZE(st_lsm6dsox_acc_channels);
|
||||
iio_dev->name = ST_LSM6DSOX_DEV_NAME "_accel";
|
||||
scnprintf(sensor->name, sizeof(sensor->name), "%s_accel",
|
||||
hw->dev_name);
|
||||
iio_dev->info = &st_lsm6dsox_acc_info;
|
||||
iio_dev->available_scan_masks =
|
||||
st_lsm6dsox_available_scan_masks;
|
||||
sensor->max_watermark = ST_LSM6DSOX_MAX_FIFO_DEPTH;
|
||||
sensor->gain = st_lsm6dsox_fs_table[id].fs_avl[0].gain;
|
||||
st_lsm6dsox_set_full_scale(sensor,
|
||||
sensor->hw->settings->fs_table[id].fs_avl[0].gain);
|
||||
sensor->offset = 0;
|
||||
sensor->pm = ST_LSM6DSOX_HP_MODE;
|
||||
sensor->odr = st_lsm6dsox_odr_table[id].odr_avl[1].hz;
|
||||
@ -1766,12 +1862,14 @@ static struct iio_dev *st_lsm6dsox_alloc_iiodev(struct st_lsm6dsox_hw *hw,
|
||||
case ST_LSM6DSOX_ID_GYRO:
|
||||
iio_dev->channels = st_lsm6dsox_gyro_channels;
|
||||
iio_dev->num_channels = ARRAY_SIZE(st_lsm6dsox_gyro_channels);
|
||||
iio_dev->name = ST_LSM6DSOX_DEV_NAME "_gyro";
|
||||
scnprintf(sensor->name, sizeof(sensor->name), "%s_gyro",
|
||||
hw->dev_name);
|
||||
iio_dev->info = &st_lsm6dsox_gyro_info;
|
||||
iio_dev->available_scan_masks =
|
||||
st_lsm6dsox_available_scan_masks;
|
||||
sensor->max_watermark = ST_LSM6DSOX_MAX_FIFO_DEPTH;
|
||||
sensor->gain = st_lsm6dsox_fs_table[id].fs_avl[0].gain;
|
||||
st_lsm6dsox_set_full_scale(sensor,
|
||||
sensor->hw->settings->fs_table[id].fs_avl[0].gain);
|
||||
sensor->offset = 0;
|
||||
sensor->pm = ST_LSM6DSOX_HP_MODE;
|
||||
sensor->odr = st_lsm6dsox_odr_table[id].odr_avl[1].hz;
|
||||
@ -1782,12 +1880,12 @@ static struct iio_dev *st_lsm6dsox_alloc_iiodev(struct st_lsm6dsox_hw *hw,
|
||||
case ST_LSM6DSOX_ID_TEMP:
|
||||
iio_dev->channels = st_lsm6dsox_temp_channels;
|
||||
iio_dev->num_channels = ARRAY_SIZE(st_lsm6dsox_temp_channels);
|
||||
iio_dev->name = ST_LSM6DSOX_DEV_NAME "_temp";
|
||||
scnprintf(sensor->name, sizeof(sensor->name), "%s_temp",
|
||||
hw->dev_name);
|
||||
iio_dev->info = &st_lsm6dsox_temp_info;
|
||||
iio_dev->available_scan_masks =
|
||||
st_lsm6dsox_temp_available_scan_masks;
|
||||
sensor->max_watermark = ST_LSM6DSOX_MAX_FIFO_DEPTH;
|
||||
sensor->gain = st_lsm6dsox_fs_table[id].fs_avl[0].gain;
|
||||
sensor->offset = ST_LSM6DSOX_TEMP_OFFSET;
|
||||
sensor->pm = ST_LSM6DSOX_NO_MODE;
|
||||
sensor->odr = st_lsm6dsox_odr_table[id].odr_avl[1].hz;
|
||||
@ -1797,7 +1895,8 @@ static struct iio_dev *st_lsm6dsox_alloc_iiodev(struct st_lsm6dsox_hw *hw,
|
||||
iio_dev->channels = st_lsm6dsox_step_counter_channels;
|
||||
iio_dev->num_channels =
|
||||
ARRAY_SIZE(st_lsm6dsox_step_counter_channels);
|
||||
iio_dev->name = "lsm6dsox_step_c";
|
||||
scnprintf(sensor->name, sizeof(sensor->name),
|
||||
"%s_step_c", hw->dev_name);
|
||||
iio_dev->info = &st_lsm6dsox_step_counter_info;
|
||||
iio_dev->available_scan_masks =
|
||||
st_lsm6dsox_emb_available_scan_masks;
|
||||
@ -1813,7 +1912,8 @@ static struct iio_dev *st_lsm6dsox_alloc_iiodev(struct st_lsm6dsox_hw *hw,
|
||||
iio_dev->channels = st_lsm6dsox_step_detector_channels;
|
||||
iio_dev->num_channels =
|
||||
ARRAY_SIZE(st_lsm6dsox_step_detector_channels);
|
||||
iio_dev->name = "lsm6dsox_step_d";
|
||||
scnprintf(sensor->name, sizeof(sensor->name),
|
||||
"%s_step_d", hw->dev_name);
|
||||
iio_dev->info = &st_lsm6dsox_step_detector_info;
|
||||
iio_dev->available_scan_masks =
|
||||
st_lsm6dsox_emb_available_scan_masks;
|
||||
@ -1827,7 +1927,8 @@ static struct iio_dev *st_lsm6dsox_alloc_iiodev(struct st_lsm6dsox_hw *hw,
|
||||
iio_dev->channels = st_lsm6dsox_sign_motion_channels;
|
||||
iio_dev->num_channels =
|
||||
ARRAY_SIZE(st_lsm6dsox_sign_motion_channels);
|
||||
iio_dev->name = "lsm6dsox_sign_motion";
|
||||
scnprintf(sensor->name, sizeof(sensor->name),
|
||||
"%s_sign_motion", hw->dev_name);
|
||||
iio_dev->info = &st_lsm6dsox_sign_motion_info;
|
||||
iio_dev->available_scan_masks =
|
||||
st_lsm6dsox_emb_available_scan_masks;
|
||||
@ -1840,7 +1941,8 @@ static struct iio_dev *st_lsm6dsox_alloc_iiodev(struct st_lsm6dsox_hw *hw,
|
||||
case ST_LSM6DSOX_ID_TILT:
|
||||
iio_dev->channels = st_lsm6dsox_tilt_channels;
|
||||
iio_dev->num_channels = ARRAY_SIZE(st_lsm6dsox_tilt_channels);
|
||||
iio_dev->name = "lsm6dsox_tilt";
|
||||
scnprintf(sensor->name, sizeof(sensor->name),
|
||||
"%s_tilt", hw->dev_name);
|
||||
iio_dev->info = &st_lsm6dsox_tilt_info;
|
||||
iio_dev->available_scan_masks =
|
||||
st_lsm6dsox_emb_available_scan_masks;
|
||||
@ -1854,6 +1956,8 @@ static struct iio_dev *st_lsm6dsox_alloc_iiodev(struct st_lsm6dsox_hw *hw,
|
||||
return NULL;
|
||||
}
|
||||
|
||||
iio_dev->name = sensor->name;
|
||||
|
||||
return iio_dev;
|
||||
}
|
||||
|
||||
@ -1867,9 +1971,21 @@ static void st_lsm6dsox_disable_regulator_action(void *_data)
|
||||
}
|
||||
#endif /* CONFIG_IIO_ST_LSM6DSOX_EN_REGULATOR */
|
||||
|
||||
int st_lsm6dsox_probe(struct device *dev, int irq, struct regmap *regmap)
|
||||
/**
|
||||
* Probe device function
|
||||
* Implements [MODULE] feature for Power Management
|
||||
*
|
||||
* @param dev: Device pointer.
|
||||
* @param irq: I2C/SPI/I3C client irq.
|
||||
* @param hw_id: Sensor HW id.
|
||||
* @param regmap: Bus Transfer Function pointer.
|
||||
* @retval 0 if OK, < 0 for error
|
||||
*/
|
||||
int st_lsm6dsox_probe(struct device *dev, int irq, int hw_id,
|
||||
struct regmap *regmap)
|
||||
{
|
||||
struct st_lsm6dsox_hw *hw;
|
||||
const char *name = NULL;
|
||||
int i, err;
|
||||
|
||||
hw = devm_kzalloc(dev, sizeof(*hw), GFP_KERNEL);
|
||||
@ -1884,7 +2000,6 @@ int st_lsm6dsox_probe(struct device *dev, int irq, struct regmap *regmap)
|
||||
hw->regmap = regmap;
|
||||
hw->dev = dev;
|
||||
hw->irq = irq;
|
||||
hw->odr_table_entry = st_lsm6dsox_odr_table;
|
||||
|
||||
#ifdef CONFIG_IIO_ST_LSM6DSOX_EN_REGULATOR
|
||||
hw->vdd_supply = devm_regulator_get(dev, "vdd");
|
||||
@ -1932,10 +2047,12 @@ int st_lsm6dsox_probe(struct device *dev, int irq, struct regmap *regmap)
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
err = st_lsm6dsox_check_whoami(hw);
|
||||
err = st_lsm6dsox_check_whoami(hw, hw_id, &name);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
scnprintf(hw->dev_name, sizeof(hw->dev_name), "%s", name);
|
||||
|
||||
err = st_lsm6dsox_get_odr_calibration(hw);
|
||||
if (err < 0)
|
||||
return err;
|
||||
@ -1974,11 +2091,11 @@ int st_lsm6dsox_probe(struct device *dev, int irq, struct regmap *regmap)
|
||||
return err;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_IIO_ST_LSM6DSOX_MLC
|
||||
err = st_lsm6dsox_mlc_probe(hw);
|
||||
if (err < 0)
|
||||
return err;
|
||||
#endif /* CONFIG_IIO_ST_LSM6DSOX_MLC */
|
||||
if (hw->settings->st_mlc_probe) {
|
||||
err = st_lsm6dsox_mlc_probe(hw);
|
||||
if (err < 0)
|
||||
return err;
|
||||
}
|
||||
|
||||
for (i = 0; i < ST_LSM6DSOX_ID_MAX; i++) {
|
||||
if (!hw->iio_devs[i])
|
||||
@ -1989,11 +2106,11 @@ int st_lsm6dsox_probe(struct device *dev, int irq, struct regmap *regmap)
|
||||
return err;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_IIO_ST_LSM6DSOX_MLC
|
||||
err = st_lsm6dsox_mlc_init_preload(hw);
|
||||
if (err)
|
||||
return err;
|
||||
#endif /* CONFIG_IIO_ST_LSM6DSOX_MLC */
|
||||
if (hw->settings->st_mlc_probe) {
|
||||
err = st_lsm6dsox_mlc_init_preload(hw);
|
||||
if (err)
|
||||
return err;
|
||||
}
|
||||
|
||||
err = st_lsm6dsox_embedded_function_init(hw);
|
||||
if (err)
|
||||
|
@ -23,6 +23,7 @@ static const struct regmap_config st_lsm6dsox_i2c_regmap_config = {
|
||||
static int st_lsm6dsox_i2c_probe(struct i2c_client *client,
|
||||
const struct i2c_device_id *id)
|
||||
{
|
||||
int hw_id = id->driver_data;
|
||||
struct regmap *regmap;
|
||||
|
||||
regmap = devm_regmap_init_i2c(client, &st_lsm6dsox_i2c_regmap_config);
|
||||
@ -32,28 +33,47 @@ static int st_lsm6dsox_i2c_probe(struct i2c_client *client,
|
||||
return PTR_ERR(regmap);
|
||||
}
|
||||
|
||||
return st_lsm6dsox_probe(&client->dev, client->irq, regmap);
|
||||
return st_lsm6dsox_probe(&client->dev, client->irq,
|
||||
hw_id, regmap);
|
||||
}
|
||||
|
||||
static int st_lsm6dsox_i2c_remove(struct i2c_client *client)
|
||||
{
|
||||
#ifdef CONFIG_IIO_ST_LSM6DSOX_MLC
|
||||
return st_lsm6dsox_mlc_remove(&client->dev);
|
||||
#else /* CONFIG_IIO_ST_LSM6DSOX_MLC */
|
||||
return 0;
|
||||
#endif /* CONFIG_IIO_ST_LSM6DSOX_MLC */
|
||||
int err = 0;
|
||||
struct st_lsm6dsox_hw *hw = dev_get_drvdata(&client->dev);
|
||||
|
||||
if (hw->settings->st_mlc_probe)
|
||||
err = st_lsm6dsox_mlc_remove(&client->dev);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
static const struct of_device_id st_lsm6dsox_i2c_of_match[] = {
|
||||
{
|
||||
.compatible = "st," ST_LSM6DSOX_DEV_NAME,
|
||||
.compatible = "st,lsm6dso",
|
||||
.data = (void *)ST_LSM6DSO_ID,
|
||||
},
|
||||
{
|
||||
.compatible = "st,lsm6dsox",
|
||||
.data = (void *)ST_LSM6DSOX_ID,
|
||||
},
|
||||
{
|
||||
.compatible = "st,lsm6dso32",
|
||||
.data = (void *)ST_LSM6DSO32_ID,
|
||||
},
|
||||
{
|
||||
.compatible = "st,lsm6dso32x",
|
||||
.data = (void *)ST_LSM6DSO32X_ID,
|
||||
},
|
||||
{},
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, st_lsm6dsox_i2c_of_match);
|
||||
|
||||
static const struct i2c_device_id st_lsm6dsox_i2c_id_table[] = {
|
||||
{ ST_LSM6DSOX_DEV_NAME },
|
||||
{ ST_LSM6DSO_DEV_NAME, ST_LSM6DSO_ID },
|
||||
{ ST_LSM6DSOX_DEV_NAME, ST_LSM6DSOX_ID },
|
||||
{ ST_LSM6DSO32_DEV_NAME, ST_LSM6DSO32_ID },
|
||||
{ ST_LSM6DSO32X_DEV_NAME, ST_LSM6DSO32X_ID },
|
||||
{},
|
||||
};
|
||||
MODULE_DEVICE_TABLE(i2c, st_lsm6dsox_i2c_id_table);
|
||||
|
@ -18,7 +18,7 @@
|
||||
#include "st_lsm6dsox.h"
|
||||
|
||||
static const struct i3c_device_id st_lsm6dsox_i3c_ids[] = {
|
||||
I3C_DEVICE(0x0104, ST_LSM6DSOX_WHOAMI_VAL, NULL),
|
||||
I3C_DEVICE(0x0104, ST_LSM6DSOX_WHOAMI_VAL, (void *)ST_LSM6DSO_ID),
|
||||
{},
|
||||
};
|
||||
MODULE_DEVICE_TABLE(i3c, st_lsm6dsox_i3c_ids);
|
||||
@ -40,7 +40,8 @@ static int st_lsm6dsox_i3c_probe(struct i3c_device *i3cdev)
|
||||
return PTR_ERR(regmap);
|
||||
}
|
||||
|
||||
return st_lsm6dsox_probe(&i3cdev->dev, 0, regmap);
|
||||
return st_lsm6dsox_probe(&i3cdev->dev, 0,
|
||||
(uintptr_t)id->data, regmap);
|
||||
}
|
||||
|
||||
static struct i3c_driver st_lsm6dsox_driver = {
|
||||
|
@ -7,8 +7,6 @@
|
||||
* Tesi Mario <mario.tesi@st.com>
|
||||
*/
|
||||
|
||||
#ifdef CONFIG_IIO_ST_LSM6DSOX_MLC
|
||||
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/delay.h>
|
||||
@ -38,7 +36,6 @@ DECLARE_BUILTIN_FIRMWARE(LSM6DSOX_MLC_FIRMWARE_NAME, st_lsm6dsox_mlc_fw);
|
||||
#define LSM6DSOX_MLC_FIRMWARE_NAME "st_lsm6dsox_mlc.bin"
|
||||
#endif /* CONFIG_IIO_LSM6DSOX_MLC_BUILTIN_FIRMWARE */
|
||||
|
||||
#ifdef CONFIG_IIO_ST_LSM6DSOX_MLC_PRELOAD
|
||||
static const u8 mlcdata[] = {
|
||||
/*
|
||||
* Machine Learning Core Tool v1.2.0.0 Beta, LSM6DSOX
|
||||
@ -111,7 +108,6 @@ static const struct firmware st_lsm6dsox_mlc_preload = {
|
||||
.size = sizeof(mlcdata),
|
||||
.data = mlcdata
|
||||
};
|
||||
#endif /* CONFIG_IIO_ST_LSM6DSOX_MLC_PRELOAD */
|
||||
|
||||
/* Converts MLC odr to main sensor trigger odr (acc) */
|
||||
static const uint16_t mlc_odr_data[] = {
|
||||
@ -391,7 +387,8 @@ static int st_lsm6dsox_program_mlc(const struct firmware *fw,
|
||||
return fsm_num + mlc_num;
|
||||
}
|
||||
|
||||
static void st_lsm6dsox_mlc_update(const struct firmware *fw, void *context)
|
||||
static void st_lsm6dsox_mlc_update(const struct firmware *fw,
|
||||
void *context)
|
||||
{
|
||||
struct st_lsm6dsox_hw *hw = context;
|
||||
enum st_lsm6dsox_sensor_id id;
|
||||
@ -638,7 +635,7 @@ struct iio_dev *st_lsm6dsox_mlc_alloc_iio_dev(struct st_lsm6dsox_hw *hw,
|
||||
iio_dev->num_channels = ARRAY_SIZE(st_lsm6dsox_mlc_channels);
|
||||
iio_dev->info = &st_lsm6dsox_mlc_event_info;
|
||||
scnprintf(sensor->name, sizeof(sensor->name),
|
||||
ST_LSM6DSOX_DEV_NAME "_mlc");
|
||||
"%s_mlc", hw->dev_name);
|
||||
break;
|
||||
}
|
||||
case ST_LSM6DSOX_ID_MLC_0:
|
||||
@ -666,7 +663,7 @@ struct iio_dev *st_lsm6dsox_mlc_alloc_iio_dev(struct st_lsm6dsox_hw *hw,
|
||||
iio_dev->num_channels = ARRAY_SIZE(st_lsm6dsox_mlc_x_ch);
|
||||
iio_dev->info = &st_lsm6dsox_mlc_x_event_info;
|
||||
scnprintf(sensor->name, sizeof(sensor->name),
|
||||
ST_LSM6DSOX_DEV_NAME "_mlc_%d",
|
||||
"%s_mlc_%d", hw->dev_name,
|
||||
id - ST_LSM6DSOX_ID_MLC_0);
|
||||
sensor->outreg_addr = ST_LSM6DSOX_REG_MLC0_SRC_ADDR +
|
||||
id - ST_LSM6DSOX_ID_MLC_0;
|
||||
@ -709,7 +706,7 @@ struct iio_dev *st_lsm6dsox_mlc_alloc_iio_dev(struct st_lsm6dsox_hw *hw,
|
||||
iio_dev->num_channels = ARRAY_SIZE(st_lsm6dsox_fsm_x_ch);
|
||||
iio_dev->info = &st_lsm6dsox_mlc_x_event_info;
|
||||
scnprintf(sensor->name, sizeof(sensor->name),
|
||||
ST_LSM6DSOX_DEV_NAME "_fsm_%d",
|
||||
"%s_fsm_%d", hw->dev_name,
|
||||
id - ST_LSM6DSOX_ID_FSM_0);
|
||||
sensor->outreg_addr = ST_LSM6DSOX_FSM_OUTS1_ADDR +
|
||||
id - ST_LSM6DSOX_ID_FSM_0;
|
||||
@ -846,11 +843,8 @@ EXPORT_SYMBOL(st_lsm6dsox_mlc_remove);
|
||||
|
||||
int st_lsm6dsox_mlc_init_preload(struct st_lsm6dsox_hw *hw)
|
||||
{
|
||||
#ifdef CONFIG_IIO_ST_LSM6DSOX_MLC_PRELOAD
|
||||
hw->preload_mlc = 1;
|
||||
st_lsm6dsox_mlc_update(&st_lsm6dsox_mlc_preload, hw);
|
||||
#endif /* CONFIG_IIO_ST_LSM6DSOX_MLC_PRELOAD */
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif /* CONFIG_IIO_ST_LSM6DSOX_MLC */
|
||||
|
@ -86,7 +86,7 @@ static const struct st_lsm6dsox_ext_dev_settings st_lsm6dsox_ext_dev_table[] = {
|
||||
.odr_avl[4] = { 100, 0, 0x3, 0 },
|
||||
},
|
||||
.fs_table = {
|
||||
.size = 1,
|
||||
.fs_len = 1,
|
||||
.fs_avl[0] = {
|
||||
.gain = 1500,
|
||||
.val = 0x0,
|
||||
@ -146,36 +146,24 @@ static const struct st_lsm6dsox_ext_dev_settings st_lsm6dsox_ext_dev_table[] = {
|
||||
.odr_avl[5] = { 100, 0, 0x7, 0 },
|
||||
},
|
||||
.fs_table = {
|
||||
.size = 4,
|
||||
.fs_len = 4,
|
||||
.reg = {
|
||||
.addr = 0x21,
|
||||
.mask = GENMASK(6, 5),
|
||||
},
|
||||
.fs_avl[0] = {
|
||||
.reg = {
|
||||
.addr = 0x21,
|
||||
.mask = GENMASK(6, 5),
|
||||
},
|
||||
.gain = 6842,
|
||||
.val = 0x0,
|
||||
},
|
||||
.fs_avl[1] = {
|
||||
.reg = {
|
||||
.addr = 0x21,
|
||||
.mask = GENMASK(6, 5),
|
||||
},
|
||||
.gain = 3421,
|
||||
.val = 0x1,
|
||||
},
|
||||
.fs_avl[2] = {
|
||||
.reg = {
|
||||
.addr = 0x21,
|
||||
.mask = GENMASK(6, 5),
|
||||
},
|
||||
.gain = 2281,
|
||||
.val = 0x2,
|
||||
},
|
||||
.fs_avl[3] = {
|
||||
.reg = {
|
||||
.addr = 0x21,
|
||||
.mask = GENMASK(6, 5),
|
||||
},
|
||||
.gain = 1711,
|
||||
.val = 0x3,
|
||||
},
|
||||
@ -228,7 +216,7 @@ static const struct st_lsm6dsox_ext_dev_settings st_lsm6dsox_ext_dev_table[] = {
|
||||
.odr_avl[3] = { 50, 0, 0x4, 0 },
|
||||
},
|
||||
.fs_table = {
|
||||
.size = 1,
|
||||
.fs_len = 1,
|
||||
/* hPa miscro scale */
|
||||
.fs_avl[0] = {
|
||||
.gain = 1000000UL/4096UL,
|
||||
@ -267,7 +255,7 @@ static const struct st_lsm6dsox_ext_dev_settings st_lsm6dsox_ext_dev_table[] = {
|
||||
.odr_avl[4] = { 100, 0, 0x6, 0 },
|
||||
},
|
||||
.fs_table = {
|
||||
.size = 1,
|
||||
.fs_len = 1,
|
||||
/* hPa miscro scale */
|
||||
.fs_avl[0] = {
|
||||
.gain = 1000000UL/4096UL,
|
||||
@ -877,7 +865,7 @@ static ssize_t st_lsm6dsox_sysfs_shub_scale_avail(struct device *dev,
|
||||
struct st_lsm6dsox_ext_dev_info *ext_info = &sensor->ext_dev_info;
|
||||
int i, len = 0;
|
||||
|
||||
for (i = 0; i < ext_info->ext_dev_settings->fs_table.size; i++) {
|
||||
for (i = 0; i < ext_info->ext_dev_settings->fs_table.fs_len; i++) {
|
||||
u16 val = ext_info->ext_dev_settings->fs_table.fs_avl[i].gain;
|
||||
|
||||
if (val > 0)
|
||||
@ -943,19 +931,6 @@ static struct iio_dev *st_lsm6dsox_shub_alloc_iio_dev(struct st_lsm6dsox_hw *hw,
|
||||
iio_dev->info = &st_lsm6dsox_ext_info;
|
||||
iio_dev->channels = ext_settings->ext_channels;
|
||||
iio_dev->num_channels = ext_settings->ext_chan_depth;
|
||||
|
||||
switch (iio_dev->channels[0].type) {
|
||||
case IIO_MAGN:
|
||||
iio_dev->name = ST_LSM6DSOX_DEV_NAME "_magn";
|
||||
break;
|
||||
case IIO_PRESSURE:
|
||||
iio_dev->name = ST_LSM6DSOX_DEV_NAME "_press";
|
||||
break;
|
||||
default:
|
||||
iio_dev->name = ST_LSM6DSOX_DEV_NAME "_ext";
|
||||
break;
|
||||
}
|
||||
|
||||
sensor = iio_priv(iio_dev);
|
||||
sensor->id = id;
|
||||
sensor->hw = hw;
|
||||
@ -969,6 +944,23 @@ static struct iio_dev *st_lsm6dsox_shub_alloc_iio_dev(struct st_lsm6dsox_hw *hw,
|
||||
sensor->dec_counter = 0;
|
||||
sensor->pm = ST_LSM6DSOX_NO_MODE;
|
||||
|
||||
switch (iio_dev->channels[0].type) {
|
||||
case IIO_MAGN:
|
||||
scnprintf(sensor->name, sizeof(sensor->name), "%s_magn",
|
||||
hw->dev_name);
|
||||
break;
|
||||
case IIO_PRESSURE:
|
||||
scnprintf(sensor->name, sizeof(sensor->name), "%s_press",
|
||||
hw->dev_name);
|
||||
break;
|
||||
default:
|
||||
scnprintf(sensor->name, sizeof(sensor->name), "%s_ext",
|
||||
hw->dev_name);
|
||||
break;
|
||||
}
|
||||
|
||||
iio_dev->name = sensor->name;
|
||||
|
||||
return iio_dev;
|
||||
}
|
||||
|
||||
|
@ -22,6 +22,8 @@ static const struct regmap_config st_lsm6dsox_spi_regmap_config = {
|
||||
|
||||
static int st_lsm6dsox_spi_probe(struct spi_device *spi)
|
||||
{
|
||||
const struct spi_device_id *id = spi_get_device_id(spi);
|
||||
int hw_id = id->driver_data;
|
||||
struct regmap *regmap;
|
||||
|
||||
regmap = devm_regmap_init_spi(spi, &st_lsm6dsox_spi_regmap_config);
|
||||
@ -31,28 +33,46 @@ static int st_lsm6dsox_spi_probe(struct spi_device *spi)
|
||||
return PTR_ERR(regmap);
|
||||
}
|
||||
|
||||
return st_lsm6dsox_probe(&spi->dev, spi->irq, regmap);
|
||||
return st_lsm6dsox_probe(&spi->dev, spi->irq, hw_id, regmap);
|
||||
}
|
||||
|
||||
static int st_lsm6dsox_spi_remove(struct spi_device *spi)
|
||||
{
|
||||
#ifdef CONFIG_IIO_ST_LSM6DSOX_MLC
|
||||
return st_lsm6dsox_mlc_remove(&spi->dev);
|
||||
#else /* CONFIG_IIO_ST_LSM6DSOX_MLC */
|
||||
return 0;
|
||||
#endif /* CONFIG_IIO_ST_LSM6DSOX_MLC */
|
||||
int err = 0;
|
||||
struct st_lsm6dsox_hw *hw = dev_get_drvdata(&spi->dev);
|
||||
|
||||
if (hw->settings->st_mlc_probe)
|
||||
err = st_lsm6dsox_mlc_remove(&spi->dev);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
static const struct of_device_id st_lsm6dsox_spi_of_match[] = {
|
||||
{
|
||||
.compatible = "st," ST_LSM6DSOX_DEV_NAME,
|
||||
.compatible = "st,lsm6dso",
|
||||
.data = (void *)ST_LSM6DSO_ID,
|
||||
},
|
||||
{
|
||||
.compatible = "st,lsm6dsox",
|
||||
.data = (void *)ST_LSM6DSOX_ID,
|
||||
},
|
||||
{
|
||||
.compatible = "st,lsm6dso32",
|
||||
.data = (void *)ST_LSM6DSO32_ID,
|
||||
},
|
||||
{
|
||||
.compatible = "st,lsm6dso32x",
|
||||
.data = (void *)ST_LSM6DSO32X_ID,
|
||||
},
|
||||
{},
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, st_lsm6dsox_spi_of_match);
|
||||
|
||||
static const struct spi_device_id st_lsm6dsox_spi_id_table[] = {
|
||||
{ ST_LSM6DSOX_DEV_NAME },
|
||||
{ ST_LSM6DSO_DEV_NAME, ST_LSM6DSO_ID },
|
||||
{ ST_LSM6DSOX_DEV_NAME, ST_LSM6DSOX_ID },
|
||||
{ ST_LSM6DSO32_DEV_NAME, ST_LSM6DSO32_ID },
|
||||
{ ST_LSM6DSO32X_DEV_NAME, ST_LSM6DSO32X_ID },
|
||||
{},
|
||||
};
|
||||
MODULE_DEVICE_TABLE(spi, st_lsm6dsox_spi_id_table);
|
||||
|
@ -2,7 +2,5 @@ CONFIG_IIO_ST_LSM6DSOX=m
|
||||
CONFIG_IIO_ST_LSM6DSOX_I2C=m
|
||||
CONFIG_IIO_ST_LSM6DSOX_SPI=m
|
||||
CONFIG_IIO_ST_LSM6DSOX_I3C=m
|
||||
CONFIG_IIO_ST_LSM6DSOX_MLC=y
|
||||
CONFIG_IIO_ST_LSM6DSOX_MLC_PRELOAD=y
|
||||
CONFIG_IIO_ST_LSM6DSOX_MAY_WAKEUP=y
|
||||
CONFIG_IIO_ST_LSM6DSOX_EN_REGULATOR=y
|
||||
|
Loading…
Reference in New Issue
Block a user