diff options
Diffstat (limited to 'drivers/iio/imu')
20 files changed, 568 insertions, 173 deletions
diff --git a/drivers/iio/imu/adis.c b/drivers/iio/imu/adis.c index f7fcfd04f659..bc40240b29e2 100644 --- a/drivers/iio/imu/adis.c +++ b/drivers/iio/imu/adis.c @@ -270,23 +270,19 @@ EXPORT_SYMBOL_NS(adis_debugfs_reg_access, IIO_ADISLIB); #endif /** - * adis_enable_irq() - Enable or disable data ready IRQ + * __adis_enable_irq() - Enable or disable data ready IRQ (unlocked) * @adis: The adis device * @enable: Whether to enable the IRQ * * Returns 0 on success, negative error code otherwise */ -int adis_enable_irq(struct adis *adis, bool enable) +int __adis_enable_irq(struct adis *adis, bool enable) { - int ret = 0; + int ret; u16 msc; - mutex_lock(&adis->state_lock); - - if (adis->data->enable_irq) { - ret = adis->data->enable_irq(adis, enable); - goto out_unlock; - } + if (adis->data->enable_irq) + return adis->data->enable_irq(adis, enable); if (adis->data->unmasked_drdy) { if (enable) @@ -294,12 +290,12 @@ int adis_enable_irq(struct adis *adis, bool enable) else disable_irq(adis->spi->irq); - goto out_unlock; + return 0; } ret = __adis_read_reg_16(adis, adis->data->msc_ctrl_reg, &msc); if (ret) - goto out_unlock; + return ret; msc |= ADIS_MSC_CTRL_DATA_RDY_POL_HIGH; msc &= ~ADIS_MSC_CTRL_DATA_RDY_DIO2; @@ -308,13 +304,9 @@ int adis_enable_irq(struct adis *adis, bool enable) else msc &= ~ADIS_MSC_CTRL_DATA_RDY_EN; - ret = __adis_write_reg_16(adis, adis->data->msc_ctrl_reg, msc); - -out_unlock: - mutex_unlock(&adis->state_lock); - return ret; + return __adis_write_reg_16(adis, adis->data->msc_ctrl_reg, msc); } -EXPORT_SYMBOL_NS(adis_enable_irq, IIO_ADISLIB); +EXPORT_SYMBOL_NS(__adis_enable_irq, IIO_ADISLIB); /** * __adis_check_status() - Check the device for error conditions (unlocked) @@ -445,7 +437,7 @@ int __adis_initial_startup(struct adis *adis) * with 'IRQF_NO_AUTOEN' anyways. */ if (!adis->data->unmasked_drdy) - adis_enable_irq(adis, false); + __adis_enable_irq(adis, false); if (!adis->data->prod_id_reg) return 0; diff --git a/drivers/iio/imu/adis16400.c b/drivers/iio/imu/adis16400.c index 17bb0c40a149..c02fc35dceb4 100644 --- a/drivers/iio/imu/adis16400.c +++ b/drivers/iio/imu/adis16400.c @@ -445,7 +445,7 @@ static int adis16400_initial_setup(struct iio_dev *indio_dev) st->adis.spi->mode = SPI_MODE_3; spi_setup(st->adis.spi); - ret = adis_initial_startup(&st->adis); + ret = __adis_initial_startup(&st->adis); if (ret) return ret; diff --git a/drivers/iio/imu/bmi160/bmi160_i2c.c b/drivers/iio/imu/bmi160/bmi160_i2c.c index d93f4fa2ad55..2ca907d396a0 100644 --- a/drivers/iio/imu/bmi160/bmi160_i2c.c +++ b/drivers/iio/imu/bmi160/bmi160_i2c.c @@ -15,9 +15,9 @@ #include "bmi160.h" -static int bmi160_i2c_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int bmi160_i2c_probe(struct i2c_client *client) { + const struct i2c_device_id *id = i2c_client_get_device_id(client); struct regmap *regmap; const char *name; @@ -60,7 +60,7 @@ static struct i2c_driver bmi160_i2c_driver = { .acpi_match_table = bmi160_acpi_match, .of_match_table = bmi160_of_match, }, - .probe = bmi160_i2c_probe, + .probe_new = bmi160_i2c_probe, .id_table = bmi160_i2c_id, }; module_i2c_driver(bmi160_i2c_driver); diff --git a/drivers/iio/imu/fxos8700_i2c.c b/drivers/iio/imu/fxos8700_i2c.c index 40a570325b0a..a74a15fda8cb 100644 --- a/drivers/iio/imu/fxos8700_i2c.c +++ b/drivers/iio/imu/fxos8700_i2c.c @@ -18,9 +18,9 @@ #include "fxos8700.h" -static int fxos8700_i2c_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int fxos8700_i2c_probe(struct i2c_client *client) { + const struct i2c_device_id *id = i2c_client_get_device_id(client); struct regmap *regmap; const char *name = NULL; @@ -60,7 +60,7 @@ static struct i2c_driver fxos8700_i2c_driver = { .acpi_match_table = ACPI_PTR(fxos8700_acpi_match), .of_match_table = fxos8700_of_match, }, - .probe = fxos8700_i2c_probe, + .probe_new = fxos8700_i2c_probe, .id_table = fxos8700_i2c_id, }; module_i2c_driver(fxos8700_i2c_driver); diff --git a/drivers/iio/imu/inv_icm42600/inv_icm42600.h b/drivers/iio/imu/inv_icm42600/inv_icm42600.h index 3d91469beccb..0e290c807b0f 100644 --- a/drivers/iio/imu/inv_icm42600/inv_icm42600.h +++ b/drivers/iio/imu/inv_icm42600/inv_icm42600.h @@ -22,6 +22,7 @@ enum inv_icm42600_chip { INV_CHIP_ICM42602, INV_CHIP_ICM42605, INV_CHIP_ICM42622, + INV_CHIP_ICM42631, INV_CHIP_NB, }; @@ -303,6 +304,7 @@ struct inv_icm42600_state { #define INV_ICM42600_WHOAMI_ICM42602 0x41 #define INV_ICM42600_WHOAMI_ICM42605 0x42 #define INV_ICM42600_WHOAMI_ICM42622 0x46 +#define INV_ICM42600_WHOAMI_ICM42631 0x5C /* User bank 1 (MSB 0x10) */ #define INV_ICM42600_REG_SENSOR_CONFIG0 0x1003 diff --git a/drivers/iio/imu/inv_icm42600/inv_icm42600_core.c b/drivers/iio/imu/inv_icm42600/inv_icm42600_core.c index ca85fccc9839..7b3a2a0dc2cb 100644 --- a/drivers/iio/imu/inv_icm42600/inv_icm42600_core.c +++ b/drivers/iio/imu/inv_icm42600/inv_icm42600_core.c @@ -41,7 +41,7 @@ const struct regmap_config inv_icm42600_regmap_config = { .ranges = inv_icm42600_regmap_ranges, .num_ranges = ARRAY_SIZE(inv_icm42600_regmap_ranges), }; -EXPORT_SYMBOL_GPL(inv_icm42600_regmap_config); +EXPORT_SYMBOL_NS_GPL(inv_icm42600_regmap_config, IIO_ICM42600); struct inv_icm42600_hw { uint8_t whoami; @@ -87,6 +87,11 @@ static const struct inv_icm42600_hw inv_icm42600_hw[INV_CHIP_NB] = { .name = "icm42622", .conf = &inv_icm42600_default_conf, }, + [INV_CHIP_ICM42631] = { + .whoami = INV_ICM42600_WHOAMI_ICM42631, + .name = "icm42631", + .conf = &inv_icm42600_default_conf, + }, }; const struct iio_mount_matrix * @@ -660,13 +665,13 @@ int inv_icm42600_core_probe(struct regmap *regmap, int chip, int irq, return devm_add_action_or_reset(dev, inv_icm42600_disable_pm, dev); } -EXPORT_SYMBOL_GPL(inv_icm42600_core_probe); +EXPORT_SYMBOL_NS_GPL(inv_icm42600_core_probe, IIO_ICM42600); /* * Suspend saves sensors state and turns everything off. * Check first if runtime suspend has not already done the job. */ -static int __maybe_unused inv_icm42600_suspend(struct device *dev) +static int inv_icm42600_suspend(struct device *dev) { struct inv_icm42600_state *st = dev_get_drvdata(dev); int ret; @@ -706,7 +711,7 @@ out_unlock: * System resume gets the system back on and restores the sensors state. * Manually put runtime power management in system active state. */ -static int __maybe_unused inv_icm42600_resume(struct device *dev) +static int inv_icm42600_resume(struct device *dev) { struct inv_icm42600_state *st = dev_get_drvdata(dev); int ret; @@ -739,7 +744,7 @@ out_unlock: } /* Runtime suspend will turn off sensors that are enabled by iio devices. */ -static int __maybe_unused inv_icm42600_runtime_suspend(struct device *dev) +static int inv_icm42600_runtime_suspend(struct device *dev) { struct inv_icm42600_state *st = dev_get_drvdata(dev); int ret; @@ -761,7 +766,7 @@ error_unlock: } /* Sensors are enabled by iio devices, no need to turn them back on here. */ -static int __maybe_unused inv_icm42600_runtime_resume(struct device *dev) +static int inv_icm42600_runtime_resume(struct device *dev) { struct inv_icm42600_state *st = dev_get_drvdata(dev); int ret; @@ -774,12 +779,11 @@ static int __maybe_unused inv_icm42600_runtime_resume(struct device *dev) return ret; } -const struct dev_pm_ops inv_icm42600_pm_ops = { - SET_SYSTEM_SLEEP_PM_OPS(inv_icm42600_suspend, inv_icm42600_resume) - SET_RUNTIME_PM_OPS(inv_icm42600_runtime_suspend, - inv_icm42600_runtime_resume, NULL) +EXPORT_NS_GPL_DEV_PM_OPS(inv_icm42600_pm_ops, IIO_ICM42600) = { + SYSTEM_SLEEP_PM_OPS(inv_icm42600_suspend, inv_icm42600_resume) + RUNTIME_PM_OPS(inv_icm42600_runtime_suspend, + inv_icm42600_runtime_resume, NULL) }; -EXPORT_SYMBOL_GPL(inv_icm42600_pm_ops); MODULE_AUTHOR("InvenSense, Inc."); MODULE_DESCRIPTION("InvenSense ICM-426xx device driver"); diff --git a/drivers/iio/imu/inv_icm42600/inv_icm42600_i2c.c b/drivers/iio/imu/inv_icm42600/inv_icm42600_i2c.c index d4a692b838d0..eb2681ad375f 100644 --- a/drivers/iio/imu/inv_icm42600/inv_icm42600_i2c.c +++ b/drivers/iio/imu/inv_icm42600/inv_icm42600_i2c.c @@ -84,6 +84,9 @@ static const struct of_device_id inv_icm42600_of_matches[] = { }, { .compatible = "invensense,icm42622", .data = (void *)INV_CHIP_ICM42622, + }, { + .compatible = "invensense,icm42631", + .data = (void *)INV_CHIP_ICM42631, }, {} }; @@ -93,7 +96,7 @@ static struct i2c_driver inv_icm42600_driver = { .driver = { .name = "inv-icm42600-i2c", .of_match_table = inv_icm42600_of_matches, - .pm = &inv_icm42600_pm_ops, + .pm = pm_ptr(&inv_icm42600_pm_ops), }, .probe_new = inv_icm42600_probe, }; @@ -102,3 +105,4 @@ module_i2c_driver(inv_icm42600_driver); MODULE_AUTHOR("InvenSense, Inc."); MODULE_DESCRIPTION("InvenSense ICM-426xx I2C driver"); MODULE_LICENSE("GPL"); +MODULE_IMPORT_NS(IIO_ICM42600); diff --git a/drivers/iio/imu/inv_icm42600/inv_icm42600_spi.c b/drivers/iio/imu/inv_icm42600/inv_icm42600_spi.c index e6305e5fa975..6be4ac794937 100644 --- a/drivers/iio/imu/inv_icm42600/inv_icm42600_spi.c +++ b/drivers/iio/imu/inv_icm42600/inv_icm42600_spi.c @@ -80,6 +80,9 @@ static const struct of_device_id inv_icm42600_of_matches[] = { }, { .compatible = "invensense,icm42622", .data = (void *)INV_CHIP_ICM42622, + }, { + .compatible = "invensense,icm42631", + .data = (void *)INV_CHIP_ICM42631, }, {} }; @@ -89,7 +92,7 @@ static struct spi_driver inv_icm42600_driver = { .driver = { .name = "inv-icm42600-spi", .of_match_table = inv_icm42600_of_matches, - .pm = &inv_icm42600_pm_ops, + .pm = pm_ptr(&inv_icm42600_pm_ops), }, .probe = inv_icm42600_probe, }; @@ -98,3 +101,4 @@ module_spi_driver(inv_icm42600_driver); MODULE_AUTHOR("InvenSense, Inc."); MODULE_DESCRIPTION("InvenSense ICM-426xx SPI driver"); MODULE_LICENSE("GPL"); +MODULE_IMPORT_NS(IIO_ICM42600); diff --git a/drivers/iio/imu/inv_mpu6050/inv_mpu_core.c b/drivers/iio/imu/inv_mpu6050/inv_mpu_core.c index 86fbbe904050..8a129120b73d 100644 --- a/drivers/iio/imu/inv_mpu6050/inv_mpu_core.c +++ b/drivers/iio/imu/inv_mpu6050/inv_mpu_core.c @@ -1653,9 +1653,9 @@ error_power_off: inv_mpu6050_set_power_itg(st, false); return result; } -EXPORT_SYMBOL_GPL(inv_mpu_core_probe); +EXPORT_SYMBOL_NS_GPL(inv_mpu_core_probe, IIO_MPU6050); -static int __maybe_unused inv_mpu_resume(struct device *dev) +static int inv_mpu_resume(struct device *dev) { struct iio_dev *indio_dev = dev_get_drvdata(dev); struct inv_mpu6050_state *st = iio_priv(indio_dev); @@ -1687,7 +1687,7 @@ out_unlock: return result; } -static int __maybe_unused inv_mpu_suspend(struct device *dev) +static int inv_mpu_suspend(struct device *dev) { struct iio_dev *indio_dev = dev_get_drvdata(dev); struct inv_mpu6050_state *st = iio_priv(indio_dev); @@ -1730,7 +1730,7 @@ out_unlock: return result; } -static int __maybe_unused inv_mpu_runtime_suspend(struct device *dev) +static int inv_mpu_runtime_suspend(struct device *dev) { struct inv_mpu6050_state *st = iio_priv(dev_get_drvdata(dev)); unsigned int sensors; @@ -1755,7 +1755,7 @@ out_unlock: return ret; } -static int __maybe_unused inv_mpu_runtime_resume(struct device *dev) +static int inv_mpu_runtime_resume(struct device *dev) { struct inv_mpu6050_state *st = iio_priv(dev_get_drvdata(dev)); int ret; @@ -1767,11 +1767,10 @@ static int __maybe_unused inv_mpu_runtime_resume(struct device *dev) return inv_mpu6050_set_power_itg(st, true); } -const struct dev_pm_ops inv_mpu_pmops = { - SET_SYSTEM_SLEEP_PM_OPS(inv_mpu_suspend, inv_mpu_resume) - SET_RUNTIME_PM_OPS(inv_mpu_runtime_suspend, inv_mpu_runtime_resume, NULL) +EXPORT_NS_GPL_DEV_PM_OPS(inv_mpu_pmops, IIO_MPU6050) = { + SYSTEM_SLEEP_PM_OPS(inv_mpu_suspend, inv_mpu_resume) + RUNTIME_PM_OPS(inv_mpu_runtime_suspend, inv_mpu_runtime_resume, NULL) }; -EXPORT_SYMBOL_GPL(inv_mpu_pmops); MODULE_AUTHOR("Invensense Corporation"); MODULE_DESCRIPTION("Invensense device MPU6050 driver"); diff --git a/drivers/iio/imu/inv_mpu6050/inv_mpu_i2c.c b/drivers/iio/imu/inv_mpu6050/inv_mpu_i2c.c index 14255a918eb1..2f2da4cb7321 100644 --- a/drivers/iio/imu/inv_mpu6050/inv_mpu_i2c.c +++ b/drivers/iio/imu/inv_mpu6050/inv_mpu_i2c.c @@ -91,13 +91,12 @@ static int inv_mpu_i2c_aux_setup(struct iio_dev *indio_dev) /** * inv_mpu_probe() - probe function. * @client: i2c client. - * @id: i2c device id. * * Returns 0 on success, a negative error code otherwise. */ -static int inv_mpu_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int inv_mpu_probe(struct i2c_client *client) { + const struct i2c_device_id *id = i2c_client_get_device_id(client); const void *match; struct inv_mpu6050_state *st; int result; @@ -260,14 +259,14 @@ static const struct acpi_device_id inv_acpi_match[] = { MODULE_DEVICE_TABLE(acpi, inv_acpi_match); static struct i2c_driver inv_mpu_driver = { - .probe = inv_mpu_probe, + .probe_new = inv_mpu_probe, .remove = inv_mpu_remove, .id_table = inv_mpu_id, .driver = { .of_match_table = inv_of_match, .acpi_match_table = inv_acpi_match, .name = "inv-mpu6050-i2c", - .pm = &inv_mpu_pmops, + .pm = pm_ptr(&inv_mpu_pmops), }, }; @@ -276,3 +275,4 @@ module_i2c_driver(inv_mpu_driver); MODULE_AUTHOR("Invensense Corporation"); MODULE_DESCRIPTION("Invensense device MPU6050 driver"); MODULE_LICENSE("GPL"); +MODULE_IMPORT_NS(IIO_MPU6050); diff --git a/drivers/iio/imu/inv_mpu6050/inv_mpu_spi.c b/drivers/iio/imu/inv_mpu6050/inv_mpu_spi.c index e6107b0cc38f..89f46c2f213d 100644 --- a/drivers/iio/imu/inv_mpu6050/inv_mpu_spi.c +++ b/drivers/iio/imu/inv_mpu6050/inv_mpu_spi.c @@ -154,7 +154,7 @@ static struct spi_driver inv_mpu_driver = { .of_match_table = inv_of_match, .acpi_match_table = inv_acpi_match, .name = "inv-mpu6000-spi", - .pm = &inv_mpu_pmops, + .pm = pm_ptr(&inv_mpu_pmops), }, }; @@ -163,3 +163,4 @@ module_spi_driver(inv_mpu_driver); MODULE_AUTHOR("Adriana Reus <adriana.reus@intel.com>"); MODULE_DESCRIPTION("Invensense device MPU6000 driver"); MODULE_LICENSE("GPL"); +MODULE_IMPORT_NS(IIO_MPU6050); diff --git a/drivers/iio/imu/kmx61.c b/drivers/iio/imu/kmx61.c index b10c0dcac0bb..e692dfeeda44 100644 --- a/drivers/iio/imu/kmx61.c +++ b/drivers/iio/imu/kmx61.c @@ -1276,9 +1276,9 @@ static struct iio_trigger *kmx61_trigger_setup(struct kmx61_data *data, return trig; } -static int kmx61_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int kmx61_probe(struct i2c_client *client) { + const struct i2c_device_id *id = i2c_client_get_device_id(client); int ret; struct kmx61_data *data; const char *name = NULL; @@ -1517,7 +1517,7 @@ static struct i2c_driver kmx61_driver = { .acpi_match_table = ACPI_PTR(kmx61_acpi_match), .pm = pm_ptr(&kmx61_pm_ops), }, - .probe = kmx61_probe, + .probe_new = kmx61_probe, .remove = kmx61_remove, .id_table = kmx61_id, }; diff --git a/drivers/iio/imu/st_lsm6dsx/Kconfig b/drivers/iio/imu/st_lsm6dsx/Kconfig index 2ed2b3f40c0b..f6660847fb58 100644 --- a/drivers/iio/imu/st_lsm6dsx/Kconfig +++ b/drivers/iio/imu/st_lsm6dsx/Kconfig @@ -13,7 +13,8 @@ config IIO_ST_LSM6DSX sensor. Supported devices: lsm6ds3, lsm6ds3h, lsm6dsl, lsm6dsm, ism330dlc, lsm6dso, lsm6dsox, asm330lhh, asm330lhhx, lsm6dsr, lsm6ds3tr-c, ism330dhcx, lsm6dsrx, lsm6ds0, lsm6dsop, lsm6dstx, - the accelerometer/gyroscope of lsm9ds1 and lsm6dst. + lsm6dsv, lsm6dsv16x, lsm6dso16is, ism330is, lsm6dst and the + accelerometer/gyroscope of lsm9ds1. To compile this driver as a module, choose M here: the module will be called st_lsm6dsx. diff --git a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx.h b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx.h index 6b57d47be69e..5b6f195748fc 100644 --- a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx.h +++ b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx.h @@ -33,6 +33,10 @@ #define ST_LSM6DSOP_DEV_NAME "lsm6dsop" #define ST_ASM330LHHX_DEV_NAME "asm330lhhx" #define ST_LSM6DSTX_DEV_NAME "lsm6dstx" +#define ST_LSM6DSV_DEV_NAME "lsm6dsv" +#define ST_LSM6DSV16X_DEV_NAME "lsm6dsv16x" +#define ST_LSM6DSO16IS_DEV_NAME "lsm6dso16is" +#define ST_ISM330IS_DEV_NAME "ism330is" enum st_lsm6dsx_hw_id { ST_LSM6DS3_ID, @@ -53,6 +57,10 @@ enum st_lsm6dsx_hw_id { ST_LSM6DSOP_ID, ST_ASM330LHHX_ID, ST_LSM6DSTX_ID, + ST_LSM6DSV_ID, + ST_LSM6DSV16X_ID, + ST_LSM6DSO16IS_ID, + ST_ISM330IS_ID, ST_LSM6DSX_MAX_ID, }; @@ -374,7 +382,6 @@ struct st_lsm6dsx_sensor { * struct st_lsm6dsx_hw - ST IMU MEMS hw instance * @dev: Pointer to instance of struct device (I2C or SPI). * @regmap: Register map of the device. - * @regulators: VDD/VDDIO voltage regulators. * @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. @@ -397,7 +404,6 @@ struct st_lsm6dsx_sensor { struct st_lsm6dsx_hw { struct device *dev; struct regmap *regmap; - struct regulator_bulk_data regulators[2]; int irq; struct mutex fifo_lock; @@ -426,7 +432,7 @@ struct st_lsm6dsx_hw { struct { __le16 channels[3]; s64 ts __aligned(8); - } scan[3]; + } scan[ST_LSM6DSX_ID_MAX]; }; static __maybe_unused const struct iio_event_spec st_lsm6dsx_event = { @@ -458,6 +464,7 @@ int st_lsm6dsx_read_tagged_fifo(struct st_lsm6dsx_hw *hw); int st_lsm6dsx_check_odr(struct st_lsm6dsx_sensor *sensor, u32 odr, u8 *val); int st_lsm6dsx_shub_probe(struct st_lsm6dsx_hw *hw, const char *name); int st_lsm6dsx_shub_set_enable(struct st_lsm6dsx_sensor *sensor, bool enable); +int st_lsm6dsx_shub_read_output(struct st_lsm6dsx_hw *hw, u8 *data, int len); int st_lsm6dsx_set_page(struct st_lsm6dsx_hw *hw, bool enable); static inline int @@ -509,6 +516,17 @@ st_lsm6dsx_get_mount_matrix(const struct iio_dev *iio_dev, return &hw->orientation; } +static inline int +st_lsm6dsx_device_set_enable(struct st_lsm6dsx_sensor *sensor, bool enable) +{ + if (sensor->id == ST_LSM6DSX_ID_EXT0 || + sensor->id == ST_LSM6DSX_ID_EXT1 || + sensor->id == ST_LSM6DSX_ID_EXT2) + return st_lsm6dsx_shub_set_enable(sensor, enable); + + return st_lsm6dsx_sensor_set_enable(sensor, enable); +} + static const struct iio_chan_spec_ext_info __maybe_unused st_lsm6dsx_accel_ext_info[] = { IIO_MOUNT_MATRIX(IIO_SHARED_BY_ALL, st_lsm6dsx_get_mount_matrix), diff --git a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_buffer.c b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_buffer.c index e49f2d120ed3..7dd5205aea5b 100644 --- a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_buffer.c +++ b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_buffer.c @@ -15,7 +15,7 @@ * value of the decimation factor and ODR set for each FIFO data set. * * LSM6DSO/LSM6DSOX/ASM330LHH/ASM330LHHX/LSM6DSR/LSM6DSRX/ISM330DHCX/ - * LSM6DST/LSM6DSOP/LSM6DSTX: + * LSM6DST/LSM6DSOP/LSM6DSTX/LSM6DSV: * The FIFO buffer can be configured to store data from gyroscope and * accelerometer. Each sample is queued with a tag (1B) indicating data * source (gyroscope, accelerometer, hw timer). @@ -673,17 +673,9 @@ int st_lsm6dsx_update_fifo(struct st_lsm6dsx_sensor *sensor, bool enable) 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_device_set_enable(sensor, enable); + if (err < 0) + goto out; err = st_lsm6dsx_set_fifo_odr(sensor, enable); if (err < 0) diff --git a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c index f8bbb005718e..3f6060c64f32 100644 --- a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c +++ b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c @@ -27,13 +27,20 @@ * - FIFO size: 4KB * * - LSM6DSO/LSM6DSOX/ASM330LHH/ASM330LHHX/LSM6DSR/ISM330DHCX/LSM6DST/LSM6DSOP/ - * LSM6DSTX: + * LSM6DSTX/LSM6DSO16IS/ISM330IS: * - Accelerometer/Gyroscope supported ODR [Hz]: 12.5, 26, 52, 104, 208, 416, * 833 * - Accelerometer supported full-scale [g]: +-2/+-4/+-8/+-16 * - Gyroscope supported full-scale [dps]: +-125/+-245/+-500/+-1000/+-2000 * - FIFO size: 3KB * + * - LSM6DSV/LSM6DSV16X: + * - Accelerometer/Gyroscope supported ODR [Hz]: 7.5, 15, 30, 60, 120, 240, + * 480, 960 + * - Accelerometer supported full-scale [g]: +-2/+-4/+-8/+-16 + * - Gyroscope supported full-scale [dps]: +-125/+-250/+-500/+-1000/+-2000 + * - FIFO size: 3KB + * * - LSM9DS1/LSM6DS0: * - Accelerometer supported ODR [Hz]: 10, 50, 119, 238, 476, 952 * - Accelerometer supported full-scale [g]: +-2/+-4/+-8/+-16 @@ -53,6 +60,8 @@ #include <linux/iio/events.h> #include <linux/iio/iio.h> #include <linux/iio/sysfs.h> +#include <linux/iio/triggered_buffer.h> +#include <linux/iio/trigger_consumer.h> #include <linux/interrupt.h> #include <linux/irq.h> #include <linux/minmax.h> @@ -1160,6 +1169,342 @@ static const struct st_lsm6dsx_settings st_lsm6dsx_sensor_settings[] = { .wakeup_src_x_mask = BIT(2), }, }, + { + .reset = { + .addr = 0x12, + .mask = BIT(0), + }, + .boot = { + .addr = 0x12, + .mask = BIT(7), + }, + .bdu = { + .addr = 0x12, + .mask = BIT(6), + }, + .id = { + { + .hw_id = ST_LSM6DSV_ID, + .name = ST_LSM6DSV_DEV_NAME, + .wai = 0x70, + }, { + .hw_id = ST_LSM6DSV16X_ID, + .name = ST_LSM6DSV16X_DEV_NAME, + .wai = 0x70, + }, + }, + .channels = { + [ST_LSM6DSX_ID_ACC] = { + .chan = st_lsm6dsx_acc_channels, + .len = ARRAY_SIZE(st_lsm6dsx_acc_channels), + }, + [ST_LSM6DSX_ID_GYRO] = { + .chan = st_lsm6dsx_gyro_channels, + .len = ARRAY_SIZE(st_lsm6dsx_gyro_channels), + }, + }, + .drdy_mask = { + .addr = 0x13, + .mask = BIT(3), + }, + .odr_table = { + [ST_LSM6DSX_ID_ACC] = { + .reg = { + .addr = 0x10, + .mask = GENMASK(3, 0), + }, + .odr_avl[0] = { 7500, 0x02 }, + .odr_avl[1] = { 15000, 0x03 }, + .odr_avl[2] = { 30000, 0x04 }, + .odr_avl[3] = { 60000, 0x05 }, + .odr_avl[4] = { 120000, 0x06 }, + .odr_avl[5] = { 240000, 0x07 }, + .odr_avl[6] = { 480000, 0x08 }, + .odr_avl[7] = { 960000, 0x09 }, + .odr_len = 8, + }, + [ST_LSM6DSX_ID_GYRO] = { + .reg = { + .addr = 0x11, + .mask = GENMASK(3, 0), + }, + .odr_avl[0] = { 7500, 0x02 }, + .odr_avl[1] = { 15000, 0x03 }, + .odr_avl[2] = { 30000, 0x04 }, + .odr_avl[3] = { 60000, 0x05 }, + .odr_avl[4] = { 120000, 0x06 }, + .odr_avl[5] = { 240000, 0x07 }, + .odr_avl[6] = { 480000, 0x08 }, + .odr_avl[7] = { 960000, 0x09 }, + .odr_len = 8, + }, + }, + .fs_table = { + [ST_LSM6DSX_ID_ACC] = { + .reg = { + .addr = 0x17, + .mask = GENMASK(1, 0), + }, + .fs_avl[0] = { IIO_G_TO_M_S_2(61000), 0x0 }, + .fs_avl[1] = { IIO_G_TO_M_S_2(122000), 0x1 }, + .fs_avl[2] = { IIO_G_TO_M_S_2(244000), 0x2 }, + .fs_avl[3] = { IIO_G_TO_M_S_2(488000), 0x3 }, + .fs_len = 4, + }, + [ST_LSM6DSX_ID_GYRO] = { + .reg = { + .addr = 0x15, + .mask = GENMASK(3, 0), + }, + .fs_avl[0] = { IIO_DEGREE_TO_RAD(8750000), 0x1 }, + .fs_avl[1] = { IIO_DEGREE_TO_RAD(17500000), 0x2 }, + .fs_avl[2] = { IIO_DEGREE_TO_RAD(35000000), 0x3 }, + .fs_avl[3] = { IIO_DEGREE_TO_RAD(70000000), 0x4 }, + .fs_len = 4, + }, + }, + .irq_config = { + .irq1 = { + .addr = 0x0d, + .mask = BIT(3), + }, + .irq2 = { + .addr = 0x0e, + .mask = BIT(3), + }, + .lir = { + .addr = 0x56, + .mask = BIT(0), + }, + .irq1_func = { + .addr = 0x5e, + .mask = BIT(5), + }, + .irq2_func = { + .addr = 0x5f, + .mask = BIT(5), + }, + .hla = { + .addr = 0x03, + .mask = BIT(4), + }, + .od = { + .addr = 0x03, + .mask = BIT(3), + }, + }, + .batch = { + [ST_LSM6DSX_ID_ACC] = { + .addr = 0x09, + .mask = GENMASK(3, 0), + }, + [ST_LSM6DSX_ID_GYRO] = { + .addr = 0x09, + .mask = GENMASK(7, 4), + }, + }, + .fifo_ops = { + .update_fifo = st_lsm6dsx_update_fifo, + .read_fifo = st_lsm6dsx_read_tagged_fifo, + .fifo_th = { + .addr = 0x07, + .mask = GENMASK(7, 0), + }, + .fifo_diff = { + .addr = 0x1b, + .mask = GENMASK(8, 0), + }, + .max_size = 512, + .th_wl = 1, + }, + .ts_settings = { + .timer_en = { + .addr = 0x50, + .mask = BIT(6), + }, + .decimator = { + .addr = 0x0a, + .mask = GENMASK(7, 6), + }, + .freq_fine = 0x4f, + }, + .shub_settings = { + .page_mux = { + .addr = 0x01, + .mask = BIT(6), + }, + .master_en = { + .sec_page = true, + .addr = 0x14, + .mask = BIT(2), + }, + .pullup_en = { + .addr = 0x03, + .mask = BIT(6), + }, + .aux_sens = { + .addr = 0x14, + .mask = GENMASK(1, 0), + }, + .wr_once = { + .addr = 0x14, + .mask = BIT(6), + }, + .num_ext_dev = 3, + .shub_out = { + .sec_page = true, + .addr = 0x02, + }, + .slv0_addr = 0x15, + .dw_slv0_addr = 0x21, + .batch_en = BIT(3), + }, + .event_settings = { + .enable_reg = { + .addr = 0x50, + .mask = BIT(7), + }, + .wakeup_reg = { + .addr = 0x5b, + .mask = GENMASK(5, 0), + }, + .wakeup_src_reg = 0x45, + .wakeup_src_status_mask = BIT(3), + .wakeup_src_z_mask = BIT(0), + .wakeup_src_y_mask = BIT(1), + .wakeup_src_x_mask = BIT(2), + }, + }, + { + .reset = { + .addr = 0x12, + .mask = BIT(0), + }, + .boot = { + .addr = 0x12, + .mask = BIT(7), + }, + .bdu = { + .addr = 0x12, + .mask = BIT(6), + }, + .id = { + { + .hw_id = ST_LSM6DSO16IS_ID, + .name = ST_LSM6DSO16IS_DEV_NAME, + .wai = 0x22, + }, { + .hw_id = ST_ISM330IS_ID, + .name = ST_ISM330IS_DEV_NAME, + .wai = 0x22, + } + }, + .channels = { + [ST_LSM6DSX_ID_ACC] = { + .chan = st_lsm6dsx_acc_channels, + .len = ARRAY_SIZE(st_lsm6dsx_acc_channels), + }, + [ST_LSM6DSX_ID_GYRO] = { + .chan = st_lsm6dsx_gyro_channels, + .len = ARRAY_SIZE(st_lsm6dsx_gyro_channels), + }, + }, + .odr_table = { + [ST_LSM6DSX_ID_ACC] = { + .reg = { + .addr = 0x10, + .mask = GENMASK(7, 4), + }, + .odr_avl[0] = { 12500, 0x01 }, + .odr_avl[1] = { 26000, 0x02 }, + .odr_avl[2] = { 52000, 0x03 }, + .odr_avl[3] = { 104000, 0x04 }, + .odr_avl[4] = { 208000, 0x05 }, + .odr_avl[5] = { 416000, 0x06 }, + .odr_avl[6] = { 833000, 0x07 }, + .odr_len = 7, + }, + [ST_LSM6DSX_ID_GYRO] = { + .reg = { + .addr = 0x11, + .mask = GENMASK(7, 4), + }, + .odr_avl[0] = { 12500, 0x01 }, + .odr_avl[1] = { 26000, 0x02 }, + .odr_avl[2] = { 52000, 0x03 }, + .odr_avl[3] = { 104000, 0x04 }, + .odr_avl[4] = { 208000, 0x05 }, + .odr_avl[5] = { 416000, 0x06 }, + .odr_avl[6] = { 833000, 0x07 }, + .odr_len = 7, + }, + }, + .fs_table = { + [ST_LSM6DSX_ID_ACC] = { + .reg = { + .addr = 0x10, + .mask = GENMASK(3, 2), + }, + .fs_avl[0] = { IIO_G_TO_M_S_2(61000), 0x0 }, + .fs_avl[1] = { IIO_G_TO_M_S_2(122000), 0x2 }, + .fs_avl[2] = { IIO_G_TO_M_S_2(244000), 0x3 }, + .fs_avl[3] = { IIO_G_TO_M_S_2(488000), 0x1 }, + .fs_len = 4, + }, + [ST_LSM6DSX_ID_GYRO] = { + .reg = { + .addr = 0x11, + .mask = GENMASK(3, 2), + }, + .fs_avl[0] = { IIO_DEGREE_TO_RAD(8750000), 0x0 }, + .fs_avl[1] = { IIO_DEGREE_TO_RAD(17500000), 0x1 }, + .fs_avl[2] = { IIO_DEGREE_TO_RAD(35000000), 0x2 }, + .fs_avl[3] = { IIO_DEGREE_TO_RAD(70000000), 0x3 }, + .fs_len = 4, + }, + }, + .irq_config = { + .hla = { + .addr = 0x12, + .mask = BIT(5), + }, + .od = { + .addr = 0x12, + .mask = BIT(4), + }, + }, + .shub_settings = { + .page_mux = { + .addr = 0x01, + .mask = BIT(6), + }, + .master_en = { + .sec_page = true, + .addr = 0x14, + .mask = BIT(2), + }, + .pullup_en = { + .sec_page = true, + .addr = 0x14, + .mask = BIT(3), + }, + .aux_sens = { + .addr = 0x14, + .mask = GENMASK(1, 0), + }, + .wr_once = { + .addr = 0x14, + .mask = BIT(6), + }, + .num_ext_dev = 3, + .shub_out = { + .sec_page = true, + .addr = 0x02, + }, + .slv0_addr = 0x15, + .dw_slv0_addr = 0x21, + }, + }, }; int st_lsm6dsx_set_page(struct st_lsm6dsx_hw *hw, bool enable) @@ -2117,6 +2462,32 @@ static irqreturn_t st_lsm6dsx_handler_thread(int irq, void *private) return fifo_len || event ? IRQ_HANDLED : IRQ_NONE; } +static irqreturn_t st_lsm6dsx_sw_trigger_handler_thread(int irq, + void *private) +{ + struct iio_poll_func *pf = private; + struct iio_dev *iio_dev = pf->indio_dev; + struct st_lsm6dsx_sensor *sensor = iio_priv(iio_dev); + struct st_lsm6dsx_hw *hw = sensor->hw; + + if (sensor->id == ST_LSM6DSX_ID_EXT0 || + sensor->id == ST_LSM6DSX_ID_EXT1 || + sensor->id == ST_LSM6DSX_ID_EXT2) + st_lsm6dsx_shub_read_output(hw, + (u8 *)hw->scan[sensor->id].channels, + sizeof(hw->scan[sensor->id].channels)); + else + st_lsm6dsx_read_locked(hw, iio_dev->channels[0].address, + hw->scan[sensor->id].channels, + sizeof(hw->scan[sensor->id].channels)); + + iio_push_to_buffers_with_timestamp(iio_dev, &hw->scan[sensor->id], + iio_get_time_ns(iio_dev)); + iio_trigger_notify_done(iio_dev->trig); + + return IRQ_HANDLED; +} + static int st_lsm6dsx_irq_setup(struct st_lsm6dsx_hw *hw) { struct st_sensors_platform_data *pdata; @@ -2175,36 +2546,60 @@ static int st_lsm6dsx_irq_setup(struct st_lsm6dsx_hw *hw) return 0; } -static int st_lsm6dsx_init_regulators(struct device *dev) +static int st_lsm6dsx_sw_buffer_preenable(struct iio_dev *iio_dev) { - struct st_lsm6dsx_hw *hw = dev_get_drvdata(dev); - int err; + struct st_lsm6dsx_sensor *sensor = iio_priv(iio_dev); - /* vdd-vddio power regulators */ - hw->regulators[0].supply = "vdd"; - hw->regulators[1].supply = "vddio"; - err = devm_regulator_bulk_get(dev, ARRAY_SIZE(hw->regulators), - hw->regulators); - if (err) - return dev_err_probe(dev, err, "failed to get regulators\n"); + return st_lsm6dsx_device_set_enable(sensor, true); +} - err = regulator_bulk_enable(ARRAY_SIZE(hw->regulators), - hw->regulators); - if (err) { - dev_err(dev, "failed to enable regulators: %d\n", err); - return err; - } +static int st_lsm6dsx_sw_buffer_postdisable(struct iio_dev *iio_dev) +{ + struct st_lsm6dsx_sensor *sensor = iio_priv(iio_dev); - msleep(50); + return st_lsm6dsx_device_set_enable(sensor, false); +} + +static const struct iio_buffer_setup_ops st_lsm6dsx_sw_buffer_ops = { + .preenable = st_lsm6dsx_sw_buffer_preenable, + .postdisable = st_lsm6dsx_sw_buffer_postdisable, +}; + +static int st_lsm6dsx_sw_buffers_setup(struct st_lsm6dsx_hw *hw) +{ + int i; + + for (i = 0; i < ST_LSM6DSX_ID_MAX; i++) { + int err; + + if (!hw->iio_devs[i]) + continue; + + err = devm_iio_triggered_buffer_setup(hw->dev, + hw->iio_devs[i], NULL, + st_lsm6dsx_sw_trigger_handler_thread, + &st_lsm6dsx_sw_buffer_ops); + if (err) + return err; + } return 0; } -static void st_lsm6dsx_chip_uninit(void *data) +static int st_lsm6dsx_init_regulators(struct device *dev) { - struct st_lsm6dsx_hw *hw = data; + /* vdd-vddio power regulators */ + static const char * const regulators[] = { "vdd", "vddio" }; + int err; - regulator_bulk_disable(ARRAY_SIZE(hw->regulators), hw->regulators); + err = devm_regulator_bulk_get_enable(dev, ARRAY_SIZE(regulators), + regulators); + if (err) + return dev_err_probe(dev, err, "failed to enable regulators\n"); + + msleep(50); + + return 0; } int st_lsm6dsx_probe(struct device *dev, int irq, int hw_id, @@ -2230,10 +2625,6 @@ int st_lsm6dsx_probe(struct device *dev, int irq, int hw_id, if (err) return err; - err = devm_add_action_or_reset(dev, st_lsm6dsx_chip_uninit, hw); - if (err) - return err; - hw->buff = devm_kzalloc(dev, ST_LSM6DSX_BUFF_SIZE, GFP_KERNEL); if (!hw->buff) return -ENOMEM; @@ -2275,6 +2666,16 @@ int st_lsm6dsx_probe(struct device *dev, int irq, int hw_id, return err; } + if (!hw->irq || !hw->settings->fifo_ops.read_fifo) { + /* + * Rely on sw triggers (e.g. hr-timers) if irq pin is not + * connected of if the device does not support HW FIFO + */ + err = st_lsm6dsx_sw_buffers_setup(hw); + if (err) + return err; + } + err = iio_read_mount_matrix(hw->dev, &hw->orientation); if (err) return err; @@ -2317,12 +2718,7 @@ static int st_lsm6dsx_suspend(struct device *dev) continue; } - 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, false); - else - err = st_lsm6dsx_sensor_set_enable(sensor, false); + err = st_lsm6dsx_device_set_enable(sensor, false); if (err < 0) return err; @@ -2353,12 +2749,7 @@ static int st_lsm6dsx_resume(struct device *dev) if (!(hw->suspend_mask & BIT(sensor->id))) continue; - 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, true); - else - err = st_lsm6dsx_sensor_set_enable(sensor, true); + err = st_lsm6dsx_device_set_enable(sensor, true); if (err < 0) return err; diff --git a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_i2c.c b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_i2c.c index 307c8c436862..df5f60925260 100644 --- a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_i2c.c +++ b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_i2c.c @@ -21,9 +21,9 @@ static const struct regmap_config st_lsm6dsx_i2c_regmap_config = { .val_bits = 8, }; -static int st_lsm6dsx_i2c_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int st_lsm6dsx_i2c_probe(struct i2c_client *client) { + const struct i2c_device_id *id = i2c_client_get_device_id(client); int hw_id = id->driver_data; struct regmap *regmap; @@ -109,6 +109,22 @@ static const struct of_device_id st_lsm6dsx_i2c_of_match[] = { .compatible = "st,lsm6dstx", .data = (void *)ST_LSM6DSTX_ID, }, + { + .compatible = "st,lsm6dsv", + .data = (void *)ST_LSM6DSV_ID, + }, + { + .compatible = "st,lsm6dsv16x", + .data = (void *)ST_LSM6DSV16X_ID, + }, + { + .compatible = "st,lsm6dso16is", + .data = (void *)ST_LSM6DSO16IS_ID, + }, + { + .compatible = "st,ism330is", + .data = (void *)ST_ISM330IS_ID, + }, {}, }; MODULE_DEVICE_TABLE(of, st_lsm6dsx_i2c_of_match); @@ -132,6 +148,10 @@ static const struct i2c_device_id st_lsm6dsx_i2c_id_table[] = { { ST_LSM6DSOP_DEV_NAME, ST_LSM6DSOP_ID }, { ST_ASM330LHHX_DEV_NAME, ST_ASM330LHHX_ID }, { ST_LSM6DSTX_DEV_NAME, ST_LSM6DSTX_ID }, + { ST_LSM6DSV_DEV_NAME, ST_LSM6DSV_ID }, + { ST_LSM6DSV16X_DEV_NAME, ST_LSM6DSV16X_ID }, + { ST_LSM6DSO16IS_DEV_NAME, ST_LSM6DSO16IS_ID }, + { ST_ISM330IS_DEV_NAME, ST_ISM330IS_ID }, {}, }; MODULE_DEVICE_TABLE(i2c, st_lsm6dsx_i2c_id_table); @@ -142,7 +162,7 @@ static struct i2c_driver st_lsm6dsx_driver = { .pm = pm_sleep_ptr(&st_lsm6dsx_pm_ops), .of_match_table = st_lsm6dsx_i2c_of_match, }, - .probe = st_lsm6dsx_i2c_probe, + .probe_new = st_lsm6dsx_i2c_probe, .id_table = st_lsm6dsx_i2c_id_table, }; module_i2c_driver(st_lsm6dsx_driver); diff --git a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_shub.c b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_shub.c index 99562ba85ee4..f2b64b4956a3 100644 --- a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_shub.c +++ b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_shub.c @@ -170,9 +170,7 @@ static void st_lsm6dsx_shub_wait_complete(struct st_lsm6dsx_hw *hw) * * Read st_lsm6dsx i2c controller register */ -static int -st_lsm6dsx_shub_read_output(struct st_lsm6dsx_hw *hw, u8 *data, - int len) +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; diff --git a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_spi.c b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_spi.c index 6a4eecf4bb05..974584bda875 100644 --- a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_spi.c +++ b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_spi.c @@ -109,6 +109,22 @@ static const struct of_device_id st_lsm6dsx_spi_of_match[] = { .compatible = "st,lsm6dstx", .data = (void *)ST_LSM6DSTX_ID, }, + { + .compatible = "st,lsm6dsv", + .data = (void *)ST_LSM6DSV_ID, + }, + { + .compatible = "st,lsm6dsv16x", + .data = (void *)ST_LSM6DSV16X_ID, + }, + { + .compatible = "st,lsm6dso16is", + .data = (void *)ST_LSM6DSO16IS_ID, + }, + { + .compatible = "st,ism330is", + .data = (void *)ST_ISM330IS_ID, + }, {}, }; MODULE_DEVICE_TABLE(of, st_lsm6dsx_spi_of_match); @@ -132,6 +148,10 @@ static const struct spi_device_id st_lsm6dsx_spi_id_table[] = { { ST_LSM6DSOP_DEV_NAME, ST_LSM6DSOP_ID }, { ST_ASM330LHHX_DEV_NAME, ST_ASM330LHHX_ID }, { ST_LSM6DSTX_DEV_NAME, ST_LSM6DSTX_ID }, + { ST_LSM6DSV_DEV_NAME, ST_LSM6DSV_ID }, + { ST_LSM6DSV16X_DEV_NAME, ST_LSM6DSV16X_ID }, + { ST_LSM6DSO16IS_DEV_NAME, ST_LSM6DSO16IS_ID }, + { ST_ISM330IS_DEV_NAME, ST_ISM330IS_ID }, {}, }; MODULE_DEVICE_TABLE(spi, st_lsm6dsx_spi_id_table); diff --git a/drivers/iio/imu/st_lsm9ds0/st_lsm9ds0_core.c b/drivers/iio/imu/st_lsm9ds0/st_lsm9ds0_core.c index ae7bc815382f..e887b45cdbcd 100644 --- a/drivers/iio/imu/st_lsm9ds0/st_lsm9ds0_core.c +++ b/drivers/iio/imu/st_lsm9ds0/st_lsm9ds0_core.c @@ -18,58 +18,6 @@ #include "st_lsm9ds0.h" -static int st_lsm9ds0_power_enable(struct device *dev, struct st_lsm9ds0 *lsm9ds0) -{ - int ret; - - /* Regulators not mandatory, but if requested we should enable them. */ - lsm9ds0->vdd = devm_regulator_get(dev, "vdd"); - if (IS_ERR(lsm9ds0->vdd)) - return dev_err_probe(dev, PTR_ERR(lsm9ds0->vdd), - "unable to get Vdd supply\n"); - - ret = regulator_enable(lsm9ds0->vdd); - if (ret) { - dev_warn(dev, "Failed to enable specified Vdd supply\n"); - return ret; - } - - lsm9ds0->vdd_io = devm_regulator_get(dev, "vddio"); - if (IS_ERR(lsm9ds0->vdd_io)) { - regulator_disable(lsm9ds0->vdd); - return dev_err_probe(dev, PTR_ERR(lsm9ds0->vdd_io), - "unable to get Vdd_IO supply\n"); - } - ret = regulator_enable(lsm9ds0->vdd_io); - if (ret) { - dev_warn(dev, "Failed to enable specified Vdd_IO supply\n"); - regulator_disable(lsm9ds0->vdd); - return ret; - } - - return 0; -} - -static void st_lsm9ds0_power_disable(void *data) -{ - struct st_lsm9ds0 *lsm9ds0 = data; - - regulator_disable(lsm9ds0->vdd_io); - regulator_disable(lsm9ds0->vdd); -} - -static int devm_st_lsm9ds0_power_enable(struct st_lsm9ds0 *lsm9ds0) -{ - struct device *dev = lsm9ds0->dev; - int ret; - - ret = st_lsm9ds0_power_enable(dev, lsm9ds0); - if (ret) - return ret; - - return devm_add_action_or_reset(dev, st_lsm9ds0_power_disable, lsm9ds0); -} - static int st_lsm9ds0_probe_accel(struct st_lsm9ds0 *lsm9ds0, struct regmap *regmap) { const struct st_sensor_settings *settings; @@ -92,8 +40,6 @@ static int st_lsm9ds0_probe_accel(struct st_lsm9ds0 *lsm9ds0, struct regmap *reg data->sensor_settings = (struct st_sensor_settings *)settings; data->irq = lsm9ds0->irq; data->regmap = regmap; - data->vdd = lsm9ds0->vdd; - data->vdd_io = lsm9ds0->vdd_io; return st_accel_common_probe(lsm9ds0->accel); } @@ -120,19 +66,22 @@ static int st_lsm9ds0_probe_magn(struct st_lsm9ds0 *lsm9ds0, struct regmap *regm data->sensor_settings = (struct st_sensor_settings *)settings; data->irq = lsm9ds0->irq; data->regmap = regmap; - data->vdd = lsm9ds0->vdd; - data->vdd_io = lsm9ds0->vdd_io; return st_magn_common_probe(lsm9ds0->magn); } int st_lsm9ds0_probe(struct st_lsm9ds0 *lsm9ds0, struct regmap *regmap) { + struct device *dev = lsm9ds0->dev; + static const char * const regulator_names[] = { "vdd", "vddio" }; int ret; - ret = devm_st_lsm9ds0_power_enable(lsm9ds0); + /* Regulators not mandatory, but if requested we should enable them. */ + ret = devm_regulator_bulk_get_enable(dev, ARRAY_SIZE(regulator_names), + regulator_names); if (ret) - return ret; + return dev_err_probe(dev, ret, + "unable to enable Vdd supply\n"); /* Setup accelerometer device */ ret = st_lsm9ds0_probe_accel(lsm9ds0, regmap); |