Merge tag 'iio-fixes-for-6.9a' of https://git.kernel.org/pub/scm/linux/kernel/git...
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 24 Apr 2024 04:26:06 +0000 (21:26 -0700)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 24 Apr 2024 04:26:06 +0000 (21:26 -0700)
Jonathan writes:

IIO: 1st set of fixes for the 6.9 cycle.

adi,asdis16475
- Write the correct field in the register when setting the sync mode.
bosch,bmp280
- Wrong chip specific data being used for the bme280 in the SPI driver.
- Fix that we can't use chip IDs because Bosch reuses them for incompatible
  devices (some require a padding byte, others don't).
maxim,max30102 (dt binding)
- Fix incorrect property check to actually match on a device from the
  binding rather than a completely different one due to a typo.
memsic,mxc4005
- Fix wrong masking of interrupt register accidentally disabling temperature
  compensation. Also hammer initial state to 0 as it's not documented
  if interrupts are masked after reset.
- Explicit reset on probe() and resume() as some devices do not power up
  correctly without a reset.

* tag 'iio-fixes-for-6.9a' of https://git.kernel.org/pub/scm/linux/kernel/git/jic23/iio:
  iio:imu: adis16475: Fix sync mode setting
  iio: accel: mxc4005: Reset chip on probe() and resume()
  iio: accel: mxc4005: Interrupt handling fixes
  dt-bindings: iio: health: maxim,max30102: fix compatible check
  iio: pressure: Fixes SPI support for BMP3xx devices
  iio: pressure: Fixes BME280 SPI driver data

Documentation/devicetree/bindings/iio/health/maxim,max30102.yaml
drivers/iio/accel/mxc4005.c
drivers/iio/imu/adis16475.c
drivers/iio/pressure/bmp280-core.c
drivers/iio/pressure/bmp280-spi.c
drivers/iio/pressure/bmp280.h

index c13c10c8d65da26cfc7faa0517f28332a2c9d8ae..eed0df9d3a2322d9818709588ca4c335f5f689d5 100644 (file)
@@ -42,7 +42,7 @@ allOf:
       properties:
         compatible:
           contains:
-            const: maxim,max30100
+            const: maxim,max30102
     then:
       properties:
         maxim,green-led-current-microamp: false
index 61839be501c21a023790c15c40f55a48cd8d3da3..63c3566a533bd89429b0104a563f1acc72280ad7 100644 (file)
@@ -5,6 +5,7 @@
  * Copyright (c) 2014, Intel Corporation.
  */
 
+#include <linux/delay.h>
 #include <linux/module.h>
 #include <linux/i2c.h>
 #include <linux/iio/iio.h>
 #define MXC4005_REG_ZOUT_UPPER         0x07
 #define MXC4005_REG_ZOUT_LOWER         0x08
 
+#define MXC4005_REG_INT_MASK0          0x0A
+
 #define MXC4005_REG_INT_MASK1          0x0B
 #define MXC4005_REG_INT_MASK1_BIT_DRDYE        0x01
 
+#define MXC4005_REG_INT_CLR0           0x00
+
 #define MXC4005_REG_INT_CLR1           0x01
 #define MXC4005_REG_INT_CLR1_BIT_DRDYC 0x01
+#define MXC4005_REG_INT_CLR1_SW_RST    0x10
 
 #define MXC4005_REG_CONTROL            0x0D
 #define MXC4005_REG_CONTROL_MASK_FSR   GENMASK(6, 5)
@@ -39,6 +45,9 @@
 
 #define MXC4005_REG_DEVICE_ID          0x0E
 
+/* Datasheet does not specify a reset time, this is a conservative guess */
+#define MXC4005_RESET_TIME_US          2000
+
 enum mxc4005_axis {
        AXIS_X,
        AXIS_Y,
@@ -62,6 +71,8 @@ struct mxc4005_data {
                s64 timestamp __aligned(8);
        } scan;
        bool trigger_enabled;
+       unsigned int control;
+       unsigned int int_mask1;
 };
 
 /*
@@ -113,7 +124,9 @@ static bool mxc4005_is_readable_reg(struct device *dev, unsigned int reg)
 static bool mxc4005_is_writeable_reg(struct device *dev, unsigned int reg)
 {
        switch (reg) {
+       case MXC4005_REG_INT_CLR0:
        case MXC4005_REG_INT_CLR1:
+       case MXC4005_REG_INT_MASK0:
        case MXC4005_REG_INT_MASK1:
        case MXC4005_REG_CONTROL:
                return true;
@@ -330,23 +343,20 @@ static int mxc4005_set_trigger_state(struct iio_trigger *trig,
 {
        struct iio_dev *indio_dev = iio_trigger_get_drvdata(trig);
        struct mxc4005_data *data = iio_priv(indio_dev);
+       unsigned int val;
        int ret;
 
        mutex_lock(&data->mutex);
-       if (state) {
-               ret = regmap_write(data->regmap, MXC4005_REG_INT_MASK1,
-                                  MXC4005_REG_INT_MASK1_BIT_DRDYE);
-       } else {
-               ret = regmap_write(data->regmap, MXC4005_REG_INT_MASK1,
-                                  ~MXC4005_REG_INT_MASK1_BIT_DRDYE);
-       }
 
+       val = state ? MXC4005_REG_INT_MASK1_BIT_DRDYE : 0;
+       ret = regmap_write(data->regmap, MXC4005_REG_INT_MASK1, val);
        if (ret < 0) {
                mutex_unlock(&data->mutex);
                dev_err(data->dev, "failed to update reg_int_mask1");
                return ret;
        }
 
+       data->int_mask1 = val;
        data->trigger_enabled = state;
        mutex_unlock(&data->mutex);
 
@@ -382,6 +392,21 @@ static int mxc4005_chip_init(struct mxc4005_data *data)
 
        dev_dbg(data->dev, "MXC4005 chip id %02x\n", reg);
 
+       ret = regmap_write(data->regmap, MXC4005_REG_INT_CLR1,
+                          MXC4005_REG_INT_CLR1_SW_RST);
+       if (ret < 0)
+               return dev_err_probe(data->dev, ret, "resetting chip\n");
+
+       fsleep(MXC4005_RESET_TIME_US);
+
+       ret = regmap_write(data->regmap, MXC4005_REG_INT_MASK0, 0);
+       if (ret < 0)
+               return dev_err_probe(data->dev, ret, "writing INT_MASK0\n");
+
+       ret = regmap_write(data->regmap, MXC4005_REG_INT_MASK1, 0);
+       if (ret < 0)
+               return dev_err_probe(data->dev, ret, "writing INT_MASK1\n");
+
        return 0;
 }
 
@@ -469,6 +494,58 @@ static int mxc4005_probe(struct i2c_client *client)
        return devm_iio_device_register(&client->dev, indio_dev);
 }
 
+static int mxc4005_suspend(struct device *dev)
+{
+       struct iio_dev *indio_dev = dev_get_drvdata(dev);
+       struct mxc4005_data *data = iio_priv(indio_dev);
+       int ret;
+
+       /* Save control to restore it on resume */
+       ret = regmap_read(data->regmap, MXC4005_REG_CONTROL, &data->control);
+       if (ret < 0)
+               dev_err(data->dev, "failed to read reg_control\n");
+
+       return ret;
+}
+
+static int mxc4005_resume(struct device *dev)
+{
+       struct iio_dev *indio_dev = dev_get_drvdata(dev);
+       struct mxc4005_data *data = iio_priv(indio_dev);
+       int ret;
+
+       ret = regmap_write(data->regmap, MXC4005_REG_INT_CLR1,
+                          MXC4005_REG_INT_CLR1_SW_RST);
+       if (ret) {
+               dev_err(data->dev, "failed to reset chip: %d\n", ret);
+               return ret;
+       }
+
+       fsleep(MXC4005_RESET_TIME_US);
+
+       ret = regmap_write(data->regmap, MXC4005_REG_CONTROL, data->control);
+       if (ret) {
+               dev_err(data->dev, "failed to restore control register\n");
+               return ret;
+       }
+
+       ret = regmap_write(data->regmap, MXC4005_REG_INT_MASK0, 0);
+       if (ret) {
+               dev_err(data->dev, "failed to restore interrupt 0 mask\n");
+               return ret;
+       }
+
+       ret = regmap_write(data->regmap, MXC4005_REG_INT_MASK1, data->int_mask1);
+       if (ret) {
+               dev_err(data->dev, "failed to restore interrupt 1 mask\n");
+               return ret;
+       }
+
+       return 0;
+}
+
+static DEFINE_SIMPLE_DEV_PM_OPS(mxc4005_pm_ops, mxc4005_suspend, mxc4005_resume);
+
 static const struct acpi_device_id mxc4005_acpi_match[] = {
        {"MXC4005",     0},
        {"MXC6655",     0},
@@ -496,6 +573,7 @@ static struct i2c_driver mxc4005_driver = {
                .name = MXC4005_DRV_NAME,
                .acpi_match_table = mxc4005_acpi_match,
                .of_match_table = mxc4005_of_match,
+               .pm = pm_sleep_ptr(&mxc4005_pm_ops),
        },
        .probe          = mxc4005_probe,
        .id_table       = mxc4005_id,
index 01f55cc902faad356acb1e3f52ea80ea500a4bdb..060a21c70460d290811c28fc9325a6e42df9bb01 100644 (file)
@@ -1289,6 +1289,7 @@ static int adis16475_config_sync_mode(struct adis16475 *st)
        struct device *dev = &st->adis.spi->dev;
        const struct adis16475_sync *sync;
        u32 sync_mode;
+       u16 val;
 
        /* default to internal clk */
        st->clk_freq = st->info->int_clk * 1000;
@@ -1350,8 +1351,9 @@ static int adis16475_config_sync_mode(struct adis16475 *st)
         * I'm keeping this for simplicity and avoiding extra variables
         * in chip_info.
         */
+       val = ADIS16475_SYNC_MODE(sync->sync_mode);
        ret = __adis_update_bits(&st->adis, ADIS16475_REG_MSG_CTRL,
-                                ADIS16475_SYNC_MODE_MASK, sync->sync_mode);
+                                ADIS16475_SYNC_MODE_MASK, val);
        if (ret)
                return ret;
 
