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

A mixed bunch of fixes for new and ancient issues found.
 
 multiple driver sets:
 - Stop leaking wakeup sources on device unbind.
 - Various timestamp alignment fixes that came up as part of work to add
   runtime checks on buffer sizing. Similarly a DMA buffer safety fix.
 hid-sensor-prox
 - Fix a bad merge conflict resolution that lost some variable assignments.
 - Fix handling of scale when multiple channels present.
 - Fix wrong application of exponent in offset calculation.
 adi,ad7380
 - Disable offload before using the SPI bus.
 - Fix a wrong shift on the event threshold.
 adi,ad7606
 - Check there is a sw_mode_config callback before using it as not
   all busses define one.
 - Fix missing hold of chip select on in multi word accesses.
 adi,ad7861
 - Fix wrong logic on storing of mode.
 adi,adis16201
 - Wrong resolution for inclinometer channel.
 adi,adxl367
 - Use fresh ODR when setting activity time, not previous value.
 bosch,bmi270
 - Fix initial sampling frequency configuration which was using the
   wrong register mask.
 rockchip,saradc
 - Fix clock initialization sequence to get frequency after get + enable,
   not before.
 st,lsm6dsx
 - Avoid 2 potential infinite loops if we see empty FIFOs
 ti,opt3001
 - Fix a deadlock that can occur due to concurrent access to a flag.
 -----BEGIN PGP SIGNATURE-----
 
 iQJFBAABCAAvFiEEbilms4eEBlKRJoGxVIU0mcT0FogFAmgLQQcRHGppYzIzQGtl
 cm5lbC5vcmcACgkQVIU0mcT0Fogp4xAAh6UPM7VhGpgqAyUYqxcESBJkRhkaFEJR
 l3p18QLAsbSzQRkqdLOvhctfqVGF+o7zXXyYWhxuv6jJRZ1PpUBjQPV6N4dkMIGd
 dnWbpvEuw84k/9QHFQbEAij/W1sPKPBirNXOOoX9XJQ9HO7yIqaWLMXkYNWbpBNX
 J6VqIzj+ct0FgCFAo0JX/hOBGWSE/6lY5C5qHtXC4ZMwIQEc4UP5ls9CQjrY66dU
 UwNbupYuc5USKV//JBnAAc8RD2giJgQyzTogz936kPIa0DBXmeTZXCqGbGPn/gUs
 +2WN4nzqhGqOdQCIbvvX/kN8wHL1Y4w1jmmmqIA46SV0AvamCLJWU+Lj5PzTjE8u
 K5i5p4qzrLszzxvNdzE/sgcezt8gr/kOv+/vuhQp5NtMfJHHIk279Yw+seYzH1Cr
 6G3L+1ke7HKw95aSLdUTUKlPQZ7CSiKyZ5Mith5RwqWcqXq8eyFxff2oA2ZUi2I4
 YO82O1o56VsTLzkhptL7IW4ZSbU3SUp0u7qKevPnl19xzzYkqSDUTbUYeAHA9Ja3
 /sLcnYS7AixZhr/RmVHbtAafqM+SxsthYSxLpNHCOl7v7JgaSZIyIe3VH0F14FR6
 pDn08I1NfZOuvYQ5/ZPrbKVrI3m81x+Y2h9zzli67V+a12x111pQ8QKtutHGdvoF
 M2WIw3mHF/U=
 =JQSU
 -----END PGP SIGNATURE-----

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

Jonathan writes:

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

A mixed bunch of fixes for new and ancient issues found.

multiple driver sets:
- Stop leaking wakeup sources on device unbind.
- Various timestamp alignment fixes that came up as part of work to add
  runtime checks on buffer sizing. Similarly a DMA buffer safety fix.
hid-sensor-prox
- Fix a bad merge conflict resolution that lost some variable assignments.
- Fix handling of scale when multiple channels present.
- Fix wrong application of exponent in offset calculation.
adi,ad7380
- Disable offload before using the SPI bus.
- Fix a wrong shift on the event threshold.
adi,ad7606
- Check there is a sw_mode_config callback before using it as not
  all busses define one.
- Fix missing hold of chip select on in multi word accesses.
adi,ad7861
- Fix wrong logic on storing of mode.
adi,adis16201
- Wrong resolution for inclinometer channel.
adi,adxl367
- Use fresh ODR when setting activity time, not previous value.
bosch,bmi270
- Fix initial sampling frequency configuration which was using the
  wrong register mask.
