Commit 7ab7f2ca authored by Greg Kroah-Hartman's avatar Greg Kroah-Hartman

Merge tag 'iio-fixes-for-6.9a' of...

Merge tag 'iio-fixes-for-6.9a' of https://git.kernel.org/pub/scm/linux/kernel/git/jic23/iio into char-misc-linus

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
parents ed30a4a5 74a72baf
...@@ -42,7 +42,7 @@ allOf: ...@@ -42,7 +42,7 @@ allOf:
properties: properties:
compatible: compatible:
contains: contains:
const: maxim,max30100 const: maxim,max30102
then: then:
properties: properties:
maxim,green-led-current-microamp: false maxim,green-led-current-microamp: false
......
...@@ -5,6 +5,7 @@ ...@@ -5,6 +5,7 @@
* Copyright (c) 2014, Intel Corporation. * Copyright (c) 2014, Intel Corporation.
*/ */
#include <linux/delay.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/i2c.h> #include <linux/i2c.h>
#include <linux/iio/iio.h> #include <linux/iio/iio.h>
...@@ -27,11 +28,16 @@ ...@@ -27,11 +28,16 @@
#define MXC4005_REG_ZOUT_UPPER 0x07 #define MXC4005_REG_ZOUT_UPPER 0x07
#define MXC4005_REG_ZOUT_LOWER 0x08 #define MXC4005_REG_ZOUT_LOWER 0x08
#define MXC4005_REG_INT_MASK0 0x0A
#define MXC4005_REG_INT_MASK1 0x0B #define MXC4005_REG_INT_MASK1 0x0B
#define MXC4005_REG_INT_MASK1_BIT_DRDYE 0x01 #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 0x01
#define MXC4005_REG_INT_CLR1_BIT_DRDYC 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 0x0D
#define MXC4005_REG_CONTROL_MASK_FSR GENMASK(6, 5) #define MXC4005_REG_CONTROL_MASK_FSR GENMASK(6, 5)
...@@ -39,6 +45,9 @@ ...@@ -39,6 +45,9 @@
#define MXC4005_REG_DEVICE_ID 0x0E #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 { enum mxc4005_axis {
AXIS_X, AXIS_X,
AXIS_Y, AXIS_Y,
...@@ -62,6 +71,8 @@ struct mxc4005_data { ...@@ -62,6 +71,8 @@ struct mxc4005_data {
s64 timestamp __aligned(8); s64 timestamp __aligned(8);
} scan; } scan;
bool trigger_enabled; 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) ...@@ -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) static bool mxc4005_is_writeable_reg(struct device *dev, unsigned int reg)
{ {
switch (reg) { switch (reg) {
case MXC4005_REG_INT_CLR0:
case MXC4005_REG_INT_CLR1: case MXC4005_REG_INT_CLR1:
case MXC4005_REG_INT_MASK0:
case MXC4005_REG_INT_MASK1: case MXC4005_REG_INT_MASK1:
case MXC4005_REG_CONTROL: case MXC4005_REG_CONTROL:
return true; return true;
...@@ -330,23 +343,20 @@ static int mxc4005_set_trigger_state(struct iio_trigger *trig, ...@@ -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 iio_dev *indio_dev = iio_trigger_get_drvdata(trig);
struct mxc4005_data *data = iio_priv(indio_dev); struct mxc4005_data *data = iio_priv(indio_dev);
unsigned int val;
int ret; int ret;
mutex_lock(&data->mutex); 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) { if (ret < 0) {
mutex_unlock(&data->mutex); mutex_unlock(&data->mutex);
dev_err(data->dev, "failed to update reg_int_mask1"); dev_err(data->dev, "failed to update reg_int_mask1");
return ret; return ret;
} }
data->int_mask1 = val;
data->trigger_enabled = state; data->trigger_enabled = state;
mutex_unlock(&data->mutex); mutex_unlock(&data->mutex);
...@@ -382,6 +392,21 @@ static int mxc4005_chip_init(struct mxc4005_data *data) ...@@ -382,6 +392,21 @@ static int mxc4005_chip_init(struct mxc4005_data *data)
dev_dbg(data->dev, "MXC4005 chip id %02x\n", reg); 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; return 0;
} }
...@@ -469,6 +494,58 @@ static int mxc4005_probe(struct i2c_client *client) ...@@ -469,6 +494,58 @@ static int mxc4005_probe(struct i2c_client *client)
return devm_iio_device_register(&client->dev, indio_dev); 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[] = { static const struct acpi_device_id mxc4005_acpi_match[] = {
{"MXC4005", 0}, {"MXC4005", 0},
{"MXC6655", 0}, {"MXC6655", 0},
...@@ -496,6 +573,7 @@ static struct i2c_driver mxc4005_driver = { ...@@ -496,6 +573,7 @@ static struct i2c_driver mxc4005_driver = {
.name = MXC4005_DRV_NAME, .name = MXC4005_DRV_NAME,
.acpi_match_table = mxc4005_acpi_match, .acpi_match_table = mxc4005_acpi_match,
.of_match_table = mxc4005_of_match, .of_match_table = mxc4005_of_match,
.pm = pm_sleep_ptr(&mxc4005_pm_ops),
}, },
.probe = mxc4005_probe, .probe = mxc4005_probe,
.id_table = mxc4005_id, .id_table = mxc4005_id,
......
...@@ -1289,6 +1289,7 @@ static int adis16475_config_sync_mode(struct adis16475 *st) ...@@ -1289,6 +1289,7 @@ static int adis16475_config_sync_mode(struct adis16475 *st)
struct device *dev = &st->adis.spi->dev; struct device *dev = &st->adis.spi->dev;
const struct adis16475_sync *sync; const struct adis16475_sync *sync;
u32 sync_mode; u32 sync_mode;
u16 val;
/* default to internal clk */ /* default to internal clk */
st->clk_freq = st->info->int_clk * 1000; st->clk_freq = st->info->int_clk * 1000;
...@@ -1350,8 +1351,9 @@ static int adis16475_config_sync_mode(struct adis16475 *st) ...@@ -1350,8 +1351,9 @@ static int adis16475_config_sync_mode(struct adis16475 *st)
* I'm keeping this for simplicity and avoiding extra variables * I'm keeping this for simplicity and avoiding extra variables
* in chip_info. * in chip_info.
*/ */
val = ADIS16475_SYNC_MODE(sync->sync_mode);
ret = __adis_update_bits(&st->adis, ADIS16475_REG_MSG_CTRL, ret = __adis_update_bits(&st->adis, ADIS16475_REG_MSG_CTRL,
ADIS16475_SYNC_MODE_MASK, sync->sync_mode); ADIS16475_SYNC_MODE_MASK, val);
if (ret) if (ret)
return ret; return ret;
......
...@@ -1233,6 +1233,7 @@ const struct bmp280_chip_info bmp380_chip_info = { ...@@ -1233,6 +1233,7 @@ const struct bmp280_chip_info bmp380_chip_info = {
.chip_id = bmp380_chip_ids, .chip_id = bmp380_chip_ids,
.num_chip_id = ARRAY_SIZE(bmp380_chip_ids), .num_chip_id = ARRAY_SIZE(bmp380_chip_ids),
.regmap_config = &bmp380_regmap_config, .regmap_config = &bmp380_regmap_config,
.spi_read_extra_byte = true,
.start_up_time = 2000, .start_up_time = 2000,
.channels = bmp380_channels, .channels = bmp380_channels,
.num_channels = 2, .num_channels = 2,
......
...@@ -96,15 +96,10 @@ static int bmp280_spi_probe(struct spi_device *spi) ...@@ -96,15 +96,10 @@ static int bmp280_spi_probe(struct spi_device *spi)
chip_info = spi_get_device_match_data(spi); chip_info = spi_get_device_match_data(spi);
switch (chip_info->chip_id[0]) { if (chip_info->spi_read_extra_byte)
case BMP380_CHIP_ID:
case BMP390_CHIP_ID:
bmp_regmap_bus = &bmp380_regmap_bus; bmp_regmap_bus = &bmp380_regmap_bus;
break; else
default:
bmp_regmap_bus = &bmp280_regmap_bus; bmp_regmap_bus = &bmp280_regmap_bus;
break;
}
regmap = devm_regmap_init(&spi->dev, regmap = devm_regmap_init(&spi->dev,
bmp_regmap_bus, bmp_regmap_bus,
...@@ -127,7 +122,7 @@ static const struct of_device_id bmp280_of_spi_match[] = { ...@@ -127,7 +122,7 @@ static const struct of_device_id bmp280_of_spi_match[] = {
{ .compatible = "bosch,bmp180", .data = &bmp180_chip_info }, { .compatible = "bosch,bmp180", .data = &bmp180_chip_info },
{ .compatible = "bosch,bmp181", .data = &bmp180_chip_info }, { .compatible = "bosch,bmp181", .data = &bmp180_chip_info },
{ .compatible = "bosch,bmp280", .data = &bmp280_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,bmp380", .data = &bmp380_chip_info },
{ .compatible = "bosch,bmp580", .data = &bmp580_chip_info }, { .compatible = "bosch,bmp580", .data = &bmp580_chip_info },
{ }, { },
...@@ -139,7 +134,7 @@ static const struct spi_device_id bmp280_spi_id[] = { ...@@ -139,7 +134,7 @@ static const struct spi_device_id bmp280_spi_id[] = {
{ "bmp180", (kernel_ulong_t)&bmp180_chip_info }, { "bmp180", (kernel_ulong_t)&bmp180_chip_info },
{ "bmp181", (kernel_ulong_t)&bmp180_chip_info }, { "bmp181", (kernel_ulong_t)&bmp180_chip_info },
{ "bmp280", (kernel_ulong_t)&bmp280_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 }, { "bmp380", (kernel_ulong_t)&bmp380_chip_info },
{ "bmp580", (kernel_ulong_t)&bmp580_chip_info }, { "bmp580", (kernel_ulong_t)&bmp580_chip_info },
{ } { }
......
...@@ -423,6 +423,7 @@ struct bmp280_chip_info { ...@@ -423,6 +423,7 @@ struct bmp280_chip_info {
int num_chip_id; int num_chip_id;
const struct regmap_config *regmap_config; const struct regmap_config *regmap_config;
bool spi_read_extra_byte;
const struct iio_chan_spec *channels; const struct iio_chan_spec *channels;
int num_channels; int num_channels;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment