add i2c controller support to st_lsm6dsx driver
Subsystems (3)
v2 cover add i2c controller support to st_lsm6dsx driver
Introduce i2c controller support to st_lsm6dsx driver for lsm6dso sensor. st_lsm6dsx sensor-hub supports up to 3 concurrent slave devices. Add register map for lis2mdl magnetometer sensor.
Add hw FIFO support to st_lsm6dsx sensorhub driver.
Changes since v1:
- move back st_lsm6dsx_set_fifo_mode routine in fifo_lock critical section in st_lsm6dsx_flush_fifo
- improve documentation
- move st_lsm6dsx_sensor_set_enable definition in a separated patch
- move st_lsm6dsx_push_tagged_data definition in a separated patch
- use proper ts_ref for ext devices in st_lsm6dsx_push_tagged_data
- fix invalid iio_dev identification in st_lsm6dsx_push_tagged_data when ST_LSM6DSX_EXT1_TAG is read from the FIFO
- refactor st_lsm6dsx_shub_probe moving wai check in a dedicated routine
- fix abi issue in scale_available definition
Lorenzo Bianconi (9):
iio: imu: st_lsm6dsx: introduce locked read/write utility routines
iio: imu: st_lsm6dsx: reload trimming parameter at bootstrap
iio: imu: st_lsm6dsx: remove static from st_lsm6dsx_set_watermark
iio: imu: st_lsm6dsx: introduce ST_LSM6DSX_ID_EXT sensor ids
iio: imu: st_lsm6dsx: introduce st_lsm6dsx_sensor_set_enable routine
iio: imu: st_lsm6dsx: add i2c embedded controller support
iio: imu: st_lsm6dsx: add st_lsm6dsx_push_tagged_data routine
iio: imu: st_lsm6dsx: add hw FIFO support to i2c controller
dt-bindings: iio: imu: st_lsm6dsx: add support to i2c pullup resistors
.../bindings/iio/imu/st_lsm6dsx.txt | 1 + drivers/iio/imu/st_lsm6dsx/Makefile | 3 +- drivers/iio/imu/st_lsm6dsx/st_lsm6dsx.h | 167 +++- .../iio/imu/st_lsm6dsx/st_lsm6dsx_buffer.c | 165 ++-- drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c | 283 +++++-- drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_shub.c | 777 ++++++++++++++++++ .../linux/platform_data/st_sensors_pdata.h | 2 + 7 files changed, 1263 insertions(+), 135 deletions(-) create mode 100644 drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_shub.c
Signature · 1 line
2.19.1
PATCH v2 1/9 iio: imu: st_lsm6dsx: introduce locked read/write utility routines
Add st_lsm6dsx_update_bits_locked, st_lsm6dsx_read_locked and st_lsm6dsx_write_locked utility routines in order to guarantee the bus access is atomic respect to reg page configuration. This is a preliminary patch to add i2c sensor hub support since i2c master registers are accessed through a reg page multiplexer
--- drivers/iio/imu/st_lsm6dsx/st_lsm6dsx.h | 41 ++++++++++++ .../iio/imu/st_lsm6dsx/st_lsm6dsx_buffer.c | 63 ++++++++++--------- drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c | 24 ++++--- 3 files changed, 90 insertions(+), 38 deletions(-)
drivers/iio/imu/st_lsm6dsx/st_lsm6dsx.h +41 -0
@@ -148,6 +148,7 @@ struct st_lsm6dsx_sensor {* @irq: Device interrupt line (I2C or SPI). * @fifo_lock: Mutex to prevent concurrent access to the hw FIFO. * @conf_lock: Mutex to prevent concurrent FIFO configuration update. +* @page_lock: Mutex to prevent concurrent memory page configuration. * @fifo_mode: FIFO operating mode supported by the device. * @enable_mask: Enabled sensor bitmask. * @ts_sip: Total number of timestamp samples in a given pattern.
@@ -163,6 +164,7 @@ struct st_lsm6dsx_hw {struct mutex fifo_lock;struct mutex conf_lock; +struct mutex page_lock;enum st_lsm6dsx_fifo_mode fifo_mode;u8 enable_mask;
@@ -192,4 +194,43 @@ int st_lsm6dsx_read_fifo(struct st_lsm6dsx_hw *hw);int st_lsm6dsx_read_tagged_fifo (struct st_lsm6dsx_hw *hw);int st_lsm6dsx_check_odr (struct st_lsm6dsx_sensor *sensor,u16 odr,u8 *val); +static inline int +st_lsm6dsx_update_bits_locked (struct st_lsm6dsx_hw *hw,unsigned int addr, +unsigned int mask,unsigned int val) +{ +int err; + +mutex_lock (&hw->page_lock); + err =regmap_update_bits (hw->regmap, addr, mask, val); +mutex_unlock (&hw->page_lock); + +return err; +} + +static inline int +st_lsm6dsx_read_locked (struct st_lsm6dsx_hw *hw,unsigned int addr, +void *val,unsigned int len) +{ +int err; + +mutex_lock (&hw->page_lock); + err =regmap_bulk_read (hw->regmap, addr, val, len); +mutex_unlock (&hw->page_lock); + +return err; +} + +static inline int +st_lsm6dsx_write_locked (struct st_lsm6dsx_hw *hw,unsigned int addr, +unsigned int val) +{ +int err; + +mutex_lock (&hw->page_lock); + err =regmap_write (hw->regmap, addr, val); +mutex_unlock (&hw->page_lock); + +return err; +} +#endif /* ST_LSM6DSX_H */
drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_buffer.c +34 -29
130 lines not on this page · raw message
drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c +15 -9
@@ -421,6 +421,7 @@ static int st_lsm6dsx_set_full_scale(struct st_lsm6dsx_sensor *sensor, {struct st_lsm6dsx_hw *hw = sensor->hw;const struct st_lsm6dsx_reg *reg; +unsigned int data;int i, err;u8 val;
@@ -433,8 +434,8 @@ static int st_lsm6dsx_set_full_scale(struct st_lsm6dsx_sensor *sensor, val = st_lsm6dsx_fs_table[sensor->id].fs_avl[i].val; reg = &st_lsm6dsx_fs_table[sensor->id].reg; - err =regmap_update_bits (hw->regmap, reg->addr, reg->mask, -ST_LSM6DSX_SHIFT_VAL (val, reg->mask)); + data =ST_LSM6DSX_SHIFT_VAL (val, reg->mask); + err =st_lsm6dsx_update_bits_locked (hw, reg->addr, reg->mask, data);if (err <0 )return err;
@@ -463,6 +464,7 @@ static int st_lsm6dsx_set_odr(struct st_lsm6dsx_sensor *sensor, u16 odr) {struct st_lsm6dsx_hw *hw = sensor->hw;const struct st_lsm6dsx_reg *reg; +unsigned int data;int err;u8 val;
@@ -471,8 +473,8 @@ static int st_lsm6dsx_set_odr(struct st_lsm6dsx_sensor *sensor, u16 odr)return err; reg = &st_lsm6dsx_odr_table[sensor->id].reg; -return regmap_update_bits (hw->regmap, reg->addr, reg->mask, -ST_LSM6DSX_SHIFT_VAL (val, reg->mask)); + data =ST_LSM6DSX_SHIFT_VAL (val, reg->mask); +return st_lsm6dsx_update_bits_locked (hw, reg->addr, reg->mask, data); }int st_lsm6dsx_sensor_enable (struct st_lsm6dsx_sensor *sensor)
@@ -492,11 +494,12 @@ int st_lsm6dsx_sensor_disable(struct st_lsm6dsx_sensor *sensor) {struct st_lsm6dsx_hw *hw = sensor->hw;const struct st_lsm6dsx_reg *reg; +unsigned int data;int err; reg = &st_lsm6dsx_odr_table[sensor->id].reg; - err =regmap_update_bits (hw->regmap, reg->addr, reg->mask, -ST_LSM6DSX_SHIFT_VAL (0 , reg->mask)); + data =ST_LSM6DSX_SHIFT_VAL (0 , reg->mask); + err =st_lsm6dsx_update_bits_locked (hw, reg->addr, reg->mask, data);if (err <0 )return err;
@@ -519,7 +522,7 @@ static int st_lsm6dsx_read_oneshot(struct st_lsm6dsx_sensor *sensor, delay =1000000 / sensor->odr;usleep_range (delay,2 * delay); - err =regmap_bulk_read (hw->regmap, addr, &data,sizeof (data)); + err =st_lsm6dsx_read_locked (hw, addr, &data,sizeof (data));if (err <0 )return err;
@@ -865,6 +868,7 @@ int st_lsm6dsx_probe(struct device *dev, int irq, int hw_id, const char *name,mutex_init (&hw->fifo_lock);mutex_init (&hw->conf_lock); +mutex_init (&hw->page_lock); hw->buff =devm_kzalloc (dev,ST_LSM6DSX_BUFF_SIZE ,GFP_KERNEL );if (!hw->buff)
@@ -909,6 +913,7 @@ static int __maybe_unused st_lsm6dsx_suspend(struct device *dev)struct st_lsm6dsx_hw *hw =dev_get_drvdata (dev);struct st_lsm6dsx_sensor *sensor;const struct st_lsm6dsx_reg *reg; +unsigned int data;int i, err =0 ;for (i =0 ; i <ST_LSM6DSX_ID_MAX ; i++) {
@@ -917,8 +922,9 @@ static int __maybe_unused st_lsm6dsx_suspend(struct device *dev)continue ; reg = &st_lsm6dsx_odr_table[sensor->id].reg; - err =regmap_update_bits (hw->regmap, reg->addr, reg->mask, -ST_LSM6DSX_SHIFT_VAL (0 , reg->mask)); + data =ST_LSM6DSX_SHIFT_VAL (0 , reg->mask); + err =st_lsm6dsx_update_bits_locked (hw, reg->addr, reg->mask, + data);if (err <0 )return err; }
Signature · 1 line
2.19.1
Jonathan Cameron
maintainerRe: [PATCH v2 1/9] iio: imu: st_lsm6dsx: introduce locked read/write utility routines
Quoted 7 lines · On Sun, 11 Nov 2018 15:15:28 +0100 Lorenzo Bianconi…
Add
st_lsm6dsx_update_bits_locked,st_lsm6dsx_read_lockedandst_lsm6dsx_write_lockedutility routines in order to guarantee the bus access is atomic respect to reg page configuration. This is a preliminary patch to add i2c sensor hub support since i2c master registers are accessed through a reg page multiplexerSigned-off-by Lorenzo Bianconi <[email protected]>
Applied to the togreg branch of iio.git and pushed out as testing for the autobuilders to play with it.
Thanks,
Jonathan
Quoted 307 lines
--- drivers/iio/imu/st_lsm6dsx/st_lsm6dsx.h | 41 ++++++++++++ .../iio/imu/st_lsm6dsx/st_lsm6dsx_buffer.c | 63 ++++++++++--------- drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c | 24 ++++--- 3 files changed, 90 insertions(+), 38 deletions(-)drivers/iio/imu/st_lsm6dsx/st_lsm6dsx.h +41
-0@@ -148,6 +148,7 @@ struct st_lsm6dsx_sensor {* @irq: Device interrupt line (I2C or SPI). * @fifo_lock: Mutex to prevent concurrent access to the hw FIFO. * @conf_lock: Mutex to prevent concurrent FIFO configuration update. +* @page_lock: Mutex to prevent concurrent memory page configuration. * @fifo_mode: FIFO operating mode supported by the device. * @enable_mask: Enabled sensor bitmask. * @ts_sip: Total number of timestamp samples in a given pattern. @@ -163,6 +164,7 @@ struct st_lsm6dsx_hw {struct mutex fifo_lock;struct mutex conf_lock; +struct mutex page_lock;enum st_lsm6dsx_fifo_mode fifo_mode;u8 enable_mask;@@ -192,4 +194,43 @@ int st_lsm6dsx_read_fifo(struct st_lsm6dsx_hw *hw);int st_lsm6dsx_read_tagged_fifo (struct st_lsm6dsx_hw *hw);int st_lsm6dsx_check_odr (struct st_lsm6dsx_sensor *sensor,u16 odr,u8 *val); +static inline int +st_lsm6dsx_update_bits_locked (struct st_lsm6dsx_hw *hw,unsigned int addr, +unsigned int mask,unsigned int val) +{ +int err; + +mutex_lock (&hw->page_lock); + err =regmap_update_bits (hw->regmap, addr, mask, val); +mutex_unlock (&hw->page_lock); + +return err; +} + +static inline int +st_lsm6dsx_read_locked (struct st_lsm6dsx_hw *hw,unsigned int addr, +void *val,unsigned int len) +{ +int err; + +mutex_lock (&hw->page_lock); + err =regmap_bulk_read (hw->regmap, addr, val, len); +mutex_unlock (&hw->page_lock); + +return err; +} + +static inline int +st_lsm6dsx_write_locked (struct st_lsm6dsx_hw *hw,unsigned int addr, +unsigned int val) +{ +int err; + +mutex_lock (&hw->page_lock); + err =regmap_write (hw->regmap, addr, val); +mutex_unlock (&hw->page_lock); + +return err; +} +#endif /* ST_LSM6DSX_H */ drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_buffer.c +34
-29@@ -142,8 +142,9 @@ static int st_lsm6dsx_update_decimators(struct st_lsm6dsx_hw *hw)if (dec_reg->addr) {int val =ST_LSM6DSX_SHIFT_VAL (data, dec_reg->mask); - err =regmap_update_bits (hw->regmap, dec_reg->addr, - dec_reg->mask, val); + err =st_lsm6dsx_update_bits_locked (hw, dec_reg->addr, + dec_reg->mask, + val);if (err <0 )return err; }@@ -162,8 +163,8 @@ static int st_lsm6dsx_update_decimators(struct st_lsm6dsx_hw *hw)int val, ts_dec = !!hw->ts_sip; val =ST_LSM6DSX_SHIFT_VAL (ts_dec, ts_dec_reg->mask); - err =regmap_update_bits (hw->regmap, ts_dec_reg->addr, - ts_dec_reg->mask, val); + err =st_lsm6dsx_update_bits_locked (hw, ts_dec_reg->addr, + ts_dec_reg->mask, val); }return err; }@@ -171,12 +172,12 @@ static int st_lsm6dsx_update_decimators(struct st_lsm6dsx_hw *hw)int st_lsm6dsx_set_fifo_mode (struct st_lsm6dsx_hw *hw,enum st_lsm6dsx_fifo_mode fifo_mode) { +unsigned int data;int err; - err =regmap_update_bits (hw->regmap,ST_LSM6DSX_REG_FIFO_MODE_ADDR , -ST_LSM6DSX_FIFO_MODE_MASK , -FIELD_PREP (ST_LSM6DSX_FIFO_MODE_MASK , - fifo_mode)); + data =FIELD_PREP (ST_LSM6DSX_FIFO_MODE_MASK , fifo_mode); + err =st_lsm6dsx_update_bits_locked (hw,ST_LSM6DSX_REG_FIFO_MODE_ADDR , +ST_LSM6DSX_FIFO_MODE_MASK , data);if (err <0 )return err;@@ -207,15 +208,15 @@ static int st_lsm6dsx_set_fifo_odr(struct st_lsm6dsx_sensor *sensor, data =0 ; } val =ST_LSM6DSX_SHIFT_VAL (data, batch_reg->mask); -return regmap_update_bits (hw->regmap, batch_reg->addr, - batch_reg->mask, val); +return st_lsm6dsx_update_bits_locked (hw, batch_reg->addr, + batch_reg->mask, val); }else { data = hw->enable_mask ?ST_LSM6DSX_MAX_FIFO_ODR_VAL :0 ; -return regmap_update_bits (hw->regmap, -ST_LSM6DSX_REG_FIFO_MODE_ADDR , -ST_LSM6DSX_FIFO_ODR_MASK , -FIELD_PREP (ST_LSM6DSX_FIFO_ODR_MASK , - data)); +return st_lsm6dsx_update_bits_locked (hw, +ST_LSM6DSX_REG_FIFO_MODE_ADDR , +ST_LSM6DSX_FIFO_ODR_MASK , +FIELD_PREP (ST_LSM6DSX_FIFO_ODR_MASK , + data)); } }@@ -246,19 +247,23 @@ int st_lsm6dsx_update_watermark(struct st_lsm6dsx_sensor *sensor, u16 watermark) fifo_watermark = (fifo_watermark / hw->sip) * hw->sip; fifo_watermark = fifo_watermark * hw->settings->fifo_ops.th_wl; +mutex_lock (&hw->page_lock); err =regmap_read (hw->regmap, hw->settings->fifo_ops.fifo_th.addr +1 , &data);if (err <0 ) -return err; + goto out; fifo_th_mask = hw->settings->fifo_ops.fifo_th.mask; fifo_watermark = ((data <<8 ) & ~fifo_th_mask) | (fifo_watermark & fifo_th_mask); wdata =cpu_to_le16 (fifo_watermark); -return regmap_bulk_write (hw->regmap, - hw->settings->fifo_ops.fifo_th.addr, - &wdata,sizeof (wdata)); + err =regmap_bulk_write (hw->regmap, + hw->settings->fifo_ops.fifo_th.addr, + &wdata,sizeof (wdata)); +out: +mutex_unlock (&hw->page_lock); +return err; }static int st_lsm6dsx_reset_hw_ts (struct st_lsm6dsx_hw *hw)@@ -267,8 +272,8 @@ static int st_lsm6dsx_reset_hw_ts(struct st_lsm6dsx_hw *hw)int i, err;/* reset hw ts counter */ - err =regmap_write (hw->regmap,ST_LSM6DSX_REG_TS_RESET_ADDR , -ST_LSM6DSX_TS_RESET_VAL ); + err =st_lsm6dsx_write_locked (hw,ST_LSM6DSX_REG_TS_RESET_ADDR , +ST_LSM6DSX_TS_RESET_VAL );if (err <0 )return err;@@ -297,8 +302,8 @@ static inline int st_lsm6dsx_read_block(struct st_lsm6dsx_hw *hw, u8 addr,while (read_len < data_len) { word_len = min_t(unsigned int, data_len - read_len, max_word_len); - err =regmap_bulk_read (hw->regmap, addr, data + read_len, - word_len); + err =st_lsm6dsx_read_locked (hw, addr, data + read_len, + word_len);if (err <0 )return err; read_len += word_len;@@ -328,9 +333,9 @@ int st_lsm6dsx_read_fifo(struct st_lsm6dsx_hw *hw)__le16 fifo_status;s64 ts =0 ; - err =regmap_bulk_read (hw->regmap, - hw->settings->fifo_ops.fifo_diff.addr, - &fifo_status,sizeof (fifo_status)); + err =st_lsm6dsx_read_locked (hw, + hw->settings->fifo_ops.fifo_diff.addr, + &fifo_status,sizeof (fifo_status));if (err <0 ) {dev_err (hw->dev,"failed to read fifo status (err=%d)\n" , err);@@ -455,9 +460,9 @@ int st_lsm6dsx_read_tagged_fifo(struct st_lsm6dsx_hw *hw)__le16 fifo_status;s64 ts =0 ; - err =regmap_bulk_read (hw->regmap, - hw->settings->fifo_ops.fifo_diff.addr, - &fifo_status,sizeof (fifo_status)); + err =st_lsm6dsx_read_locked (hw, + hw->settings->fifo_ops.fifo_diff.addr, + &fifo_status,sizeof (fifo_status));if (err <0 ) {dev_err (hw->dev,"failed to read fifo status (err=%d)\n" , err);drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c +15
-9@@ -421,6 +421,7 @@ static int st_lsm6dsx_set_full_scale(struct st_lsm6dsx_sensor *sensor, {struct st_lsm6dsx_hw *hw = sensor->hw;const struct st_lsm6dsx_reg *reg; +unsigned int data;int i, err;u8 val;@@ -433,8 +434,8 @@ static int st_lsm6dsx_set_full_scale(struct st_lsm6dsx_sensor *sensor, val = st_lsm6dsx_fs_table[sensor->id].fs_avl[i].val; reg = &st_lsm6dsx_fs_table[sensor->id].reg; - err =regmap_update_bits (hw->regmap, reg->addr, reg->mask, -ST_LSM6DSX_SHIFT_VAL (val, reg->mask)); + data =ST_LSM6DSX_SHIFT_VAL (val, reg->mask); + err =st_lsm6dsx_update_bits_locked (hw, reg->addr, reg->mask, data);if (err <0 )return err;@@ -463,6 +464,7 @@ static int st_lsm6dsx_set_odr(struct st_lsm6dsx_sensor *sensor, u16 odr) {struct st_lsm6dsx_hw *hw = sensor->hw;const struct st_lsm6dsx_reg *reg; +unsigned int data;int err;u8 val;@@ -471,8 +473,8 @@ static int st_lsm6dsx_set_odr(struct st_lsm6dsx_sensor *sensor, u16 odr)return err; reg = &st_lsm6dsx_odr_table[sensor->id].reg; -return regmap_update_bits (hw->regmap, reg->addr, reg->mask, -ST_LSM6DSX_SHIFT_VAL (val, reg->mask)); + data =ST_LSM6DSX_SHIFT_VAL (val, reg->mask); +return st_lsm6dsx_update_bits_locked (hw, reg->addr, reg->mask, data); }int st_lsm6dsx_sensor_enable (struct st_lsm6dsx_sensor *sensor)@@ -492,11 +494,12 @@ int st_lsm6dsx_sensor_disable(struct st_lsm6dsx_sensor *sensor) {struct st_lsm6dsx_hw *hw = sensor->hw;const struct st_lsm6dsx_reg *reg; +unsigned int data;int err; reg = &st_lsm6dsx_odr_table[sensor->id].reg; - err =regmap_update_bits (hw->regmap, reg->addr, reg->mask, -ST_LSM6DSX_SHIFT_VAL (0 , reg->mask)); + data =ST_LSM6DSX_SHIFT_VAL (0 , reg->mask); + err =st_lsm6dsx_update_bits_locked (hw, reg->addr, reg->mask, data);if (err <0 )return err;@@ -519,7 +522,7 @@ static int st_lsm6dsx_read_oneshot(struct st_lsm6dsx_sensor *sensor, delay =1000000 / sensor->odr;usleep_range (delay,2 * delay); - err =regmap_bulk_read (hw->regmap, addr, &data,sizeof (data)); + err =st_lsm6dsx_read_locked (hw, addr, &data,sizeof (data));if (err <0 )return err;@@ -865,6 +868,7 @@ int st_lsm6dsx_probe(struct device *dev, int irq, int hw_id, const char *name,mutex_init (&hw->fifo_lock);mutex_init (&hw->conf_lock); +mutex_init (&hw->page_lock); hw->buff =devm_kzalloc (dev,ST_LSM6DSX_BUFF_SIZE ,GFP_KERNEL );if (!hw->buff)@@ -909,6 +913,7 @@ static int __maybe_unused st_lsm6dsx_suspend(struct device *dev)struct st_lsm6dsx_hw *hw =dev_get_drvdata (dev);struct st_lsm6dsx_sensor *sensor;const struct st_lsm6dsx_reg *reg; +unsigned int data;int i, err =0 ;for (i =0 ; i <ST_LSM6DSX_ID_MAX ; i++) {@@ -917,8 +922,9 @@ static int __maybe_unused st_lsm6dsx_suspend(struct device *dev)continue ; reg = &st_lsm6dsx_odr_table[sensor->id].reg; - err =regmap_update_bits (hw->regmap, reg->addr, reg->mask, -ST_LSM6DSX_SHIFT_VAL (0 , reg->mask)); + data =ST_LSM6DSX_SHIFT_VAL (0 , reg->mask); + err =st_lsm6dsx_update_bits_locked (hw, reg->addr, reg->mask, + data);if (err <0 )return err; }
PATCH v2 2/9 iio: imu: st_lsm6dsx: reload trimming parameter at bootstrap
In reply to Lorenzo BianconiPerform a complete device reset at bootstrap reloading trimming parameter after sw reset is completed. Device sw reset/boot is explained here:
https://www.st.com/resource/en/application_note/dm00517282.pdf,
section 5.7
--- drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-)
drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c +15 -3
@@ -56,6 +56,7 @@#define ST_LSM6DSX_REG_WHOAMI_ADDR 0x0f#define ST_LSM6DSX_REG_RESET_ADDR 0x12#define ST_LSM6DSX_REG_RESET_MASK BIT(0) +#define ST_LSM6DSX_REG_BOOT_MASK BIT(7)#define ST_LSM6DSX_REG_BDU_ADDR 0x12#define ST_LSM6DSX_REG_BDU_MASK BIT(6)#define ST_LSM6DSX_REG_INT2_ON_INT1_ADDR 0x13
@@ -778,12 +779,23 @@ static int st_lsm6dsx_init_device(struct st_lsm6dsx_hw *hw)u8 drdy_int_reg;int err; - err =regmap_write (hw->regmap,ST_LSM6DSX_REG_RESET_ADDR , -ST_LSM6DSX_REG_RESET_MASK ); +/* device sw reset */ + err =regmap_update_bits (hw->regmap,ST_LSM6DSX_REG_RESET_ADDR , +ST_LSM6DSX_REG_RESET_MASK , +FIELD_PREP (ST_LSM6DSX_REG_RESET_MASK ,1 ));if (err <0 )return err; -msleep (200 ); +msleep (50 ); + +/* reload trimming parameter */ + err =regmap_update_bits (hw->regmap,ST_LSM6DSX_REG_RESET_ADDR , +ST_LSM6DSX_REG_BOOT_MASK , +FIELD_PREP (ST_LSM6DSX_REG_BOOT_MASK ,1 )); +if (err <0 ) +return err; + +msleep (50 );/* enable Block Data Update */ err = regmap_update_bits(hw->regmap, ST_LSM6DSX_REG_BDU_ADDR,
Signature · 1 line
2.19.1
Jonathan Cameron
maintainerRe: [PATCH v2 2/9] iio: imu: st_lsm6dsx: reload trimming parameter at bootstrap
Quoted 6 lines · On Sun, 11 Nov 2018 15:15:29 +0100 Lorenzo Bianconi…
Perform a complete device reset at bootstrap reloading trimming parameter after sw reset is completed. Device sw reset/boot is explained here:
https://www.st.com/resource/en/application_note/dm00517282.pdf,
section 5.7Signed-off-by Lorenzo Bianconi <[email protected]>
Applied to the togreg branch of iio.git and pushed out as testing for the autobuilders to play with it.
Thanks,
Jonathan
Quoted 43 lines
--- drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-)drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c +15
-3@@ -56,6 +56,7 @@#define ST_LSM6DSX_REG_WHOAMI_ADDR 0x0f#define ST_LSM6DSX_REG_RESET_ADDR 0x12#define ST_LSM6DSX_REG_RESET_MASK BIT(0) +#define ST_LSM6DSX_REG_BOOT_MASK BIT(7)#define ST_LSM6DSX_REG_BDU_ADDR 0x12#define ST_LSM6DSX_REG_BDU_MASK BIT(6)#define ST_LSM6DSX_REG_INT2_ON_INT1_ADDR 0x13@@ -778,12 +779,23 @@ static int st_lsm6dsx_init_device(struct st_lsm6dsx_hw *hw)u8 drdy_int_reg;int err; - err =regmap_write (hw->regmap,ST_LSM6DSX_REG_RESET_ADDR , -ST_LSM6DSX_REG_RESET_MASK ); +/* device sw reset */ + err =regmap_update_bits (hw->regmap,ST_LSM6DSX_REG_RESET_ADDR , +ST_LSM6DSX_REG_RESET_MASK , +FIELD_PREP (ST_LSM6DSX_REG_RESET_MASK ,1 ));if (err <0 )return err; -msleep (200 ); +msleep (50 ); + +/* reload trimming parameter */ + err =regmap_update_bits (hw->regmap,ST_LSM6DSX_REG_RESET_ADDR , +ST_LSM6DSX_REG_BOOT_MASK , +FIELD_PREP (ST_LSM6DSX_REG_BOOT_MASK ,1 )); +if (err <0 ) +return err; + +msleep (50 );/* enable Block Data Update */ err = regmap_update_bits(hw->regmap, ST_LSM6DSX_REG_BDU_ADDR,
PATCH v2 3/9 iio: imu: st_lsm6dsx: remove static from st_lsm6dsx_set_watermark
In reply to Lorenzo BianconiRemove static qualifier from st_lsm6dsx_set_watermark routine in order to be reused supporting st_lsm6dsx i2c controller
--- drivers/iio/imu/st_lsm6dsx/st_lsm6dsx.h | 1 + drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-)
drivers/iio/imu/st_lsm6dsx/st_lsm6dsx.h +1 -0
@@ -185,6 +185,7 @@ int st_lsm6dsx_probe(struct device *dev, int irq, int hw_id, const char *name,int st_lsm6dsx_sensor_enable (struct st_lsm6dsx_sensor *sensor);int st_lsm6dsx_sensor_disable (struct st_lsm6dsx_sensor *sensor);int st_lsm6dsx_fifo_setup (struct st_lsm6dsx_hw *hw); +int st_lsm6dsx_set_watermark (struct iio_dev *iio_dev,unsigned int val);int st_lsm6dsx_update_watermark (struct st_lsm6dsx_sensor *sensor,u16 watermark);int st_lsm6dsx_flush_fifo (struct st_lsm6dsx_hw *hw);
drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c +1 -1
@@ -600,7 +600,7 @@ static int st_lsm6dsx_write_raw(struct iio_dev *iio_dev,return err; } -static int st_lsm6dsx_set_watermark (struct iio_dev *iio_dev,unsigned int val) +int st_lsm6dsx_set_watermark (struct iio_dev *iio_dev,unsigned int val) {struct st_lsm6dsx_sensor *sensor =iio_priv (iio_dev);struct st_lsm6dsx_hw *hw = sensor->hw;
Signature · 1 line
2.19.1
Re: [PATCH v2 3/9] iio: imu: st_lsm6dsx: remove static from st_lsm6dsx_set_watermark
Quoted 4 lines · On Sun, 11 Nov 2018 15:15:30 +0100 Lorenzo Bianconi…
Remove static qualifier from
st_lsm6dsx_set_watermarkroutine in order to be reused supportingst_lsm6dsxi2c controllerSigned-off-by Lorenzo Bianconi <[email protected]>
Applied. This one might have been taking the one thing one patch rule a little far ;)
Does no real harm though.
Thanks,
Jonathan
Quoted 30 lines
--- drivers/iio/imu/st_lsm6dsx/st_lsm6dsx.h | 1 + drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-)drivers/iio/imu/st_lsm6dsx/st_lsm6dsx.h +1
-0@@ -185,6 +185,7 @@ int st_lsm6dsx_probe(struct device *dev, int irq, int hw_id, const char *name,int st_lsm6dsx_sensor_enable (struct st_lsm6dsx_sensor *sensor);int st_lsm6dsx_sensor_disable (struct st_lsm6dsx_sensor *sensor);int st_lsm6dsx_fifo_setup (struct st_lsm6dsx_hw *hw); +int st_lsm6dsx_set_watermark (struct iio_dev *iio_dev,unsigned int val);int st_lsm6dsx_update_watermark (struct st_lsm6dsx_sensor *sensor,u16 watermark);int st_lsm6dsx_flush_fifo (struct st_lsm6dsx_hw *hw);drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c +1
-1@@ -600,7 +600,7 @@ static int st_lsm6dsx_write_raw(struct iio_dev *iio_dev,return err; } -static int st_lsm6dsx_set_watermark (struct iio_dev *iio_dev,unsigned int val) +int st_lsm6dsx_set_watermark (struct iio_dev *iio_dev,unsigned int val) {struct st_lsm6dsx_sensor *sensor =iio_priv (iio_dev);struct st_lsm6dsx_hw *hw = sensor->hw;
PATCH v2 4/9 iio: imu: st_lsm6dsx: introduce ST_LSM6DSX_ID_EXT sensor ids
In reply to Lorenzo BianconiAdd ST_LSM6DSX_ID_EXT{0,1,2} sensor ids as reference for slave devices connected to st_lsm6dsx i2c controller. Moreover introduce odr dependency between accel and ext devices since i2c embedded controller relies on the accelerometer sensor as bus read/write trigger so we need to enable accel device at odr = max(accel_odr, ext_odr) in order to properly communicate with i2c slave devices
--- drivers/iio/imu/st_lsm6dsx/st_lsm6dsx.h | 5 +- .../iio/imu/st_lsm6dsx/st_lsm6dsx_buffer.c | 15 ++++ drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c | 77 +++++++++++++++++-- 3 files changed, 88 insertions(+), 9 deletions(-)
drivers/iio/imu/st_lsm6dsx/st_lsm6dsx.h +4 -1
@@ -105,8 +105,11 @@ struct st_lsm6dsx_settings { };enum st_lsm6dsx_sensor_id { -ST_LSM6DSX_ID_ACC ,ST_LSM6DSX_ID_GYRO , +ST_LSM6DSX_ID_ACC , +ST_LSM6DSX_ID_EXT0 , +ST_LSM6DSX_ID_EXT1 , +ST_LSM6DSX_ID_EXT2 ,ST_LSM6DSX_ID_MAX , };
drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_buffer.c +15 -0
@@ -102,6 +102,9 @@ static void st_lsm6dsx_get_max_min_odr(struct st_lsm6dsx_hw *hw, *max_odr =0 , *min_odr = ~0 ;for (i =0 ; i <ST_LSM6DSX_ID_MAX ; i++) { +if (!hw->iio_devs[i]) +continue ; + sensor =iio_priv (hw->iio_devs[i]);if (!(hw->enable_mask &BIT (sensor->id)))
@@ -125,6 +128,9 @@ static int st_lsm6dsx_update_decimators(struct st_lsm6dsx_hw *hw)for (i =0 ; i <ST_LSM6DSX_ID_MAX ; i++) {const struct st_lsm6dsx_reg *dec_reg; +if (!hw->iio_devs[i]) +continue ; + sensor =iio_priv (hw->iio_devs[i]);/* update fifo decimators and sample in pattern */ if (hw->enable_mask &BIT (sensor->id)) {
@@ -232,6 +238,9 @@ int st_lsm6dsx_update_watermark(struct st_lsm6dsx_sensor *sensor, u16 watermark)return 0 ;for (i =0 ; i <ST_LSM6DSX_ID_MAX ; i++) { +if (!hw->iio_devs[i]) +continue ; + cur_sensor =iio_priv (hw->iio_devs[i]);if (!(hw->enable_mask &BIT (cur_sensor->id)))
@@ -278,6 +287,9 @@ static int st_lsm6dsx_reset_hw_ts(struct st_lsm6dsx_hw *hw)return err;for (i =0 ; i <ST_LSM6DSX_ID_MAX ; i++) { +if (!hw->iio_devs[i]) +continue ; + sensor =iio_priv (hw->iio_devs[i]);/* * store enable buffer timestamp as reference for
@@ -695,6 +707,9 @@ int st_lsm6dsx_fifo_setup(struct st_lsm6dsx_hw *hw) }for (i =0 ; i <ST_LSM6DSX_ID_MAX ; i++) { +if (!hw->iio_devs[i]) +continue ; + buffer =devm_iio_kfifo_allocate (hw->dev);if (!buffer)return -ENOMEM ;
drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c +69 -8
120 lines not on this page · raw message
Signature · 1 line
2.19.1
Jonathan Cameron
maintainerRe: [PATCH v2 4/9] iio: imu: st_lsm6dsx: introduce ST_LSM6DSX_ID_EXT sensor ids
Quoted 8 lines · On Sun, 11 Nov 2018 15:15:31 +0100 Lorenzo Bianconi…
Add ST_LSM6DSX_ID_EXT{0,1,2} sensor ids as reference for slave devices connected to
st_lsm6dsxi2c controller. Moreover introduce odr dependency between accel and ext devices since i2c embedded controller relies on the accelerometer sensor as bus read/write trigger so we need to enable accel device at odr =max(accel_odr, ext_odr)in order to properly communicate with i2c slave devicesSigned-off-by Lorenzo Bianconi <[email protected]>
Applied to the togreg branch of iio.git and pushed out as testing for the autobuilders to play with it.
Thanks,
Jonathan
Quoted 207 lines
--- drivers/iio/imu/st_lsm6dsx/st_lsm6dsx.h | 5 +- .../iio/imu/st_lsm6dsx/st_lsm6dsx_buffer.c | 15 ++++ drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c | 77 +++++++++++++++++-- 3 files changed, 88 insertions(+), 9 deletions(-)drivers/iio/imu/st_lsm6dsx/st_lsm6dsx.h +4
-1@@ -105,8 +105,11 @@ struct st_lsm6dsx_settings { };enum st_lsm6dsx_sensor_id { -ST_LSM6DSX_ID_ACC ,ST_LSM6DSX_ID_GYRO , +ST_LSM6DSX_ID_ACC , +ST_LSM6DSX_ID_EXT0 , +ST_LSM6DSX_ID_EXT1 , +ST_LSM6DSX_ID_EXT2 ,ST_LSM6DSX_ID_MAX , };drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_buffer.c +15
-0@@ -102,6 +102,9 @@ static void st_lsm6dsx_get_max_min_odr(struct st_lsm6dsx_hw *hw, *max_odr =0 , *min_odr = ~0 ;for (i =0 ; i <ST_LSM6DSX_ID_MAX ; i++) { +if (!hw->iio_devs[i]) +continue ; + sensor =iio_priv (hw->iio_devs[i]);if (!(hw->enable_mask &BIT (sensor->id)))@@ -125,6 +128,9 @@ static int st_lsm6dsx_update_decimators(struct st_lsm6dsx_hw *hw)for (i =0 ; i <ST_LSM6DSX_ID_MAX ; i++) {const struct st_lsm6dsx_reg *dec_reg; +if (!hw->iio_devs[i]) +continue ; + sensor =iio_priv (hw->iio_devs[i]);/* update fifo decimators and sample in pattern */ if (hw->enable_mask &BIT (sensor->id)) {@@ -232,6 +238,9 @@ int st_lsm6dsx_update_watermark(struct st_lsm6dsx_sensor *sensor, u16 watermark)return 0 ;for (i =0 ; i <ST_LSM6DSX_ID_MAX ; i++) { +if (!hw->iio_devs[i]) +continue ; + cur_sensor =iio_priv (hw->iio_devs[i]);if (!(hw->enable_mask &BIT (cur_sensor->id)))@@ -278,6 +287,9 @@ static int st_lsm6dsx_reset_hw_ts(struct st_lsm6dsx_hw *hw)return err;for (i =0 ; i <ST_LSM6DSX_ID_MAX ; i++) { +if (!hw->iio_devs[i]) +continue ; + sensor =iio_priv (hw->iio_devs[i]);/* * store enable buffer timestamp as reference for @@ -695,6 +707,9 @@ int st_lsm6dsx_fifo_setup(struct st_lsm6dsx_hw *hw) }for (i =0 ; i <ST_LSM6DSX_ID_MAX ; i++) { +if (!hw->iio_devs[i]) +continue ; + buffer =devm_iio_kfifo_allocate (hw->dev);if (!buffer)return -ENOMEM ;drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c +69
-8@@ -450,7 +450,11 @@ int st_lsm6dsx_check_odr(struct st_lsm6dsx_sensor *sensor, u16 odr, u8 *val)int i;for (i =0 ; i <ST_LSM6DSX_ODR_LIST_SIZE ; i++) -if (st_lsm6dsx_odr_table[sensor->id].odr_avl[i].hz == odr) +/* +* ext devices can run at different odr respect to +* accel sensor +*/ +if (st_lsm6dsx_odr_table[sensor->id].odr_avl[i].hz >= odr)break ;if (i ==ST_LSM6DSX_ODR_LIST_SIZE )@@ -461,19 +465,67 @@ int st_lsm6dsx_check_odr(struct st_lsm6dsx_sensor *sensor, u16 odr, u8 *val)return 0 ; } -static int st_lsm6dsx_set_odr (struct st_lsm6dsx_sensor *sensor,u16 odr) +static u16 st_lsm6dsx_check_odr_dependency (struct st_lsm6dsx_hw *hw,u16 odr, +enum st_lsm6dsx_sensor_id id) { +struct st_lsm6dsx_sensor *ref =iio_priv (hw->iio_devs[id]); + +if (odr >0 ) { +if (hw->enable_mask &BIT (id)) +return max_t (u16, ref->odr, odr); +else +return odr; + }else { +return (hw->enable_mask &BIT (id)) ? ref->odr :0 ; + } +} + +static int st_lsm6dsx_set_odr (struct st_lsm6dsx_sensor *sensor,u16 req_odr) +{ +struct st_lsm6dsx_sensor *ref_sensor = sensor;struct st_lsm6dsx_hw *hw = sensor->hw;const struct st_lsm6dsx_reg *reg;unsigned int data; +u8 val =0 ;int err; -u8 val; - err =st_lsm6dsx_check_odr (sensor, odr, &val); -if (err <0 ) -return err; +switch (sensor->id) { +case ST_LSM6DSX_ID_EXT0 : +case ST_LSM6DSX_ID_EXT1 : +case ST_LSM6DSX_ID_EXT2 : +case ST_LSM6DSX_ID_ACC : { +u16 odr; +int i; + +/* +* i2c embedded controller relies on the accelerometer sensor as +* bus read/write trigger so we need to enable accel device +* at odr = max(accel_odr, ext_odr) in order to properly +* communicate with i2c slave devices +*/ + ref_sensor =iio_priv (hw->iio_devs[ST_LSM6DSX_ID_ACC ]); +for (i =ST_LSM6DSX_ID_ACC ; i <ST_LSM6DSX_ID_MAX ; i++) { +if (!hw->iio_devs[i] || i == sensor->id) +continue ; + + odr =st_lsm6dsx_check_odr_dependency (hw, req_odr, i); +if (odr != req_odr) +/* device already configured */ +return 0 ; + } +break ; + } +default : +break ; + } - reg = &st_lsm6dsx_odr_table[sensor->id].reg; +if (req_odr >0 ) { + err =st_lsm6dsx_check_odr (ref_sensor, req_odr, &val); +if (err <0 ) +return err; + } + + reg = &st_lsm6dsx_odr_table[ref_sensor->id].reg; data =ST_LSM6DSX_SHIFT_VAL (val, reg->mask);return st_lsm6dsx_update_bits_locked (hw, reg->addr, reg->mask, data); }@@ -894,7 +946,7 @@ int st_lsm6dsx_probe(struct device *dev, int irq, int hw_id, const char *name,if (err <0 )return err; -for (i =0 ; i <ST_LSM6DSX_ID_MAX ; i++) { +for (i =0 ; i <ST_LSM6DSX_ID_EXT0 ; i++) { hw->iio_devs[i] =st_lsm6dsx_alloc_iiodev (hw, i, name);if (!hw->iio_devs[i])return -ENOMEM ;@@ -911,6 +963,9 @@ int st_lsm6dsx_probe(struct device *dev, int irq, int hw_id, const char *name, }for (i =0 ; i <ST_LSM6DSX_ID_MAX ; i++) { +if (!hw->iio_devs[i]) +continue ; + err =devm_iio_device_register (hw->dev, hw->iio_devs[i]);if (err)return err;@@ -929,6 +984,9 @@ static int __maybe_unused st_lsm6dsx_suspend(struct device *dev)int i, err =0 ;for (i =0 ; i <ST_LSM6DSX_ID_MAX ; i++) { +if (!hw->iio_devs[i]) +continue ; + sensor =iio_priv (hw->iio_devs[i]);if (!(hw->enable_mask &BIT (sensor->id)))continue ;@@ -954,6 +1012,9 @@ static int __maybe_unused st_lsm6dsx_resume(struct device *dev)int i, err =0 ;for (i =0 ; i <ST_LSM6DSX_ID_MAX ; i++) { +if (!hw->iio_devs[i]) +continue ; + sensor =iio_priv (hw->iio_devs[i]);if (!(hw->enable_mask &BIT (sensor->id)))continue ;
PATCH v2 5/9 iio: imu: st_lsm6dsx: introduce st_lsm6dsx_sensor_set_enable routine
In reply to Lorenzo BianconiAdd st_lsm6dsx_sensor_set_enable routine and remove st_lsm6dsx_sensor_{enable/disable} ones in order to make the code more readable and remove unnecessary functions
--- drivers/iio/imu/st_lsm6dsx/st_lsm6dsx.h | 4 +-- .../iio/imu/st_lsm6dsx/st_lsm6dsx_buffer.c | 12 ++----- drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c | 32 ++++++------------- 3 files changed, 15 insertions(+), 33 deletions(-)
drivers/iio/imu/st_lsm6dsx/st_lsm6dsx.h +2 -2
@@ -185,8 +185,8 @@ extern const struct dev_pm_ops st_lsm6dsx_pm_ops;int st_lsm6dsx_probe (struct device *dev,int irq,int hw_id,const char *name,struct regmap *regmap); -int st_lsm6dsx_sensor_enable (struct st_lsm6dsx_sensor *sensor); -int st_lsm6dsx_sensor_disable (struct st_lsm6dsx_sensor *sensor); +int st_lsm6dsx_sensor_set_enable (struct st_lsm6dsx_sensor *sensor, +bool enable);int st_lsm6dsx_fifo_setup (struct st_lsm6dsx_hw *hw);int st_lsm6dsx_set_watermark (struct iio_dev *iio_dev,unsigned int val); int st_lsm6dsx_update_watermark(struct st_lsm6dsx_sensor *sensor,
drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_buffer.c +3 -9
@@ -579,15 +579,9 @@ static int st_lsm6dsx_update_fifo(struct iio_dev *iio_dev, bool enable) goto out; } -if (enable) { - err =st_lsm6dsx_sensor_enable (sensor); -if (err <0 ) - goto out; - }else { - err =st_lsm6dsx_sensor_disable (sensor); -if (err <0 ) - goto out; - } + err =st_lsm6dsx_sensor_set_enable (sensor, enable); +if (err <0 ) + goto out; err =st_lsm6dsx_set_fifo_odr (sensor, enable);if (err <0 )
drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c +10 -22
@@ -530,33 +530,21 @@ static int st_lsm6dsx_set_odr(struct st_lsm6dsx_sensor *sensor, u16 req_odr)return st_lsm6dsx_update_bits_locked (hw, reg->addr, reg->mask, data); } -int st_lsm6dsx_sensor_enable (struct st_lsm6dsx_sensor *sensor) -{ -int err; - - err =st_lsm6dsx_set_odr (sensor, sensor->odr); -if (err <0 ) -return err; - - sensor->hw->enable_mask |=BIT (sensor->id); - -return 0 ; -} - -int st_lsm6dsx_sensor_disable (struct st_lsm6dsx_sensor *sensor) +int st_lsm6dsx_sensor_set_enable (struct st_lsm6dsx_sensor *sensor, +bool enable) {struct st_lsm6dsx_hw *hw = sensor->hw; -const struct st_lsm6dsx_reg *reg; -unsigned int data; +u16 odr = enable ? sensor->odr :0 ;int err; - reg = &st_lsm6dsx_odr_table[sensor->id].reg; - data =ST_LSM6DSX_SHIFT_VAL (0 , reg->mask); - err =st_lsm6dsx_update_bits_locked (hw, reg->addr, reg->mask, data); + err =st_lsm6dsx_set_odr (sensor, odr);if (err <0 )return err; - sensor->hw->enable_mask &= ~BIT (sensor->id); +if (enable) + hw->enable_mask |=BIT (sensor->id); +else + hw->enable_mask &= ~BIT (sensor->id);return 0 ; }
@@ -568,7 +556,7 @@ static int st_lsm6dsx_read_oneshot(struct st_lsm6dsx_sensor *sensor,int err, delay;__le16 data; - err =st_lsm6dsx_sensor_enable (sensor); + err =st_lsm6dsx_sensor_set_enable (sensor, true);if (err <0 )return err;
@@ -579,7 +567,7 @@ static int st_lsm6dsx_read_oneshot(struct st_lsm6dsx_sensor *sensor,if (err <0 )return err; -st_lsm6dsx_sensor_disable (sensor); +st_lsm6dsx_sensor_set_enable (sensor, false); *val = (s16 )le16_to_cpu (data);
Signature · 1 line
2.19.1
Jonathan Cameron
maintainerRe: [PATCH v2 5/9] iio: imu: st_lsm6dsx: introduce st_lsm6dsx_sensor_set_enable routine
Quoted 5 lines · On Sun, 11 Nov 2018 15:15:32 +0100 Lorenzo Bianconi…
Add
st_lsm6dsx_sensor_set_enableroutine and remove st_lsm6dsx_sensor_{enable/disable} ones in order to make the code more readable and remove unnecessary functionsSigned-off-by Lorenzo Bianconi <[email protected]>
Applied to the togreg branch of iio.git and pushed out as testing for the autobuilders to play with it.
Thanks,
Jonathan
Quoted 108 lines
--- drivers/iio/imu/st_lsm6dsx/st_lsm6dsx.h | 4 +-- .../iio/imu/st_lsm6dsx/st_lsm6dsx_buffer.c | 12 ++----- drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c | 32 ++++++------------- 3 files changed, 15 insertions(+), 33 deletions(-)drivers/iio/imu/st_lsm6dsx/st_lsm6dsx.h +2
-2@@ -185,8 +185,8 @@ extern const struct dev_pm_ops st_lsm6dsx_pm_ops;int st_lsm6dsx_probe (struct device *dev,int irq,int hw_id,const char *name,struct regmap *regmap); -int st_lsm6dsx_sensor_enable (struct st_lsm6dsx_sensor *sensor); -int st_lsm6dsx_sensor_disable (struct st_lsm6dsx_sensor *sensor); +int st_lsm6dsx_sensor_set_enable (struct st_lsm6dsx_sensor *sensor, +bool enable);int st_lsm6dsx_fifo_setup (struct st_lsm6dsx_hw *hw);int st_lsm6dsx_set_watermark (struct iio_dev *iio_dev,unsigned int val); int st_lsm6dsx_update_watermark(struct st_lsm6dsx_sensor *sensor,drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_buffer.c +3
-9@@ -579,15 +579,9 @@ static int st_lsm6dsx_update_fifo(struct iio_dev *iio_dev, bool enable) goto out; } -if (enable) { - err =st_lsm6dsx_sensor_enable (sensor); -if (err <0 ) - goto out; - }else { - err =st_lsm6dsx_sensor_disable (sensor); -if (err <0 ) - goto out; - } + err =st_lsm6dsx_sensor_set_enable (sensor, enable); +if (err <0 ) + goto out; err =st_lsm6dsx_set_fifo_odr (sensor, enable);if (err <0 )drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c +10
-22@@ -530,33 +530,21 @@ static int st_lsm6dsx_set_odr(struct st_lsm6dsx_sensor *sensor, u16 req_odr)return st_lsm6dsx_update_bits_locked (hw, reg->addr, reg->mask, data); } -int st_lsm6dsx_sensor_enable (struct st_lsm6dsx_sensor *sensor) -{ -int err; - - err =st_lsm6dsx_set_odr (sensor, sensor->odr); -if (err <0 ) -return err; - - sensor->hw->enable_mask |=BIT (sensor->id); - -return 0 ; -} - -int st_lsm6dsx_sensor_disable (struct st_lsm6dsx_sensor *sensor) +int st_lsm6dsx_sensor_set_enable (struct st_lsm6dsx_sensor *sensor, +bool enable) {struct st_lsm6dsx_hw *hw = sensor->hw; -const struct st_lsm6dsx_reg *reg; -unsigned int data; +u16 odr = enable ? sensor->odr :0 ;int err; - reg = &st_lsm6dsx_odr_table[sensor->id].reg; - data =ST_LSM6DSX_SHIFT_VAL (0 , reg->mask); - err =st_lsm6dsx_update_bits_locked (hw, reg->addr, reg->mask, data); + err =st_lsm6dsx_set_odr (sensor, odr);if (err <0 )return err; - sensor->hw->enable_mask &= ~BIT (sensor->id); +if (enable) + hw->enable_mask |=BIT (sensor->id); +else + hw->enable_mask &= ~BIT (sensor->id);return 0 ; }@@ -568,7 +556,7 @@ static int st_lsm6dsx_read_oneshot(struct st_lsm6dsx_sensor *sensor,int err, delay;__le16 data; - err =st_lsm6dsx_sensor_enable (sensor); + err =st_lsm6dsx_sensor_set_enable (sensor, true);if (err <0 )return err;@@ -579,7 +567,7 @@ static int st_lsm6dsx_read_oneshot(struct st_lsm6dsx_sensor *sensor,if (err <0 )return err; -st_lsm6dsx_sensor_disable (sensor); +st_lsm6dsx_sensor_set_enable (sensor, false); *val = (s16 )le16_to_cpu (data);
PATCH v2 6/9 iio: imu: st_lsm6dsx: add i2c embedded controller support
In reply to Lorenzo Bianconii2c controller embedded in lsm6dx series can connect up to four slave devices using accelerometer sensor as trigger for i2c read/write operations.
Introduce sensor hub support for lsm6dso sensor. Add register map for lis2mdl magnetometer sensor.
In order to perform single read/write operations st_lsm6dsx driver relies on SLV0 channel (hw FIFO is not supported yet)
--- drivers/iio/imu/st_lsm6dsx/Makefile | 3 +- drivers/iio/imu/st_lsm6dsx/st_lsm6dsx.h | 112 +++ drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c | 135 ++-- drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_shub.c | 702 ++++++++++++++++++ .../linux/platform_data/st_sensors_pdata.h | 2 + 5 files changed, 911 insertions(+), 43 deletions(-) create mode 100644 drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_shub.c
drivers/iio/imu/st_lsm6dsx/Makefile +2 -1
@@ -1,4 +1,5 @@ -st_lsm6dsx-y := st_lsm6dsx_core.o st_lsm6dsx_buffer.o +st_lsm6dsx-y := st_lsm6dsx_core.o st_lsm6dsx_buffer.o \ + st_lsm6dsx_shub.o obj-$(CONFIG_IIO_ST_LSM6DSX) += st_lsm6dsx.o obj-$(CONFIG_IIO_ST_LSM6DSX_I2C) += st_lsm6dsx_i2c.o
drivers/iio/imu/st_lsm6dsx/st_lsm6dsx.h +112 -0
166 lines not on this page · raw message
drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c +93 -42
192 lines not on this page · raw message
drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_shub.c new file +702 -0
702 lines not on this page · raw message
include/linux/platform_data/st_sensors_pdata.h +2 -0
@@ -18,11 +18,13 @@* Accelerometer DRDY on LSM330 available only on pin 1 (see datasheet). * @open_drain: set the interrupt line to be open drain if possible. * @spi_3wire: enable spi-3wire mode. +* @pullups: enable/disable i2c controller pullup resistors. */ struct st_sensors_platform_data {u8 drdy_int_pin;bool open_drain;bool spi_3wire; +bool pullups; };#endif /* ST_SENSORS_PDATA_H */
Signature · 1 line
2.19.1
Jonathan Cameron
maintainerRe: [PATCH v2 6/9] iio: imu: st_lsm6dsx: add i2c embedded controller support
Quoted 9 lines · On Sun, 11 Nov 2018 15:15:33 +0100 Lorenzo Bianconi…
i2c controller embedded in lsm6dx series can connect up to four slave devices using accelerometer sensor as trigger for i2c read/write operations.
Introduce sensor hub support for lsm6dso sensor. Add register map for lis2mdl magnetometer sensor.
In order to perform single read/write operationsst_lsm6dsxdriver relies on SLV0 channel (hw FIFO is not supported yet)Signed-off-by Lorenzo Bianconi <[email protected]>
Hi Lorenzo.
A build warning came up pointing out an issue with little endian sizes.
I've 'guessed' that data is actually meant to be __le16 but please confirm I got that right!
Quoted 14 lines
drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_shub.c new file +14
-0+static int +st_lsm6dsx_shub_read_oneshot (struct st_lsm6dsx_sensor *sensor, +struct iio_chan_spec const *ch, +int *val) +{ +int err, delay, len = ch->scan_type.realbits >>3 ; +__le32 data; + + err =st_lsm6dsx_shub_set_enable (sensor, true); +if (err <0 ) +return err; + + delay =1000000 / sensor->odr; +usleep_range (delay,2 * delay);
drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_shub.c line 378
Quoted 10 lines
drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_shub.c new file +10
-0+ + err =st_lsm6dsx_shub_read (sensor, ch->address, (u8 *)&data, len); +if (err <0 ) +return err; + +st_lsm6dsx_shub_set_enable (sensor, false); + +switch (len) { +case 2 : + *val = (s16 )le16_to_cpu (data);
This one is odd given data is an __le32?
What's going on here?
Quoted 8 lines
drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_shub.c new file +8
-0+break ; +default : +return -EINVAL ; + } + +return IIO_VAL_INT ; +} +
PATCH v2 7/9 iio: imu: st_lsm6dsx: add st_lsm6dsx_push_tagged_data routine
In reply to Lorenzo BianconiIntroduce st_lsm6dsx_push_tagged_data routine to push samples to iio buffers. st_lsm6dsx_push_tagged_data will be reused adding hw fifo support to st_lsm6dsx i2c embedded controller in order to improve code readability
--- .../iio/imu/st_lsm6dsx/st_lsm6dsx_buffer.c | 44 ++++++++++++------- 1 file changed, 29 insertions(+), 15 deletions(-)
drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_buffer.c +29 -15
@@ -453,6 +453,31 @@ int st_lsm6dsx_read_fifo(struct st_lsm6dsx_hw *hw)return read_len; } +static int +st_lsm6dsx_push_tagged_data (struct st_lsm6dsx_hw *hw,u8 tag, +u8 *data,s64 ts) +{ +struct st_lsm6dsx_sensor *sensor; +struct iio_dev *iio_dev; + +switch (tag) { +case ST_LSM6DSX_GYRO_TAG : + iio_dev = hw->iio_devs[ST_LSM6DSX_ID_GYRO ]; +break ; +case ST_LSM6DSX_ACC_TAG : + iio_dev = hw->iio_devs[ST_LSM6DSX_ID_ACC ]; +break ; +default : +return -EINVAL ; + } + + sensor =iio_priv (iio_dev); +iio_push_to_buffers_with_timestamp (iio_dev, data, + ts + sensor->ts_ref); + +return 0 ; +} +/** * st_lsm6dsx_read_tagged_fifo() - LSM6DSO read FIFO routine * @hw: Pointer to instance of struct st_lsm6dsx_hw.
@@ -508,8 +533,7 @@ int st_lsm6dsx_read_tagged_fifo(struct st_lsm6dsx_hw *hw) ST_LSM6DSX_SAMPLE_SIZE); tag = hw->buff[i] >>3 ; -switch (tag) { -case ST_LSM6DSX_TS_TAG : +if (tag ==ST_LSM6DSX_TS_TAG ) {/* * hw timestamp is 4B long and it is stored * in FIFO according to this schema:
@@ -526,19 +550,9 @@ int st_lsm6dsx_read_tagged_fifo(struct st_lsm6dsx_hw *hw)if (!reset_ts && ts >=0xffff0000 ) reset_ts = true; ts *=ST_LSM6DSX_TS_SENSITIVITY ; -break ; -case ST_LSM6DSX_GYRO_TAG : -iio_push_to_buffers_with_timestamp ( - hw->iio_devs[ST_LSM6DSX_ID_GYRO ], - iio_buff, gyro_sensor->ts_ref + ts); -break ; -case ST_LSM6DSX_ACC_TAG : -iio_push_to_buffers_with_timestamp ( - hw->iio_devs[ST_LSM6DSX_ID_ACC ], - iio_buff, acc_sensor->ts_ref + ts); -break ; -default : -break ; + }else { +st_lsm6dsx_push_tagged_data (hw, tag, iio_buff, + ts); } } }
Signature · 1 line
2.19.1
Jonathan Cameron
maintainerRe: [PATCH v2 7/9] iio: imu: st_lsm6dsx: add st_lsm6dsx_push_tagged_data routine
Quoted 6 lines · On Sun, 11 Nov 2018 15:15:34 +0100 Lorenzo Bianconi…
Introduce
st_lsm6dsx_push_tagged_dataroutine to push samples to iio buffers.st_lsm6dsx_push_tagged_datawill be reused adding hw fifo support tost_lsm6dsxi2c embedded controller in order to improve code readabilitySigned-off-by Lorenzo Bianconi <[email protected]>
Applied to the togreg branch of iio.git and pushed out as testing for the autobuilders to play with it.
Thanks,
Jonathan
Quoted 73 lines
--- .../iio/imu/st_lsm6dsx/st_lsm6dsx_buffer.c | 44 ++++++++++++------- 1 file changed, 29 insertions(+), 15 deletions(-)drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_buffer.c +29
-15@@ -453,6 +453,31 @@ int st_lsm6dsx_read_fifo(struct st_lsm6dsx_hw *hw)return read_len; } +static int +st_lsm6dsx_push_tagged_data (struct st_lsm6dsx_hw *hw,u8 tag, +u8 *data,s64 ts) +{ +struct st_lsm6dsx_sensor *sensor; +struct iio_dev *iio_dev; + +switch (tag) { +case ST_LSM6DSX_GYRO_TAG : + iio_dev = hw->iio_devs[ST_LSM6DSX_ID_GYRO ]; +break ; +case ST_LSM6DSX_ACC_TAG : + iio_dev = hw->iio_devs[ST_LSM6DSX_ID_ACC ]; +break ; +default : +return -EINVAL ; + } + + sensor =iio_priv (iio_dev); +iio_push_to_buffers_with_timestamp (iio_dev, data, + ts + sensor->ts_ref); + +return 0 ; +} +/** * st_lsm6dsx_read_tagged_fifo() - LSM6DSO read FIFO routine * @hw: Pointer to instance of struct st_lsm6dsx_hw. @@ -508,8 +533,7 @@ int st_lsm6dsx_read_tagged_fifo(struct st_lsm6dsx_hw *hw) ST_LSM6DSX_SAMPLE_SIZE); tag = hw->buff[i] >>3 ; -switch (tag) { -case ST_LSM6DSX_TS_TAG : +if (tag ==ST_LSM6DSX_TS_TAG ) {/* * hw timestamp is 4B long and it is stored * in FIFO according to this schema: @@ -526,19 +550,9 @@ int st_lsm6dsx_read_tagged_fifo(struct st_lsm6dsx_hw *hw)if (!reset_ts && ts >=0xffff0000 ) reset_ts = true; ts *=ST_LSM6DSX_TS_SENSITIVITY ; -break ; -case ST_LSM6DSX_GYRO_TAG : -iio_push_to_buffers_with_timestamp ( - hw->iio_devs[ST_LSM6DSX_ID_GYRO ], - iio_buff, gyro_sensor->ts_ref + ts); -break ; -case ST_LSM6DSX_ACC_TAG : -iio_push_to_buffers_with_timestamp ( - hw->iio_devs[ST_LSM6DSX_ID_ACC ], - iio_buff, acc_sensor->ts_ref + ts); -break ; -default : -break ; + }else { +st_lsm6dsx_push_tagged_data (hw, tag, iio_buff, + ts); } } }
PATCH v2 8/9 iio: imu: st_lsm6dsx: add hw FIFO support to i2c controller
In reply to Lorenzo BianconiIntroduce hw FIFO support to lsm6dsx i2c controller. st_lsm6dsx sensor-hub relies on SLV0 for slave configuration since SLV0 is the only channel that can be used to write into i2c slave devices. SLV{1,2,3} channels are used to read external data and push them into the hw FIFO
--- drivers/iio/imu/st_lsm6dsx/st_lsm6dsx.h | 4 + .../iio/imu/st_lsm6dsx/st_lsm6dsx_buffer.c | 47 ++++++++++-- drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c | 5 ++ drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_shub.c | 75 +++++++++++++++++++ 4 files changed, 125 insertions(+), 6 deletions(-)
drivers/iio/imu/st_lsm6dsx/st_lsm6dsx.h +4 -0
@@ -130,18 +130,22 @@ struct st_lsm6dsx_hw_ts_settings {* @master_en: master config register info (addr + mask). * @pullup_en: i2c controller pull-up register info (addr + mask). * @aux_sens: aux sensor register info (addr + mask). +* @wr_once: write_once register info (addr + mask). * @shub_out: sensor hub first output register info. * @slv0_addr: slave0 address in secondary page. * @dw_slv0_addr: slave0 write register address in secondary page. +* @batch_en: Enable/disable FIFO batching. */ struct st_lsm6dsx_shub_settings {struct st_lsm6dsx_reg page_mux;struct st_lsm6dsx_reg master_en;struct st_lsm6dsx_reg pullup_en;struct st_lsm6dsx_reg aux_sens; +struct st_lsm6dsx_reg wr_once;u8 shub_out;u8 slv0_addr;u8 dw_slv0_addr; +u8 batch_en; };enum st_lsm6dsx_ext_sensor_id {
drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_buffer.c +41 -6
72 lines not on this page · raw message
drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c +5 -0
@@ -337,9 +337,14 @@ static const struct st_lsm6dsx_settings st_lsm6dsx_sensor_settings[] = { .addr = 0x14, .mask = GENMASK(1, 0), }, + .wr_once = { + .addr = 0x14, + .mask = BIT(6), + }, .shub_out = 0x02, .slv0_addr = 0x15, .dw_slv0_addr = 0x21, + .batch_en = BIT(3), } }, };
drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_shub.c +75 -0
98 lines not on this page · raw message
Signature · 1 line
2.19.1
Jonathan Cameron
maintainerRe: [PATCH v2 8/9] iio: imu: st_lsm6dsx: add hw FIFO support to i2c controller
Quoted 7 lines · On Sun, 11 Nov 2018 15:15:35 +0100 Lorenzo Bianconi…
Introduce hw FIFO support to lsm6dsx i2c controller.
st_lsm6dsxsensor-hub relies on SLV0 for slave configuration since SLV0 is the only channel that can be used to write into i2c slave devices. SLV{1,2,3} channels are used to read external data and push them into the hw FIFOSigned-off-by Lorenzo Bianconi <[email protected]>
Applied to the togreg branch of iio.git and pushed out as testing for the autobuilders to play with it.
Thanks,
Jonathan
Quoted 238 lines
--- drivers/iio/imu/st_lsm6dsx/st_lsm6dsx.h | 4 + .../iio/imu/st_lsm6dsx/st_lsm6dsx_buffer.c | 47 ++++++++++-- drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c | 5 ++ drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_shub.c | 75 +++++++++++++++++++ 4 files changed, 125 insertions(+), 6 deletions(-)drivers/iio/imu/st_lsm6dsx/st_lsm6dsx.h +4
-0@@ -130,18 +130,22 @@ struct st_lsm6dsx_hw_ts_settings {* @master_en: master config register info (addr + mask). * @pullup_en: i2c controller pull-up register info (addr + mask). * @aux_sens: aux sensor register info (addr + mask). +* @wr_once: write_once register info (addr + mask). * @shub_out: sensor hub first output register info. * @slv0_addr: slave0 address in secondary page. * @dw_slv0_addr: slave0 write register address in secondary page. +* @batch_en: Enable/disable FIFO batching. */ struct st_lsm6dsx_shub_settings {struct st_lsm6dsx_reg page_mux;struct st_lsm6dsx_reg master_en;struct st_lsm6dsx_reg pullup_en;struct st_lsm6dsx_reg aux_sens; +struct st_lsm6dsx_reg wr_once;u8 shub_out;u8 slv0_addr;u8 dw_slv0_addr; +u8 batch_en; };enum st_lsm6dsx_ext_sensor_id {drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_buffer.c +41
-6@@ -68,6 +68,9 @@ enum st_lsm6dsx_fifo_tag {ST_LSM6DSX_GYRO_TAG =0x01 ,ST_LSM6DSX_ACC_TAG =0x02 ,ST_LSM6DSX_TS_TAG =0x04 , +ST_LSM6DSX_EXT0_TAG =0x0f , +ST_LSM6DSX_EXT1_TAG =0x10 , + ST_LSM6DSX_EXT2_TAG = 0x11, }; static const@@ -460,6 +463,12 @@ st_lsm6dsx_push_tagged_data(struct st_lsm6dsx_hw *hw, u8 tag,struct st_lsm6dsx_sensor *sensor;struct iio_dev *iio_dev; +/* +* EXT_TAG are managed in FIFO fashion so ST_LSM6DSX_EXT0_TAG +* corresponds to the first enabled channel, ST_LSM6DSX_EXT1_TAG +* to the second one and ST_LSM6DSX_EXT2_TAG to the last enabled +* channel +*/ switch (tag) {case ST_LSM6DSX_GYRO_TAG : iio_dev = hw->iio_devs[ST_LSM6DSX_ID_GYRO ];@@ -467,6 +476,24 @@ st_lsm6dsx_push_tagged_data(struct st_lsm6dsx_hw *hw, u8 tag,case ST_LSM6DSX_ACC_TAG : iio_dev = hw->iio_devs[ST_LSM6DSX_ID_ACC ];break ; +case ST_LSM6DSX_EXT0_TAG : +if (hw->enable_mask &BIT (ST_LSM6DSX_ID_EXT0 )) + iio_dev = hw->iio_devs[ST_LSM6DSX_ID_EXT0 ]; +else if (hw->enable_mask &BIT (ST_LSM6DSX_ID_EXT1 )) + iio_dev = hw->iio_devs[ST_LSM6DSX_ID_EXT1 ]; +else + iio_dev = hw->iio_devs[ST_LSM6DSX_ID_EXT2 ]; +break ; +case ST_LSM6DSX_EXT1_TAG : +if ((hw->enable_mask &BIT (ST_LSM6DSX_ID_EXT0 )) && + (hw->enable_mask &BIT (ST_LSM6DSX_ID_EXT1 ))) + iio_dev = hw->iio_devs[ST_LSM6DSX_ID_EXT1 ]; +else + iio_dev = hw->iio_devs[ST_LSM6DSX_ID_EXT2 ]; +break ; +case ST_LSM6DSX_EXT2_TAG : + iio_dev = hw->iio_devs[ST_LSM6DSX_ID_EXT2 ]; +break ;default :return -EINVAL ; }@@ -593,13 +620,21 @@ static int st_lsm6dsx_update_fifo(struct iio_dev *iio_dev, bool enable) goto out; } - err =st_lsm6dsx_sensor_set_enable (sensor, enable); -if (err <0 ) - goto out; +if (sensor->id ==ST_LSM6DSX_ID_EXT0 || + sensor->id ==ST_LSM6DSX_ID_EXT1 || + sensor->id ==ST_LSM6DSX_ID_EXT2 ) { + err =st_lsm6dsx_shub_set_enable (sensor, enable); +if (err <0 ) + goto out; + }else { + err =st_lsm6dsx_sensor_set_enable (sensor, enable); +if (err <0 ) + goto out; - err =st_lsm6dsx_set_fifo_odr (sensor, enable); -if (err <0 ) - goto out; + err =st_lsm6dsx_set_fifo_odr (sensor, enable); +if (err <0 ) + goto out; + } err =st_lsm6dsx_update_decimators (hw);if (err <0 )drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c +5
-0@@ -337,9 +337,14 @@ static const struct st_lsm6dsx_settings st_lsm6dsx_sensor_settings[] = { .addr = 0x14, .mask = GENMASK(1, 0), }, + .wr_once = { + .addr = 0x14, + .mask = BIT(6), + }, .shub_out = 0x02, .slv0_addr = 0x15, .dw_slv0_addr = 0x21, + .batch_en = BIT(3), } }, };drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_shub.c +75
-0@@ -148,6 +148,26 @@ static int st_lsm6dsx_shub_write_reg(struct st_lsm6dsx_hw *hw, u8 addr,return err; } +static int +st_lsm6dsx_shub_write_reg_with_mask (struct st_lsm6dsx_hw *hw,u8 addr, +u8 mask,u8 val) +{ +int err; + +mutex_lock (&hw->page_lock); + err =st_lsm6dsx_set_page (hw, true); +if (err <0 ) + goto out; + + err =regmap_update_bits (hw->regmap, addr, mask, val); + +st_lsm6dsx_set_page (hw, false); +out: +mutex_unlock (&hw->page_lock); + +return err; +} +static int st_lsm6dsx_shub_master_enable (struct st_lsm6dsx_sensor *sensor,bool enable) {@@ -238,6 +258,18 @@ st_lsm6dsx_shub_write(struct st_lsm6dsx_sensor *sensor, u8 addr,int err, i; hub_settings = &hw->settings->shub_settings; +if (hub_settings->wr_once.addr) { +unsigned int data; + + data =ST_LSM6DSX_SHIFT_VAL (1 , hub_settings->wr_once.mask); + err =st_lsm6dsx_shub_write_reg_with_mask (hw, + hub_settings->wr_once.addr, + hub_settings->wr_once.mask, + data); +if (err <0 ) +return err; + } + slv_addr =ST_LSM6DSX_SLV_ADDR (0 , hub_settings->slv0_addr); config[0 ] = sensor->ext_info.addr <<1 ;for (i =0 ; i < len; i++) {@@ -319,11 +351,54 @@ st_lsm6dsx_shub_set_odr(struct st_lsm6dsx_sensor *sensor, u16 odr) val); } +/* use SLV{1,2,3} for FIFO read operations */ +static int +st_lsm6dsx_shub_config_channels (struct st_lsm6dsx_sensor *sensor, +bool enable) +{ +const struct st_lsm6dsx_shub_settings *hub_settings; +const struct st_lsm6dsx_ext_dev_settings *settings; +u8 config[9 ] = {}, enable_mask, slv_addr; +struct st_lsm6dsx_hw *hw = sensor->hw; +struct st_lsm6dsx_sensor *cur_sensor; +int i, j =0 ; + + hub_settings = &hw->settings->shub_settings; +if (enable) + enable_mask = hw->enable_mask |BIT (sensor->id); +else + enable_mask = hw->enable_mask & ~BIT (sensor->id); + +for (i =ST_LSM6DSX_ID_EXT0 ; i <=ST_LSM6DSX_ID_EXT2 ; i++) { +if (!hw->iio_devs[i]) +continue ; + + cur_sensor =iio_priv (hw->iio_devs[i]); +if (!(enable_mask &BIT (cur_sensor->id))) +continue ; + + settings = cur_sensor->ext_info.settings; + config[j] = (sensor->ext_info.addr <<1 ) |1 ; + config[j +1 ] = settings->out.addr; + config[j +2 ] = (settings->out.len &ST_LS6DSX_READ_OP_MASK ) | + hub_settings->batch_en; + j +=3 ; + } + + slv_addr =ST_LSM6DSX_SLV_ADDR (1 , hub_settings->slv0_addr); +return st_lsm6dsx_shub_write_reg (hw, slv_addr, config, +sizeof (config)); +} +int st_lsm6dsx_shub_set_enable (struct st_lsm6dsx_sensor *sensor,bool enable) {const struct st_lsm6dsx_ext_dev_settings *settings;int err; + err =st_lsm6dsx_shub_config_channels (sensor, enable); +if (err <0 ) +return err; + settings = sensor->ext_info.settings;if (enable) { err =st_lsm6dsx_shub_set_odr (sensor, sensor->odr);
PATCH v2 9/9 dt-bindings: iio: imu: st_lsm6dsx: add support to i2c pullup resistors
In reply to Lorenzo Bianconi--- Documentation/devicetree/bindings/iio/imu/st_lsm6dsx.txt | 1 + 1 file changed, 1 insertion(+)
Documentation/devicetree/bindings/iio/imu/st_lsm6dsx.txt +1 -0
@@ -13,6 +13,7 @@ Required properties: Optional properties: - st,drdy-int-pin: the pin on the package that will be used to signal "data ready" (valid values: 1 or 2). +- st,pullups : enable/disable internal i2c controller pullup resistors. - drive-open-drain: the interrupt/data ready line will be configured as open drain, which is useful if several sensors share the same interrupt line. This is a boolean property.
Signature · 1 line
2.19.1
Jonathan Cameron
maintainerRe: [PATCH v2 9/9] dt-bindings: iio: imu: st_lsm6dsx: add support to i2c pullup resistors
Quoted 1 line · On Sun, 11 Nov 2018 15:15:36 +0100 Lorenzo Bianconi…
Signed-off-by Lorenzo Bianconi <[email protected]>
There seems to be some precedents in tree for this, so fair enough. It's one of those things that almost seems worth standardising, but it's not totally apparent where it would be done as it can apply to any bus or gpio.
Anyhow, applied this as is (Rob / Mark input of course welcome) to my togreg branch which will be pushed out in a few mins as testing for the autobuilders to play with it.
Thanks,
Jonathan
Quoted 16 lines
--- Documentation/devicetree/bindings/iio/imu/st_lsm6dsx.txt | 1 + 1 file changed, 1 insertion(+)Documentation/devicetree/bindings/iio/imu/st_lsm6dsx.txt +1
-0@@ -13,6 +13,7 @@ Required properties: Optional properties: - st,drdy-int-pin: the pin on the package that will be used to signal "data ready" (valid values: 1 or 2). +- st,pullups : enable/disable internal i2c controller pullup resistors. - drive-open-drain: the interrupt/data ready line will be configured as open drain, which is useful if several sensors share the same interrupt line. This is a boolean property.
Rob Herring
maintainerRe: [PATCH v2 9/9] dt-bindings: iio: imu: st_lsm6dsx: add support to i2c pullup resistors
In reply to Lorenzo BianconiQuoted 10 lines · Lorenzo Bianconi
Signed-off-by Lorenzo Bianconi <[email protected]>--- Documentation/devicetree/bindings/iio/imu/st_lsm6dsx.txt | 1 + 1 file changed, 1 insertion(+)Documentation/devicetree/bindings/iio/imu/st_lsm6dsx.txt +0
-0
Documentation/devicetree/bindings/iio/imu/st_lsm6dsx.txt Required properties: · line 16
Quoted 4 lines
Documentation/devicetree/bindings/iio/imu/st_lsm6dsx.txt +1
-0@@ -13,6 +13,7 @@ Required properties: Optional properties: - st,drdy-int-pin: the pin on the package that will be used to signal "data ready" (valid values: 1 or 2). +- st,pullups : enable/disable internal i2c controller pullup resistors.
bias-pull-up is the standard property for this.
Quoted 6 lines
Documentation/devicetree/bindings/iio/imu/st_lsm6dsx.txt +0
-0- drive-open-drain: the interrupt/data ready line will be configured as open drain, which is useful if several sensors share the same interrupt line. This is a boolean property.Signature · 1 line
2.19.1
Jonathan Cameron
maintainerRe: [PATCH v2 9/9] dt-bindings: iio: imu: st_lsm6dsx: add support to i2c pullup resistors
Quoted 6 lines · On Sat, 17 Nov 2018 09:37:54 -0600 Rob Herring <[email protected]> wrote:
Quoted 5 lines · Lorenzo Bianconi
Signed-off-by Lorenzo Bianconi <[email protected]>--- Documentation/devicetree/bindings/iio/imu/st_lsm6dsx.txt | 1 + 1 file changed, 1 insertion(+)
Quoted 11 lines
Documentation/devicetree/bindings/iio/imu/st_lsm6dsx.txt Required properties: · line 16
Quoted 9 lines
Documentation/devicetree/bindings/iio/imu/st_lsm6dsx.txt +1
-0@@ -13,6 +13,7 @@ Required properties: Optional properties: - st,drdy-int-pin: the pin on the package that will be used to signal "data ready" (valid values: 1 or 2). +- st,pullups : enable/disable internal i2c controller pullup resistors.bias-pull-up is the standard property for this.
The problem here is 'of what?'. Perhaps it wasn't clear in the current binding either, but we are talking the pull ups on the auxilliary i2c bus (which doesn't really have a direct representation in DT at all). If we just go with bias-pull-up my instinct would be that it was applying to the drdy pin for example.
Lorenzo, could you send a follow up patch fixing this once we have it pinned down?
We have plenty of time to get it in before the end of the cycle, so I would rather do that than revert this series over it. Conversely I don't want a binding we are still discussing getting into a release. I should have given Rob time to get to this. Lots of precedence doesn't mean there isn't a better way! Sorry All.
Thanks,
Jonathan
Quoted 7 lines
Quoted 7 lines
Documentation/devicetree/bindings/iio/imu/st_lsm6dsx.txt +0
-0- drive-open-drain: the interrupt/data ready line will be configured as open drain, which is useful if several sensors share the same interrupt line. This is a boolean property.Signature · 1 line
2.19.1
Re: [PATCH v2 9/9] dt-bindings: iio: imu: st_lsm6dsx: add support to i2c pullup resistors
Quoted 3 lines
On Sat, 17 Nov 2018 09:37:54 -0600
Rob Herring <[email protected]> wrote:
[...]
Quoted 7 lines
Quoted 6 lines
Quoted 4 lines
Optional properties:
- st,drdy-int-pin: the pin on the package that will be used to signal "data ready" (valid values: 1 or 2).
+- st,pullups : enable/disable internal i2c controller pullup resistors.bias-pull-up is the standard property for this.
Quoted 9 lines
The problem here is 'of what?'. Perhaps it wasn't clear in the current binding either, but we are talking the pull ups on the auxilliary i2c bus (which doesn't really have a direct representation in DT at all). If we just go with bias-pull-up my instinct would be that it was applying to the drdy pin for example.
Lorenzo, could you send a follow up patch fixing this once we have it pinned down?
Sure, it sounds good. IIUC we should use 'bias-pull-up' here, without vendor info, right?
Regards,
Lorenzo
Quoted 18 lines
We have plenty of time to get it in before the end of the cycle, so I would rather do that than revert this series over it. Conversely I don't want a binding we are still discussing getting into a release. I should have given Rob time to get to this. Lots of precedence doesn't mean there isn't a better way! Sorry All.
Thanks,
Jonathan
Quoted 7 lines
Quoted 7 lines
- drive-open-drain: the interrupt/data ready line will be configured as open drain, which is useful if several sensors share the same interrupt line. This is a boolean property.
--
2.19.1
Jonathan Cameron
maintainerRe: [PATCH v2 9/9] dt-bindings: iio: imu: st_lsm6dsx: add support to i2c pullup resistors
Quoted 19 lines · On Sat, 17 Nov 2018 18:24:03 +0100 Lorenzo Bianconi…
Quoted 3 lines
On Sat, 17 Nov 2018 09:37:54 -0600
Rob Herring <[email protected]> wrote:[...]
Quoted 13 lines
Quoted 6 lines
Quoted 4 lines
Optional properties:
- st,drdy-int-pin: the pin on the package that will be used to signal "data ready" (valid values: 1 or 2).
+- st,pullups : enable/disable internal i2c controller pullup resistors.bias-pull-up is the standard property for this.
The problem here is 'of what?'. Perhaps it wasn't clear in the current binding either, but we are talking the pull ups on the auxilliary i2c bus (which doesn't really have a direct representation in DT at all). If we just go with bias-pull-up my instinct would be that it was applying to the drdy pin for example.
Quoted 6 lines
Quoted 3 lines
Lorenzo, could you send a follow up patch fixing this once we have it pinned down?
Sure, it sounds good. IIUC we should use 'bias-pull-up' here, without vendor info, right?
Yes, though my concern about it being on it's own without any reference points. Makes it unobvious what we are applying the pull up on.
Jonathan
Quoted 22 lines
Regards,
LorenzoQuoted 18 lines
We have plenty of time to get it in before the end of the cycle, so I would rather do that than revert this series over it. Conversely I don't want a binding we are still discussing getting into a release. I should have given Rob time to get to this. Lots of precedence doesn't mean there isn't a better way! Sorry All.
Thanks,
Jonathan
Quoted 7 lines
Quoted 7 lines
- drive-open-drain: the interrupt/data ready line will be configured as open drain, which is useful if several sensors share the same interrupt line. This is a boolean property.
--
2.19.1
Re: [PATCH v2 9/9] dt-bindings: iio: imu: st_lsm6dsx: add support to i2c pullup resistors
Quoted 27 lines
Quoted 23 lines · On Sat, 17 Nov 2018 18:24:03 +0100 Lorenzo Bianconi…
Quoted 3 lines
On Sat, 17 Nov 2018 09:37:54 -0600
Rob Herring <[email protected]> wrote:[...]
Quoted 16 lines
Quoted 6 lines
Quoted 4 lines
Optional properties:
- st,drdy-int-pin: the pin on the package that will be used to signal "data ready" (valid values: 1 or 2).
+- st,pullups : enable/disable internal i2c controller pullup resistors.bias-pull-up is the standard property for this.
The problem here is 'of what?'. Perhaps it wasn't clear in the current binding either, but we are talking the pull ups on the auxilliary i2c bus (which doesn't really have a direct representation in DT at all). If we just go with bias-pull-up my instinct would be that it was applying to the drdy pin for example.
Lorenzo, could you send a follow up patch fixing this once we have it pinned down?
Quoted 7 lines
Quoted 2 lines
Sure, it sounds good. IIUC we should use 'bias-pull-up' here, without vendor info, right?
Yes, though my concern about it being on it's own without any reference points. Makes it unobvious what we are applying the pull up on.
Jonathan
@Rob: do you agree to use 'bias-pull-up' also in this particular case? If so I will send a follow-up patch to fix it
Regards,
Lorenzo
Jonathan Cameron
maintainerQuoted 4 lines · On Sun, 11 Nov 2018 15:15:27 +0100 Lorenzo Bianconi…
Introduce i2c controller support to
st_lsm6dsxdriver for lsm6dso sensor.st_lsm6dsxsensor-hub supports up to 3 concurrent slave devices. Add register map for lis2mdl magnetometer sensor.
Add hw FIFO support tost_lsm6dsxsensorhub driver.
Hi Lorenzo.
A very nice series in general, though I did make a small change in patch 6 so please check I didn't mess that up. It seemed fairly obvious but I've been wrong on obvious things many times before :)
Thanks,
Jonathan
Quoted 34 lines
Changes since v1:
- move backst_lsm6dsx_set_fifo_moderoutine infifo_lockcritical section inst_lsm6dsx_flush_fifo
- improve documentation
- movest_lsm6dsx_sensor_set_enabledefinition in a separated patch
- movest_lsm6dsx_push_tagged_datadefinition in a separated patch
- use properts_reffor ext devices inst_lsm6dsx_push_tagged_data
- fix invalidiio_devidentification inst_lsm6dsx_push_tagged_datawhenST_LSM6DSX_EXT1_TAGis read from the FIFO
- refactorst_lsm6dsx_shub_probemoving wai check in a dedicated routine
- fix abi issue inscale_availabledefinitionLorenzo Bianconi (9):
iio: imu:st_lsm6dsx: introduce locked read/write utility routines
iio: imu:st_lsm6dsx: reload trimming parameter at bootstrap
iio: imu:st_lsm6dsx: remove static fromst_lsm6dsx_set_watermark
iio: imu:st_lsm6dsx: introduceST_LSM6DSX_ID_EXTsensor ids
iio: imu:st_lsm6dsx: introducest_lsm6dsx_sensor_set_enableroutine
iio: imu:st_lsm6dsx: add i2c embedded controller support
iio: imu:st_lsm6dsx: addst_lsm6dsx_push_tagged_dataroutine
iio: imu:st_lsm6dsx: add hw FIFO support to i2c controller
dt-bindings: iio: imu:st_lsm6dsx: add support to i2c pullup resistors.../bindings/iio/imu/st_lsm6dsx.txt | 1 + drivers/iio/imu/st_lsm6dsx/Makefile | 3 +- drivers/iio/imu/st_lsm6dsx/st_lsm6dsx.h | 167 +++- .../iio/imu/st_lsm6dsx/st_lsm6dsx_buffer.c | 165 ++-- drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c | 283 +++++-- drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_shub.c | 777 ++++++++++++++++++ .../linux/platform_data/st_sensors_pdata.h | 2 + 7 files changed, 1263 insertions(+), 135 deletions(-) create mode 100644 drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_shub.c
Quoted 9 lines
Quoted 4 lines · On Sun, 11 Nov 2018 15:15:27 +0100 Lorenzo Bianconi…
Introduce i2c controller support to
st_lsm6dsxdriver for lsm6dso sensor.st_lsm6dsxsensor-hub supports up to 3 concurrent slave devices. Add register map for lis2mdl magnetometer sensor.
Add hw FIFO support tost_lsm6dsxsensorhub driver.Hi Lorenzo.
Hi Jonathan,
Quoted 5 lines
A very nice series in general, though I did make a small change in patch 6 so please check I didn't mess that up. It seemed fairly obvious but I've been wrong on obvious things many times before :)
Thx for the fast review :) Looking at the code I think it is fine. Moreover I guess we
can generalize it taking into account different channel lengths (e.g. if we want to connect a pressure sensor). I will send a follow-up patch.
Regards,
Lorenzo
Quoted 4 lines
Thanks,
Jonathan