rockchip,saradc
- Fix clock initialization sequence to get frequency after get + enable,
  not before.
st,lsm6dsx
- Avoid 2 potential infinite loops if we see empty FIFOs
ti,opt3001
- Fix a deadlock that can occur due to concurrent access to a flag.

* tag 'iio-fixes-for-6.15a' of ssh://gitolite.kernel.org/pub/scm/linux/kernel/git/jic23/iio: (28 commits)
  iio: adis16201: Correct inclinometer channel resolution
  iio: adc: ad7606: fix serial register access
  iio: pressure: mprls0025pa: use aligned_s64 for timestamp
  iio: imu: adis16550: align buffers for timestamp
  staging: iio: adc: ad7816: Correct conditional logic for store mode
  iio: adc: ad7266: Fix potential timestamp alignment issue.
  iio: adc: ad7768-1: Fix insufficient alignment of timestamp.
  iio: adc: dln2: Use aligned_s64 for timestamp
  iio: accel: adxl355: Make timestamp 64-bit aligned using aligned_s64
  iio: temp: maxim-thermocouple: Fix potential lack of DMA safe buffer.
  iio: chemical: pms7003: use aligned_s64 for timestamp
  iio: chemical: sps30: use aligned_s64 for timestamp
  iio: imu: inv_mpu6050: align buffer for timestamp
  iio: imu: st_lsm6dsx: Fix wakeup source leaks on device unbind
  iio: adc: qcom-spmi-iadc: Fix wakeup source leaks on device unbind
  iio: accel: fxls8962af: Fix wakeup source leaks on device unbind
  iio: adc: ad7380: fix event threshold shift
  iio: hid-sensor-prox: Fix incorrect OFFSET calculation
  iio: hid-sensor-prox: support multi-channel SCALE calculation
  iio: hid-sensor-prox: Restore lost scale assignments
  ...
This commit is contained in:
Greg Kroah-Hartman 2025-05-01 17:47:49 +02:00
commit f55aaec4fc
25 changed files with 104 additions and 73 deletions

View File

@ -211,9 +211,9 @@ static const struct iio_chan_spec adis16201_channels[] = {
BIT(IIO_CHAN_INFO_CALIBBIAS), 0, 14),
ADIS_AUX_ADC_CHAN(ADIS16201_AUX_ADC_REG, ADIS16201_SCAN_AUX_ADC, 0, 12),
ADIS_INCLI_CHAN(X, ADIS16201_XINCL_OUT_REG, ADIS16201_SCAN_INCLI_X,
BIT(IIO_CHAN_INFO_CALIBBIAS), 0, 14),
BIT(IIO_CHAN_INFO_CALIBBIAS), 0, 12),
ADIS_INCLI_CHAN(Y, ADIS16201_YINCL_OUT_REG, ADIS16201_SCAN_INCLI_Y,
BIT(IIO_CHAN_INFO_CALIBBIAS), 0, 14),
BIT(IIO_CHAN_INFO_CALIBBIAS), 0, 12),
IIO_CHAN_SOFT_TIMESTAMP(7)
};

View File

@ -231,7 +231,7 @@ struct adxl355_data {
u8 transf_buf[3];
struct {
u8 buf[14];
s64 ts;
aligned_s64 ts;
} buffer;
} __aligned(IIO_DMA_MINALIGN);
};

View File

@ -601,18 +601,14 @@ static int _adxl367_set_odr(struct adxl367_state *st, enum adxl367_odr odr)
if (ret)
return ret;
st->odr = odr;
/* Activity timers depend on ODR */
ret = _adxl367_set_act_time_ms(st, st->act_time_ms);
if (ret)
return ret;
ret = _adxl367_set_inact_time_ms(st, st->inact_time_ms);
if (ret)
return ret;
st->odr = odr;
return 0;
return _adxl367_set_inact_time_ms(st, st->inact_time_ms);
}
static int adxl367_set_odr(struct iio_dev *indio_dev, enum adxl367_odr odr)

View File

