diff options
author | Rodrigo Vivi <rodrigo.vivi@intel.com> | 2020-02-25 20:29:58 +0300 |
---|---|---|
committer | Rodrigo Vivi <rodrigo.vivi@intel.com> | 2020-02-25 20:39:23 +0300 |
commit | ff36e78fdb251b9fa65028554689806961e011eb (patch) | |
tree | f5af925d509224e06a10936196be6c06bcbdc6ae /drivers/iio/imu/st_lsm6dsx | |
parent | 143d9c3e7b6aa2b785abba04266ed75f2b52e94a (diff) | |
parent | 1b245ec5b685ebf8e6e5d1e6b5bcc03b6608e8b0 (diff) | |
download | linux-ff36e78fdb251b9fa65028554689806961e011eb.tar.xz |
Merge drm/drm-next into drm-intel-next-queued
Some DSI and VBT pending patches from Hans will apply
cleanly and with less ugly conflicts if they are rebuilt
on top of other patches that recently landed on drm-next.
Reference: https://patchwork.freedesktop.org/series/70952/
Cc: Hans de Goede <hdegoede@redhat.com>
Signed-off-by: Rodrigo Vivi <rodrigo.vivi@intel.com
Diffstat (limited to 'drivers/iio/imu/st_lsm6dsx')
-rw-r--r-- | drivers/iio/imu/st_lsm6dsx/st_lsm6dsx.h | 49 | ||||
-rw-r--r-- | drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_buffer.c | 27 | ||||
-rw-r--r-- | drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c | 121 | ||||
-rw-r--r-- | drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_i2c.c | 3 | ||||
-rw-r--r-- | drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_shub.c | 76 | ||||
-rw-r--r-- | drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_spi.c | 3 |
6 files changed, 210 insertions, 69 deletions
diff --git a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx.h b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx.h index dc55d7dff3eb..9c3486a8134f 100644 --- a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx.h +++ b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx.h @@ -76,6 +76,7 @@ enum st_lsm6dsx_hw_id { .endianness = IIO_LE, \ }, \ .event_spec = &st_lsm6dsx_event, \ + .ext_info = st_lsm6dsx_accel_ext_info, \ .num_event_specs = 1, \ } @@ -176,21 +177,38 @@ struct st_lsm6dsx_hw_ts_settings { * @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). + * @emb_func: embedded function register info (addr + mask). + * @num_ext_dev: max number of slave devices. * @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. + * @pause: controller pause value. */ struct st_lsm6dsx_shub_settings { struct st_lsm6dsx_reg page_mux; - struct st_lsm6dsx_reg master_en; - struct st_lsm6dsx_reg pullup_en; + struct { + bool sec_page; + u8 addr; + u8 mask; + } master_en; + struct { + bool sec_page; + u8 addr; + u8 mask; + } pullup_en; struct st_lsm6dsx_reg aux_sens; struct st_lsm6dsx_reg wr_once; - u8 shub_out; + struct st_lsm6dsx_reg emb_func; + u8 num_ext_dev; + struct { + bool sec_page; + u8 addr; + } shub_out; u8 slv0_addr; u8 dw_slv0_addr; u8 batch_en; + u8 pause; }; struct st_lsm6dsx_event_settings { @@ -361,6 +379,7 @@ struct st_lsm6dsx_sensor { * @enable_event: enabled event bitmask. * @iio_devs: Pointers to acc/gyro iio_dev instances. * @settings: Pointer to the specific sensor settings in use. + * @orientation: sensor chip orientation relative to main hardware. */ struct st_lsm6dsx_hw { struct device *dev; @@ -387,16 +406,21 @@ struct st_lsm6dsx_hw { struct iio_dev *iio_devs[ST_LSM6DSX_ID_MAX]; const struct st_lsm6dsx_settings *settings; + + struct iio_mount_matrix orientation; }; -static const struct iio_event_spec st_lsm6dsx_event = { +static __maybe_unused const struct iio_event_spec st_lsm6dsx_event = { .type = IIO_EV_TYPE_THRESH, .dir = IIO_EV_DIR_EITHER, .mask_separate = BIT(IIO_EV_INFO_VALUE) | BIT(IIO_EV_INFO_ENABLE) }; -static const unsigned long st_lsm6dsx_available_scan_masks[] = {0x7, 0x0}; +static __maybe_unused const unsigned long st_lsm6dsx_available_scan_masks[] = { + 0x7, 0x0, +}; + extern const struct dev_pm_ops st_lsm6dsx_pm_ops; int st_lsm6dsx_probe(struct device *dev, int irq, int hw_id, @@ -457,4 +481,19 @@ st_lsm6dsx_write_locked(struct st_lsm6dsx_hw *hw, unsigned int addr, return err; } +static const inline struct iio_mount_matrix * +st_lsm6dsx_get_mount_matrix(const struct iio_dev *iio_dev, + const struct iio_chan_spec *chan) +{ + struct st_lsm6dsx_sensor *sensor = iio_priv(iio_dev); + struct st_lsm6dsx_hw *hw = sensor->hw; + + return &hw->orientation; +} + +static const struct iio_chan_spec_ext_info st_lsm6dsx_accel_ext_info[] = { + IIO_MOUNT_MATRIX(IIO_SHARED_BY_ALL, st_lsm6dsx_get_mount_matrix), + { } +}; + #endif /* ST_LSM6DSX_H */ diff --git a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_buffer.c b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_buffer.c index cb536b81a1c2..bb899345f2bb 100644 --- a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_buffer.c +++ b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_buffer.c @@ -336,12 +336,13 @@ static inline int st_lsm6dsx_read_block(struct st_lsm6dsx_hw *hw, u8 addr, */ int st_lsm6dsx_read_fifo(struct st_lsm6dsx_hw *hw) { + struct st_lsm6dsx_sensor *acc_sensor, *gyro_sensor, *ext_sensor = NULL; + int err, acc_sip, gyro_sip, ts_sip, ext_sip, read_len, offset; u16 fifo_len, pattern_len = hw->sip * ST_LSM6DSX_SAMPLE_SIZE; u16 fifo_diff_mask = hw->settings->fifo_ops.fifo_diff.mask; - int err, acc_sip, gyro_sip, ts_sip, read_len, offset; - struct st_lsm6dsx_sensor *acc_sensor, *gyro_sensor; u8 gyro_buff[ST_LSM6DSX_IIO_BUFF_SIZE]; u8 acc_buff[ST_LSM6DSX_IIO_BUFF_SIZE]; + u8 ext_buff[ST_LSM6DSX_IIO_BUFF_SIZE]; bool reset_ts = false; __le16 fifo_status; s64 ts = 0; @@ -364,6 +365,8 @@ int st_lsm6dsx_read_fifo(struct st_lsm6dsx_hw *hw) acc_sensor = iio_priv(hw->iio_devs[ST_LSM6DSX_ID_ACC]); gyro_sensor = iio_priv(hw->iio_devs[ST_LSM6DSX_ID_GYRO]); + if (hw->iio_devs[ST_LSM6DSX_ID_EXT0]) + ext_sensor = iio_priv(hw->iio_devs[ST_LSM6DSX_ID_EXT0]); for (read_len = 0; read_len < fifo_len; read_len += pattern_len) { err = st_lsm6dsx_read_block(hw, ST_LSM6DSX_REG_FIFO_OUTL_ADDR, @@ -391,12 +394,13 @@ int st_lsm6dsx_read_fifo(struct st_lsm6dsx_hw *hw) * following pattern is repeated every 9 samples: * - Gx, Gy, Gz, Ax, Ay, Az, Ts, Gx, Gy, Gz, Ts, Gx, .. */ + ext_sip = ext_sensor ? ext_sensor->sip : 0; gyro_sip = gyro_sensor->sip; acc_sip = acc_sensor->sip; ts_sip = hw->ts_sip; offset = 0; - while (acc_sip > 0 || gyro_sip > 0) { + while (acc_sip > 0 || gyro_sip > 0 || ext_sip > 0) { if (gyro_sip > 0) { memcpy(gyro_buff, &hw->buff[offset], ST_LSM6DSX_SAMPLE_SIZE); @@ -407,6 +411,11 @@ int st_lsm6dsx_read_fifo(struct st_lsm6dsx_hw *hw) ST_LSM6DSX_SAMPLE_SIZE); offset += ST_LSM6DSX_SAMPLE_SIZE; } + if (ext_sip > 0) { + memcpy(ext_buff, &hw->buff[offset], + ST_LSM6DSX_SAMPLE_SIZE); + offset += ST_LSM6DSX_SAMPLE_SIZE; + } if (ts_sip-- > 0) { u8 data[ST_LSM6DSX_SAMPLE_SIZE]; @@ -440,6 +449,10 @@ int st_lsm6dsx_read_fifo(struct st_lsm6dsx_hw *hw) iio_push_to_buffers_with_timestamp( hw->iio_devs[ST_LSM6DSX_ID_ACC], acc_buff, acc_sensor->ts_ref + ts); + if (ext_sip-- > 0) + iio_push_to_buffers_with_timestamp( + hw->iio_devs[ST_LSM6DSX_ID_EXT0], + ext_buff, ext_sensor->ts_ref + ts); } } @@ -638,12 +651,12 @@ int st_lsm6dsx_update_fifo(struct st_lsm6dsx_sensor *sensor, bool enable) 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) goto out; diff --git a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c index b921dd9e108f..84d219ae6aee 100644 --- a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c +++ b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c @@ -54,6 +54,7 @@ #include <linux/interrupt.h> #include <linux/irq.h> #include <linux/pm.h> +#include <linux/property.h> #include <linux/regmap.h> #include <linux/bitfield.h> @@ -655,6 +656,10 @@ static const struct st_lsm6dsx_settings st_lsm6dsx_sensor_settings[] = { .addr = 0x08, .mask = GENMASK(5, 3), }, + [ST_LSM6DSX_ID_EXT0] = { + .addr = 0x09, + .mask = GENMASK(2, 0), + }, }, .fifo_ops = { .update_fifo = st_lsm6dsx_update_fifo, @@ -687,6 +692,39 @@ static const struct st_lsm6dsx_settings st_lsm6dsx_sensor_settings[] = { .mask = GENMASK(5, 3), }, }, + .shub_settings = { + .page_mux = { + .addr = 0x01, + .mask = BIT(7), + }, + .master_en = { + .addr = 0x1a, + .mask = BIT(0), + }, + .pullup_en = { + .addr = 0x1a, + .mask = BIT(3), + }, + .aux_sens = { + .addr = 0x04, + .mask = GENMASK(5, 4), + }, + .wr_once = { + .addr = 0x07, + .mask = BIT(5), + }, + .emb_func = { + .addr = 0x19, + .mask = BIT(2), + }, + .num_ext_dev = 1, + .shub_out = { + .addr = 0x2e, + }, + .slv0_addr = 0x02, + .dw_slv0_addr = 0x0e, + .pause = 0x7, + }, .event_settings = { .enable_reg = { .addr = 0x58, @@ -867,10 +905,12 @@ static const struct st_lsm6dsx_settings st_lsm6dsx_sensor_settings[] = { .mask = BIT(6), }, .master_en = { + .sec_page = true, .addr = 0x14, .mask = BIT(2), }, .pullup_en = { + .sec_page = true, .addr = 0x14, .mask = BIT(3), }, @@ -882,7 +922,11 @@ static const struct st_lsm6dsx_settings st_lsm6dsx_sensor_settings[] = { .addr = 0x14, .mask = BIT(6), }, - .shub_out = 0x02, + .num_ext_dev = 3, + .shub_out = { + .sec_page = true, + .addr = 0x02, + }, .slv0_addr = 0x15, .dw_slv0_addr = 0x21, .batch_en = BIT(3), @@ -1241,10 +1285,12 @@ static const struct st_lsm6dsx_settings st_lsm6dsx_sensor_settings[] = { .mask = BIT(6), }, .master_en = { + .sec_page = true, .addr = 0x14, .mask = BIT(2), }, .pullup_en = { + .sec_page = true, .addr = 0x14, .mask = BIT(3), }, @@ -1256,7 +1302,11 @@ static const struct st_lsm6dsx_settings st_lsm6dsx_sensor_settings[] = { .addr = 0x14, .mask = BIT(6), }, - .shub_out = 0x02, + .num_ext_dev = 3, + .shub_out = { + .sec_page = true, + .addr = 0x02, + }, .slv0_addr = 0x15, .dw_slv0_addr = 0x21, .batch_en = BIT(3), @@ -1506,8 +1556,11 @@ static int st_lsm6dsx_read_oneshot(struct st_lsm6dsx_sensor *sensor, if (err < 0) return err; - if (!hw->enable_event) - st_lsm6dsx_sensor_set_enable(sensor, false); + if (!hw->enable_event) { + err = st_lsm6dsx_sensor_set_enable(sensor, false); + if (err < 0) + return err; + } *val = (s16)le16_to_cpu(data); @@ -1609,11 +1662,11 @@ static int st_lsm6dsx_event_setup(struct st_lsm6dsx_hw *hw, int state) } static int st_lsm6dsx_read_event(struct iio_dev *iio_dev, - const struct iio_chan_spec *chan, - enum iio_event_type type, - enum iio_event_direction dir, - enum iio_event_info info, - int *val, int *val2) + const struct iio_chan_spec *chan, + enum iio_event_type type, + enum iio_event_direction dir, + enum iio_event_info info, + int *val, int *val2) { struct st_lsm6dsx_sensor *sensor = iio_priv(iio_dev); struct st_lsm6dsx_hw *hw = sensor->hw; @@ -1827,14 +1880,14 @@ static const struct iio_info st_lsm6dsx_gyro_info = { .hwfifo_set_watermark = st_lsm6dsx_set_watermark, }; -static int st_lsm6dsx_of_get_drdy_pin(struct st_lsm6dsx_hw *hw, int *drdy_pin) +static int st_lsm6dsx_get_drdy_pin(struct st_lsm6dsx_hw *hw, int *drdy_pin) { - struct device_node *np = hw->dev->of_node; + struct device *dev = hw->dev; - if (!np) + if (!dev_fwnode(dev)) return -EINVAL; - return of_property_read_u32(np, "st,drdy-int-pin", drdy_pin); + return device_property_read_u32(dev, "st,drdy-int-pin", drdy_pin); } static int @@ -1843,7 +1896,7 @@ st_lsm6dsx_get_drdy_reg(struct st_lsm6dsx_hw *hw, { int err = 0, drdy_pin; - if (st_lsm6dsx_of_get_drdy_pin(hw, &drdy_pin) < 0) { + if (st_lsm6dsx_get_drdy_pin(hw, &drdy_pin) < 0) { struct st_sensors_platform_data *pdata; struct device *dev = hw->dev; @@ -1872,26 +1925,29 @@ st_lsm6dsx_get_drdy_reg(struct st_lsm6dsx_hw *hw, static int st_lsm6dsx_init_shub(struct st_lsm6dsx_hw *hw) { const struct st_lsm6dsx_shub_settings *hub_settings; - struct device_node *np = hw->dev->of_node; struct st_sensors_platform_data *pdata; + struct device *dev = hw->dev; unsigned int data; int err = 0; hub_settings = &hw->settings->shub_settings; - pdata = (struct st_sensors_platform_data *)hw->dev->platform_data; - if ((np && of_property_read_bool(np, "st,pullups")) || + pdata = (struct st_sensors_platform_data *)dev->platform_data; + if ((dev_fwnode(dev) && device_property_read_bool(dev, "st,pullups")) || (pdata && pdata->pullups)) { - err = st_lsm6dsx_set_page(hw, true); - if (err < 0) - return err; + if (hub_settings->pullup_en.sec_page) { + err = st_lsm6dsx_set_page(hw, true); + if (err < 0) + return err; + } data = ST_LSM6DSX_SHIFT_VAL(1, hub_settings->pullup_en.mask); err = regmap_update_bits(hw->regmap, hub_settings->pullup_en.addr, hub_settings->pullup_en.mask, data); - st_lsm6dsx_set_page(hw, false); + if (hub_settings->pullup_en.sec_page) + st_lsm6dsx_set_page(hw, false); if (err < 0) return err; @@ -1909,6 +1965,16 @@ static int st_lsm6dsx_init_shub(struct st_lsm6dsx_hw *hw) hub_settings->aux_sens.mask, data); st_lsm6dsx_set_page(hw, false); + + if (err < 0) + return err; + } + + if (hub_settings->emb_func.addr) { + data = ST_LSM6DSX_SHIFT_VAL(1, hub_settings->emb_func.mask); + err = regmap_update_bits(hw->regmap, + hub_settings->emb_func.addr, + hub_settings->emb_func.mask, data); } return err; @@ -2158,9 +2224,9 @@ static irqreturn_t st_lsm6dsx_handler_thread(int irq, void *private) static int st_lsm6dsx_irq_setup(struct st_lsm6dsx_hw *hw) { - struct device_node *np = hw->dev->of_node; struct st_sensors_platform_data *pdata; const struct st_lsm6dsx_reg *reg; + struct device *dev = hw->dev; unsigned long irq_type; bool irq_active_low; int err; @@ -2188,8 +2254,8 @@ static int st_lsm6dsx_irq_setup(struct st_lsm6dsx_hw *hw) if (err < 0) return err; - pdata = (struct st_sensors_platform_data *)hw->dev->platform_data; - if ((np && of_property_read_bool(np, "drive-open-drain")) || + pdata = (struct st_sensors_platform_data *)dev->platform_data; + if ((dev_fwnode(dev) && device_property_read_bool(dev, "drive-open-drain")) || (pdata && pdata->open_drain)) { reg = &hw->settings->irq_config.od; err = regmap_update_bits(hw->regmap, reg->addr, reg->mask, @@ -2219,7 +2285,6 @@ int st_lsm6dsx_probe(struct device *dev, int irq, int hw_id, { struct st_sensors_platform_data *pdata = dev->platform_data; const struct st_lsm6dsx_shub_settings *hub_settings; - struct device_node *np = dev->of_node; struct st_lsm6dsx_hw *hw; const char *name = NULL; int i, err; @@ -2273,6 +2338,10 @@ int st_lsm6dsx_probe(struct device *dev, int irq, int hw_id, return err; } + err = iio_read_mount_matrix(hw->dev, "mount-matrix", &hw->orientation); + if (err) + return err; + for (i = 0; i < ST_LSM6DSX_ID_MAX; i++) { if (!hw->iio_devs[i]) continue; @@ -2282,7 +2351,7 @@ int st_lsm6dsx_probe(struct device *dev, int irq, int hw_id, return err; } - if ((np && of_property_read_bool(np, "wakeup-source")) || + if ((dev_fwnode(dev) && device_property_read_bool(dev, "wakeup-source")) || (pdata && pdata->wakeup_source)) device_init_wakeup(dev, true); diff --git a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_i2c.c b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_i2c.c index cd47ec1fedcb..0fb32131afce 100644 --- a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_i2c.c +++ b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_i2c.c @@ -12,7 +12,6 @@ #include <linux/module.h> #include <linux/i2c.h> #include <linux/slab.h> -#include <linux/of.h> #include <linux/regmap.h> #include "st_lsm6dsx.h" @@ -122,7 +121,7 @@ static struct i2c_driver st_lsm6dsx_driver = { .driver = { .name = "st_lsm6dsx_i2c", .pm = &st_lsm6dsx_pm_ops, - .of_match_table = of_match_ptr(st_lsm6dsx_i2c_of_match), + .of_match_table = st_lsm6dsx_i2c_of_match, }, .probe = st_lsm6dsx_i2c_probe, .id_table = st_lsm6dsx_i2c_id_table, diff --git a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_shub.c b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_shub.c index fa5d1001a46c..eea555617d4a 100644 --- a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_shub.c +++ b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_shub.c @@ -30,7 +30,6 @@ #include "st_lsm6dsx.h" -#define ST_LSM6DSX_MAX_SLV_NUM 3 #define ST_LSM6DSX_SLV_ADDR(n, base) ((base) + (n) * 3) #define ST_LSM6DSX_SLV_SUB_ADDR(n, base) ((base) + 1 + (n) * 3) #define ST_LSM6DSX_SLV_CONFIG(n, base) ((base) + 2 + (n) * 3) @@ -102,24 +101,31 @@ static void st_lsm6dsx_shub_wait_complete(struct st_lsm6dsx_hw *hw) } /** - * st_lsm6dsx_shub_read_reg - read i2c controller register + * st_lsm6dsx_shub_read_output - read i2c controller register * * Read st_lsm6dsx i2c controller register */ -static int st_lsm6dsx_shub_read_reg(struct st_lsm6dsx_hw *hw, u8 addr, - u8 *data, int len) +static int +st_lsm6dsx_shub_read_output(struct st_lsm6dsx_hw *hw, u8 *data, + int len) { + const struct st_lsm6dsx_shub_settings *hub_settings; int err; mutex_lock(&hw->page_lock); - err = st_lsm6dsx_set_page(hw, true); - if (err < 0) - goto out; + hub_settings = &hw->settings->shub_settings; + if (hub_settings->shub_out.sec_page) { + err = st_lsm6dsx_set_page(hw, true); + if (err < 0) + goto out; + } - err = regmap_bulk_read(hw->regmap, addr, data, len); + err = regmap_bulk_read(hw->regmap, hub_settings->shub_out.addr, + data, len); - st_lsm6dsx_set_page(hw, false); + if (hub_settings->shub_out.sec_page) + st_lsm6dsx_set_page(hw, false); out: mutex_unlock(&hw->page_lock); @@ -186,15 +192,18 @@ static int st_lsm6dsx_shub_master_enable(struct st_lsm6dsx_sensor *sensor, mutex_lock(&hw->page_lock); hub_settings = &hw->settings->shub_settings; - err = st_lsm6dsx_set_page(hw, true); - if (err < 0) - goto out; + if (hub_settings->master_en.sec_page) { + err = st_lsm6dsx_set_page(hw, true); + if (err < 0) + goto out; + } data = ST_LSM6DSX_SHIFT_VAL(enable, hub_settings->master_en.mask); err = regmap_update_bits(hw->regmap, hub_settings->master_en.addr, hub_settings->master_en.mask, data); - st_lsm6dsx_set_page(hw, false); + if (hub_settings->master_en.sec_page) + st_lsm6dsx_set_page(hw, false); out: mutex_unlock(&hw->page_lock); @@ -212,16 +221,21 @@ st_lsm6dsx_shub_read(struct st_lsm6dsx_sensor *sensor, u8 addr, u8 *data, int len) { const struct st_lsm6dsx_shub_settings *hub_settings; + u8 config[3], slv_addr, slv_config = 0; struct st_lsm6dsx_hw *hw = sensor->hw; - u8 config[3], slv_addr; + const struct st_lsm6dsx_reg *aux_sens; int err; hub_settings = &hw->settings->shub_settings; slv_addr = ST_LSM6DSX_SLV_ADDR(0, hub_settings->slv0_addr); + aux_sens = &hw->settings->shub_settings.aux_sens; + /* do not overwrite aux_sens */ + if (slv_addr + 2 == aux_sens->addr) + slv_config = ST_LSM6DSX_SHIFT_VAL(3, aux_sens->mask); config[0] = (sensor->ext_info.addr << 1) | 1; config[1] = addr; - config[2] = len & ST_LS6DSX_READ_OP_MASK; + config[2] = (len & ST_LS6DSX_READ_OP_MASK) | slv_config; err = st_lsm6dsx_shub_write_reg(hw, slv_addr, config, sizeof(config)); @@ -234,12 +248,14 @@ st_lsm6dsx_shub_read(struct st_lsm6dsx_sensor *sensor, u8 addr, st_lsm6dsx_shub_wait_complete(hw); - err = st_lsm6dsx_shub_read_reg(hw, hub_settings->shub_out, data, - len & ST_LS6DSX_READ_OP_MASK); + err = st_lsm6dsx_shub_read_output(hw, data, + len & ST_LS6DSX_READ_OP_MASK); st_lsm6dsx_shub_master_enable(sensor, false); - memset(config, 0, sizeof(config)); + config[0] = hub_settings->pause; + config[1] = 0; + config[2] = slv_config; return st_lsm6dsx_shub_write_reg(hw, slv_addr, config, sizeof(config)); } @@ -296,7 +312,8 @@ st_lsm6dsx_shub_write(struct st_lsm6dsx_sensor *sensor, u8 addr, st_lsm6dsx_shub_master_enable(sensor, false); } - memset(config, 0, sizeof(config)); + config[0] = hub_settings->pause; + config[1] = 0; return st_lsm6dsx_shub_write_reg(hw, slv_addr, config, sizeof(config)); } @@ -688,14 +705,19 @@ st_lsm6dsx_shub_check_wai(struct st_lsm6dsx_hw *hw, u8 *i2c_addr, const struct st_lsm6dsx_ext_dev_settings *settings) { const struct st_lsm6dsx_shub_settings *hub_settings; + u8 config[3], data, slv_addr, slv_config = 0; + const struct st_lsm6dsx_reg *aux_sens; struct st_lsm6dsx_sensor *sensor; - u8 config[3], data, slv_addr; bool found = false; int i, err; + sensor = iio_priv(hw->iio_devs[ST_LSM6DSX_ID_ACC]); hub_settings = &hw->settings->shub_settings; + aux_sens = &hw->settings->shub_settings.aux_sens; slv_addr = ST_LSM6DSX_SLV_ADDR(0, hub_settings->slv0_addr); - sensor = iio_priv(hw->iio_devs[ST_LSM6DSX_ID_ACC]); + /* do not overwrite aux_sens */ + if (slv_addr + 2 == aux_sens->addr) + slv_config = ST_LSM6DSX_SHIFT_VAL(3, aux_sens->mask); for (i = 0; i < ARRAY_SIZE(settings->i2c_addr); i++) { if (!settings->i2c_addr[i]) @@ -704,7 +726,7 @@ st_lsm6dsx_shub_check_wai(struct st_lsm6dsx_hw *hw, u8 *i2c_addr, /* read wai slave register */ config[0] = (settings->i2c_addr[i] << 1) | 0x1; config[1] = settings->wai.addr; - config[2] = 0x1; + config[2] = 0x1 | slv_config; err = st_lsm6dsx_shub_write_reg(hw, slv_addr, config, sizeof(config)); @@ -717,9 +739,7 @@ st_lsm6dsx_shub_check_wai(struct st_lsm6dsx_hw *hw, u8 *i2c_addr, st_lsm6dsx_shub_wait_complete(hw); - err = st_lsm6dsx_shub_read_reg(hw, - hub_settings->shub_out, - &data, sizeof(data)); + err = st_lsm6dsx_shub_read_output(hw, &data, sizeof(data)); st_lsm6dsx_shub_master_enable(sensor, false); @@ -735,7 +755,9 @@ st_lsm6dsx_shub_check_wai(struct st_lsm6dsx_hw *hw, u8 *i2c_addr, } /* reset SLV0 channel */ - memset(config, 0, sizeof(config)); + config[0] = hub_settings->pause; + config[1] = 0; + config[2] = slv_config; err = st_lsm6dsx_shub_write_reg(hw, slv_addr, config, sizeof(config)); if (err < 0) @@ -770,7 +792,7 @@ int st_lsm6dsx_shub_probe(struct st_lsm6dsx_hw *hw, const char *name) if (err < 0) return err; - if (++num_ext_dev >= ST_LSM6DSX_MAX_SLV_NUM) + if (++num_ext_dev >= hw->settings->shub_settings.num_ext_dev) break; id++; } diff --git a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_spi.c b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_spi.c index 67ff36eac247..eb1086e4a951 100644 --- a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_spi.c +++ b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_spi.c @@ -12,7 +12,6 @@ #include <linux/module.h> #include <linux/spi/spi.h> #include <linux/slab.h> -#include <linux/of.h> #include <linux/regmap.h> #include "st_lsm6dsx.h" @@ -122,7 +121,7 @@ static struct spi_driver st_lsm6dsx_driver = { .driver = { .name = "st_lsm6dsx_spi", .pm = &st_lsm6dsx_pm_ops, - .of_match_table = of_match_ptr(st_lsm6dsx_spi_of_match), + .of_match_table = st_lsm6dsx_spi_of_match, }, .probe = st_lsm6dsx_spi_probe, .id_table = st_lsm6dsx_spi_id_table, |