index fe8734468ed352589a0d09ddc9c3a3509b3d3fad..62e9e93d915dc8662b672b4aecb44d3ebf3e8081 100644 (file)
@@ -1233,6 +1233,7 @@ const struct bmp280_chip_info bmp380_chip_info = {
        .chip_id = bmp380_chip_ids,
        .num_chip_id = ARRAY_SIZE(bmp380_chip_ids),
        .regmap_config = &bmp380_regmap_config,
+       .spi_read_extra_byte = true,
        .start_up_time = 2000,
        .channels = bmp380_channels,
        .num_channels = 2,
index a444d4b2978b581ed8f4cd63b6821e23a45a0560..4e19ea0b4d398404340338db851b3033db8ab816 100644 (file)
@@ -96,15 +96,10 @@ static int bmp280_spi_probe(struct spi_device *spi)
 
        chip_info = spi_get_device_match_data(spi);
 
-       switch (chip_info->chip_id[0]) {
-       case BMP380_CHIP_ID:
-       case BMP390_CHIP_ID:
+       if (chip_info->spi_read_extra_byte)
                bmp_regmap_bus = &bmp380_regmap_bus;
-               break;
-       default:
+       else
                bmp_regmap_bus = &bmp280_regmap_bus;
-               break;
-       }
 
        regmap = devm_regmap_init(&spi->dev,
                                  bmp_regmap_bus,
@@ -127,7 +122,7 @@ static const struct of_device_id bmp280_of_spi_match[] = {
        { .compatible = "bosch,bmp180", .data = &bmp180_chip_info },
        { .compatible = "bosch,bmp181", .data = &bmp180_chip_info },
        { .compatible = "bosch,bmp280", .data = &bmp280_chip_info },
-       { .compatible = "bosch,bme280", .data = &bmp280_chip_info },
+       { .compatible = "bosch,bme280", .data = &bme280_chip_info },
        { .compatible = "bosch,bmp380", .data = &bmp380_chip_info },
        { .compatible = "bosch,bmp580", .data = &bmp580_chip_info },
        { },
@@ -139,7 +134,7 @@ static const struct spi_device_id bmp280_spi_id[] = {
        { "bmp180", (kernel_ulong_t)&bmp180_chip_info },
        { "bmp181", (kernel_ulong_t)&bmp180_chip_info },
        { "bmp280", (kernel_ulong_t)&bmp280_chip_info },
-       { "bme280", (kernel_ulong_t)&bmp280_chip_info },
+       { "bme280", (kernel_ulong_t)&bme280_chip_info },
        { "bmp380", (kernel_ulong_t)&bmp380_chip_info },
        { "bmp580", (kernel_ulong_t)&bmp580_chip_info },
        { }
index 4012387d79565631e9c8fdd0152f859c80eac485..5812a344ed8e889c441e9b21fc623f98a2e23333 100644 (file)
@@ -423,6 +423,7 @@ struct bmp280_chip_info {
        int num_chip_id;
 
        const struct regmap_config *regmap_config;
+       bool spi_read_extra_byte;
 
        const struct iio_chan_spec *channels;
        int num_channels;