@ -1226,8 +1226,11 @@ int fxls8962af_core_probe(struct device *dev, struct regmap *regmap, int irq)
if (ret)
return ret;
if (device_property_read_bool(dev, "wakeup-source"))
device_init_wakeup(dev, true);
if (device_property_read_bool(dev, "wakeup-source")) {
ret = devm_device_init_wakeup(dev);
if (ret)
return dev_err_probe(dev, ret, "Failed to init wakeup\n");
}
return devm_iio_device_register(dev, indio_dev);
}

View File

@ -45,7 +45,7 @@ struct ad7266_state {
*/
struct {
__be16 sample[2];
s64 timestamp;
aligned_s64 timestamp;
} data __aligned(IIO_DMA_MINALIGN);
};

View File

@ -1211,6 +1211,9 @@ static int ad7380_offload_buffer_predisable(struct iio_dev *indio_dev)
struct ad7380_state *st = iio_priv(indio_dev);
int ret;
spi_offload_trigger_disable(st->offload, st->offload_trigger);
spi_unoptimize_message(&st->offload_msg);
if (st->seq) {
ret = regmap_update_bits(st->regmap,
AD7380_REG_ADDR_CONFIG1,
@ -1222,10 +1225,6 @@ static int ad7380_offload_buffer_predisable(struct iio_dev *indio_dev)
st->seq = false;
}
spi_offload_trigger_disable(st->offload, st->offload_trigger);
spi_unoptimize_message(&st->offload_msg);
return 0;
}
@ -1611,11 +1610,25 @@ static int ad7380_write_event_config(struct iio_dev *indio_dev,
return ret;
}
static int ad7380_get_alert_th(struct ad7380_state *st,
static int ad7380_get_alert_th(struct iio_dev *indio_dev,
const struct iio_chan_spec *chan,
enum iio_event_direction dir,
int *val)
{
int ret, tmp;
struct ad7380_state *st = iio_priv(indio_dev);
const struct iio_scan_type *scan_type;
int ret, tmp, shift;
scan_type = iio_get_current_scan_type(indio_dev, chan);
if (IS_ERR(scan_type))
return PTR_ERR(scan_type);
/*
* The register value is 12-bits and is compared to the most significant
* bits of raw value, therefore a shift is required to convert this to
* the same scale as the raw value.
*/
shift = scan_type->realbits - 12;
switch (dir) {
case IIO_EV_DIR_RISING:
@ -1625,7 +1638,7 @@ static int ad7380_get_alert_th(struct ad7380_state *st,
if (ret)
return ret;
*val = FIELD_GET(AD7380_ALERT_HIGH_TH, tmp);
*val = FIELD_GET(AD7380_ALERT_HIGH_TH, tmp) << shift;
return IIO_VAL_INT;
case IIO_EV_DIR_FALLING:
ret = regmap_read(st->regmap,
@ -1634,7 +1647,7 @@ static int ad7380_get_alert_th(struct ad7380_state *st,
if (ret)
return ret;
*val = FIELD_GET(AD7380_ALERT_LOW_TH, tmp);
*val = FIELD_GET(AD7380_ALERT_LOW_TH, tmp) << shift;
return IIO_VAL_INT;
default:
return -EINVAL;
@ -1648,7 +1661,6 @@ static int ad7380_read_event_value(struct iio_dev *indio_dev,
enum iio_event_info info,
int *val, int *val2)
{
struct ad7380_state *st = iio_priv(indio_dev);
int ret;
switch (info) {
@ -1656,7 +1668,7 @@ static int ad7380_read_event_value(struct iio_dev *indio_dev,
if (!iio_device_claim_direct(indio_dev))
return -EBUSY;
ret = ad7380_get_alert_th(st, dir, val);
ret = ad7380_get_alert_th(indio_dev, chan, dir, val);
iio_device_release_direct(indio_dev);
return ret;

View File

@ -1236,9 +1236,11 @@ static int ad7616_sw_mode_setup(struct iio_dev *indio_dev)
st->write_scale = ad7616_write_scale_sw;
st->write_os = &ad7616_write_os_sw;
if (st->bops->sw_mode_config) {
ret = st->bops->sw_mode_config(indio_dev);
if (ret)
return ret;
}
/* Activate Burst mode and SEQEN MODE */
return ad7606_write_mask(st, AD7616_CONFIGURATION_REGISTER,
@ -1268,6 +1270,9 @@ static int ad7606b_sw_mode_setup(struct iio_dev *indio_dev)
st->write_scale = ad7606_write_scale_sw;
st->write_os = &ad7606_write_os_sw;
if (!st->bops->sw_mode_config)
return 0;
return st->bops->sw_mode_config(indio_dev);
}

View File

@ -131,7 +131,7 @@ static int ad7606_spi_reg_read(struct ad7606_state *st, unsigned int addr)
{
.tx_buf = &st->d16[0],
.len = 2,
.cs_change = 0,
.cs_change = 1,
}, {
.rx_buf = &st->d16[1],
.len = 2,

View File

@ -168,7 +168,7 @@ struct ad7768_state {
union {
struct {
__be32 chan;
s64 timestamp;
aligned_s64 timestamp;
} scan;
__be32 d32;
u8 d8[2];

View File

@ -466,7 +466,7 @@ static irqreturn_t dln2_adc_trigger_h(int irq, void *p)
struct iio_dev *indio_dev = pf->indio_dev;
struct {
__le16 values[DLN2_ADC_MAX_CHANNELS];
int64_t timestamp_space;
aligned_s64 timestamp_space;
} data;
struct dln2_adc_get_all_vals dev_data;
struct dln2_adc *dln2 = iio_priv(indio_dev);

View File

@ -543,7 +543,9 @@ static int iadc_probe(struct platform_device *pdev)
else
return ret;
} else {
device_init_wakeup(iadc->dev, 1);
ret = devm_device_init_wakeup(iadc->dev);
if (ret)
return dev_err_probe(iadc->dev, ret, "Failed to init wakeup\n");
}
ret = iadc_update_offset(iadc);

View File

@ -520,15 +520,6 @@ static int rockchip_saradc_probe(struct platform_device *pdev)
if (info->reset)
rockchip_saradc_reset_controller(info->reset);
/*
* Use a default value for the converter clock.
* This may become user-configurable in the future.
*/
ret = clk_set_rate(info->clk, info->data->clk_rate);
if (ret < 0)
return dev_err_probe(&pdev->dev, ret,
"failed to set adc clk rate\n");
ret = regulator_enable(info->vref);
if (ret < 0)
return dev_err_probe(&pdev->dev, ret,
@ -555,6 +546,14 @@ static int rockchip_saradc_probe(struct platform_device *pdev)
if (IS_ERR(info->clk))
return dev_err_probe(&pdev->dev, PTR_ERR(info->clk),
"failed to get adc clock\n");
/*
* Use a default value for the converter clock.
* This may become user-configurable in the future.
*/
ret = clk_set_rate(info->clk, info->data->clk_rate);
if (ret < 0)
return dev_err_probe(&pdev->dev, ret,
"failed to set adc clk rate\n");
platform_set_drvdata(pdev, indio_dev);

View File

@ -5,7 +5,6 @@
* Copyright (c) Tomasz Duszynski <tduszyns@gmail.com>
*/
#include <linux/unaligned.h>
#include <linux/completion.h>
#include <linux/device.h>
#include <linux/errno.h>
@ -19,6 +18,8 @@
#include <linux/module.h>
#include <linux/mutex.h>
#include <linux/serdev.h>
#include <linux/types.h>
#include <linux/unaligned.h>
#define PMS7003_DRIVER_NAME "pms7003"
@ -76,7 +77,7 @@ struct pms7003_state {
/* Used to construct scan to push to the IIO buffer */
struct {
u16 data[3]; /* PM1, PM2P5, PM10 */
s64 ts;
aligned_s64 ts;
} scan;
};

View File

@ -108,7 +108,7 @@ static irqreturn_t sps30_trigger_handler(int irq, void *p)
int ret;
struct {
s32 data[4]; /* PM1, PM2P5, PM4, PM10 */
s64 ts;
aligned_s64 ts;
} scan;
mutex_lock(&state->lock);

View File

@ -66,6 +66,10 @@ static struct {
{HID_USAGE_SENSOR_HUMIDITY, 0, 1000, 0},
{HID_USAGE_SENSOR_HINGE, 0, 0, 17453293},
{HID_USAGE_SENSOR_HINGE, HID_USAGE_SENSOR_UNITS_DEGREES, 0, 17453293},
{HID_USAGE_SENSOR_HUMAN_PRESENCE, 0, 1, 0},
{HID_USAGE_SENSOR_HUMAN_PROXIMITY, 0, 1, 0},
{HID_USAGE_SENSOR_HUMAN_ATTENTION, 0, 1, 0},
};
static void simple_div(int dividend, int divisor, int *whole,

View File

@ -836,7 +836,7 @@ static irqreturn_t adis16550_trigger_handler(int irq, void *p)
u16 dummy;
bool valid;
struct iio_poll_func *pf = p;
__be32 data[ADIS16550_MAX_SCAN_DATA];
__be32 data[ADIS16550_MAX_SCAN_DATA] __aligned(8);
struct iio_dev *indio_dev = pf->indio_dev;
struct adis16550 *st = iio_priv(indio_dev);
struct adis *adis = iio_device_get_drvdata(indio_dev);

View File

@ -918,8 +918,7 @@ static int bmi270_configure_imu(struct bmi270_data *data)
FIELD_PREP(BMI270_ACC_CONF_ODR_MSK,
BMI270_ACC_CONF_ODR_100HZ) |
FIELD_PREP(BMI270_ACC_CONF_BWP_MSK,
BMI270_ACC_CONF_BWP_NORMAL_MODE) |
BMI270_PWR_CONF_ADV_PWR_SAVE_MSK);
BMI270_ACC_CONF_BWP_NORMAL_MODE));
if (ret)
return dev_err_probe(dev, ret, "Failed to configure accelerometer");
@ -927,8 +926,7 @@ static int bmi270_configure_imu(struct bmi270_data *data)
FIELD_PREP(BMI270_GYR_CONF_ODR_MSK,
BMI270_GYR_CONF_ODR_200HZ) |
FIELD_PREP(BMI270_GYR_CONF_BWP_MSK,
BMI270_GYR_CONF_BWP_NORMAL_MODE) |
BMI270_PWR_CONF_ADV_PWR_SAVE_MSK);
BMI270_GYR_CONF_BWP_NORMAL_MODE));
if (ret)
return dev_err_probe(dev, ret, "Failed to configure gyroscope");

View File

@ -50,7 +50,7 @@ irqreturn_t inv_mpu6050_read_fifo(int irq, void *p)
u16 fifo_count;
u32 fifo_period;
s64 timestamp;
u8 data[INV_MPU6050_OUTPUT_DATA_SIZE];
u8 data[INV_MPU6050_OUTPUT_DATA_SIZE] __aligned(8);
size_t i, nb;
mutex_lock(&st->lock);

View File

@ -392,6 +392,9 @@ int st_lsm6dsx_read_fifo(struct st_lsm6dsx_hw *hw)
if (fifo_status & cpu_to_le16(ST_LSM6DSX_FIFO_EMPTY_MASK))
return 0;
if (!pattern_len)
pattern_len = ST_LSM6DSX_SAMPLE_SIZE;
fifo_len = (le16_to_cpu(fifo_status) & fifo_diff_mask) *
ST_LSM6DSX_CHAN_SIZE;
fifo_len = (fifo_len / pattern_len) * pattern_len;
@ -623,6 +626,9 @@ int st_lsm6dsx_read_tagged_fifo(struct st_lsm6dsx_hw *hw)
if (!fifo_len)
return 0;
if (!pattern_len)
pattern_len = ST_LSM6DSX_TAGGED_SAMPLE_SIZE;
for (read_len = 0; read_len < fifo_len; read_len += pattern_len) {
err = st_lsm6dsx_read_block(hw,
ST_LSM6DSX_REG_FIFO_OUT_TAG_ADDR,

View File

@ -2719,8 +2719,11 @@ int st_lsm6dsx_probe(struct device *dev, int irq, int hw_id,
}
if (device_property_read_bool(dev, "wakeup-source") ||
(pdata && pdata->wakeup_source))
device_init_wakeup(dev, true);
(pdata && pdata->wakeup_source)) {
err = devm_device_init_wakeup(dev);
if (err)
return dev_err_probe(dev, err, "Failed to init wakeup\n");
}
return 0;
}

View File

@ -34,9 +34,9 @@ struct prox_state {
struct iio_chan_spec channels[MAX_CHANNELS];
u32 channel2usage[MAX_CHANNELS];
u32 human_presence[MAX_CHANNELS];
int scale_pre_decml;
int scale_post_decml;
int scale_precision;
int scale_pre_decml[MAX_CHANNELS];
int scale_post_decml[MAX_CHANNELS];
int scale_precision[MAX_CHANNELS];
unsigned long scan_mask[2]; /* One entry plus one terminator. */
int num_channels;
};
@ -116,13 +116,15 @@ static int prox_read_raw(struct iio_dev *indio_dev,
ret_type = IIO_VAL_INT;
break;
case IIO_CHAN_INFO_SCALE:
*val = prox_state->scale_pre_decml;
*val2 = prox_state->scale_post_decml;
ret_type = prox_state->scale_precision;
if (chan->scan_index >= prox_state->num_channels)
return -EINVAL;
*val = prox_state->scale_pre_decml[chan->scan_index];
*val2 = prox_state->scale_post_decml[chan->scan_index];
ret_type = prox_state->scale_precision[chan->scan_index];
break;
case IIO_CHAN_INFO_OFFSET:
*val = hid_sensor_convert_exponent(
prox_state->prox_attr[chan->scan_index].unit_expo);
*val = 0;
ret_type = IIO_VAL_INT;
break;
case IIO_CHAN_INFO_SAMP_FREQ:
@ -249,6 +251,10 @@ static int prox_parse_report(struct platform_device *pdev,
st->prox_attr[index].size);
dev_dbg(&pdev->dev, "prox %x:%x\n", st->prox_attr[index].index,
st->prox_attr[index].report_id);
st->scale_precision[index] =
hid_sensor_format_scale(usage_id, &st->prox_attr[index],
&st->scale_pre_decml[index],
&st->scale_post_decml[index]);
index++;
}

View File

@ -788,8 +788,9 @@ static irqreturn_t opt3001_irq(int irq, void *_iio)
int ret;
bool wake_result_ready_queue = false;
enum iio_chan_type chan_type = opt->chip_info->chan_type;
bool ok_to_ignore_lock = opt->ok_to_ignore_lock;
if (!opt->ok_to_ignore_lock)
if (!ok_to_ignore_lock)
mutex_lock(&opt->lock);
ret = i2c_smbus_read_word_swapped(opt->client, OPT3001_CONFIGURATION);
@ -826,7 +827,7 @@ static irqreturn_t opt3001_irq(int irq, void *_iio)
}
out:
if (!opt->ok_to_ignore_lock)
if (!ok_to_ignore_lock)
mutex_unlock(&opt->lock);
if (wake_result_ready_queue)

View File

@ -34,16 +34,6 @@ struct iio_dev;
struct mpr_data;
struct mpr_ops;
/**
* struct mpr_chan
* @pres: pressure value
* @ts: timestamp
*/
struct mpr_chan {
s32 pres;
s64 ts;
};
enum mpr_func_id {
MPR_FUNCTION_A,
MPR_FUNCTION_B,
@ -69,6 +59,8 @@ enum mpr_func_id {
* reading in a loop until data is ready
* @completion: handshake from irq to read
* @chan: channel values for buffered mode
* @chan.pres: pressure value
* @chan.ts: timestamp
* @buffer: raw conversion data
*/
struct mpr_data {
@ -87,7 +79,10 @@ struct mpr_data {
struct gpio_desc *gpiod_reset;
int irq;
struct completion completion;
struct mpr_chan chan;
struct {
s32 pres;
aligned_s64 ts;
} chan;
u8 buffer[MPR_MEASUREMENT_RD_SIZE] __aligned(IIO_DMA_MINALIGN);
};

View File

@ -121,9 +121,9 @@ static const struct maxim_thermocouple_chip maxim_thermocouple_chips[] = {
struct maxim_thermocouple_data {
struct spi_device *spi;
const struct maxim_thermocouple_chip *chip;
char tc_type;
u8 buffer[16] __aligned(IIO_DMA_MINALIGN);
char tc_type;
};
static int maxim_thermocouple_read(struct maxim_thermocouple_data *data,

View File

@ -136,7 +136,7 @@ static ssize_t ad7816_store_mode(struct device *dev,
struct iio_dev *indio_dev = dev_to_iio_dev(dev);
struct ad7816_chip_info *chip = iio_priv(indio_dev);
if (strcmp(buf, "full")) {
if (strcmp(buf, "full") == 0) {
gpiod_set_value(chip->rdwr_pin, 1);
chip->mode = AD7816_FULL;
} else {