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:
Mario Tesi 2022-01-20 18:10:36 +01:00 committed by Denis CIOCCA
parent 9c104992b5
commit 9c1ca8655c
10 changed files with 397 additions and 238 deletions

View File

@ -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

View File

@ -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);

View File

@ -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);

View File

@ -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)

View File

@ -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);

View File

@ -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 = {

View File

@ -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 */

View File

@ -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;
}

View File

@ -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);

View File

@ -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