summaryrefslogtreecommitdiffstats
path: root/drivers/iio
diff options
context:
space:
mode:
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>2019-09-03 22:27:46 +0200
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2019-09-03 22:27:46 +0200
commit74eb9c06b1d722468db397595ac6834b9e4ac235 (patch)
treea201cde5eb2ce3f1785f4f4c2a650782e5c967b8 /drivers/iio
parentdfa5b30b12aa8c324d6b90c369e71c90061a8a33 (diff)
parent6fa029486b74c266c39b718b8643ed42d24f977a (diff)
downloadlinux-74eb9c06b1d722468db397595ac6834b9e4ac235.tar.gz
linux-74eb9c06b1d722468db397595ac6834b9e4ac235.tar.bz2
linux-74eb9c06b1d722468db397595ac6834b9e4ac235.zip
Merge tag 'iio-for-5.4b-take3' of git://git.kernel.org/pub/scm/linux/kernel/git/jic23/iio into staging-next
Jonathan writes: Second set of new device support, cleanups and features for IIO in the 5.4 cycle Revised pull request to fix up a missing Signed-off-by and roll in a fix in the lsm9ds1 support after I broke it when applying. Revised again because the fix changed a hash meaning a fix that previously followed it now had the wrong fixes tag. A few fixes in here that could have gone a faster path but aren't quite worth the rush for 5.3. New device support * ad7606 - Support the ad7606b which adds a software controlled mode alongside the pin controlled only approach of the ad7606. Including dt-bindings. * lsm6dsx - Add support for the gyro and accelerometer part of the lsm9ds1 which is a compound device also including a magnetometer (st_sensors driver). Includes bindings and precursor rework of the driver. Features * ad7192 - Add support for low pass filter control. - DT binding docs. Cleanups and minor fixes * MAINTAINERS - Fix a typo in a path. - Add entry for ad7606 * ad5380 - Fix a failure to dereference a pointer before atempting to assign the value. * ad7192 - Drop platform data as not used in mainline and we now have full DT bindings. * ad7606 - YAML conversion for dt-bindings. * adis16240 - Rework write_raw to make it more readable using GENMASK. * adis16460 - Fix and issue with an unsigned variable holding potential negatives. * cros_ec - Fix missing default of calibration vector so that we get 'something' before calibration is complete on a given axis. * hid-sensors - Use int_pow instead of opencoding. * isl29501 - rename dt-binding docs to include renesas inline with other renesas parts and general current convention. * kxcjk1013 - Improve comments on the 'unusual' ACPI ids used to identify which sensor is which in certain laptops. * lsm6dsx - Add one bit to the fifo status masks for a number of parts. - Drop a reserved entry from the sensitivity values to tidy up interface. - Use core conversion macro from G to m/s^2 for lsm9ds1 to make it easier to relate to the datasheet and consistent with other parts supported. * max1027 - Use device managed APIs to avoid manual error handling and cleanup. * rfd77402 - Typo in Kconfig help. * sc27xx - Switch to polling mode from interrupts as interrupt handling typically to slow for very short sleeps. * st-sensors - Fix some missing selects for regmap. * tools - Add a .gitignore containing the binary outputs. * tag 'iio-for-5.4b-take3' of git://git.kernel.org/pub/scm/linux/kernel/git/jic23/iio: (27 commits) iio: imu: st_lsm6dsx: rely on IIO_G_TO_M_S_2 for gain definition for LSM9DS1 iio: imu: st_lsm6dsx: remove invalid gain value for LSM9DS1 iio: cros_ec: set calibscale for 3d MEMS to unit vector iio: dac: ad5380: fix incorrect assignment to val iio: imu: st_lsm6dsx: Fix FIFO diff mask for tagged fifo dt-bindings: iio: imu: st_lsm6dsx: add lsm9ds1 device bindings iio: imu: st_lsm6dsx: add support for accel/gyro unit of lsm9ds1 iio: imu: st_lsm6dsx: move register definitions to sensor_settings struct iio: imu: st_lsm6dsx: introduce update_fifo function pointer dt-bindings: iio: light: isl29501: Rename bindings documentation file Kconfig: Fix the reference to the RFD77402 ToF sensor in the 'help' section iio: st_sensors: Fix build error dt-bindings: iio: adc: Add AD7606B ADC documentation dt-bindings: iio: adc: Migrate AD7606 documentation to yaml MAINTAINERS: Add Beniamin Bia for AD7606 driver iio: adc: ad7606: Add support for AD7606B ADC tools: iio: add .gitignore iio: adc: sc27xx: Change to polling mode to read data iio: hid-sensor-attributes: Convert to use int_pow() iio: adc: max1027: Use device-managed APIs ...
Diffstat (limited to 'drivers/iio')
-rw-r--r--drivers/iio/accel/kxcjk-1013.c4
-rw-r--r--drivers/iio/adc/ad7606.c13
-rw-r--r--drivers/iio/adc/ad7606.h4
-rw-r--r--drivers/iio/adc/ad7606_spi.c109
-rw-r--r--drivers/iio/adc/max1027.c38
-rw-r--r--drivers/iio/adc/sc27xx_adc.c81
-rw-r--r--drivers/iio/common/cros_ec_sensors/cros_ec_sensors_core.c5
-rw-r--r--drivers/iio/common/hid-sensors/hid-sensor-attributes.c53
-rw-r--r--drivers/iio/common/st_sensors/Kconfig2
-rw-r--r--drivers/iio/dac/ad5380.c2
-rw-r--r--drivers/iio/imu/adis16460.c2
-rw-r--r--drivers/iio/imu/st_lsm6dsx/Kconfig2
-rw-r--r--drivers/iio/imu/st_lsm6dsx/st_lsm6dsx.h12
-rw-r--r--drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_buffer.c19
-rw-r--r--drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c139
-rw-r--r--drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_i2c.c5
-rw-r--r--drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_spi.c5
-rw-r--r--drivers/iio/proximity/Kconfig2
18 files changed, 353 insertions, 144 deletions
diff --git a/drivers/iio/accel/kxcjk-1013.c b/drivers/iio/accel/kxcjk-1013.c
index 6645771aa349..fee535d6e45b 100644
--- a/drivers/iio/accel/kxcjk-1013.c
+++ b/drivers/iio/accel/kxcjk-1013.c
@@ -1486,8 +1486,8 @@ static const struct acpi_device_id kx_acpi_match[] = {
{"KIOX0008", KXCJ91008},
{"KIOX0009", KXTJ21009},
{"KIOX000A", KXCJ91008},
- {"KIOX010A", KXCJ91008}, /* KXCJ91008 inside the display of a 2-in-1 */
- {"KIOX020A", KXCJ91008},
+ {"KIOX010A", KXCJ91008}, /* KXCJ91008 in the display of a yoga 2-in-1 */
+ {"KIOX020A", KXCJ91008}, /* KXCJ91008 in the base of a yoga 2-in-1 */
{"KXTJ1009", KXTJ21009},
{"KXJ2109", KXTJ21009},
{"SMO8500", KXCJ91008},
diff --git a/drivers/iio/adc/ad7606.c b/drivers/iio/adc/ad7606.c
index ed2d08437e5d..f5ba94c03a8d 100644
--- a/drivers/iio/adc/ad7606.c
+++ b/drivers/iio/adc/ad7606.c
@@ -410,12 +410,19 @@ static const struct ad7606_chip_info ad7606_chip_info_tbl[] = {
.oversampling_avail = ad7606_oversampling_avail,
.oversampling_num = ARRAY_SIZE(ad7606_oversampling_avail),
},
+ [ID_AD7606B] = {
+ .channels = ad7606_channels,
+ .num_channels = 9,
+ .oversampling_avail = ad7606_oversampling_avail,
+ .oversampling_num = ARRAY_SIZE(ad7606_oversampling_avail),
+ },
[ID_AD7616] = {
.channels = ad7616_channels,
.num_channels = 17,
.oversampling_avail = ad7616_oversampling_avail,
.oversampling_num = ARRAY_SIZE(ad7616_oversampling_avail),
.os_req_reset = true,
+ .init_delay_ms = 15,
},
};
@@ -631,8 +638,10 @@ int ad7606_probe(struct device *dev, int irq, void __iomem *base_address,
dev_warn(st->dev, "failed to RESET: no RESET GPIO specified\n");
/* AD7616 requires al least 15ms to reconfigure after a reset */
- if (msleep_interruptible(15))
- return -ERESTARTSYS;
+ if (st->chip_info->init_delay_ms) {
+ if (msleep_interruptible(st->chip_info->init_delay_ms))
+ return -ERESTARTSYS;
+ }
st->write_scale = ad7606_write_scale_hw;
st->write_os = ad7606_write_os_hw;
diff --git a/drivers/iio/adc/ad7606.h b/drivers/iio/adc/ad7606.h
index eeaaa8b905db..9350ef1f63b5 100644
--- a/drivers/iio/adc/ad7606.h
+++ b/drivers/iio/adc/ad7606.h
@@ -46,6 +46,8 @@
* oversampling ratios.
* @oversampling_num number of elements stored in oversampling_avail array
* @os_req_reset some devices require a reset to update oversampling
+ * @init_delay_ms required delay in miliseconds for initialization
+ * after a restart
*/
struct ad7606_chip_info {
const struct iio_chan_spec *channels;
@@ -53,6 +55,7 @@ struct ad7606_chip_info {
const unsigned int *oversampling_avail;
unsigned int oversampling_num;
bool os_req_reset;
+ unsigned long init_delay_ms;
};
/**
@@ -155,6 +158,7 @@ enum ad7606_supported_device_ids {
ID_AD7606_8,
ID_AD7606_6,
ID_AD7606_4,
+ ID_AD7606B,
ID_AD7616,
};
diff --git a/drivers/iio/adc/ad7606_spi.c b/drivers/iio/adc/ad7606_spi.c
index 98ed52b74507..29945ad07dca 100644
--- a/drivers/iio/adc/ad7606_spi.c
+++ b/drivers/iio/adc/ad7606_spi.c
@@ -28,9 +28,23 @@
* an offset of 2 for register address.
*/
#define AD7616_RANGE_CH_ADDR(ch) ((ch) >> 2)
-/* The range of the channel is stored on 2 bits*/
+/* The range of the channel is stored in 2 bits */
#define AD7616_RANGE_CH_MSK(ch) (0b11 << (((ch) & 0b11) * 2))
#define AD7616_RANGE_CH_MODE(ch, mode) ((mode) << ((((ch) & 0b11)) * 2))
+
+#define AD7606_CONFIGURATION_REGISTER 0x02
+#define AD7606_SINGLE_DOUT 0x00
+
+/*
+ * Range for AD7606B channels are stored in registers starting with address 0x3.
+ * Each register stores range for 2 channels(4 bits per channel).
+ */
+#define AD7606_RANGE_CH_MSK(ch) (GENMASK(3, 0) << (4 * ((ch) & 0x1)))
+#define AD7606_RANGE_CH_MODE(ch, mode) \
+ ((GENMASK(3, 0) & mode) << (4 * ((ch) & 0x1)))
+#define AD7606_RANGE_CH_ADDR(ch) (0x03 + ((ch) >> 1))
+#define AD7606_OS_MODE 0x08
+
static const struct iio_chan_spec ad7616_sw_channels[] = {
IIO_CHAN_SOFT_TIMESTAMP(16),
AD7616_CHANNEL(0),
@@ -51,6 +65,22 @@ static const struct iio_chan_spec ad7616_sw_channels[] = {
AD7616_CHANNEL(15),
};
+static const struct iio_chan_spec ad7606b_sw_channels[] = {
+ IIO_CHAN_SOFT_TIMESTAMP(8),
+ AD7616_CHANNEL(0),
+ AD7616_CHANNEL(1),
+ AD7616_CHANNEL(2),
+ AD7616_CHANNEL(3),
+ AD7616_CHANNEL(4),
+ AD7616_CHANNEL(5),
+ AD7616_CHANNEL(6),
+ AD7616_CHANNEL(7),
+};
+
+static const unsigned int ad7606B_oversampling_avail[9] = {
+ 1, 2, 4, 8, 16, 32, 64, 128, 256
+};
+
static u16 ad7616_spi_rd_wr_cmd(int addr, char isWriteOp)
{
/*
@@ -60,6 +90,16 @@ static u16 ad7616_spi_rd_wr_cmd(int addr, char isWriteOp)
return ((addr & 0x7F) << 1) | ((isWriteOp & 0x1) << 7);
}
+static u16 ad7606B_spi_rd_wr_cmd(int addr, char is_write_op)
+{
+ /*
+ * The address of register consists of one bit which
+ * specifies a read command placed in bit 6, followed by
+ * 6 bits of address.
+ */
+ return (addr & 0x3F) | (((~is_write_op) & 0x1) << 6);
+}
+
static int ad7606_spi_read_block(struct device *dev,
int count, void *buf)
{
@@ -169,6 +209,23 @@ static int ad7616_write_os_sw(struct iio_dev *indio_dev, int val)
AD7616_OS_MASK, val << 2);
}
+static int ad7606_write_scale_sw(struct iio_dev *indio_dev, int ch, int val)
+{
+ struct ad7606_state *st = iio_priv(indio_dev);
+
+ return ad7606_spi_write_mask(st,
+ AD7606_RANGE_CH_ADDR(ch),
+ AD7606_RANGE_CH_MSK(ch),
+ AD7606_RANGE_CH_MODE(ch, val));
+}
+
+static int ad7606_write_os_sw(struct iio_dev *indio_dev, int val)
+{
+ struct ad7606_state *st = iio_priv(indio_dev);
+
+ return ad7606_spi_reg_write(st, AD7606_OS_MODE, val);
+}
+
static int ad7616_sw_mode_config(struct iio_dev *indio_dev)
{
struct ad7606_state *st = iio_priv(indio_dev);
@@ -189,6 +246,42 @@ static int ad7616_sw_mode_config(struct iio_dev *indio_dev)
AD7616_BURST_MODE | AD7616_SEQEN_MODE);
}
+static int ad7606B_sw_mode_config(struct iio_dev *indio_dev)
+{
+ struct ad7606_state *st = iio_priv(indio_dev);
+ unsigned long os[3] = {1};
+
+ /*
+ * Software mode is enabled when all three oversampling
+ * pins are set to high. If oversampling gpios are defined
+ * in the device tree, then they need to be set to high,
+ * otherwise, they must be hardwired to VDD
+ */
+ if (st->gpio_os) {
+ gpiod_set_array_value(ARRAY_SIZE(os),
+ st->gpio_os->desc, st->gpio_os->info, os);
+ }
+ /* OS of 128 and 256 are available only in software mode */
+ st->oversampling_avail = ad7606B_oversampling_avail;
+ st->num_os_ratios = ARRAY_SIZE(ad7606B_oversampling_avail);
+
+ st->write_scale = ad7606_write_scale_sw;
+ st->write_os = &ad7606_write_os_sw;
+
+ /* Configure device spi to output on a single channel */
+ st->bops->reg_write(st,
+ AD7606_CONFIGURATION_REGISTER,
+ AD7606_SINGLE_DOUT);
+
+ /*
+ * Scale can be configured individually for each channel
+ * in software mode.
+ */
+ indio_dev->channels = ad7606b_sw_channels;
+
+ return 0;
+}
+
static const struct ad7606_bus_ops ad7606_spi_bops = {
.read_block = ad7606_spi_read_block,
};
@@ -202,6 +295,15 @@ static const struct ad7606_bus_ops ad7616_spi_bops = {
.sw_mode_config = ad7616_sw_mode_config,
};
+static const struct ad7606_bus_ops ad7606B_spi_bops = {
+ .read_block = ad7606_spi_read_block,
+ .reg_read = ad7606_spi_reg_read,
+ .reg_write = ad7606_spi_reg_write,
+ .write_mask = ad7606_spi_write_mask,
+ .rd_wr_cmd = ad7606B_spi_rd_wr_cmd,
+ .sw_mode_config = ad7606B_sw_mode_config,
+};
+
static int ad7606_spi_probe(struct spi_device *spi)
{
const struct spi_device_id *id = spi_get_device_id(spi);
@@ -211,6 +313,9 @@ static int ad7606_spi_probe(struct spi_device *spi)
case ID_AD7616:
bops = &ad7616_spi_bops;
break;
+ case ID_AD7606B:
+ bops = &ad7606B_spi_bops;
+ break;
default:
bops = &ad7606_spi_bops;
break;
@@ -226,6 +331,7 @@ static const struct spi_device_id ad7606_id_table[] = {
{ "ad7606-4", ID_AD7606_4 },
{ "ad7606-6", ID_AD7606_6 },
{ "ad7606-8", ID_AD7606_8 },
+ { "ad7606b", ID_AD7606B },
{ "ad7616", ID_AD7616 },
{}
};
@@ -236,6 +342,7 @@ static const struct of_device_id ad7606_of_match[] = {
{ .compatible = "adi,ad7606-4" },
{ .compatible = "adi,ad7606-6" },
{ .compatible = "adi,ad7606-8" },
+ { .compatible = "adi,ad7606b" },
{ .compatible = "adi,ad7616" },
{ },
};
diff --git a/drivers/iio/adc/max1027.c b/drivers/iio/adc/max1027.c
index da84adfdb819..214883458582 100644
--- a/drivers/iio/adc/max1027.c
+++ b/drivers/iio/adc/max1027.c
@@ -427,8 +427,9 @@ static int max1027_probe(struct spi_device *spi)
return -ENOMEM;
}
- ret = iio_triggered_buffer_setup(indio_dev, &iio_pollfunc_store_time,
- &max1027_trigger_handler, NULL);
+ ret = devm_iio_triggered_buffer_setup(&spi->dev, indio_dev,
+ &iio_pollfunc_store_time,
+ &max1027_trigger_handler, NULL);
if (ret < 0) {
dev_err(&indio_dev->dev, "Failed to setup buffer\n");
return ret;
@@ -439,7 +440,7 @@ static int max1027_probe(struct spi_device *spi)
if (st->trig == NULL) {
ret = -ENOMEM;
dev_err(&indio_dev->dev, "Failed to allocate iio trigger\n");
- goto fail_trigger_alloc;
+ return ret;
}
st->trig->ops = &max1027_trigger_ops;
@@ -454,7 +455,7 @@ static int max1027_probe(struct spi_device *spi)
spi->dev.driver->name, st->trig);
if (ret < 0) {
dev_err(&indio_dev->dev, "Failed to allocate IRQ.\n");
- goto fail_dev_register;
+ return ret;
}
/* Disable averaging */
@@ -462,34 +463,10 @@ static int max1027_probe(struct spi_device *spi)
ret = spi_write(st->spi, &st->reg, 1);
if (ret < 0) {
dev_err(&indio_dev->dev, "Failed to configure averaging register\n");
- goto fail_dev_register;
- }
-
- ret = iio_device_register(indio_dev);
- if (ret < 0) {
- dev_err(&indio_dev->dev, "Failed to register iio device\n");
- goto fail_dev_register;
+ return ret;
}
- return 0;
-
-fail_dev_register:
-fail_trigger_alloc:
- iio_triggered_buffer_cleanup(indio_dev);
-
- return ret;
-}
-
-static int max1027_remove(struct spi_device *spi)
-{
- struct iio_dev *indio_dev = spi_get_drvdata(spi);
-
- pr_debug("%s: remove(spi = 0x%p)\n", __func__, spi);
-
- iio_device_unregister(indio_dev);
- iio_triggered_buffer_cleanup(indio_dev);
-
- return 0;
+ return devm_iio_device_register(&spi->dev, indio_dev);
}
static struct spi_driver max1027_driver = {
@@ -498,7 +475,6 @@ static struct spi_driver max1027_driver = {
.of_match_table = of_match_ptr(max1027_adc_dt_ids),
},
.probe = max1027_probe,
- .remove = max1027_remove,
.id_table = max1027_id,
};
module_spi_driver(max1027_driver);
diff --git a/drivers/iio/adc/sc27xx_adc.c b/drivers/iio/adc/sc27xx_adc.c
index c2203a46f0d8..a6c046575ec3 100644
--- a/drivers/iio/adc/sc27xx_adc.c
+++ b/drivers/iio/adc/sc27xx_adc.c
@@ -3,7 +3,6 @@
#include <linux/hwspinlock.h>
#include <linux/iio/iio.h>
-#include <linux/interrupt.h>
#include <linux/module.h>
#include <linux/nvmem-consumer.h>
#include <linux/of.h>
@@ -46,14 +45,18 @@
/* Bits definitions for SC27XX_ADC_INT_CLR registers */
#define SC27XX_ADC_IRQ_CLR BIT(0)
+/* Bits definitions for SC27XX_ADC_INT_RAW registers */
+#define SC27XX_ADC_IRQ_RAW BIT(0)
+
/* Mask definition for SC27XX_ADC_DATA register */
#define SC27XX_ADC_DATA_MASK GENMASK(11, 0)
/* Timeout (ms) for the trylock of hardware spinlocks */
#define SC27XX_ADC_HWLOCK_TIMEOUT 5000
-/* Timeout (ms) for ADC data conversion according to ADC datasheet */
-#define SC27XX_ADC_RDY_TIMEOUT 100
+/* Timeout (us) for ADC data conversion according to ADC datasheet */
+#define SC27XX_ADC_RDY_TIMEOUT 1000000
+#define SC27XX_ADC_POLL_RAW_STATUS 500
/* Maximum ADC channel number */
#define SC27XX_ADC_CHANNEL_MAX 32
@@ -72,10 +75,8 @@ struct sc27xx_adc_data {
* subsystems which will access the unique ADC controller.
*/
struct hwspinlock *hwlock;
- struct completion completion;
int channel_scale[SC27XX_ADC_CHANNEL_MAX];
u32 base;
- int value;
int irq;
};
@@ -188,9 +189,7 @@ static int sc27xx_adc_read(struct sc27xx_adc_data *data, int channel,
int scale, int *val)
{
int ret;
- u32 tmp;
-
- reinit_completion(&data->completion);
+ u32 tmp, value, status;
ret = hwspin_lock_timeout_raw(data->hwlock, SC27XX_ADC_HWLOCK_TIMEOUT);
if (ret) {
@@ -203,6 +202,11 @@ static int sc27xx_adc_read(struct sc27xx_adc_data *data, int channel,
if (ret)
goto unlock_adc;
+ ret = regmap_update_bits(data->regmap, data->base + SC27XX_ADC_INT_CLR,
+ SC27XX_ADC_IRQ_CLR, SC27XX_ADC_IRQ_CLR);
+ if (ret)
+ goto disable_adc;
+
/* Configure the channel id and scale */
tmp = (scale << SC27XX_ADC_SCALE_SHIFT) & SC27XX_ADC_SCALE_MASK;
tmp |= channel & SC27XX_ADC_CHN_ID_MASK;
@@ -226,15 +230,22 @@ static int sc27xx_adc_read(struct sc27xx_adc_data *data, int channel,
if (ret)
goto disable_adc;
- ret = wait_for_completion_timeout(&data->completion,
- msecs_to_jiffies(SC27XX_ADC_RDY_TIMEOUT));
- if (!ret) {
- dev_err(data->dev, "read ADC data timeout\n");
- ret = -ETIMEDOUT;
- } else {
- ret = 0;
+ ret = regmap_read_poll_timeout(data->regmap,
+ data->base + SC27XX_ADC_INT_RAW,
+ status, (status & SC27XX_ADC_IRQ_RAW),
+ SC27XX_ADC_POLL_RAW_STATUS,
+ SC27XX_ADC_RDY_TIMEOUT);
+ if (ret) {
+ dev_err(data->dev, "read adc timeout, status = 0x%x\n", status);
+ goto disable_adc;
}
+ ret = regmap_read(data->regmap, data->base + SC27XX_ADC_DATA, &value);
+ if (ret)
+ goto disable_adc;
+
+ value &= SC27XX_ADC_DATA_MASK;
+
disable_adc:
regmap_update_bits(data->regmap, data->base + SC27XX_ADC_CTL,
SC27XX_ADC_EN, 0);
@@ -242,32 +253,11 @@ unlock_adc:
hwspin_unlock_raw(data->hwlock);
if (!ret)
- *val = data->value;
+ *val = value;
return ret;
}
-static irqreturn_t sc27xx_adc_isr(int irq, void *dev_id)
-{
- struct sc27xx_adc_data *data = dev_id;
- int ret;
-
- ret = regmap_update_bits(data->regmap, data->base + SC27XX_ADC_INT_CLR,
- SC27XX_ADC_IRQ_CLR, SC27XX_ADC_IRQ_CLR);
- if (ret)
- return IRQ_RETVAL(ret);
-
- ret = regmap_read(data->regmap, data->base + SC27XX_ADC_DATA,
- &data->value);
- if (ret)
- return IRQ_RETVAL(ret);
-
- data->value &= SC27XX_ADC_DATA_MASK;
- complete(&data->completion);
-
- return IRQ_HANDLED;
-}
-
static void sc27xx_adc_volt_ratio(struct sc27xx_adc_data *data,
int channel, int scale,
u32 *div_numerator, u32 *div_denominator)
@@ -454,11 +444,6 @@ static int sc27xx_adc_enable(struct sc27xx_adc_data *data)
if (ret)
goto disable_adc;
- ret = regmap_update_bits(data->regmap, data->base + SC27XX_ADC_INT_EN,
- SC27XX_ADC_IRQ_EN, SC27XX_ADC_IRQ_EN);
- if (ret)
- goto disable_clk;
-
/* ADC channel scales' calibration from nvmem device */
ret = sc27xx_adc_scale_calibration(data, true);
if (ret)
@@ -484,9 +469,6 @@ static void sc27xx_adc_disable(void *_data)
{
struct sc27xx_adc_data *data = _data;
- regmap_update_bits(data->regmap, data->base + SC27XX_ADC_INT_EN,
- SC27XX_ADC_IRQ_EN, 0);
-
/* Disable ADC work clock and controller clock */
regmap_update_bits(data->regmap, SC27XX_ARM_CLK_EN,
SC27XX_CLK_ADC_EN | SC27XX_CLK_ADC_CLK_EN, 0);
@@ -551,7 +533,6 @@ static int sc27xx_adc_probe(struct platform_device *pdev)
return ret;
}
- init_completion(&sc27xx_data->completion);
sc27xx_data->dev = dev;
ret = sc27xx_adc_enable(sc27xx_data);
@@ -566,14 +547,6 @@ static int sc27xx_adc_probe(struct platform_device *pdev)
return ret;
}
- ret = devm_request_threaded_irq(dev, sc27xx_data->irq, NULL,
- sc27xx_adc_isr, IRQF_ONESHOT,
- pdev->name, sc27xx_data);
- if (ret) {
- dev_err(dev, "failed to request ADC irq\n");
- return ret;
- }
-
indio_dev->dev.parent = dev;
indio_dev->name = dev_name(dev);
indio_dev->modes = INDIO_DIRECT_MODE;
diff --git a/drivers/iio/common/cros_ec_sensors/cros_ec_sensors_core.c b/drivers/iio/common/cros_ec_sensors/cros_ec_sensors_core.c
index fd833295bb17..d44ae126f457 100644
--- a/drivers/iio/common/cros_ec_sensors/cros_ec_sensors_core.c
+++ b/drivers/iio/common/cros_ec_sensors/cros_ec_sensors_core.c
@@ -90,7 +90,7 @@ int cros_ec_sensors_core_init(struct platform_device *pdev,
struct cros_ec_dev *ec = dev_get_drvdata(pdev->dev.parent);
struct cros_ec_sensor_platform *sensor_platform = dev_get_platdata(dev);
u32 ver_mask;
- int ret;
+ int ret, i;
platform_set_drvdata(pdev, indio_dev);
@@ -136,6 +136,9 @@ int cros_ec_sensors_core_init(struct platform_device *pdev,
/* Set sign vector, only used for backward compatibility. */
memset(state->sign, 1, CROS_EC_SENSOR_MAX_AXIS);
+ for (i = CROS_EC_SENSOR_X; i < CROS_EC_SENSOR_MAX_AXIS; i++)
+ state->calib[i].scale = MOTION_SENSE_DEFAULT_SCALE;
+
/* 0 is a correct value used to stop the device */
state->frequencies[0] = 0;
if (state->msg->version < 3) {
diff --git a/drivers/iio/common/hid-sensors/hid-sensor-attributes.c b/drivers/iio/common/hid-sensors/hid-sensor-attributes.c
index a8a3fe428d8d..b9dd19b34267 100644
--- a/drivers/iio/common/hid-sensors/hid-sensor-attributes.c
+++ b/drivers/iio/common/hid-sensors/hid-sensor-attributes.c
@@ -8,6 +8,7 @@
#include <linux/module.h>
#include <linux/interrupt.h>
#include <linux/irq.h>
+#include <linux/kernel.h>
#include <linux/slab.h>
#include <linux/hid-sensor-hub.h>
#include <linux/iio/iio.h>
@@ -68,16 +69,6 @@ static struct {
{HID_USAGE_SENSOR_HUMIDITY, 0, 1000, 0},
};
-static int pow_10(unsigned power)
-{
- int i;
- int ret = 1;
- for (i = 0; i < power; ++i)
- ret = ret * 10;
-
- return ret;
-}
-
static void simple_div(int dividend, int divisor, int *whole,
int *micro_frac)
{
@@ -96,14 +87,14 @@ static void simple_div(int dividend, int divisor, int *whole,
rem *= 10;
exp++;
}
- *micro_frac = (rem / divisor) * pow_10(6-exp);
+ *micro_frac = (rem / divisor) * int_pow(10, 6 - exp);
}
}
static void split_micro_fraction(unsigned int no, int exp, int *val1, int *val2)
{
- *val1 = no/pow_10(exp);
- *val2 = no%pow_10(exp) * pow_10(6-exp);
+ *val1 = no / int_pow(10, exp);
+ *val2 = no % int_pow(10, exp) * int_pow(10, 6 - exp);
}
/*
@@ -125,7 +116,7 @@ static void convert_from_vtf_format(u32 value, int size, int exp,
}
exp = hid_sensor_convert_exponent(exp);
if (exp >= 0) {
- *val1 = sign * value * pow_10(exp);
+ *val1 = sign * value * int_pow(10, exp);
*val2 = 0;
} else {
split_micro_fraction(value, -exp, val1, val2);
@@ -145,10 +136,10 @@ static u32 convert_to_vtf_format(int size, int exp, int val1, int val2)
sign = -1;
exp = hid_sensor_convert_exponent(exp);
if (exp < 0) {
- value = abs(val1) * pow_10(-exp);
- value += abs(val2) / pow_10(6+exp);
+ value = abs(val1) * int_pow(10, -exp);
+ value += abs(val2) / int_pow(10, 6 + exp);
} else
- value = abs(val1) / pow_10(exp);
+ value = abs(val1) / int_pow(10, exp);
if (sign < 0)
value = ((1LL << (size * 8)) - value);
@@ -211,12 +202,12 @@ int hid_sensor_write_samp_freq_value(struct hid_sensor_common *st,
if (val1 < 0 || val2 < 0)
return -EINVAL;
- value = val1 * pow_10(6) + val2;
+ value = val1 * int_pow(10, 6) + val2;
if (value) {
if (st->poll.units == HID_USAGE_SENSOR_UNITS_MILLISECOND)
- value = pow_10(9)/value;
+ value = int_pow(10, 9) / value;
else if (st->poll.units == HID_USAGE_SENSOR_UNITS_SECOND)
- value = pow_10(6)/value;
+ value = int_pow(10, 6) / value;
else
value = 0;
}
@@ -311,34 +302,34 @@ static void adjust_exponent_nano(int *val0, int *val1, int scale0,
int rem;
if (exp > 0) {
- *val0 = scale0 * pow_10(exp);
+ *val0 = scale0 * int_pow(10, exp);
res = 0;
if (exp > 9) {
*val1 = 0;
return;
}
for (i = 0; i < exp; ++i) {
- x = scale1 / pow_10(8 - i);
- res += (pow_10(exp - 1 - i) * x);
- scale1 = scale1 % pow_10(8 - i);
+ x = scale1 / int_pow(10, 8 - i);
+ res += int_pow(10, exp - 1 - i) * x;
+ scale1 = scale1 % int_pow(10, 8 - i);
}
*val0 += res;
- *val1 = scale1 * pow_10(exp);
+ *val1 = scale1 * int_pow(10, exp);
} else if (exp < 0) {
exp = abs(exp);
if (exp > 9) {
*val0 = *val1 = 0;
return;
}
- *val0 = scale0 / pow_10(exp);
- rem = scale0 % pow_10(exp);
+ *val0 = scale0 / int_pow(10, exp);
+ rem = scale0 % int_pow(10, exp);
res = 0;
for (i = 0; i < (9 - exp); ++i) {
- x = scale1 / pow_10(8 - i);
- res += (pow_10(8 - exp - i) * x);
- scale1 = scale1 % pow_10(8 - i);
+ x = scale1 / int_pow(10, 8 - i);
+ res += int_pow(10, 8 - exp - i) * x;
+ scale1 = scale1 % int_pow(10, 8 - i);
}
- *val1 = rem * pow_10(9 - exp) + res;
+ *val1 = rem * int_pow(10, 9 - exp) + res;
} else {
*val0 = scale0;
*val1 = scale1;
diff --git a/drivers/iio/common/st_sensors/Kconfig b/drivers/iio/common/st_sensors/Kconfig
index 91b98e152d75..9364ec7a811f 100644
--- a/drivers/iio/common/st_sensors/Kconfig
+++ b/drivers/iio/common/st_sensors/Kconfig
@@ -5,9 +5,11 @@
config IIO_ST_SENSORS_I2C
tristate
+ select REGMAP_I2C
config IIO_ST_SENSORS_SPI
tristate
+ select REGMAP_SPI
config IIO_ST_SENSORS_CORE
tristate
diff --git a/drivers/iio/dac/ad5380.c b/drivers/iio/dac/ad5380.c
index 4335214800d2..2ebe08326048 100644
--- a/drivers/iio/dac/ad5380.c
+++ b/drivers/iio/dac/ad5380.c
@@ -220,7 +220,7 @@ static int ad5380_read_raw(struct iio_dev *indio_dev,
if (ret)
return ret;
*val >>= chan->scan_type.shift;
- val -= (1 << chan->scan_type.realbits) / 2;
+ *val -= (1 << chan->scan_type.realbits) / 2;
return IIO_VAL_INT;
case IIO_CHAN_INFO_SCALE:
*val = 2 * st->vref;
diff --git a/drivers/iio/imu/adis16460.c b/drivers/iio/imu/adis16460.c
index 1ef11640ee20..6aed9e84abbf 100644
--- a/drivers/iio/imu/adis16460.c
+++ b/drivers/iio/imu/adis16460.c
@@ -152,7 +152,7 @@ static int adis16460_debugfs_init(struct iio_dev *indio_dev)
static int adis16460_set_freq(struct iio_dev *indio_dev, int val, int val2)
{
struct adis16460 *st = iio_priv(indio_dev);
- unsigned int t;
+ int t;
t = val * 1000 + val2 / 1000;
if (t <= 0)
diff --git a/drivers/iio/imu/st_lsm6dsx/Kconfig b/drivers/iio/imu/st_lsm6dsx/Kconfig
index 939058b27746..77aa0e77212d 100644
--- a/drivers/iio/imu/st_lsm6dsx/Kconfig
+++ b/drivers/iio/imu/st_lsm6dsx/Kconfig
@@ -12,7 +12,7 @@ config IIO_ST_LSM6DSX
Say yes here to build support for STMicroelectronics LSM6DSx imu
sensor. Supported devices: lsm6ds3, lsm6ds3h, lsm6dsl, lsm6dsm,
ism330dlc, lsm6dso, lsm6dsox, asm330lhh, lsm6dsr, lsm6ds3tr-c,
- ism330dhcx
+ ism330dhcx 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 4e8e67ae1632..80e42c7dbcbe 100644
--- a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx.h
+++ b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx.h
@@ -24,6 +24,7 @@
#define ST_LSM6DSR_DEV_NAME "lsm6dsr"
#define ST_LSM6DS3TRC_DEV_NAME "lsm6ds3tr-c"
#define ST_ISM330DHCX_DEV_NAME "ism330dhcx"
+#define ST_LSM9DS1_DEV_NAME "lsm9ds1-imu"
enum st_lsm6dsx_hw_id {
ST_LSM6DS3_ID,
@@ -37,6 +38,7 @@ enum st_lsm6dsx_hw_id {
ST_LSM6DSR_ID,
ST_LSM6DS3TRC_ID,
ST_ISM330DHCX_ID,
+ ST_LSM9DS1_ID,
ST_LSM6DSX_MAX_ID,
};
@@ -75,6 +77,7 @@ struct st_lsm6dsx_reg {
u8 mask;
};
+struct st_lsm6dsx_sensor;
struct st_lsm6dsx_hw;
struct st_lsm6dsx_odr {
@@ -101,12 +104,14 @@ struct st_lsm6dsx_fs_table_entry {
/**
* struct st_lsm6dsx_fifo_ops - ST IMU FIFO settings
+ * @update_fifo: Update FIFO configuration callback.
* @read_fifo: Read FIFO callback.
* @fifo_th: FIFO threshold register info (addr + mask).
* @fifo_diff: FIFO diff status register info (addr + mask).
* @th_wl: FIFO threshold word length.
*/
struct st_lsm6dsx_fifo_ops {
+ int (*update_fifo)(struct st_lsm6dsx_sensor *sensor, bool enable);
int (*read_fifo)(struct st_lsm6dsx_hw *hw);
struct {
u8 addr;
@@ -200,6 +205,9 @@ struct st_lsm6dsx_ext_dev_settings {
/**
* struct st_lsm6dsx_settings - ST IMU sensor settings
* @wai: Sensor WhoAmI default value.
+ * @int1_addr: Control Register address for INT1
+ * @int2_addr: Control Register address for INT2
+ * @reset_addr: register address for reset/reboot
* @max_fifo_size: Sensor max fifo length in FIFO words.
* @id: List of hw id/device name supported by the driver configuration.
* @channels: IIO channels supported by the device.
@@ -213,6 +221,9 @@ struct st_lsm6dsx_ext_dev_settings {
*/
struct st_lsm6dsx_settings {
u8 wai;
+ u8 int1_addr;
+ u8 int2_addr;
+ u8 reset_addr;
u16 max_fifo_size;
struct {
enum st_lsm6dsx_hw_id hw_id;
@@ -327,6 +338,7 @@ 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_update_fifo(struct st_lsm6dsx_sensor *sensor, bool enable);
int st_lsm6dsx_flush_fifo(struct st_lsm6dsx_hw *hw);
int st_lsm6dsx_set_fifo_mode(struct st_lsm6dsx_hw *hw,
enum st_lsm6dsx_fifo_mode fifo_mode);
diff --git a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_buffer.c b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_buffer.c
index 2c03a5b80f80..b0f3da1976e4 100644
--- a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_buffer.c
+++ b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_buffer.c
@@ -602,9 +602,8 @@ int st_lsm6dsx_flush_fifo(struct st_lsm6dsx_hw *hw)
return err;
}
-static int st_lsm6dsx_update_fifo(struct iio_dev *iio_dev, bool enable)
+int st_lsm6dsx_update_fifo(struct st_lsm6dsx_sensor *sensor, bool enable)
{
- struct st_lsm6dsx_sensor *sensor = iio_priv(iio_dev);
struct st_lsm6dsx_hw *hw = sensor->hw;
int err;
@@ -676,12 +675,24 @@ static irqreturn_t st_lsm6dsx_handler_thread(int irq, void *private)
static int st_lsm6dsx_buffer_preenable(struct iio_dev *iio_dev)
{
- return st_lsm6dsx_update_fifo(iio_dev, true);
+ struct st_lsm6dsx_sensor *sensor = iio_priv(iio_dev);
+ struct st_lsm6dsx_hw *hw = sensor->hw;
+
+ if (!hw->settings->fifo_ops.update_fifo)
+ return -ENOTSUPP;
+
+ return hw->settings->fifo_ops.update_fifo(sensor, true);
}
static int st_lsm6dsx_buffer_postdisable(struct iio_dev *iio_dev)
{
- return st_lsm6dsx_update_fifo(iio_dev, false);
+ struct st_lsm6dsx_sensor *sensor = iio_priv(iio_dev);
+ struct st_lsm6dsx_hw *hw = sensor->hw;
+
+ if (!hw->settings->fifo_ops.update_fifo)
+ return -ENOTSUPP;
+
+ return hw->settings->fifo_ops.update_fifo(sensor, false);
}
static const struct iio_buffer_setup_ops st_lsm6dsx_buffer_ops = {
diff --git a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c
index 85824d6739ee..2d3495560136 100644
--- a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c
+++ b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c
@@ -10,6 +10,8 @@
* +-125/+-245/+-500/+-1000/+-2000 dps
* LSM6DSx series has an integrated First-In-First-Out (FIFO) buffer
* allowing dynamic batching of sensor data.
+ * LSM9DSx series is similar but includes an additional magnetometer, handled
+ * by a different driver.
*
* Supported sensors:
* - LSM6DS3:
@@ -30,6 +32,13 @@
* - Gyroscope supported full-scale [dps]: +-125/+-245/+-500/+-1000/+-2000
* - FIFO size: 3KB
*
+ * - LSM9DS1:
+ * - Accelerometer supported ODR [Hz]: 10, 50, 119, 238, 476, 952
+ * - Accelerometer supported full-scale [g]: +-2/+-4/+-8/+-16
+ * - Gyroscope supported ODR [Hz]: 15, 60, 119, 238, 476, 952
+ * - Gyroscope supported full-scale [dps]: +-245/+-500/+-2000
+ * - FIFO size: 32
+ *
* Copyright 2016 STMicroelectronics Inc.
*
* Lorenzo Bianconi <lorenzo.bianconi@st.com>
@@ -49,17 +58,12 @@
#include "st_lsm6dsx.h"
-#define ST_LSM6DSX_REG_INT1_ADDR 0x0d
-#define ST_LSM6DSX_REG_INT2_ADDR 0x0e
#define ST_LSM6DSX_REG_FIFO_FTH_IRQ_MASK BIT(3)
#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
-#define ST_LSM6DSX_REG_INT2_ON_INT1_MASK BIT(5)
static const struct iio_chan_spec st_lsm6dsx_acc_channels[] = {
ST_LSM6DSX_CHANNEL(IIO_ACCEL, 0x28, IIO_MOD_X, 0),
@@ -75,9 +79,89 @@ static const struct iio_chan_spec st_lsm6dsx_gyro_channels[] = {
IIO_CHAN_SOFT_TIMESTAMP(3),
};
+static const struct iio_chan_spec st_lsm6ds0_gyro_channels[] = {
+ ST_LSM6DSX_CHANNEL(IIO_ANGL_VEL, 0x18, IIO_MOD_X, 0),
+ ST_LSM6DSX_CHANNEL(IIO_ANGL_VEL, 0x1a, IIO_MOD_Y, 1),
+ ST_LSM6DSX_CHANNEL(IIO_ANGL_VEL, 0x1c, IIO_MOD_Z, 2),
+ IIO_CHAN_SOFT_TIMESTAMP(3),
+};
+
static const struct st_lsm6dsx_settings st_lsm6dsx_sensor_settings[] = {
{
+ .wai = 0x68,
+ .int1_addr = 0x0c,
+ .int2_addr = 0x0d,
+ .reset_addr = 0x22,
+ .max_fifo_size = 32,
+ .id = {
+ {
+ .hw_id = ST_LSM9DS1_ID,
+ .name = ST_LSM9DS1_DEV_NAME,
+ },
+ },
+ .channels = {
+ [ST_LSM6DSX_ID_ACC] = {
+ .chan = st_lsm6dsx_acc_channels,
+ .len = ARRAY_SIZE(st_lsm6dsx_acc_channels),
+ },
+ [ST_LSM6DSX_ID_GYRO] = {
+ .chan = st_lsm6ds0_gyro_channels,
+ .len = ARRAY_SIZE(st_lsm6ds0_gyro_channels),
+ },
+ },
+ .odr_table = {
+ [ST_LSM6DSX_ID_ACC] = {
+ .reg = {
+ .addr = 0x20,
+ .mask = GENMASK(7, 5),
+ },
+ .odr_avl[0] = { 10, 0x01 },
+ .odr_avl[1] = { 50, 0x02 },
+ .odr_avl[2] = { 119, 0x03 },
+ .odr_avl[3] = { 238, 0x04 },
+ .odr_avl[4] = { 476, 0x05 },
+ .odr_avl[5] = { 952, 0x06 },
+ },
+ [ST_LSM6DSX_ID_GYRO] = {
+ .reg = {
+ .addr = 0x10,
+ .mask = GENMASK(7, 5),
+ },
+ .odr_avl[0] = { 15, 0x01 },
+ .odr_avl[1] = { 60, 0x02 },
+ .odr_avl[2] = { 119, 0x03 },
+ .odr_avl[3] = { 238, 0x04 },
+ .odr_avl[4] = { 476, 0x05 },
+ .odr_avl[5] = { 952, 0x06 },
+ },
+ },
+ .fs_table = {
+ [ST_LSM6DSX_ID_ACC] = {
+ .reg = {
+ .addr = 0x20,
+ .mask = GENMASK(4, 3),
+ },
+ .fs_avl[0] = { IIO_G_TO_M_S_2(61), 0x0 },
+ .fs_avl[1] = { IIO_G_TO_M_S_2(122), 0x2 },
+ .fs_avl[2] = { IIO_G_TO_M_S_2(244), 0x3 },
+ .fs_avl[3] = { IIO_G_TO_M_S_2(732), 0x1 },
+ },
+ [ST_LSM6DSX_ID_GYRO] = {
+ .reg = {
+ .addr = 0x10,
+ .mask = GENMASK(4, 3),
+ },
+ .fs_avl[0] = { IIO_DEGREE_TO_RAD(245), 0x0 },
+ .fs_avl[1] = { IIO_DEGREE_TO_RAD(500), 0x1 },
+ .fs_avl[2] = { IIO_DEGREE_TO_RAD(2000), 0x3 },
+ },
+ },
+ },
+ {
.wai = 0x69,
+ .int1_addr = 0x0d,
+ .int2_addr = 0x0e,
+ .reset_addr = 0x12,
.max_fifo_size = 1365,
.id = {
{
@@ -154,6 +238,7 @@ static const struct st_lsm6dsx_settings st_lsm6dsx_sensor_settings[] = {
},
},
.fifo_ops = {
+ .update_fifo = st_lsm6dsx_update_fifo,
.read_fifo = st_lsm6dsx_read_fifo,
.fifo_th = {
.addr = 0x06,
@@ -186,6 +271,9 @@ static const struct st_lsm6dsx_settings st_lsm6dsx_sensor_settings[] = {
},
{
.wai = 0x69,
+ .int1_addr = 0x0d,
+ .int2_addr = 0x0e,
+ .reset_addr = 0x12,
.max_fifo_size = 682,
.id = {
{
@@ -262,6 +350,7 @@ static const struct st_lsm6dsx_settings st_lsm6dsx_sensor_settings[] = {
},
},
.fifo_ops = {
+ .update_fifo = st_lsm6dsx_update_fifo,
.read_fifo = st_lsm6dsx_read_fifo,
.fifo_th = {
.addr = 0x06,
@@ -294,6 +383,9 @@ static const struct st_lsm6dsx_settings st_lsm6dsx_sensor_settings[] = {
},
{
.wai = 0x6a,
+ .int1_addr = 0x0d,
+ .int2_addr = 0x0e,
+ .reset_addr = 0x12,
.max_fifo_size = 682,
.id = {
{
@@ -379,6 +471,7 @@ static const struct st_lsm6dsx_settings st_lsm6dsx_sensor_settings[] = {
},
},
.fifo_ops = {
+ .update_fifo = st_lsm6dsx_update_fifo,
.read_fifo = st_lsm6dsx_read_fifo,
.fifo_th = {
.addr = 0x06,
@@ -411,6 +504,9 @@ static const struct st_lsm6dsx_settings st_lsm6dsx_sensor_settings[] = {
},
{
.wai = 0x6c,
+ .int1_addr = 0x0d,
+ .int2_addr = 0x0e,
+ .reset_addr = 0x12,
.max_fifo_size = 512,
.id = {
{
@@ -490,6 +586,7 @@ static const struct st_lsm6dsx_settings st_lsm6dsx_sensor_settings[] = {
},
},
.fifo_ops = {
+ .update_fifo = st_lsm6dsx_update_fifo,
.read_fifo = st_lsm6dsx_read_tagged_fifo,
.fifo_th = {
.addr = 0x07,
@@ -497,7 +594,7 @@ static const struct st_lsm6dsx_settings st_lsm6dsx_sensor_settings[] = {
},
.fifo_diff = {
.addr = 0x3a,
- .mask = GENMASK(8, 0),
+ .mask = GENMASK(9, 0),
},
.th_wl = 1,
},
@@ -540,6 +637,9 @@ static const struct st_lsm6dsx_settings st_lsm6dsx_sensor_settings[] = {
},
{
.wai = 0x6b,
+ .int1_addr = 0x0d,
+ .int2_addr = 0x0e,
+ .reset_addr = 0x12,
.max_fifo_size = 512,
.id = {
{
@@ -616,6 +716,7 @@ static const struct st_lsm6dsx_settings st_lsm6dsx_sensor_settings[] = {
},
},
.fifo_ops = {
+ .update_fifo = st_lsm6dsx_update_fifo,
.read_fifo = st_lsm6dsx_read_tagged_fifo,
.fifo_th = {
.addr = 0x07,
@@ -623,7 +724,7 @@ static const struct st_lsm6dsx_settings st_lsm6dsx_sensor_settings[] = {
},
.fifo_diff = {
.addr = 0x3a,
- .mask = GENMASK(8, 0),
+ .mask = GENMASK(9, 0),
},
.th_wl = 1,
},
@@ -640,6 +741,9 @@ static const struct st_lsm6dsx_settings st_lsm6dsx_sensor_settings[] = {
},
{
.wai = 0x6b,
+ .int1_addr = 0x0d,
+ .int2_addr = 0x0e,
+ .reset_addr = 0x12,
.max_fifo_size = 512,
.id = {
{
@@ -719,6 +823,7 @@ static const struct st_lsm6dsx_settings st_lsm6dsx_sensor_settings[] = {
},
},
.fifo_ops = {
+ .update_fifo = st_lsm6dsx_update_fifo,
.read_fifo = st_lsm6dsx_read_tagged_fifo,
.fifo_th = {
.addr = 0x07,
@@ -726,7 +831,7 @@ static const struct st_lsm6dsx_settings st_lsm6dsx_sensor_settings[] = {
},
.fifo_diff = {
.addr = 0x3a,
- .mask = GENMASK(8, 0),
+ .mask = GENMASK(9, 0),
},
.th_wl = 1,
},
@@ -1090,13 +1195,19 @@ static ssize_t st_lsm6dsx_sysfs_scale_avail(struct device *dev,
char *buf)
{
struct st_lsm6dsx_sensor *sensor = iio_priv(dev_get_drvdata(dev));
+ const struct st_lsm6dsx_fs_table_entry *fs_table;
enum st_lsm6dsx_sensor_id id = sensor->id;
struct st_lsm6dsx_hw *hw = sensor->hw;
int i, len = 0;
- for (i = 0; i < ST_LSM6DSX_FS_LIST_SIZE; i++)
+ fs_table = &hw->settings->fs_table[id];
+ for (i = 0; i < ST_LSM6DSX_FS_LIST_SIZE; i++) {
+ if (!fs_table->fs_avl[i].gain)
+ break;
+
len += scnprintf(buf + len, PAGE_SIZE - len, "0.%06u ",
- hw->settings->fs_table[id].fs_avl[i].gain);
+ fs_table->fs_avl[i].gain);
+ }
buf[len - 1] = '\n';
return len;
@@ -1166,10 +1277,10 @@ static int st_lsm6dsx_get_drdy_reg(struct st_lsm6dsx_hw *hw, u8 *drdy_reg)
switch (drdy_pin) {
case 1:
- *drdy_reg = ST_LSM6DSX_REG_INT1_ADDR;
+ *drdy_reg = hw->settings->int1_addr;
break;
case 2:
- *drdy_reg = ST_LSM6DSX_REG_INT2_ADDR;
+ *drdy_reg = hw->settings->int2_addr;
break;
default:
dev_err(hw->dev, "unsupported data ready pin\n");
@@ -1269,7 +1380,7 @@ static int st_lsm6dsx_init_device(struct st_lsm6dsx_hw *hw)
int err;
/* device sw reset */
- err = regmap_update_bits(hw->regmap, ST_LSM6DSX_REG_RESET_ADDR,
+ err = regmap_update_bits(hw->regmap, hw->settings->reset_addr,
ST_LSM6DSX_REG_RESET_MASK,
FIELD_PREP(ST_LSM6DSX_REG_RESET_MASK, 1));
if (err < 0)
@@ -1278,7 +1389,7 @@ static int st_lsm6dsx_init_device(struct st_lsm6dsx_hw *hw)
msleep(50);
/* reload trimming parameter */
- err = regmap_update_bits(hw->regmap, ST_LSM6DSX_REG_RESET_ADDR,
+ err = regmap_update_bits(hw->regmap, hw->settings->reset_addr,
ST_LSM6DSX_REG_BOOT_MASK,
FIELD_PREP(ST_LSM6DSX_REG_BOOT_MASK, 1));
if (err < 0)
diff --git a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_i2c.c b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_i2c.c
index 15c6aa5b6caa..f52511059545 100644
--- a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_i2c.c
+++ b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_i2c.c
@@ -83,6 +83,10 @@ static const struct of_device_id st_lsm6dsx_i2c_of_match[] = {
.compatible = "st,ism330dhcx",
.data = (void *)ST_ISM330DHCX_ID,
},
+ {
+ .compatible = "st,lsm9ds1-imu",
+ .data = (void *)ST_LSM9DS1_ID,
+ },
{},
};
MODULE_DEVICE_TABLE(of, st_lsm6dsx_i2c_of_match);
@@ -99,6 +103,7 @@ static const struct i2c_device_id st_lsm6dsx_i2c_id_table[] = {
{ ST_LSM6DSR_DEV_NAME, ST_LSM6DSR_ID },
{ ST_LSM6DS3TRC_DEV_NAME, ST_LSM6DS3TRC_ID },
{ ST_ISM330DHCX_DEV_NAME, ST_ISM330DHCX_ID },
+ { ST_LSM9DS1_DEV_NAME, ST_LSM9DS1_ID },
{},
};
MODULE_DEVICE_TABLE(i2c, st_lsm6dsx_i2c_id_table);
diff --git a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_spi.c b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_spi.c
index a8430ee11310..344b28dddebb 100644
--- a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_spi.c
+++ b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_spi.c
@@ -83,6 +83,10 @@ static const struct of_device_id st_lsm6dsx_spi_of_match[] = {
.compatible = "st,ism330dhcx",
.data = (void *)ST_ISM330DHCX_ID,
},
+ {
+ .compatible = "st,lsm9ds1-imu",
+ .data = (void *)ST_LSM9DS1_ID,
+ },
{},
};
MODULE_DEVICE_TABLE(of, st_lsm6dsx_spi_of_match);
@@ -99,6 +103,7 @@ static const struct spi_device_id st_lsm6dsx_spi_id_table[] = {
{ ST_LSM6DSR_DEV_NAME, ST_LSM6DSR_ID },
{ ST_LSM6DS3TRC_DEV_NAME, ST_LSM6DS3TRC_ID },
{ ST_ISM330DHCX_DEV_NAME, ST_ISM330DHCX_ID },
+ { ST_LSM9DS1_DEV_NAME, ST_LSM9DS1_ID },
{},
};
MODULE_DEVICE_TABLE(spi, st_lsm6dsx_spi_id_table);
diff --git a/drivers/iio/proximity/Kconfig b/drivers/iio/proximity/Kconfig
index 6b5cce6f1a7b..d53601447da4 100644
--- a/drivers/iio/proximity/Kconfig
+++ b/drivers/iio/proximity/Kconfig
@@ -62,7 +62,7 @@ config RFD77402
tristate "RFD77402 ToF sensor"
depends on I2C
help
- Say Y to build a driver for the RFD77420 Time-of-Flight (distance)
+ Say Y to build a driver for the RFD77402 Time-of-Flight (distance)
sensor module with I2C interface.
To compile this driver as a module, choose M here: the