From 86fdd15e10e404e70ecb2a3bff24d70356d42b36 Mon Sep 17 00:00:00 2001 From: Zeng Heng Date: Tue, 15 Nov 2022 10:37:12 +0800 Subject: iio: fix memory leak in iio_device_register_eventset() When iio_device_register_sysfs_group() returns failed, iio_device_register_eventset() needs to free attrs array. Otherwise, kmemleak would scan & report memory leak as below: unreferenced object 0xffff88810a1cc3c0 (size 32): comm "100-i2c-vcnl302", pid 728, jiffies 4295052307 (age 156.027s) backtrace: __kmalloc+0x46/0x1b0 iio_device_register_eventset at drivers/iio/industrialio-event.c:541 __iio_device_register at drivers/iio/industrialio-core.c:1959 __devm_iio_device_register at drivers/iio/industrialio-core.c:2040 Fixes: 32f171724e5c ("iio: core: rework iio device group creation") Signed-off-by: Zeng Heng Link: https://lore.kernel.org/r/20221115023712.3726854-1-zengheng4@huawei.com Cc: Signed-off-by: Jonathan Cameron --- drivers/iio/industrialio-event.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'drivers/iio') diff --git a/drivers/iio/industrialio-event.c b/drivers/iio/industrialio-event.c index 3d78da2531a9..727e2ef66aa4 100644 --- a/drivers/iio/industrialio-event.c +++ b/drivers/iio/industrialio-event.c @@ -556,7 +556,7 @@ int iio_device_register_eventset(struct iio_dev *indio_dev) ret = iio_device_register_sysfs_group(indio_dev, &ev_int->group); if (ret) - goto error_free_setup_event_lines; + goto error_free_group_attrs; ev_int->ioctl_handler.ioctl = iio_event_ioctl; iio_device_ioctl_handler_register(&iio_dev_opaque->indio_dev, @@ -564,6 +564,8 @@ int iio_device_register_eventset(struct iio_dev *indio_dev) return 0; +error_free_group_attrs: + kfree(ev_int->group.attrs); error_free_setup_event_lines: iio_free_chan_devattr_list(&ev_int->dev_attr_list); kfree(ev_int); -- cgit v1.2.3 From 20228a1d5a55e7db0c6720840f2c7d2b48c55f69 Mon Sep 17 00:00:00 2001 From: Nuno Sá Date: Tue, 20 Sep 2022 13:28:07 +0200 Subject: iio: adc: ad_sigma_delta: do not use internal iio_dev lock MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Drop 'mlock' usage by making use of iio_device_claim_direct_mode(). This change actually makes sure we cannot do a single conversion while buffering is enable. Note there was a potential race in the previous code since we were only acquiring the lock after checking if the bus is enabled. Fixes: af3008485ea0 ("iio:adc: Add common code for ADI Sigma Delta devices") Signed-off-by: Nuno Sá Reviewed-by: Miquel Raynal Cc: #No rush as race is very old. Link: https://lore.kernel.org/r/20220920112821.975359-2-nuno.sa@analog.com Signed-off-by: Jonathan Cameron --- drivers/iio/adc/ad_sigma_delta.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers/iio') diff --git a/drivers/iio/adc/ad_sigma_delta.c b/drivers/iio/adc/ad_sigma_delta.c index 261a9a6b45e1..d8570f620785 100644 --- a/drivers/iio/adc/ad_sigma_delta.c +++ b/drivers/iio/adc/ad_sigma_delta.c @@ -281,10 +281,10 @@ int ad_sigma_delta_single_conversion(struct iio_dev *indio_dev, unsigned int data_reg; int ret = 0; - if (iio_buffer_enabled(indio_dev)) - return -EBUSY; + ret = iio_device_claim_direct_mode(indio_dev); + if (ret) + return ret; - mutex_lock(&indio_dev->mlock); ad_sigma_delta_set_channel(sigma_delta, chan->address); spi_bus_lock(sigma_delta->spi->master); @@ -323,7 +323,7 @@ out: ad_sigma_delta_set_mode(sigma_delta, AD_SD_MODE_IDLE); sigma_delta->bus_locked = false; spi_bus_unlock(sigma_delta->spi->master); - mutex_unlock(&indio_dev->mlock); + iio_device_release_direct_mode(indio_dev); if (ret) return ret; -- cgit v1.2.3 From 2a22b40aea42dd516e669257ab5faf10396c2fad Mon Sep 17 00:00:00 2001 From: Yuan Can Date: Wed, 21 Sep 2022 02:39:15 +0000 Subject: iio: accel: bma400: Switch to use dev_err_probe() helper In the probe path, dev_err() can be replace with dev_err_probe() which will check if error code is -EPROBE_DEFER and prints the error name. Signed-off-by: Yuan Can Link: https://lore.kernel.org/r/20220921023915.47300-1-yuancan@huawei.com Signed-off-by: Jonathan Cameron --- drivers/iio/accel/bma400_core.c | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) (limited to 'drivers/iio') diff --git a/drivers/iio/accel/bma400_core.c b/drivers/iio/accel/bma400_core.c index ad8fce3e08cd..e8de88e6cfb9 100644 --- a/drivers/iio/accel/bma400_core.c +++ b/drivers/iio/accel/bma400_core.c @@ -886,14 +886,10 @@ static int bma400_init(struct bma400_data *data) ret = devm_regulator_bulk_get(data->dev, ARRAY_SIZE(data->regulators), data->regulators); - if (ret) { - if (ret != -EPROBE_DEFER) - dev_err(data->dev, - "Failed to get regulators: %d\n", - ret); + if (ret) + return dev_err_probe(data->dev, ret, "Failed to get regulators: %d\n", + ret); - return ret; - } ret = regulator_bulk_enable(ARRAY_SIZE(data->regulators), data->regulators); if (ret) { -- cgit v1.2.3 From 2aebc223fc7ce613140ef2b64ca3c0f1a4f458cb Mon Sep 17 00:00:00 2001 From: Crt Mori Date: Thu, 22 Sep 2022 10:13:22 +0200 Subject: iio: temperature: mlx90632 Add runtime powermanagement modes The sensor can operate in lower power modes and even make measurements when in those lower powered modes. The decision was taken that if measurement is not requested within 2 seconds the sensor will remain in SLEEP_STEP power mode, where measurements are triggered on request with setting the start of measurement bit (SOB). In this mode the measurements are taking a bit longer because we need to start it and complete it. Currently, in continuous mode we read ready data and this mode is activated if sensor measurement is requested within 2 seconds. The suspend timeout is increased to 6 seconds (instead of 3 before), because that enables more measurements in lower power mode (SLEEP_STEP), with the lowest refresh rate (2 seconds). Signed-off-by: Crt Mori Link: https://lore.kernel.org/r/be405068f081f2d518843897b13cd0289c280b5d.1663834141.git.cmo@melexis.com Signed-off-by: Jonathan Cameron --- drivers/iio/temperature/mlx90632.c | 377 ++++++++++++++++++++++++++++++------- 1 file changed, 309 insertions(+), 68 deletions(-) (limited to 'drivers/iio') diff --git a/drivers/iio/temperature/mlx90632.c b/drivers/iio/temperature/mlx90632.c index f6dec0e5f097..71130d237a69 100644 --- a/drivers/iio/temperature/mlx90632.c +++ b/drivers/iio/temperature/mlx90632.c @@ -6,11 +6,14 @@ * * Driver for the Melexis MLX90632 I2C 16-bit IR thermopile sensor */ +#include #include +#include #include #include #include #include +#include #include #include #include @@ -55,6 +58,12 @@ #define MLX90632_EE_Ha 0x2481 /* Ha customer calib value reg 16bit */ #define MLX90632_EE_Hb 0x2482 /* Hb customer calib value reg 16bit */ +#define MLX90632_EE_MEDICAL_MEAS1 0x24E1 /* Medical measurement 1 16bit */ +#define MLX90632_EE_MEDICAL_MEAS2 0x24E2 /* Medical measurement 2 16bit */ +#define MLX90632_EE_EXTENDED_MEAS1 0x24F1 /* Extended measurement 1 16bit */ +#define MLX90632_EE_EXTENDED_MEAS2 0x24F2 /* Extended measurement 2 16bit */ +#define MLX90632_EE_EXTENDED_MEAS3 0x24F3 /* Extended measurement 3 16bit */ + /* Register addresses - volatile */ #define MLX90632_REG_I2C_ADDR 0x3000 /* Chip I2C address register */ @@ -62,13 +71,16 @@ #define MLX90632_REG_CONTROL 0x3001 /* Control Register address */ #define MLX90632_CFG_PWR_MASK GENMASK(2, 1) /* PowerMode Mask */ #define MLX90632_CFG_MTYP_MASK GENMASK(8, 4) /* Meas select Mask */ +#define MLX90632_CFG_SOB_MASK BIT(11) /* PowerModes statuses */ #define MLX90632_PWR_STATUS(ctrl_val) (ctrl_val << 1) #define MLX90632_PWR_STATUS_HALT MLX90632_PWR_STATUS(0) /* hold */ -#define MLX90632_PWR_STATUS_SLEEP_STEP MLX90632_PWR_STATUS(1) /* sleep step*/ +#define MLX90632_PWR_STATUS_SLEEP_STEP MLX90632_PWR_STATUS(1) /* sleep step */ #define MLX90632_PWR_STATUS_STEP MLX90632_PWR_STATUS(2) /* step */ -#define MLX90632_PWR_STATUS_CONTINUOUS MLX90632_PWR_STATUS(3) /* continuous*/ +#define MLX90632_PWR_STATUS_CONTINUOUS MLX90632_PWR_STATUS(3) /* continuous */ + +#define MLX90632_EE_RR GENMASK(10, 8) /* Only Refresh Rate bits */ /* Measurement types */ #define MLX90632_MTYP_MEDICAL 0 @@ -116,8 +128,9 @@ #define MLX90632_REF_12 12LL /* ResCtrlRef value of Ch 1 or Ch 2 */ #define MLX90632_REF_3 12LL /* ResCtrlRef value of Channel 3 */ #define MLX90632_MAX_MEAS_NUM 31 /* Maximum measurements in list */ -#define MLX90632_SLEEP_DELAY_MS 3000 /* Autosleep delay */ +#define MLX90632_SLEEP_DELAY_MS 6000 /* Autosleep delay */ #define MLX90632_EXTENDED_LIMIT 27000 /* Extended mode raw value limit */ +#define MLX90632_MEAS_MAX_TIME 2000 /* Max measurement time in ms for the lowest refresh rate */ /** * struct mlx90632_data - private data for the MLX90632 device @@ -130,6 +143,9 @@ * @object_ambient_temperature: Ambient temperature at object (might differ of * the ambient temperature of sensor. * @regulator: Regulator of the device + * @powerstatus: Current POWER status of the device + * @interaction_ts: Timestamp of the last temperature read that is used + * for power management in jiffies */ struct mlx90632_data { struct i2c_client *client; @@ -139,6 +155,8 @@ struct mlx90632_data { u8 mtyp; u32 object_ambient_temperature; struct regulator *regulator; + int powerstatus; + unsigned long interaction_ts; }; static const struct regmap_range mlx90632_volatile_reg_range[] = { @@ -158,6 +176,8 @@ static const struct regmap_range mlx90632_read_reg_range[] = { regmap_reg_range(MLX90632_EE_VERSION, MLX90632_EE_Ka), regmap_reg_range(MLX90632_EE_CTRL, MLX90632_EE_I2C_ADDR), regmap_reg_range(MLX90632_EE_Ha, MLX90632_EE_Hb), + regmap_reg_range(MLX90632_EE_MEDICAL_MEAS1, MLX90632_EE_MEDICAL_MEAS2), + regmap_reg_range(MLX90632_EE_EXTENDED_MEAS1, MLX90632_EE_EXTENDED_MEAS3), regmap_reg_range(MLX90632_REG_I2C_ADDR, MLX90632_REG_CONTROL), regmap_reg_range(MLX90632_REG_I2C_CMD, MLX90632_REG_I2C_CMD), regmap_reg_range(MLX90632_REG_STATUS, MLX90632_REG_STATUS), @@ -198,16 +218,38 @@ static const struct regmap_config mlx90632_regmap = { static s32 mlx90632_pwr_set_sleep_step(struct regmap *regmap) { - return regmap_update_bits(regmap, MLX90632_REG_CONTROL, - MLX90632_CFG_PWR_MASK, - MLX90632_PWR_STATUS_SLEEP_STEP); + struct mlx90632_data *data = + iio_priv(dev_get_drvdata(regmap_get_device(regmap))); + s32 ret; + + if (data->powerstatus == MLX90632_PWR_STATUS_SLEEP_STEP) + return 0; + + ret = regmap_write_bits(regmap, MLX90632_REG_CONTROL, MLX90632_CFG_PWR_MASK, + MLX90632_PWR_STATUS_SLEEP_STEP); + if (ret < 0) + return ret; + + data->powerstatus = MLX90632_PWR_STATUS_SLEEP_STEP; + return ret; } static s32 mlx90632_pwr_continuous(struct regmap *regmap) { - return regmap_update_bits(regmap, MLX90632_REG_CONTROL, - MLX90632_CFG_PWR_MASK, - MLX90632_PWR_STATUS_CONTINUOUS); + struct mlx90632_data *data = + iio_priv(dev_get_drvdata(regmap_get_device(regmap))); + s32 ret; + + if (data->powerstatus == MLX90632_PWR_STATUS_CONTINUOUS) + return 0; + + ret = regmap_write_bits(regmap, MLX90632_REG_CONTROL, MLX90632_CFG_PWR_MASK, + MLX90632_PWR_STATUS_CONTINUOUS); + if (ret < 0) + return ret; + + data->powerstatus = MLX90632_PWR_STATUS_CONTINUOUS; + return ret; } /** @@ -219,6 +261,63 @@ static void mlx90632_reset_delay(void) usleep_range(150, 200); } +static int mlx90632_get_measurement_time(struct regmap *regmap, u16 meas) +{ + unsigned int reg; + int ret; + + ret = regmap_read(regmap, meas, ®); + if (ret < 0) + return ret; + + return MLX90632_MEAS_MAX_TIME >> FIELD_GET(MLX90632_EE_RR, reg); +} + +static int mlx90632_calculate_dataset_ready_time(struct mlx90632_data *data) +{ + unsigned int refresh_time; + int ret; + + if (data->mtyp == MLX90632_MTYP_MEDICAL) { + ret = mlx90632_get_measurement_time(data->regmap, + MLX90632_EE_MEDICAL_MEAS1); + if (ret < 0) + return ret; + + refresh_time = ret; + + ret = mlx90632_get_measurement_time(data->regmap, + MLX90632_EE_MEDICAL_MEAS2); + if (ret < 0) + return ret; + + refresh_time += ret; + } else { + ret = mlx90632_get_measurement_time(data->regmap, + MLX90632_EE_EXTENDED_MEAS1); + if (ret < 0) + return ret; + + refresh_time = ret; + + ret = mlx90632_get_measurement_time(data->regmap, + MLX90632_EE_EXTENDED_MEAS2); + if (ret < 0) + return ret; + + refresh_time += ret; + + ret = mlx90632_get_measurement_time(data->regmap, + MLX90632_EE_EXTENDED_MEAS3); + if (ret < 0) + return ret; + + refresh_time += ret; + } + + return refresh_time; +} + /** * mlx90632_perform_measurement() - Trigger and retrieve current measurement cycle * @data: pointer to mlx90632_data object containing regmap information @@ -249,26 +348,75 @@ static int mlx90632_perform_measurement(struct mlx90632_data *data) return (reg_status & MLX90632_STAT_CYCLE_POS) >> 2; } -static int mlx90632_set_meas_type(struct regmap *regmap, u8 type) +/** + * mlx90632_perform_measurement_burst() - Trigger and retrieve current measurement + * cycle in step sleep mode + * @data: pointer to mlx90632_data object containing regmap information + * + * Perform a measurement and return 2 as measurement cycle position reported + * by sensor. This is a blocking function for amount dependent on the sensor + * refresh rate. + */ +static int mlx90632_perform_measurement_burst(struct mlx90632_data *data) { + unsigned int reg_status; int ret; - if ((type != MLX90632_MTYP_MEDICAL) && (type != MLX90632_MTYP_EXTENDED)) - return -EINVAL; + ret = regmap_write_bits(data->regmap, MLX90632_REG_CONTROL, + MLX90632_CFG_SOB_MASK, MLX90632_CFG_SOB_MASK); + if (ret < 0) + return ret; + + ret = mlx90632_calculate_dataset_ready_time(data); + if (ret < 0) + return ret; - ret = regmap_write(regmap, MLX90632_REG_I2C_CMD, MLX90632_RESET_CMD); + msleep(ret); /* Wait minimum time for dataset to be ready */ + + ret = regmap_read_poll_timeout(data->regmap, MLX90632_REG_STATUS, + reg_status, + (reg_status & MLX90632_STAT_BUSY) == 0, + 10000, 100 * 10000); + if (ret < 0) { + dev_err(&data->client->dev, "data not ready"); + return -ETIMEDOUT; + } + + return 2; +} + +static int mlx90632_set_meas_type(struct mlx90632_data *data, u8 type) +{ + int current_powerstatus; + int ret; + + if (data->mtyp == type) + return 0; + + current_powerstatus = data->powerstatus; + ret = mlx90632_pwr_continuous(data->regmap); + if (ret < 0) + return ret; + + ret = regmap_write(data->regmap, MLX90632_REG_I2C_CMD, MLX90632_RESET_CMD); if (ret < 0) return ret; mlx90632_reset_delay(); - ret = regmap_write_bits(regmap, MLX90632_REG_CONTROL, + ret = regmap_update_bits(data->regmap, MLX90632_REG_CONTROL, (MLX90632_CFG_MTYP_MASK | MLX90632_CFG_PWR_MASK), (MLX90632_MTYP_STATUS(type) | MLX90632_PWR_STATUS_HALT)); if (ret < 0) return ret; - return mlx90632_pwr_continuous(regmap); + data->mtyp = type; + data->powerstatus = MLX90632_PWR_STATUS_HALT; + + if (current_powerstatus == MLX90632_PWR_STATUS_SLEEP_STEP) + return mlx90632_pwr_set_sleep_step(data->regmap); + + return mlx90632_pwr_continuous(data->regmap); } static int mlx90632_channel_new_select(int perform_ret, uint8_t *channel_new, @@ -355,11 +503,30 @@ static int mlx90632_read_all_channel(struct mlx90632_data *data, s32 ret, measurement; mutex_lock(&data->lock); - measurement = mlx90632_perform_measurement(data); - if (measurement < 0) { - ret = measurement; + ret = mlx90632_set_meas_type(data, MLX90632_MTYP_MEDICAL); + if (ret < 0) + goto read_unlock; + + switch (data->powerstatus) { + case MLX90632_PWR_STATUS_CONTINUOUS: + measurement = mlx90632_perform_measurement(data); + if (measurement < 0) { + ret = measurement; + goto read_unlock; + } + break; + case MLX90632_PWR_STATUS_SLEEP_STEP: + measurement = mlx90632_perform_measurement_burst(data); + if (measurement < 0) { + ret = measurement; + goto read_unlock; + } + break; + default: + ret = -EOPNOTSUPP; goto read_unlock; } + ret = mlx90632_read_ambient_raw(data->regmap, ambient_new_raw, ambient_old_raw); if (ret < 0) @@ -441,14 +608,20 @@ static int mlx90632_read_all_channel_extended(struct mlx90632_data *data, s16 *o s32 ret, meas; mutex_lock(&data->lock); - ret = mlx90632_set_meas_type(data->regmap, MLX90632_MTYP_EXTENDED); + ret = mlx90632_set_meas_type(data, MLX90632_MTYP_EXTENDED); if (ret < 0) goto read_unlock; - ret = read_poll_timeout(mlx90632_perform_measurement, meas, meas == 19, - 50000, 800000, false, data); - if (ret != 0) - goto read_unlock; + if (data->powerstatus == MLX90632_PWR_STATUS_CONTINUOUS) { + ret = read_poll_timeout(mlx90632_perform_measurement, meas, meas == 19, + 50000, 800000, false, data); + if (ret) + goto read_unlock; + } else if (data->powerstatus == MLX90632_PWR_STATUS_SLEEP_STEP) { + ret = mlx90632_perform_measurement_burst(data); + if (ret < 0) + goto read_unlock; + } ret = mlx90632_read_object_raw_extended(data->regmap, object_new_raw); if (ret < 0) @@ -457,8 +630,6 @@ static int mlx90632_read_all_channel_extended(struct mlx90632_data *data, s16 *o ret = mlx90632_read_ambient_raw_extended(data->regmap, ambient_new_raw, ambient_old_raw); read_unlock: - (void) mlx90632_set_meas_type(data->regmap, MLX90632_MTYP_MEDICAL); - mutex_unlock(&data->lock); return ret; } @@ -743,12 +914,47 @@ static int mlx90632_calc_ambient_dsp105(struct mlx90632_data *data, int *val) return ret; } +/** + * mlx90632_pm_interraction_wakeup() - Measure time between user interactions to change powermode + * @data: pointer to mlx90632_data object containing interaction_ts information + * + * Switch to continuous mode when interaction is faster than MLX90632_MEAS_MAX_TIME. Update the + * interaction_ts for each function call with the jiffies to enable measurement between function + * calls. Initial value of the interaction_ts needs to be set before this function call. + */ +static int mlx90632_pm_interraction_wakeup(struct mlx90632_data *data) +{ + unsigned long now; + int ret; + + now = jiffies; + if (time_in_range(now, data->interaction_ts, + data->interaction_ts + + msecs_to_jiffies(MLX90632_MEAS_MAX_TIME + 100))) { + if (data->powerstatus == MLX90632_PWR_STATUS_SLEEP_STEP) { + ret = mlx90632_pwr_continuous(data->regmap); + if (ret < 0) + return ret; + } + } + + data->interaction_ts = now; + + return 0; +} + static int mlx90632_read_raw(struct iio_dev *indio_dev, struct iio_chan_spec const *channel, int *val, int *val2, long mask) { struct mlx90632_data *data = iio_priv(indio_dev); int ret; + int cr; + + pm_runtime_get_sync(&data->client->dev); + ret = mlx90632_pm_interraction_wakeup(data); + if (ret < 0) + goto mlx90632_read_raw_pm; switch (mask) { case IIO_CHAN_INFO_PROCESSED: @@ -756,16 +962,22 @@ static int mlx90632_read_raw(struct iio_dev *indio_dev, case IIO_MOD_TEMP_AMBIENT: ret = mlx90632_calc_ambient_dsp105(data, val); if (ret < 0) - return ret; - return IIO_VAL_INT; + goto mlx90632_read_raw_pm; + + ret = IIO_VAL_INT; + break; case IIO_MOD_TEMP_OBJECT: ret = mlx90632_calc_object_dsp105(data, val); if (ret < 0) - return ret; - return IIO_VAL_INT; + goto mlx90632_read_raw_pm; + + ret = IIO_VAL_INT; + break; default: - return -EINVAL; + ret = -EINVAL; + break; } + break; case IIO_CHAN_INFO_CALIBEMISSIVITY: if (data->emissivity == 1000) { *val = 1; @@ -774,13 +986,21 @@ static int mlx90632_read_raw(struct iio_dev *indio_dev, *val = 0; *val2 = data->emissivity * 1000; } - return IIO_VAL_INT_PLUS_MICRO; + ret = IIO_VAL_INT_PLUS_MICRO; + break; case IIO_CHAN_INFO_CALIBAMBIENT: *val = data->object_ambient_temperature; - return IIO_VAL_INT; + ret = IIO_VAL_INT; + break; default: - return -EINVAL; + ret = -EINVAL; + break; } + +mlx90632_read_raw_pm: + pm_runtime_mark_last_busy(&data->client->dev); + pm_runtime_put_autosuspend(&data->client->dev); + return ret; } static int mlx90632_write_raw(struct iio_dev *indio_dev, @@ -826,11 +1046,18 @@ static const struct iio_info mlx90632_info = { .write_raw = mlx90632_write_raw, }; -static int mlx90632_sleep(struct mlx90632_data *data) +static void mlx90632_sleep(void *_data) +{ + struct mlx90632_data *data = _data; + + mlx90632_pwr_set_sleep_step(data->regmap); +} + +static int mlx90632_suspend(struct mlx90632_data *data) { regcache_mark_dirty(data->regmap); - dev_dbg(&data->client->dev, "Requesting sleep"); + dev_dbg(&data->client->dev, "Requesting suspend"); return mlx90632_pwr_set_sleep_step(data->regmap); } @@ -902,6 +1129,7 @@ static int mlx90632_probe(struct i2c_client *client, mlx90632->client = client; mlx90632->regmap = regmap; mlx90632->mtyp = MLX90632_MTYP_MEDICAL; + mlx90632->powerstatus = MLX90632_PWR_STATUS_HALT; mutex_init(&mlx90632->lock); indio_dev->name = id->name; @@ -933,6 +1161,13 @@ static int mlx90632_probe(struct i2c_client *client, return ret; } + ret = devm_add_action_or_reset(&client->dev, mlx90632_sleep, mlx90632); + if (ret < 0) { + dev_err(&client->dev, "Failed to setup low power cleanup action %d\n", + ret); + return ret; + } + ret = regmap_read(mlx90632->regmap, MLX90632_EE_VERSION, &read); if (ret < 0) { dev_err(&client->dev, "read of version failed: %d\n", ret); @@ -961,32 +1196,17 @@ static int mlx90632_probe(struct i2c_client *client, mlx90632->emissivity = 1000; mlx90632->object_ambient_temperature = 25000; /* 25 degrees milliCelsius */ + mlx90632->interaction_ts = jiffies; /* Set initial value */ - pm_runtime_disable(&client->dev); - ret = pm_runtime_set_active(&client->dev); - if (ret < 0) { - mlx90632_sleep(mlx90632); - return ret; - } - pm_runtime_enable(&client->dev); + pm_runtime_get_noresume(&client->dev); + pm_runtime_set_active(&client->dev); + + devm_pm_runtime_enable(&client->dev); pm_runtime_set_autosuspend_delay(&client->dev, MLX90632_SLEEP_DELAY_MS); pm_runtime_use_autosuspend(&client->dev); + pm_runtime_put_autosuspend(&client->dev); - return iio_device_register(indio_dev); -} - -static void mlx90632_remove(struct i2c_client *client) -{ - struct iio_dev *indio_dev = i2c_get_clientdata(client); - struct mlx90632_data *data = iio_priv(indio_dev); - - iio_device_unregister(indio_dev); - - pm_runtime_disable(&client->dev); - pm_runtime_set_suspended(&client->dev); - pm_runtime_put_noidle(&client->dev); - - mlx90632_sleep(data); + return devm_iio_device_register(&client->dev, indio_dev); } static const struct i2c_device_id mlx90632_id[] = { @@ -1001,33 +1221,54 @@ static const struct of_device_id mlx90632_of_match[] = { }; MODULE_DEVICE_TABLE(of, mlx90632_of_match); -static int __maybe_unused mlx90632_pm_suspend(struct device *dev) +static int mlx90632_pm_suspend(struct device *dev) { - struct iio_dev *indio_dev = i2c_get_clientdata(to_i2c_client(dev)); - struct mlx90632_data *data = iio_priv(indio_dev); + struct mlx90632_data *data = iio_priv(dev_get_drvdata(dev)); + int ret; + + ret = mlx90632_suspend(data); + if (ret < 0) + return ret; - return mlx90632_sleep(data); + ret = regulator_disable(data->regulator); + if (ret < 0) + dev_err(regmap_get_device(data->regmap), + "Failed to disable power regulator: %d\n", ret); + + return ret; } -static int __maybe_unused mlx90632_pm_resume(struct device *dev) +static int mlx90632_pm_resume(struct device *dev) { - struct iio_dev *indio_dev = i2c_get_clientdata(to_i2c_client(dev)); - struct mlx90632_data *data = iio_priv(indio_dev); + struct mlx90632_data *data = iio_priv(dev_get_drvdata(dev)); + int ret; + + ret = mlx90632_enable_regulator(data); + if (ret < 0) + return ret; return mlx90632_wakeup(data); } -static UNIVERSAL_DEV_PM_OPS(mlx90632_pm_ops, mlx90632_pm_suspend, - mlx90632_pm_resume, NULL); +static int mlx90632_pm_runtime_suspend(struct device *dev) +{ + struct mlx90632_data *data = iio_priv(dev_get_drvdata(dev)); + + return mlx90632_pwr_set_sleep_step(data->regmap); +} + +const struct dev_pm_ops mlx90632_pm_ops = { + SYSTEM_SLEEP_PM_OPS(mlx90632_pm_suspend, mlx90632_pm_resume) + RUNTIME_PM_OPS(mlx90632_pm_runtime_suspend, NULL, NULL) +}; static struct i2c_driver mlx90632_driver = { .driver = { .name = "mlx90632", .of_match_table = mlx90632_of_match, - .pm = &mlx90632_pm_ops, + .pm = pm_ptr(&mlx90632_pm_ops), }, .probe = mlx90632_probe, - .remove = mlx90632_remove, .id_table = mlx90632_id, }; module_i2c_driver(mlx90632_driver); -- cgit v1.2.3 From eff07b20700a55e5b39e76960934d6eeb56a12d9 Mon Sep 17 00:00:00 2001 From: Crt Mori Date: Thu, 22 Sep 2022 10:13:23 +0200 Subject: iio: temperature: mlx90632 Read sampling frequency Allow users to read sensor sampling frequency to better plan the application measurement requests. Signed-off-by: Crt Mori Link: https://lore.kernel.org/r/0bd6d6d665b4bd39e4565f6f44cb1bdc03386e23.1663834141.git.cmo@melexis.com Signed-off-by: Jonathan Cameron --- drivers/iio/temperature/mlx90632.c | 59 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 59 insertions(+) (limited to 'drivers/iio') diff --git a/drivers/iio/temperature/mlx90632.c b/drivers/iio/temperature/mlx90632.c index 71130d237a69..081803940261 100644 --- a/drivers/iio/temperature/mlx90632.c +++ b/drivers/iio/temperature/mlx90632.c @@ -81,6 +81,9 @@ #define MLX90632_PWR_STATUS_CONTINUOUS MLX90632_PWR_STATUS(3) /* continuous */ #define MLX90632_EE_RR GENMASK(10, 8) /* Only Refresh Rate bits */ +#define MLX90632_REFRESH_RATE(ee_val) FIELD_GET(MLX90632_EE_RR, ee_val) + /* Extract Refresh Rate from ee register */ +#define MLX90632_REFRESH_RATE_STATUS(refresh_rate) (refresh_rate << 8) /* Measurement types */ #define MLX90632_MTYP_MEDICAL 0 @@ -914,6 +917,32 @@ static int mlx90632_calc_ambient_dsp105(struct mlx90632_data *data, int *val) return ret; } +static int mlx90632_get_refresh_rate(struct mlx90632_data *data, + int *refresh_rate) +{ + unsigned int meas1; + int ret; + + ret = regmap_read(data->regmap, MLX90632_EE_MEDICAL_MEAS1, &meas1); + if (ret < 0) + return ret; + + *refresh_rate = MLX90632_REFRESH_RATE(meas1); + + return ret; +} + +static const int mlx90632_freqs[][2] = { + {0, 500000}, + {1, 0}, + {2, 0}, + {4, 0}, + {8, 0}, + {16, 0}, + {32, 0}, + {64, 0} +}; + /** * mlx90632_pm_interraction_wakeup() - Measure time between user interactions to change powermode * @data: pointer to mlx90632_data object containing interaction_ts information @@ -992,6 +1021,15 @@ static int mlx90632_read_raw(struct iio_dev *indio_dev, *val = data->object_ambient_temperature; ret = IIO_VAL_INT; break; + case IIO_CHAN_INFO_SAMP_FREQ: + ret = mlx90632_get_refresh_rate(data, &cr); + if (ret < 0) + goto mlx90632_read_raw_pm; + + *val = mlx90632_freqs[cr][0]; + *val2 = mlx90632_freqs[cr][1]; + ret = IIO_VAL_INT_PLUS_MICRO; + break; default: ret = -EINVAL; break; @@ -1025,12 +1063,30 @@ static int mlx90632_write_raw(struct iio_dev *indio_dev, } } +static int mlx90632_read_avail(struct iio_dev *indio_dev, + struct iio_chan_spec const *chan, + const int **vals, int *type, int *length, + long mask) +{ + switch (mask) { + case IIO_CHAN_INFO_SAMP_FREQ: + *vals = (int *)mlx90632_freqs; + *type = IIO_VAL_INT_PLUS_MICRO; + *length = 2 * ARRAY_SIZE(mlx90632_freqs); + return IIO_AVAIL_LIST; + default: + return -EINVAL; + } +} + static const struct iio_chan_spec mlx90632_channels[] = { { .type = IIO_TEMP, .modified = 1, .channel2 = IIO_MOD_TEMP_AMBIENT, .info_mask_separate = BIT(IIO_CHAN_INFO_PROCESSED), + .info_mask_shared_by_all = BIT(IIO_CHAN_INFO_SAMP_FREQ), + .info_mask_shared_by_all_available = BIT(IIO_CHAN_INFO_SAMP_FREQ), }, { .type = IIO_TEMP, @@ -1038,12 +1094,15 @@ static const struct iio_chan_spec mlx90632_channels[] = { .channel2 = IIO_MOD_TEMP_OBJECT, .info_mask_separate = BIT(IIO_CHAN_INFO_PROCESSED) | BIT(IIO_CHAN_INFO_CALIBEMISSIVITY) | BIT(IIO_CHAN_INFO_CALIBAMBIENT), + .info_mask_shared_by_all = BIT(IIO_CHAN_INFO_SAMP_FREQ), + .info_mask_shared_by_all_available = BIT(IIO_CHAN_INFO_SAMP_FREQ), }, }; static const struct iio_info mlx90632_info = { .read_raw = mlx90632_read_raw, .write_raw = mlx90632_write_raw, + .read_avail = mlx90632_read_avail, }; static void mlx90632_sleep(void *_data) -- cgit v1.2.3 From 4e6151403631255828a5530d9d6233caedcd2976 Mon Sep 17 00:00:00 2001 From: Crt Mori Date: Thu, 22 Sep 2022 10:13:24 +0200 Subject: iio: temperature: mlx90632 Change return value of sensor measurement channel The current EINVAL value is more applicable to embedded library, where user can actually put the fixed value to the sensor. In case of the driver if the value of the channel is invalid it is better in inform userspace that Channel was out of range as that implies more to internal driver error than invalid input. It also makes for easier debugging of where the error comes from during the development. Signed-off-by: Crt Mori Link: https://lore.kernel.org/r/565d4df2592d751dc0f40908f2569b7c9af8e56e.1663834141.git.cmo@melexis.com Signed-off-by: Jonathan Cameron --- drivers/iio/temperature/mlx90632.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/iio') diff --git a/drivers/iio/temperature/mlx90632.c b/drivers/iio/temperature/mlx90632.c index 081803940261..224db7513baa 100644 --- a/drivers/iio/temperature/mlx90632.c +++ b/drivers/iio/temperature/mlx90632.c @@ -435,7 +435,7 @@ static int mlx90632_channel_new_select(int perform_ret, uint8_t *channel_new, *channel_old = 1; break; default: - return -EINVAL; + return -ECHRNG; } return 0; -- cgit v1.2.3 From 8cf5f0329128efdfe18f12a8697752d39821fbdf Mon Sep 17 00:00:00 2001 From: Marcus Folkesson Date: Thu, 22 Sep 2022 21:46:39 +0200 Subject: iio: adc: mcp3911: add support to set PGA Add support for setting the Programmable Gain Amplifiers by adjust the scale value. Signed-off-by: Marcus Folkesson Reviewed-by: Andy Shevchenko Link: https://lore.kernel.org/r/20220922194639.1118971-1-marcus.folkesson@gmail.com Signed-off-by: Jonathan Cameron --- drivers/iio/adc/mcp3911.c | 104 +++++++++++++++++++++++++++++++++++----------- 1 file changed, 80 insertions(+), 24 deletions(-) (limited to 'drivers/iio') diff --git a/drivers/iio/adc/mcp3911.c b/drivers/iio/adc/mcp3911.c index 76b334f5ac61..974c5bd923a6 100644 --- a/drivers/iio/adc/mcp3911.c +++ b/drivers/iio/adc/mcp3911.c @@ -29,6 +29,8 @@ #define MCP3911_REG_MOD 0x06 #define MCP3911_REG_PHASE 0x07 #define MCP3911_REG_GAIN 0x09 +#define MCP3911_GAIN_MASK(ch) (GENMASK(2, 0) << 3 * ch) +#define MCP3911_GAIN_VAL(ch, val) ((val << 3 * ch) & MCP3911_GAIN_MASK(ch)) #define MCP3911_REG_STATUSCOM 0x0a #define MCP3911_STATUSCOM_DRHIZ BIT(12) @@ -60,8 +62,10 @@ #define MCP3911_REG_MASK GENMASK(4, 1) #define MCP3911_NUM_CHANNELS 2 +#define MCP3911_NUM_SCALES 6 static const int mcp3911_osr_table[] = { 32, 64, 128, 256, 512, 1024, 2048, 4096 }; +static u32 mcp3911_scale_table[MCP3911_NUM_SCALES][2]; struct mcp3911 { struct spi_device *spi; @@ -70,6 +74,7 @@ struct mcp3911 { struct clk *clki; u32 dev_addr; struct iio_trigger *trig; + u32 gain[MCP3911_NUM_CHANNELS]; struct { u32 channels[MCP3911_NUM_CHANNELS]; s64 ts __aligned(8); @@ -146,6 +151,11 @@ static int mcp3911_read_avail(struct iio_dev *indio_dev, *vals = mcp3911_osr_table; *length = ARRAY_SIZE(mcp3911_osr_table); return IIO_AVAIL_LIST; + case IIO_CHAN_INFO_SCALE: + *type = IIO_VAL_INT_PLUS_NANO; + *vals = (int *)mcp3911_scale_table; + *length = ARRAY_SIZE(mcp3911_scale_table) * 2; + return IIO_AVAIL_LIST; default: return -EINVAL; } @@ -190,29 +200,9 @@ static int mcp3911_read_raw(struct iio_dev *indio_dev, break; case IIO_CHAN_INFO_SCALE: - if (adc->vref) { - ret = regulator_get_voltage(adc->vref); - if (ret < 0) { - dev_err(indio_dev->dev.parent, - "failed to get vref voltage: %d\n", - ret); - goto out; - } - - *val = ret / 1000; - } else { - *val = MCP3911_INT_VREF_MV; - } - - /* - * For 24bit Conversion - * Raw = ((Voltage)/(Vref) * 2^23 * Gain * 1.5 - * Voltage = Raw * (Vref)/(2^23 * Gain * 1.5) - */ - - /* val2 = (2^23 * 1.5) */ - *val2 = 12582912; - ret = IIO_VAL_FRACTIONAL; + *val = mcp3911_scale_table[ilog2(adc->gain[channel->channel])][0]; + *val2 = mcp3911_scale_table[ilog2(adc->gain[channel->channel])][1]; + ret = IIO_VAL_INT_PLUS_NANO; break; } @@ -230,6 +220,18 @@ static int mcp3911_write_raw(struct iio_dev *indio_dev, mutex_lock(&adc->lock); switch (mask) { + case IIO_CHAN_INFO_SCALE: + for (int i = 0; i < MCP3911_NUM_SCALES; i++) { + if (val == mcp3911_scale_table[i][0] && + val2 == mcp3911_scale_table[i][1]) { + + adc->gain[channel->channel] = BIT(i); + ret = mcp3911_update(adc, MCP3911_REG_GAIN, + MCP3911_GAIN_MASK(channel->channel), + MCP3911_GAIN_VAL(channel->channel, i), 1); + } + } + break; case IIO_CHAN_INFO_OFFSET: if (val2 != 0) { ret = -EINVAL; @@ -265,6 +267,44 @@ out: return ret; } +static int mcp3911_calc_scale_table(struct mcp3911 *adc) +{ + u32 ref = MCP3911_INT_VREF_MV; + u32 div; + int ret; + u64 tmp; + + if (adc->vref) { + ret = regulator_get_voltage(adc->vref); + if (ret < 0) { + dev_err(&adc->spi->dev, + "failed to get vref voltage: %d\n", + ret); + return ret; + } + + ref = ret / 1000; + } + + /* + * For 24-bit Conversion + * Raw = ((Voltage)/(Vref) * 2^23 * Gain * 1.5 + * Voltage = Raw * (Vref)/(2^23 * Gain * 1.5) + * + * ref = Reference voltage + * div = (2^23 * 1.5 * gain) = 12582912 * gain + */ + for (int i = 0; i < MCP3911_NUM_SCALES; i++) { + div = 12582912 * BIT(i); + tmp = div_s64((s64)ref * 1000000000LL, div); + + mcp3911_scale_table[i][0] = 0; + mcp3911_scale_table[i][1] = tmp; + } + + return 0; +} + #define MCP3911_CHAN(idx) { \ .type = IIO_VOLTAGE, \ .indexed = 1, \ @@ -274,8 +314,10 @@ out: .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | \ BIT(IIO_CHAN_INFO_OFFSET) | \ BIT(IIO_CHAN_INFO_SCALE), \ - .info_mask_shared_by_type_available = \ + .info_mask_shared_by_type_available = \ BIT(IIO_CHAN_INFO_OVERSAMPLING_RATIO), \ + .info_mask_separate_available = \ + BIT(IIO_CHAN_INFO_SCALE), \ .scan_type = { \ .sign = 's', \ .realbits = 24, \ @@ -482,6 +524,20 @@ static int mcp3911_probe(struct spi_device *spi) if (ret) return ret; + ret = mcp3911_calc_scale_table(adc); + if (ret) + return ret; + + /* Set gain to 1 for all channels */ + for (int i = 0; i < MCP3911_NUM_CHANNELS; i++) { + adc->gain[i] = 1; + ret = mcp3911_update(adc, MCP3911_REG_GAIN, + MCP3911_GAIN_MASK(i), + MCP3911_GAIN_VAL(i, 0), 1); + if (ret) + return ret; + } + indio_dev->name = spi_get_device_id(spi)->name; indio_dev->modes = INDIO_DIRECT_MODE; indio_dev->info = &mcp3911_info; -- cgit v1.2.3 From 3f4033a811bcd1a1f077ce5297488a5c4dd30eb1 Mon Sep 17 00:00:00 2001 From: Wei Yongjun Date: Thu, 22 Sep 2022 11:58:48 +0000 Subject: iio: filter: admv8818: close potential out-of-bounds read in __admv8818_read_[h|l]pf_freq() ADMV8818_SW_IN_WR0_MSK and ADMV8818_SW_OUT_WR0_MSK have 3 bits, which means a length of 8, but freq_range_hpf and freq_range_lpf array size is 4, may end up reading 4 elements beyond the end of those arrays. Check value first before access freq_range_hpf and freq_range_lpf to harden against the hardware allowing out of range values. Signed-off-by: Wei Yongjun Reviewed-by: Antoniu Miclaus Link: https://lore.kernel.org/r/20220922115848.1800021-1-weiyongjun@huaweicloud.com Signed-off-by: Jonathan Cameron --- drivers/iio/filter/admv8818.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/iio') diff --git a/drivers/iio/filter/admv8818.c b/drivers/iio/filter/admv8818.c index 68de45fe21b4..fe8d46cb7f1d 100644 --- a/drivers/iio/filter/admv8818.c +++ b/drivers/iio/filter/admv8818.c @@ -265,7 +265,7 @@ static int __admv8818_read_hpf_freq(struct admv8818_state *st, u64 *hpf_freq) return ret; hpf_band = FIELD_GET(ADMV8818_SW_IN_WR0_MSK, data); - if (!hpf_band) { + if (!hpf_band || hpf_band > 4) { *hpf_freq = 0; return ret; } @@ -303,7 +303,7 @@ static int __admv8818_read_lpf_freq(struct admv8818_state *st, u64 *lpf_freq) return ret; lpf_band = FIELD_GET(ADMV8818_SW_OUT_WR0_MSK, data); - if (!lpf_band) { + if (!lpf_band || lpf_band > 4) { *lpf_freq = 0; return ret; } -- cgit v1.2.3 From e21b5b1f26694a4498ca11a15e09ccc0a72abb81 Mon Sep 17 00:00:00 2001 From: Mårten Lindahl Date: Mon, 26 Sep 2022 11:18:59 +0200 Subject: iio: light: vcnl4000: Preserve conf bits when toggle power MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit As the vcnl4040 and vcnl4200 chip uses runtime power management for turning the ambient light and proximity sensors on/off, it overwrites the entire register each time. In ALS_CONF register bit fields ALS_IT, ALS_PERS, ALS_INT_EN are overwritten. In PS_CONF1 register bit fields PS_DUTY, PS_PERS, PS_IT, PS_HD, and PS_INT are overwritten. Add functions for preserving the affected bit fields when changing power state. Signed-off-by: Mårten Lindahl Link: https://lore.kernel.org/r/20220926091900.1724105-2-marten.lindahl@axis.com Signed-off-by: Jonathan Cameron --- drivers/iio/light/vcnl4000.c | 54 +++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 51 insertions(+), 3 deletions(-) (limited to 'drivers/iio') diff --git a/drivers/iio/light/vcnl4000.c b/drivers/iio/light/vcnl4000.c index f6c83ecaad8b..bc8c974cd8b8 100644 --- a/drivers/iio/light/vcnl4000.c +++ b/drivers/iio/light/vcnl4000.c @@ -74,6 +74,9 @@ #define VCNL4000_PROX_EN BIT(1) /* start proximity measurement */ #define VCNL4000_SELF_TIMED_EN BIT(0) /* start self-timed measurement */ +#define VCNL4040_ALS_CONF_ALS_SHUTDOWN BIT(0) +#define VCNL4040_PS_CONF1_PS_SHUTDOWN BIT(0) + /* Bit masks for interrupt registers. */ #define VCNL4010_INT_THR_SEL BIT(0) /* Select threshold interrupt source */ #define VCNL4010_INT_THR_EN BIT(1) /* Threshold interrupt type */ @@ -188,16 +191,61 @@ static int vcnl4000_init(struct vcnl4000_data *data) return data->chip_spec->set_power_state(data, true); }; +static ssize_t vcnl4000_write_als_enable(struct vcnl4000_data *data, bool en) +{ + int ret; + + mutex_lock(&data->vcnl4000_lock); + + ret = i2c_smbus_read_word_data(data->client, VCNL4200_AL_CONF); + if (ret < 0) + goto out; + + if (en) + ret &= ~VCNL4040_ALS_CONF_ALS_SHUTDOWN; + else + ret |= VCNL4040_ALS_CONF_ALS_SHUTDOWN; + + ret = i2c_smbus_write_word_data(data->client, VCNL4200_AL_CONF, ret); + +out: + mutex_unlock(&data->vcnl4000_lock); + + return ret; +} + +static ssize_t vcnl4000_write_ps_enable(struct vcnl4000_data *data, bool en) +{ + int ret; + + mutex_lock(&data->vcnl4000_lock); + + ret = i2c_smbus_read_word_data(data->client, VCNL4200_PS_CONF1); + if (ret < 0) + goto out; + + if (en) + ret &= ~VCNL4040_PS_CONF1_PS_SHUTDOWN; + else + ret |= VCNL4040_PS_CONF1_PS_SHUTDOWN; + + ret = i2c_smbus_write_word_data(data->client, VCNL4200_PS_CONF1, ret); + +out: + mutex_unlock(&data->vcnl4000_lock); + + return ret; +} + static int vcnl4200_set_power_state(struct vcnl4000_data *data, bool on) { - u16 val = on ? 0 /* power on */ : 1 /* shut down */; int ret; - ret = i2c_smbus_write_word_data(data->client, VCNL4200_AL_CONF, val); + ret = vcnl4000_write_als_enable(data, on); if (ret < 0) return ret; - ret = i2c_smbus_write_word_data(data->client, VCNL4200_PS_CONF1, val); + ret = vcnl4000_write_ps_enable(data, on); if (ret < 0) return ret; -- cgit v1.2.3 From 85e2c6a23f851f65b2b14c1d87685168be620f87 Mon Sep 17 00:00:00 2001 From: Mårten Lindahl Date: Mon, 26 Sep 2022 11:19:00 +0200 Subject: iio: light: vcnl4000: Add ps_it attributes for vcnl4040 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add read/write attribute for proximity integration time, and read attribute for available proximity integration times for the vcnl4040 chip. Signed-off-by: Mårten Lindahl Link: https://lore.kernel.org/r/20220926091900.1724105-3-marten.lindahl@axis.com Signed-off-by: Jonathan Cameron --- drivers/iio/light/vcnl4000.c | 131 ++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 128 insertions(+), 3 deletions(-) (limited to 'drivers/iio') diff --git a/drivers/iio/light/vcnl4000.c b/drivers/iio/light/vcnl4000.c index bc8c974cd8b8..fdb3922ae4ac 100644 --- a/drivers/iio/light/vcnl4000.c +++ b/drivers/iio/light/vcnl4000.c @@ -17,6 +17,7 @@ * interrupts (VCNL4040, VCNL4200) */ +#include #include #include #include @@ -76,6 +77,7 @@ #define VCNL4040_ALS_CONF_ALS_SHUTDOWN BIT(0) #define VCNL4040_PS_CONF1_PS_SHUTDOWN BIT(0) +#define VCNL4040_PS_CONF2_PS_IT GENMASK(3, 1) /* Proximity integration time */ /* Bit masks for interrupt registers. */ #define VCNL4010_INT_THR_SEL BIT(0) /* Select threshold interrupt source */ @@ -104,6 +106,17 @@ static const int vcnl4010_prox_sampling_frequency[][2] = { {250, 0}, }; +static const int vcnl4040_ps_it_times[][2] = { + {0, 100}, + {0, 150}, + {0, 200}, + {0, 250}, + {0, 300}, + {0, 350}, + {0, 400}, + {0, 800}, +}; + #define VCNL4000_SLEEP_DELAY_MS 2000 /* before we enter pm_runtime_suspend */ enum vcnl4000_device_ids { @@ -470,6 +483,57 @@ static int vcnl4000_set_pm_runtime_state(struct vcnl4000_data *data, bool on) return ret; } +static int vcnl4040_read_ps_it(struct vcnl4000_data *data, int *val, int *val2) +{ + int ret; + + ret = i2c_smbus_read_word_data(data->client, VCNL4200_PS_CONF1); + if (ret < 0) + return ret; + + ret = FIELD_GET(VCNL4040_PS_CONF2_PS_IT, ret); + + if (ret >= ARRAY_SIZE(vcnl4040_ps_it_times)) + return -EINVAL; + + *val = vcnl4040_ps_it_times[ret][0]; + *val2 = vcnl4040_ps_it_times[ret][1]; + + return 0; +} + +static ssize_t vcnl4040_write_ps_it(struct vcnl4000_data *data, int val) +{ + unsigned int i; + int ret, index = -1; + u16 regval; + + for (i = 0; i < ARRAY_SIZE(vcnl4040_ps_it_times); i++) { + if (val == vcnl4040_ps_it_times[i][1]) { + index = i; + break; + } + } + + if (index < 0) + return -EINVAL; + + mutex_lock(&data->vcnl4000_lock); + + ret = i2c_smbus_read_word_data(data->client, VCNL4200_PS_CONF1); + if (ret < 0) + goto out; + + regval = (ret & ~VCNL4040_PS_CONF2_PS_IT) | + FIELD_PREP(VCNL4040_PS_CONF2_PS_IT, index); + ret = i2c_smbus_write_word_data(data->client, VCNL4200_PS_CONF1, + regval); + +out: + mutex_unlock(&data->vcnl4000_lock); + return ret; +} + static int vcnl4000_read_raw(struct iio_dev *indio_dev, struct iio_chan_spec const *chan, int *val, int *val2, long mask) @@ -506,6 +570,47 @@ static int vcnl4000_read_raw(struct iio_dev *indio_dev, *val = 0; *val2 = data->al_scale; return IIO_VAL_INT_PLUS_MICRO; + case IIO_CHAN_INFO_INT_TIME: + if (chan->type != IIO_PROXIMITY) + return -EINVAL; + ret = vcnl4040_read_ps_it(data, val, val2); + if (ret < 0) + return ret; + return IIO_VAL_INT_PLUS_MICRO; + default: + return -EINVAL; + } +} + +static int vcnl4040_write_raw(struct iio_dev *indio_dev, + struct iio_chan_spec const *chan, + int val, int val2, long mask) +{ + struct vcnl4000_data *data = iio_priv(indio_dev); + + switch (mask) { + case IIO_CHAN_INFO_INT_TIME: + if (val != 0) + return -EINVAL; + if (chan->type != IIO_PROXIMITY) + return -EINVAL; + return vcnl4040_write_ps_it(data, val2); + default: + return -EINVAL; + } +} + +static int vcnl4040_read_avail(struct iio_dev *indio_dev, + struct iio_chan_spec const *chan, + const int **vals, int *type, int *length, + long mask) +{ + switch (mask) { + case IIO_CHAN_INFO_INT_TIME: + *vals = (int *)vcnl4040_ps_it_times; + *type = IIO_VAL_INT_PLUS_MICRO; + *length = 2 * ARRAY_SIZE(vcnl4040_ps_it_times); + return IIO_AVAIL_LIST; default: return -EINVAL; } @@ -844,6 +949,20 @@ static const struct iio_chan_spec vcnl4010_channels[] = { IIO_CHAN_SOFT_TIMESTAMP(1), }; +static const struct iio_chan_spec vcnl4040_channels[] = { + { + .type = IIO_LIGHT, + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | + BIT(IIO_CHAN_INFO_SCALE), + }, { + .type = IIO_PROXIMITY, + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | + BIT(IIO_CHAN_INFO_INT_TIME), + .info_mask_separate_available = BIT(IIO_CHAN_INFO_INT_TIME), + .ext_info = vcnl4000_ext_info, + } +}; + static const struct iio_info vcnl4000_info = { .read_raw = vcnl4000_read_raw, }; @@ -858,6 +977,12 @@ static const struct iio_info vcnl4010_info = { .write_event_config = vcnl4010_write_event_config, }; +static const struct iio_info vcnl4040_info = { + .read_raw = vcnl4000_read_raw, + .write_raw = vcnl4040_write_raw, + .read_avail = vcnl4040_read_avail, +}; + static const struct vcnl4000_chip_spec vcnl4000_chip_spec_cfg[] = { [VCNL4000] = { .prod = "VCNL4000", @@ -887,9 +1012,9 @@ static const struct vcnl4000_chip_spec vcnl4000_chip_spec_cfg[] = { .measure_light = vcnl4200_measure_light, .measure_proximity = vcnl4200_measure_proximity, .set_power_state = vcnl4200_set_power_state, - .channels = vcnl4000_channels, - .num_channels = ARRAY_SIZE(vcnl4000_channels), - .info = &vcnl4000_info, + .channels = vcnl4040_channels, + .num_channels = ARRAY_SIZE(vcnl4040_channels), + .info = &vcnl4040_info, .irq_support = false, }, [VCNL4200] = { -- cgit v1.2.3 From 55e00b871ce2fc5689af7991638e5889dcd2ea7a Mon Sep 17 00:00:00 2001 From: Yang Yingliang Date: Tue, 27 Sep 2022 14:48:41 +0800 Subject: iio: multiplexer: Switch to use dev_err_probe() helper In the probe path, dev_err() can be replaced with dev_err_probe() which will check if error code is -EPROBE_DEFER and prints the error name. It also sets the defer probe reason which can be checked later through debugfs. It's more simple in error path. Signed-off-by: Yang Yingliang Link: https://lore.kernel.org/r/20220927064841.319291-1-yangyingliang@huawei.com Signed-off-by: Jonathan Cameron --- drivers/iio/multiplexer/iio-mux.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) (limited to 'drivers/iio') diff --git a/drivers/iio/multiplexer/iio-mux.c b/drivers/iio/multiplexer/iio-mux.c index 93558fddfa9b..edd8c69f6d2e 100644 --- a/drivers/iio/multiplexer/iio-mux.c +++ b/drivers/iio/multiplexer/iio-mux.c @@ -416,11 +416,9 @@ static int mux_probe(struct platform_device *pdev) } mux->control = devm_mux_control_get(dev, NULL); - if (IS_ERR(mux->control)) { - if (PTR_ERR(mux->control) != -EPROBE_DEFER) - dev_err(dev, "failed to get control-mux\n"); - return PTR_ERR(mux->control); - } + if (IS_ERR(mux->control)) + return dev_err_probe(dev, PTR_ERR(mux->control), + "failed to get control-mux\n"); i = 0; for (state = 0; state < all_children; state++) { -- cgit v1.2.3 From 4eb61e1a3338d0f8c9f7a28b72f3289cc92133c6 Mon Sep 17 00:00:00 2001 From: Wei Yongjun Date: Wed, 21 Sep 2022 16:36:16 +0000 Subject: iio: adc: ti-ads131e08: Silence no spi_device_id warnings SPI devices use the spi_device_id for module autoloading even on systems using device tree, after commit 5fa6863ba692 ("spi: Check we have a spi_device_id for each DT compatible"), kernel warns as follows since the spi_device_id is missing: SPI driver ads131e08 has no spi_device_id for ti,ads131e04 SPI driver ads131e08 has no spi_device_id for ti,ads131e06 Add spi_device_id entries to silence the warnings, and ensure driver module autoloading works. Signed-off-by: Wei Yongjun Link: https://lore.kernel.org/r/20220921163620.805879-2-weiyongjun@huaweicloud.com Signed-off-by: Jonathan Cameron --- drivers/iio/adc/ti-ads131e08.c | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'drivers/iio') diff --git a/drivers/iio/adc/ti-ads131e08.c b/drivers/iio/adc/ti-ads131e08.c index 5235a93f28bc..fcfc46254313 100644 --- a/drivers/iio/adc/ti-ads131e08.c +++ b/drivers/iio/adc/ti-ads131e08.c @@ -807,6 +807,8 @@ static int ads131e08_probe(struct spi_device *spi) int ret; info = device_get_match_data(&spi->dev); + if (!info) + info = (void *)spi_get_device_id(spi)->driver_data; if (!info) { dev_err(&spi->dev, "failed to get match data\n"); return -ENODEV; @@ -926,12 +928,21 @@ static const struct of_device_id ads131e08_of_match[] = { }; MODULE_DEVICE_TABLE(of, ads131e08_of_match); +static const struct spi_device_id ads131e08_ids[] = { + { "ads131e04", (kernel_ulong_t)&ads131e08_info_tbl[ads131e04] }, + { "ads131e06", (kernel_ulong_t)&ads131e08_info_tbl[ads131e06] }, + { "ads131e08", (kernel_ulong_t)&ads131e08_info_tbl[ads131e08] }, + {} +}; +MODULE_DEVICE_TABLE(spi, ads131e08_ids); + static struct spi_driver ads131e08_driver = { .driver = { .name = "ads131e08", .of_match_table = ads131e08_of_match, }, .probe = ads131e08_probe, + .id_table = ads131e08_ids, }; module_spi_driver(ads131e08_driver); -- cgit v1.2.3 From 35dab731c4d2b1e71827a56826ef60f53e97fc32 Mon Sep 17 00:00:00 2001 From: Wei Yongjun Date: Wed, 21 Sep 2022 16:36:17 +0000 Subject: iio: accel: sca3300: Silence no spi_device_id warning SPI devices use the spi_device_id for module autoloading even on systems using device tree, after commit 5fa6863ba692 ("spi: Check we have a spi_device_id for each DT compatible"), kernel warns as follows since the spi_device_id is missing: SPI driver sca3300 has no spi_device_id for murata,scl3300 Add spi_device_id entries to silence the warning, and ensure driver module autoloading works. Signed-off-by: Wei Yongjun Reviewed-by: Tomas Melin Link: https://lore.kernel.org/r/20220921163620.805879-3-weiyongjun@huaweicloud.com Signed-off-by: Jonathan Cameron --- drivers/iio/accel/sca3300.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) (limited to 'drivers/iio') diff --git a/drivers/iio/accel/sca3300.c b/drivers/iio/accel/sca3300.c index eaa0c9cfda44..306482b70fad 100644 --- a/drivers/iio/accel/sca3300.c +++ b/drivers/iio/accel/sca3300.c @@ -679,12 +679,20 @@ static const struct of_device_id sca3300_dt_ids[] = { }; MODULE_DEVICE_TABLE(of, sca3300_dt_ids); +static const struct spi_device_id sca3300_ids[] = { + { "sca3300" }, + { "scl3300" }, + {} +}; +MODULE_DEVICE_TABLE(spi, sca3300_ids); + static struct spi_driver sca3300_driver = { - .driver = { + .driver = { .name = SCA3300_ALIAS, .of_match_table = sca3300_dt_ids, }, - .probe = sca3300_probe, + .probe = sca3300_probe, + .id_table = sca3300_ids, }; module_spi_driver(sca3300_driver); -- cgit v1.2.3 From 283026528e0ee8ea89a60f9addaf0f2eda167c42 Mon Sep 17 00:00:00 2001 From: Wei Yongjun Date: Wed, 21 Sep 2022 16:36:18 +0000 Subject: iio: adc: ad9467: Silence no spi_device_id warnings SPI devices use the spi_device_id for module autoloading even on systems using device tree, after commit 5fa6863ba692 ("spi: Check we have a spi_device_id for each DT compatible"), kernel warns as follows since the spi_device_id is missing: SPI driver ad9467 has no spi_device_id for adi,ad9265 SPI driver ad9467 has no spi_device_id for adi,ad9434 Add spi_device_id entries to silence the warnings, and ensure driver module autoloading works. Signed-off-by: Wei Yongjun Link: https://lore.kernel.org/r/20220921163620.805879-4-weiyongjun@huaweicloud.com Signed-off-by: Jonathan Cameron --- drivers/iio/adc/ad9467.c | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'drivers/iio') diff --git a/drivers/iio/adc/ad9467.c b/drivers/iio/adc/ad9467.c index 7534572f7475..0621cf59d614 100644 --- a/drivers/iio/adc/ad9467.c +++ b/drivers/iio/adc/ad9467.c @@ -387,6 +387,8 @@ static int ad9467_probe(struct spi_device *spi) int ret; info = of_device_get_match_data(&spi->dev); + if (!info) + info = (void *)spi_get_device_id(spi)->driver_data; if (!info) return -ENODEV; @@ -447,12 +449,21 @@ static const struct of_device_id ad9467_of_match[] = { }; MODULE_DEVICE_TABLE(of, ad9467_of_match); +static const struct spi_device_id ad9467_ids[] = { + { "ad9265", (kernel_ulong_t)&ad9467_chip_tbl[ID_AD9265] }, + { "ad9434", (kernel_ulong_t)&ad9467_chip_tbl[ID_AD9434] }, + { "ad9467", (kernel_ulong_t)&ad9467_chip_tbl[ID_AD9467] }, + {} +}; +MODULE_DEVICE_TABLE(spi, ad9467_ids); + static struct spi_driver ad9467_driver = { .driver = { .name = "ad9467", .of_match_table = ad9467_of_match, }, .probe = ad9467_probe, + .id_table = ad9467_ids, }; module_spi_driver(ad9467_driver); -- cgit v1.2.3 From 935779eac00aaae02fa61e12c81775e165b11164 Mon Sep 17 00:00:00 2001 From: Wei Yongjun Date: Wed, 21 Sep 2022 16:36:19 +0000 Subject: iio: adc: ad7192: Silence no spi_device_id warnings SPI devices use the spi_device_id for module autoloading even on systems using device tree, after commit 5fa6863ba692 ("spi: Check we have a spi_device_id for each DT compatible"), kernel warns as follows since the spi_device_id is missing: SPI driver ad7192 has no spi_device_id for adi,ad7190 SPI driver ad7192 has no spi_device_id for adi,ad7193 SPI driver ad7192 has no spi_device_id for adi,ad7195 Add spi_device_id entries to silence the warnings, and ensure driver module autoloading works. Signed-off-by: Wei Yongjun Link: https://lore.kernel.org/r/20220921163620.805879-5-weiyongjun@huaweicloud.com Signed-off-by: Jonathan Cameron --- drivers/iio/adc/ad7192.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) (limited to 'drivers/iio') diff --git a/drivers/iio/adc/ad7192.c b/drivers/iio/adc/ad7192.c index d71977be7d22..f5067173deb6 100644 --- a/drivers/iio/adc/ad7192.c +++ b/drivers/iio/adc/ad7192.c @@ -1037,6 +1037,8 @@ static int ad7192_probe(struct spi_device *spi) st->int_vref_mv = ret / 1000; st->chip_info = of_device_get_match_data(&spi->dev); + if (!st->chip_info) + st->chip_info = (void *)spi_get_device_id(spi)->driver_data; indio_dev->name = st->chip_info->name; indio_dev->modes = INDIO_DIRECT_MODE; @@ -1098,12 +1100,22 @@ static const struct of_device_id ad7192_of_match[] = { }; MODULE_DEVICE_TABLE(of, ad7192_of_match); +static const struct spi_device_id ad7192_ids[] = { + { "ad7190", (kernel_ulong_t)&ad7192_chip_info_tbl[ID_AD7190] }, + { "ad7192", (kernel_ulong_t)&ad7192_chip_info_tbl[ID_AD7192] }, + { "ad7193", (kernel_ulong_t)&ad7192_chip_info_tbl[ID_AD7193] }, + { "ad7195", (kernel_ulong_t)&ad7192_chip_info_tbl[ID_AD7195] }, + {} +}; +MODULE_DEVICE_TABLE(spi, ad7192_ids); + static struct spi_driver ad7192_driver = { .driver = { .name = "ad7192", .of_match_table = ad7192_of_match, }, .probe = ad7192_probe, + .id_table = ad7192_ids, }; module_spi_driver(ad7192_driver); -- cgit v1.2.3 From 3a258747a01f1f21fd4c10a07499bde684f8ca2a Mon Sep 17 00:00:00 2001 From: Wei Yongjun Date: Wed, 21 Sep 2022 16:36:20 +0000 Subject: iio: adc: ad7124: Silence no spi_device_id warnings SPI devices use the spi_device_id for module autoloading even on systems using device tree, after commit 5fa6863ba692 ("spi: Check we have a spi_device_id for each DT compatible"), kernel warns as follows since the spi_device_id is missing: SPI driver ad7124 has no spi_device_id for adi,ad7124-4 SPI driver ad7124 has no spi_device_id for adi,ad7124-8 Add spi_device_id entries to silence the warnings, and ensure driver module autoloading works. Signed-off-by: Wei Yongjun Link: https://lore.kernel.org/r/20220921163620.805879-6-weiyongjun@huaweicloud.com Signed-off-by: Jonathan Cameron --- drivers/iio/adc/ad7124.c | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'drivers/iio') diff --git a/drivers/iio/adc/ad7124.c b/drivers/iio/adc/ad7124.c index 4088786e1026..050a2fbf5c49 100644 --- a/drivers/iio/adc/ad7124.c +++ b/drivers/iio/adc/ad7124.c @@ -944,6 +944,8 @@ static int ad7124_probe(struct spi_device *spi) int i, ret; info = of_device_get_match_data(&spi->dev); + if (!info) + info = (void *)spi_get_device_id(spi)->driver_data; if (!info) return -ENODEV; @@ -1021,12 +1023,20 @@ static const struct of_device_id ad7124_of_match[] = { }; MODULE_DEVICE_TABLE(of, ad7124_of_match); +static const struct spi_device_id ad71124_ids[] = { + { "ad7124-4", (kernel_ulong_t)&ad7124_chip_info_tbl[ID_AD7124_4] }, + { "ad7124-8", (kernel_ulong_t)&ad7124_chip_info_tbl[ID_AD7124_8] }, + {} +}; +MODULE_DEVICE_TABLE(spi, ad71124_ids); + static struct spi_driver ad71124_driver = { .driver = { .name = "ad7124", .of_match_table = ad7124_of_match, }, .probe = ad7124_probe, + .id_table = ad71124_ids, }; module_spi_driver(ad71124_driver); -- cgit v1.2.3 From 8f347c565df4e8dd2c862a48a3056bfe59d315e9 Mon Sep 17 00:00:00 2001 From: Nuno Sá Date: Tue, 4 Oct 2022 15:48:54 +0200 Subject: iio: adc: ad799x: do not use internal iio_dev lock MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 'mlock' was being grabbed when setting the device frequency. In order to not introduce any functional change a new lock is added. With that in mind, the lock also needs to be grabbed in the places where 'mlock' is since it was also being used to protect st->config against the current device state. On the other places the lock was being used, we can just drop it since we are only doing one i2c bus read/write which is already safe. While at it, properly include "mutex.h" for mutex related APIs. Signed-off-by: Nuno Sá Link: https://lore.kernel.org/r/20221004134909.1692021-2-nuno.sa@analog.com Signed-off-by: Jonathan Cameron --- drivers/iio/adc/ad799x.c | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) (limited to 'drivers/iio') diff --git a/drivers/iio/adc/ad799x.c b/drivers/iio/adc/ad799x.c index 6dbe9d5e08a2..4730d8d0f4c3 100644 --- a/drivers/iio/adc/ad799x.c +++ b/drivers/iio/adc/ad799x.c @@ -28,6 +28,7 @@ #include #include #include +#include #include #include @@ -125,6 +126,8 @@ struct ad799x_state { const struct ad799x_chip_config *chip_config; struct regulator *reg; struct regulator *vref; + /* lock to protect against multiple access to the device */ + struct mutex lock; unsigned id; u16 config; @@ -290,7 +293,9 @@ static int ad799x_read_raw(struct iio_dev *indio_dev, ret = iio_device_claim_direct_mode(indio_dev); if (ret) return ret; + mutex_lock(&st->lock); ret = ad799x_scan_direct(st, chan->scan_index); + mutex_unlock(&st->lock); iio_device_release_direct_mode(indio_dev); if (ret < 0) @@ -351,7 +356,8 @@ static ssize_t ad799x_write_frequency(struct device *dev, if (ret) return ret; - mutex_lock(&indio_dev->mlock); + mutex_lock(&st->lock); + ret = i2c_smbus_read_byte_data(st->client, AD7998_CYCLE_TMR_REG); if (ret < 0) goto error_ret_mutex; @@ -373,7 +379,7 @@ static ssize_t ad799x_write_frequency(struct device *dev, ret = len; error_ret_mutex: - mutex_unlock(&indio_dev->mlock); + mutex_unlock(&st->lock); return ret; } @@ -407,6 +413,8 @@ static int ad799x_write_event_config(struct iio_dev *indio_dev, if (ret) return ret; + mutex_lock(&st->lock); + if (state) st->config |= BIT(chan->scan_index) << AD799X_CHANNEL_SHIFT; else @@ -418,6 +426,7 @@ static int ad799x_write_event_config(struct iio_dev *indio_dev, st->config &= ~AD7998_ALERT_EN; ret = ad799x_write_config(st, st->config); + mutex_unlock(&st->lock); iio_device_release_direct_mode(indio_dev); return ret; } @@ -454,11 +463,9 @@ static int ad799x_write_event_value(struct iio_dev *indio_dev, if (val < 0 || val > GENMASK(chan->scan_type.realbits - 1, 0)) return -EINVAL; - mutex_lock(&indio_dev->mlock); ret = i2c_smbus_write_word_swapped(st->client, ad799x_threshold_reg(chan, dir, info), val << chan->scan_type.shift); - mutex_unlock(&indio_dev->mlock); return ret; } @@ -473,10 +480,8 @@ static int ad799x_read_event_value(struct iio_dev *indio_dev, int ret; struct ad799x_state *st = iio_priv(indio_dev); - mutex_lock(&indio_dev->mlock); ret = i2c_smbus_read_word_swapped(st->client, ad799x_threshold_reg(chan, dir, info)); - mutex_unlock(&indio_dev->mlock); if (ret < 0) return ret; *val = (ret >> chan->scan_type.shift) & @@ -863,6 +868,9 @@ static int ad799x_probe(struct i2c_client *client, if (ret) goto error_cleanup_ring; } + + mutex_init(&st->lock); + ret = iio_device_register(indio_dev); if (ret) goto error_cleanup_ring; -- cgit v1.2.3 From ed3aa67167bed8825993e6483c6dbeae607c1ff9 Mon Sep 17 00:00:00 2001 From: Nuno Sá Date: Tue, 4 Oct 2022 15:48:55 +0200 Subject: iio: adc: axp288_adc: do not use internal iio_dev lock MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The iio_device lock is only meant for internal use. Hence define a device local lock to protect against concurrent accesses. While at it, properly include "mutex.h" for mutex related APIs. Signed-off-by: Nuno Sá Link: https://lore.kernel.org/r/20221004134909.1692021-3-nuno.sa@analog.com Signed-off-by: Jonathan Cameron --- drivers/iio/adc/axp288_adc.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) (limited to 'drivers/iio') diff --git a/drivers/iio/adc/axp288_adc.c b/drivers/iio/adc/axp288_adc.c index 580361bd9849..49fff1cabd0d 100644 --- a/drivers/iio/adc/axp288_adc.c +++ b/drivers/iio/adc/axp288_adc.c @@ -9,6 +9,7 @@ #include #include +#include #include #include #include @@ -50,6 +51,8 @@ enum axp288_adc_id { struct axp288_adc_info { int irq; struct regmap *regmap; + /* lock to protect against multiple access to the device */ + struct mutex lock; bool ts_enabled; }; @@ -161,7 +164,7 @@ static int axp288_adc_read_raw(struct iio_dev *indio_dev, int ret; struct axp288_adc_info *info = iio_priv(indio_dev); - mutex_lock(&indio_dev->mlock); + mutex_lock(&info->lock); switch (mask) { case IIO_CHAN_INFO_RAW: if (axp288_adc_set_ts(info, AXP288_ADC_TS_CURRENT_ON_ONDEMAND, @@ -178,7 +181,7 @@ static int axp288_adc_read_raw(struct iio_dev *indio_dev, default: ret = -EINVAL; } - mutex_unlock(&indio_dev->mlock); + mutex_unlock(&info->lock); return ret; } @@ -289,6 +292,8 @@ static int axp288_adc_probe(struct platform_device *pdev) if (ret < 0) return ret; + mutex_init(&info->lock); + return devm_iio_device_register(&pdev->dev, indio_dev); } -- cgit v1.2.3 From 7dde7ec2a84d598eb755883540d48a5ee73948ec Mon Sep 17 00:00:00 2001 From: Nuno Sá Date: Tue, 4 Oct 2022 15:48:56 +0200 Subject: iio: adc: imx7d_adc: do not use internal iio_dev lock MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The iio_device lock is only meant for internal use. Hence define a device local lock to protect against concurrent accesses. While at it, properly include "mutex.h" for mutex related APIs. Signed-off-by: Nuno Sá Reviewed-by: Haibo Chen Link: https://lore.kernel.org/r/20221004134909.1692021-4-nuno.sa@analog.com Signed-off-by: Jonathan Cameron --- drivers/iio/adc/imx7d_adc.c | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) (limited to 'drivers/iio') diff --git a/drivers/iio/adc/imx7d_adc.c b/drivers/iio/adc/imx7d_adc.c index 86caff1d006b..22da81bac97f 100644 --- a/drivers/iio/adc/imx7d_adc.c +++ b/drivers/iio/adc/imx7d_adc.c @@ -13,6 +13,7 @@ #include #include #include +#include #include #include @@ -108,7 +109,8 @@ struct imx7d_adc { struct device *dev; void __iomem *regs; struct clk *clk; - + /* lock to protect against multiple access to the device */ + struct mutex lock; u32 vref_uv; u32 value; u32 channel; @@ -293,7 +295,7 @@ static int imx7d_adc_read_raw(struct iio_dev *indio_dev, switch (mask) { case IIO_CHAN_INFO_RAW: - mutex_lock(&indio_dev->mlock); + mutex_lock(&info->lock); reinit_completion(&info->completion); channel = chan->channel & 0x03; @@ -303,16 +305,16 @@ static int imx7d_adc_read_raw(struct iio_dev *indio_dev, ret = wait_for_completion_interruptible_timeout (&info->completion, IMX7D_ADC_TIMEOUT); if (ret == 0) { - mutex_unlock(&indio_dev->mlock); + mutex_unlock(&info->lock); return -ETIMEDOUT; } if (ret < 0) { - mutex_unlock(&indio_dev->mlock); + mutex_unlock(&info->lock); return ret; } *val = info->value; - mutex_unlock(&indio_dev->mlock); + mutex_unlock(&info->lock); return IIO_VAL_INT; case IIO_CHAN_INFO_SCALE: @@ -531,6 +533,8 @@ static int imx7d_adc_probe(struct platform_device *pdev) if (ret) return ret; + mutex_init(&info->lock); + ret = devm_iio_device_register(dev, indio_dev); if (ret) { dev_err(&pdev->dev, "Couldn't register the device.\n"); -- cgit v1.2.3 From 98c4fb93d1d448db191eea795a40072dc61da07d Mon Sep 17 00:00:00 2001 From: Nuno Sá Date: Tue, 4 Oct 2022 15:48:57 +0200 Subject: iio: adc: lpc32xx_adc: do not use internal iio_dev lock MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The iio_device lock is only meant for internal use. Hence define a device local lock to protect against concurrent accesses. While at it, properly include "mutex.h" for mutex related APIs. Signed-off-by: Nuno Sá Link: https://lore.kernel.org/r/20221004134909.1692021-5-nuno.sa@analog.com Signed-off-by: Jonathan Cameron --- drivers/iio/adc/lpc32xx_adc.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) (limited to 'drivers/iio') diff --git a/drivers/iio/adc/lpc32xx_adc.c b/drivers/iio/adc/lpc32xx_adc.c index b56ce15255cf..732c924a976d 100644 --- a/drivers/iio/adc/lpc32xx_adc.c +++ b/drivers/iio/adc/lpc32xx_adc.c @@ -15,6 +15,7 @@ #include #include #include +#include #include #include @@ -49,6 +50,8 @@ struct lpc32xx_adc_state { struct clk *clk; struct completion completion; struct regulator *vref; + /* lock to protect against multiple access to the device */ + struct mutex lock; u32 value; }; @@ -64,10 +67,10 @@ static int lpc32xx_read_raw(struct iio_dev *indio_dev, switch (mask) { case IIO_CHAN_INFO_RAW: - mutex_lock(&indio_dev->mlock); + mutex_lock(&st->lock); ret = clk_prepare_enable(st->clk); if (ret) { - mutex_unlock(&indio_dev->mlock); + mutex_unlock(&st->lock); return ret; } /* Measurement setup */ @@ -80,7 +83,7 @@ static int lpc32xx_read_raw(struct iio_dev *indio_dev, wait_for_completion(&st->completion); /* set by ISR */ clk_disable_unprepare(st->clk); *val = st->value; - mutex_unlock(&indio_dev->mlock); + mutex_unlock(&st->lock); return IIO_VAL_INT; @@ -201,6 +204,8 @@ static int lpc32xx_adc_probe(struct platform_device *pdev) iodev->modes = INDIO_DIRECT_MODE; iodev->num_channels = ARRAY_SIZE(lpc32xx_adc_iio_channels); + mutex_init(&st->lock); + retval = devm_iio_device_register(&pdev->dev, iodev); if (retval) return retval; -- cgit v1.2.3 From da8091f8acfa953ac55e2aa8d4218e49b18206a7 Mon Sep 17 00:00:00 2001 From: Nuno Sá Date: Tue, 4 Oct 2022 15:48:58 +0200 Subject: iio: adc: ltc2947-core: do not use internal iio_dev lock MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The iio_device lock is only meant for internal use. Hence define a device local lock to protect against concurrent accesses. While at it, properly include "mutex.h" for mutex related APIs. Signed-off-by: Nuno Sá Link: https://lore.kernel.org/r/20221004134909.1692021-6-nuno.sa@analog.com Signed-off-by: Jonathan Cameron --- drivers/iio/adc/ltc2497-core.c | 7 +++++-- drivers/iio/adc/ltc2497.h | 2 ++ 2 files changed, 7 insertions(+), 2 deletions(-) (limited to 'drivers/iio') diff --git a/drivers/iio/adc/ltc2497-core.c b/drivers/iio/adc/ltc2497-core.c index f52d37af4d1f..996f6cbbed3c 100644 --- a/drivers/iio/adc/ltc2497-core.c +++ b/drivers/iio/adc/ltc2497-core.c @@ -10,6 +10,7 @@ #include #include #include +#include #include #include "ltc2497.h" @@ -81,9 +82,9 @@ static int ltc2497core_read_raw(struct iio_dev *indio_dev, switch (mask) { case IIO_CHAN_INFO_RAW: - mutex_lock(&indio_dev->mlock); + mutex_lock(&ddata->lock); ret = ltc2497core_read(ddata, chan->address, val); - mutex_unlock(&indio_dev->mlock); + mutex_unlock(&ddata->lock); if (ret < 0) return ret; @@ -214,6 +215,8 @@ int ltc2497core_probe(struct device *dev, struct iio_dev *indio_dev) ddata->addr_prev = LTC2497_CONFIG_DEFAULT; ddata->time_prev = ktime_get(); + mutex_init(&ddata->lock); + ret = iio_device_register(indio_dev); if (ret < 0) goto err_array_unregister; diff --git a/drivers/iio/adc/ltc2497.h b/drivers/iio/adc/ltc2497.h index e023de0d88c4..781519b52475 100644 --- a/drivers/iio/adc/ltc2497.h +++ b/drivers/iio/adc/ltc2497.h @@ -12,6 +12,8 @@ struct ltc2497_chip_info { struct ltc2497core_driverdata { struct regulator *ref; ktime_t time_prev; + /* lock to protect against multiple access to the device */ + struct mutex lock; const struct ltc2497_chip_info *chip_info; u8 addr_prev; int (*result_and_measure)(struct ltc2497core_driverdata *ddata, -- cgit v1.2.3 From d0c09264f1a64ba8435acfaa70380f61239fc0d4 Mon Sep 17 00:00:00 2001 From: Nuno Sá Date: Tue, 4 Oct 2022 15:48:59 +0200 Subject: iio: adc: meson_saradc: do not use internal iio_dev lock MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The iio_device lock is only meant for internal use. Hence define a device local lock to protect against concurrent accesses. While at it, properly include "mutex.h" for mutex related APIs. Signed-off-by: Nuno Sá Reviewed-by: Martin Blumenstingl Link: https://lore.kernel.org/r/20221004134909.1692021-7-nuno.sa@analog.com Signed-off-by: Jonathan Cameron --- drivers/iio/adc/meson_saradc.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) (limited to 'drivers/iio') diff --git a/drivers/iio/adc/meson_saradc.c b/drivers/iio/adc/meson_saradc.c index 1a68b099d323..85b6826cc10c 100644 --- a/drivers/iio/adc/meson_saradc.c +++ b/drivers/iio/adc/meson_saradc.c @@ -12,6 +12,7 @@ #include #include #include +#include #include #include #include @@ -276,6 +277,8 @@ struct meson_sar_adc_priv { struct clk *adc_div_clk; struct clk_divider clk_div; struct completion done; + /* lock to protect against multiple access to the device */ + struct mutex lock; int calibbias; int calibscale; struct regmap *tsc_regmap; @@ -486,7 +489,7 @@ static int meson_sar_adc_lock(struct iio_dev *indio_dev) struct meson_sar_adc_priv *priv = iio_priv(indio_dev); int val, ret; - mutex_lock(&indio_dev->mlock); + mutex_lock(&priv->lock); if (priv->param->has_bl30_integration) { /* prevent BL30 from using the SAR ADC while we are using it */ @@ -504,7 +507,7 @@ static int meson_sar_adc_lock(struct iio_dev *indio_dev) !(val & MESON_SAR_ADC_DELAY_BL30_BUSY), 1, 10000); if (ret) { - mutex_unlock(&indio_dev->mlock); + mutex_unlock(&priv->lock); return ret; } } @@ -521,7 +524,7 @@ static void meson_sar_adc_unlock(struct iio_dev *indio_dev) regmap_update_bits(priv->regmap, MESON_SAR_ADC_DELAY, MESON_SAR_ADC_DELAY_KERNEL_BUSY, 0); - mutex_unlock(&indio_dev->mlock); + mutex_unlock(&priv->lock); } static void meson_sar_adc_clear_fifo(struct iio_dev *indio_dev) @@ -1250,6 +1253,8 @@ static int meson_sar_adc_probe(struct platform_device *pdev) if (ret) goto err; + mutex_init(&priv->lock); + ret = meson_sar_adc_hw_enable(indio_dev); if (ret) goto err; -- cgit v1.2.3 From bb690935df8dd8f97612b422c669bd1a5fe87096 Mon Sep 17 00:00:00 2001 From: Nuno Sá Date: Tue, 4 Oct 2022 15:49:00 +0200 Subject: iio: adc: rockchip_saradc: do not use internal iio_dev lock MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The iio_device lock is only meant for internal use. Hence define a device local lock to protect against concurrent accesses. While at it, properly include "mutex.h" for mutex related APIs. Signed-off-by: Nuno Sá Acked-by: Heiko Stuebner Link: https://lore.kernel.org/r/20221004134909.1692021-8-nuno.sa@analog.com Signed-off-by: Jonathan Cameron --- drivers/iio/adc/rockchip_saradc.c | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) (limited to 'drivers/iio') diff --git a/drivers/iio/adc/rockchip_saradc.c b/drivers/iio/adc/rockchip_saradc.c index b87ea7148b58..79448c5ffc2a 100644 --- a/drivers/iio/adc/rockchip_saradc.c +++ b/drivers/iio/adc/rockchip_saradc.c @@ -5,6 +5,7 @@ */ #include +#include #include #include #include @@ -49,6 +50,8 @@ struct rockchip_saradc { struct clk *clk; struct completion completion; struct regulator *vref; + /* lock to protect against multiple access to the device */ + struct mutex lock; int uv_vref; struct reset_control *reset; const struct rockchip_saradc_data *data; @@ -94,17 +97,17 @@ static int rockchip_saradc_read_raw(struct iio_dev *indio_dev, switch (mask) { case IIO_CHAN_INFO_RAW: - mutex_lock(&indio_dev->mlock); + mutex_lock(&info->lock); ret = rockchip_saradc_conversion(info, chan); if (ret) { rockchip_saradc_power_down(info); - mutex_unlock(&indio_dev->mlock); + mutex_unlock(&info->lock); return ret; } *val = info->last_val; - mutex_unlock(&indio_dev->mlock); + mutex_unlock(&info->lock); return IIO_VAL_INT; case IIO_CHAN_INFO_SCALE: *val = info->uv_vref / 1000; @@ -270,7 +273,7 @@ static irqreturn_t rockchip_saradc_trigger_handler(int irq, void *p) int ret; int i, j = 0; - mutex_lock(&i_dev->mlock); + mutex_lock(&info->lock); for_each_set_bit(i, i_dev->active_scan_mask, i_dev->masklength) { const struct iio_chan_spec *chan = &i_dev->channels[i]; @@ -287,7 +290,7 @@ static irqreturn_t rockchip_saradc_trigger_handler(int irq, void *p) iio_push_to_buffers_with_timestamp(i_dev, &data, iio_get_time_ns(i_dev)); out: - mutex_unlock(&i_dev->mlock); + mutex_unlock(&info->lock); iio_trigger_notify_done(i_dev->trig); @@ -478,6 +481,8 @@ static int rockchip_saradc_probe(struct platform_device *pdev) if (ret) return ret; + mutex_init(&info->lock); + return devm_iio_device_register(&pdev->dev, indio_dev); } -- cgit v1.2.3 From 8433aa3591afff6f4dc641a2e274e6171f66a4b7 Mon Sep 17 00:00:00 2001 From: Nuno Sá Date: Tue, 4 Oct 2022 15:49:01 +0200 Subject: iio: adc: sc27xx_adc: do not use internal iio_dev lock MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The iio_device lock is only meant for internal use. Hence define a device local lock to protect against concurrent accesses. While at it, properly include "mutex.h" for mutex related APIs. Signed-off-by: Nuno Sá Link: https://lore.kernel.org/r/20221004134909.1692021-9-nuno.sa@analog.com Signed-off-by: Jonathan Cameron --- drivers/iio/adc/sc27xx_adc.c | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) (limited to 'drivers/iio') diff --git a/drivers/iio/adc/sc27xx_adc.c b/drivers/iio/adc/sc27xx_adc.c index f8421cbba8fa..ff1fc329bb9b 100644 --- a/drivers/iio/adc/sc27xx_adc.c +++ b/drivers/iio/adc/sc27xx_adc.c @@ -4,6 +4,7 @@ #include #include #include +#include #include #include #include @@ -83,6 +84,8 @@ struct sc27xx_adc_data { struct device *dev; struct regulator *volref; struct regmap *regmap; + /* lock to protect against multiple access to the device */ + struct mutex lock; /* * One hardware spinlock to synchronize between the multiple * subsystems which will access the unique ADC controller. @@ -664,9 +667,9 @@ static int sc27xx_adc_read_raw(struct iio_dev *indio_dev, switch (mask) { case IIO_CHAN_INFO_RAW: - mutex_lock(&indio_dev->mlock); + mutex_lock(&data->lock); ret = sc27xx_adc_read(data, chan->channel, scale, &tmp); - mutex_unlock(&indio_dev->mlock); + mutex_unlock(&data->lock); if (ret) return ret; @@ -675,10 +678,10 @@ static int sc27xx_adc_read_raw(struct iio_dev *indio_dev, return IIO_VAL_INT; case IIO_CHAN_INFO_PROCESSED: - mutex_lock(&indio_dev->mlock); + mutex_lock(&data->lock); ret = sc27xx_adc_read_processed(data, chan->channel, scale, &tmp); - mutex_unlock(&indio_dev->mlock); + mutex_unlock(&data->lock); if (ret) return ret; @@ -934,6 +937,9 @@ static int sc27xx_adc_probe(struct platform_device *pdev) indio_dev->info = &sc27xx_info; indio_dev->channels = sc27xx_channels; indio_dev->num_channels = ARRAY_SIZE(sc27xx_channels); + + mutex_init(&sc27xx_data->lock); + ret = devm_iio_device_register(dev, indio_dev); if (ret) dev_err(dev, "could not register iio (ADC)"); -- cgit v1.2.3 From f2bdea865e776b571557035eac2e8afde8ea7844 Mon Sep 17 00:00:00 2001 From: Nuno Sá Date: Tue, 4 Oct 2022 15:49:02 +0200 Subject: iio: adc: vf610_adc: add helper function to read samples MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This is a precursor change to make it simpler to remove the 'mlock' usage. Having the code in it's own helper function, also makes it easier to read the error paths. Signed-off-by: Nuno Sá Reviewed-by: Haibo Chen Link: https://lore.kernel.org/r/20221004134909.1692021-10-nuno.sa@analog.com Signed-off-by: Jonathan Cameron --- drivers/iio/adc/vf610_adc.c | 94 ++++++++++++++++++++++++++------------------- 1 file changed, 54 insertions(+), 40 deletions(-) (limited to 'drivers/iio') diff --git a/drivers/iio/adc/vf610_adc.c b/drivers/iio/adc/vf610_adc.c index c6b16cf6e367..a6f9182d7766 100644 --- a/drivers/iio/adc/vf610_adc.c +++ b/drivers/iio/adc/vf610_adc.c @@ -622,6 +622,58 @@ static const struct attribute_group vf610_attribute_group = { .attrs = vf610_attributes, }; +static int vf610_read_sample(struct iio_dev *indio_dev, + struct iio_chan_spec const *chan, int *val) +{ + struct vf610_adc *info = iio_priv(indio_dev); + unsigned int hc_cfg; + int ret; + + mutex_lock(&indio_dev->mlock); + if (iio_buffer_enabled(indio_dev)) { + ret = -EBUSY; + goto out_unlock; + } + + reinit_completion(&info->completion); + hc_cfg = VF610_ADC_ADCHC(chan->channel); + hc_cfg |= VF610_ADC_AIEN; + writel(hc_cfg, info->regs + VF610_REG_ADC_HC0); + ret = wait_for_completion_interruptible_timeout(&info->completion, + VF610_ADC_TIMEOUT); + if (ret == 0) { + ret = -ETIMEDOUT; + goto out_unlock; + } + + if (ret < 0) + goto out_unlock; + + switch (chan->type) { + case IIO_VOLTAGE: + *val = info->value; + break; + case IIO_TEMP: + /* + * Calculate in degree Celsius times 1000 + * Using the typical sensor slope of 1.84 mV/°C + * and VREFH_ADC at 3.3V, V at 25°C of 699 mV + */ + *val = 25000 - ((int)info->value - VF610_VTEMP25_3V3) * + 1000000 / VF610_TEMP_SLOPE_COEFF; + + break; + default: + ret = -EINVAL; + break; + } + +out_unlock: + mutex_unlock(&indio_dev->mlock); + + return ret; +} + static int vf610_read_raw(struct iio_dev *indio_dev, struct iio_chan_spec const *chan, int *val, @@ -629,53 +681,15 @@ static int vf610_read_raw(struct iio_dev *indio_dev, long mask) { struct vf610_adc *info = iio_priv(indio_dev); - unsigned int hc_cfg; long ret; switch (mask) { case IIO_CHAN_INFO_RAW: case IIO_CHAN_INFO_PROCESSED: - mutex_lock(&indio_dev->mlock); - if (iio_buffer_enabled(indio_dev)) { - mutex_unlock(&indio_dev->mlock); - return -EBUSY; - } - - reinit_completion(&info->completion); - hc_cfg = VF610_ADC_ADCHC(chan->channel); - hc_cfg |= VF610_ADC_AIEN; - writel(hc_cfg, info->regs + VF610_REG_ADC_HC0); - ret = wait_for_completion_interruptible_timeout - (&info->completion, VF610_ADC_TIMEOUT); - if (ret == 0) { - mutex_unlock(&indio_dev->mlock); - return -ETIMEDOUT; - } - if (ret < 0) { - mutex_unlock(&indio_dev->mlock); + ret = vf610_read_sample(indio_dev, chan, val); + if (ret < 0) return ret; - } - - switch (chan->type) { - case IIO_VOLTAGE: - *val = info->value; - break; - case IIO_TEMP: - /* - * Calculate in degree Celsius times 1000 - * Using the typical sensor slope of 1.84 mV/°C - * and VREFH_ADC at 3.3V, V at 25°C of 699 mV - */ - *val = 25000 - ((int)info->value - VF610_VTEMP25_3V3) * - 1000000 / VF610_TEMP_SLOPE_COEFF; - - break; - default: - mutex_unlock(&indio_dev->mlock); - return -EINVAL; - } - mutex_unlock(&indio_dev->mlock); return IIO_VAL_INT; case IIO_CHAN_INFO_SCALE: -- cgit v1.2.3 From 4e15cad8dbf9991d430c31166040575bf972b179 Mon Sep 17 00:00:00 2001 From: Nuno Sá Date: Tue, 4 Oct 2022 15:49:03 +0200 Subject: iio: adc: vf610_adc: vf610_adc: do not use internal iio_dev lock MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit In order to drop the internal lock usage we needed two different things: 1) The first place where 'mlock' was being used was a typical case where iio_device_claim_direct_mode() fits perfectly. 2) In the second case, it was being used to prevent concurrent accesses to the device and shared data but nothing was being enforced with regards to buffering (i.e, there was nothing preventing from changing the conversion mode while buffering). Hence, in this case, a new lock was introduced in the state structure. Note that the goal is not to introduce any functional change and that is the reason why a new lock was introduced to guarantee 2). While at it, properly include "mutex.h" for mutex related APIs. Signed-off-by: Nuno Sá Reviewed-by: Haibo Chen Link: https://lore.kernel.org/r/20221004134909.1692021-11-nuno.sa@analog.com Signed-off-by: Jonathan Cameron --- drivers/iio/adc/vf610_adc.c | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) (limited to 'drivers/iio') diff --git a/drivers/iio/adc/vf610_adc.c b/drivers/iio/adc/vf610_adc.c index a6f9182d7766..ae31aafd2653 100644 --- a/drivers/iio/adc/vf610_adc.c +++ b/drivers/iio/adc/vf610_adc.c @@ -7,6 +7,7 @@ #include #include +#include #include #include #include @@ -156,6 +157,9 @@ struct vf610_adc { void __iomem *regs; struct clk *clk; + /* lock to protect against multiple access to the device */ + struct mutex lock; + u32 vref_uv; u32 value; struct regulator *vref; @@ -467,11 +471,11 @@ static int vf610_set_conversion_mode(struct iio_dev *indio_dev, { struct vf610_adc *info = iio_priv(indio_dev); - mutex_lock(&indio_dev->mlock); + mutex_lock(&info->lock); info->adc_feature.conv_mode = mode; vf610_adc_calculate_rates(info); vf610_adc_hw_init(info); - mutex_unlock(&indio_dev->mlock); + mutex_unlock(&info->lock); return 0; } @@ -629,12 +633,11 @@ static int vf610_read_sample(struct iio_dev *indio_dev, unsigned int hc_cfg; int ret; - mutex_lock(&indio_dev->mlock); - if (iio_buffer_enabled(indio_dev)) { - ret = -EBUSY; - goto out_unlock; - } + ret = iio_device_claim_direct_mode(indio_dev); + if (ret) + return ret; + mutex_lock(&info->lock); reinit_completion(&info->completion); hc_cfg = VF610_ADC_ADCHC(chan->channel); hc_cfg |= VF610_ADC_AIEN; @@ -669,7 +672,8 @@ static int vf610_read_sample(struct iio_dev *indio_dev, } out_unlock: - mutex_unlock(&indio_dev->mlock); + mutex_unlock(&info->lock); + iio_device_release_direct_mode(indio_dev); return ret; } @@ -892,6 +896,8 @@ static int vf610_adc_probe(struct platform_device *pdev) goto error_iio_device_register; } + mutex_init(&info->lock); + ret = iio_device_register(indio_dev); if (ret) { dev_err(&pdev->dev, "Couldn't register the device.\n"); -- cgit v1.2.3 From d711a5a7eff4855deb0e2c2663e679dc205e2d9f Mon Sep 17 00:00:00 2001 From: Nuno Sá Date: Tue, 4 Oct 2022 15:49:04 +0200 Subject: iio: common: scmi_iio: do not use internal iio_dev lock MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The iio_device lock is only meant for internal use. Hence define a device local lock to protect against concurrent accesses. While at it, properly include "mutex.h" for mutex related APIs. Signed-off-by: Nuno Sá Link: https://lore.kernel.org/r/20221004134909.1692021-12-nuno.sa@analog.com Signed-off-by: Jonathan Cameron --- drivers/iio/common/scmi_sensors/scmi_iio.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) (limited to 'drivers/iio') diff --git a/drivers/iio/common/scmi_sensors/scmi_iio.c b/drivers/iio/common/scmi_sensors/scmi_iio.c index 54ccf19ab2bb..d92f7f651f7b 100644 --- a/drivers/iio/common/scmi_sensors/scmi_iio.c +++ b/drivers/iio/common/scmi_sensors/scmi_iio.c @@ -15,6 +15,7 @@ #include #include #include +#include #include #include #include @@ -27,6 +28,8 @@ struct scmi_iio_priv { struct scmi_protocol_handle *ph; const struct scmi_sensor_info *sensor_info; struct iio_dev *indio_dev; + /* lock to protect against multiple access to the device */ + struct mutex lock; /* adding one additional channel for timestamp */ s64 iio_buf[SCMI_IIO_NUM_OF_AXIS + 1]; struct notifier_block sensor_update_nb; @@ -198,13 +201,14 @@ static int scmi_iio_write_raw(struct iio_dev *iio_dev, struct iio_chan_spec const *chan, int val, int val2, long mask) { + struct scmi_iio_priv *sensor = iio_priv(iio_dev); int err; switch (mask) { case IIO_CHAN_INFO_SAMP_FREQ: - mutex_lock(&iio_dev->mlock); + mutex_lock(&sensor->lock); err = scmi_iio_set_odr_val(iio_dev, val, val2); - mutex_unlock(&iio_dev->mlock); + mutex_unlock(&sensor->lock); return err; default: return -EINVAL; @@ -586,6 +590,7 @@ scmi_alloc_iiodev(struct scmi_device *sdev, sensor->sensor_info = sensor_info; sensor->sensor_update_nb.notifier_call = scmi_iio_sensor_update_cb; sensor->indio_dev = iiodev; + mutex_init(&sensor->lock); /* adding one additional channel for timestamp */ iiodev->num_channels = sensor_info->num_axis + 1; -- cgit v1.2.3 From 3cc36cabc669fffa7f04931e3dd25dc47314ec06 Mon Sep 17 00:00:00 2001 From: Nuno Sá Date: Tue, 4 Oct 2022 15:49:05 +0200 Subject: iio: gyro: itg3200_core: do not use internal iio_dev lock MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The iio_device lock is only meant for internal use. Hence define a device local lock to protect against concurrent accesses. While at it, properly include "mutex.h" for mutex related APIs. Signed-off-by: Nuno Sá Link: https://lore.kernel.org/r/20221004134909.1692021-13-nuno.sa@analog.com Signed-off-by: Jonathan Cameron --- drivers/iio/gyro/itg3200_core.c | 10 +++++++--- include/linux/iio/gyro/itg3200.h | 2 ++ 2 files changed, 9 insertions(+), 3 deletions(-) (limited to 'drivers/iio') diff --git a/drivers/iio/gyro/itg3200_core.c b/drivers/iio/gyro/itg3200_core.c index 421501584587..74ca22468496 100644 --- a/drivers/iio/gyro/itg3200_core.c +++ b/drivers/iio/gyro/itg3200_core.c @@ -18,6 +18,7 @@ #include #include #include +#include #include #include @@ -131,6 +132,7 @@ static int itg3200_write_raw(struct iio_dev *indio_dev, int val2, long mask) { + struct itg3200 *st = iio_priv(indio_dev); int ret; u8 t; @@ -139,11 +141,11 @@ static int itg3200_write_raw(struct iio_dev *indio_dev, if (val == 0 || val2 != 0) return -EINVAL; - mutex_lock(&indio_dev->mlock); + mutex_lock(&st->lock); ret = itg3200_read_reg_8(indio_dev, ITG3200_REG_DLPF, &t); if (ret) { - mutex_unlock(&indio_dev->mlock); + mutex_unlock(&st->lock); return ret; } t = ((t & ITG3200_DLPF_CFG_MASK) ? 1000u : 8000u) / val - 1; @@ -152,7 +154,7 @@ static int itg3200_write_raw(struct iio_dev *indio_dev, ITG3200_REG_SAMPLE_RATE_DIV, t); - mutex_unlock(&indio_dev->mlock); + mutex_unlock(&st->lock); return ret; default: @@ -336,6 +338,8 @@ static int itg3200_probe(struct i2c_client *client, if (ret) goto error_remove_trigger; + mutex_init(&st->lock); + ret = iio_device_register(indio_dev); if (ret) goto error_remove_trigger; diff --git a/include/linux/iio/gyro/itg3200.h b/include/linux/iio/gyro/itg3200.h index a602fe7b84fa..74b6d1cadc86 100644 --- a/include/linux/iio/gyro/itg3200.h +++ b/include/linux/iio/gyro/itg3200.h @@ -102,6 +102,8 @@ struct itg3200 { struct i2c_client *i2c; struct iio_trigger *trig; struct iio_mount_matrix orientation; + /* lock to protect against multiple access to the device */ + struct mutex lock; }; enum ITG3200_SCAN_INDEX { -- cgit v1.2.3 From a44ef7c4609724e2f395d8a24d4a863cd860bbba Mon Sep 17 00:00:00 2001 From: Ibrahim Tilki Date: Mon, 3 Oct 2022 13:59:01 +0300 Subject: iio: adc: add max11410 adc driver Adding support for max11410 24-bit, 1.9ksps delta-sigma adc which has 3 differential reference and 10 differential channel inputs. Inputs and references can be buffered internally. Inputs can also be amplified with internal PGA. Device has four digital filter modes: FIR50/60, FIR50, FIR60 and SINC4. FIR 50Hz and 60Hz rejections can be enabled/disabled separately. Digital filter selection affects sampling frequency range so driver has to consider the configured filter when configuring sampling frequency. Signed-off-by: Ibrahim Tilki Link: https://lore.kernel.org/r/20221003105903.229-2-Ibrahim.Tilki@analog.com Signed-off-by: Jonathan Cameron --- drivers/iio/adc/Kconfig | 13 + drivers/iio/adc/Makefile | 1 + drivers/iio/adc/max11410.c | 1050 ++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 1064 insertions(+) create mode 100644 drivers/iio/adc/max11410.c (limited to 'drivers/iio') diff --git a/drivers/iio/adc/Kconfig b/drivers/iio/adc/Kconfig index 791612ca6012..544986fd456d 100644 --- a/drivers/iio/adc/Kconfig +++ b/drivers/iio/adc/Kconfig @@ -667,6 +667,19 @@ config MAX11205 To compile this driver as a module, choose M here: the module will be called max11205. +config MAX11410 + tristate "Analog Devices MAX11410 ADC driver" + depends on SPI + select REGMAP_SPI + select IIO_BUFFER + select IIO_TRIGGER + select IIO_TRIGGERED_BUFFER + help + Say yes here to build support for Analog Devices MAX11410 ADCs. + + To compile this driver as a module, choose M here: the module will be + called max11410. + config MAX1241 tristate "Maxim max1241 ADC driver" depends on SPI_MASTER diff --git a/drivers/iio/adc/Makefile b/drivers/iio/adc/Makefile index 46caba7a010c..4d803413425c 100644 --- a/drivers/iio/adc/Makefile +++ b/drivers/iio/adc/Makefile @@ -62,6 +62,7 @@ obj-$(CONFIG_MAX1027) += max1027.o obj-$(CONFIG_MAX11100) += max11100.o obj-$(CONFIG_MAX1118) += max1118.o obj-$(CONFIG_MAX11205) += max11205.o +obj-$(CONFIG_MAX11410) += max11410.o obj-$(CONFIG_MAX1241) += max1241.o obj-$(CONFIG_MAX1363) += max1363.o obj-$(CONFIG_MAX9611) += max9611.o diff --git a/drivers/iio/adc/max11410.c b/drivers/iio/adc/max11410.c new file mode 100644 index 000000000000..8cd566367187 --- /dev/null +++ b/drivers/iio/adc/max11410.c @@ -0,0 +1,1050 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * MAX11410 SPI ADC driver + * + * Copyright 2022 Analog Devices Inc. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#define MAX11410_REG_CONV_START 0x01 +#define MAX11410_CONV_TYPE_SINGLE 0x00 +#define MAX11410_CONV_TYPE_CONTINUOUS 0x01 +#define MAX11410_REG_CAL_START 0x03 +#define MAX11410_CAL_START_SELF 0x00 +#define MAX11410_CAL_START_PGA 0x01 +#define MAX11410_REG_GPIO_CTRL(ch) ((ch) ? 0x05 : 0x04) +#define MAX11410_GPIO_INTRB 0xC1 +#define MAX11410_REG_FILTER 0x08 +#define MAX11410_FILTER_RATE_MASK GENMASK(3, 0) +#define MAX11410_FILTER_RATE_MAX 0x0F +#define MAX11410_FILTER_LINEF_MASK GENMASK(5, 4) +#define MAX11410_FILTER_50HZ BIT(5) +#define MAX11410_FILTER_60HZ BIT(4) +#define MAX11410_REG_CTRL 0x09 +#define MAX11410_CTRL_REFSEL_MASK GENMASK(2, 0) +#define MAX11410_CTRL_VREFN_BUF_BIT BIT(3) +#define MAX11410_CTRL_VREFP_BUF_BIT BIT(4) +#define MAX11410_CTRL_FORMAT_BIT BIT(5) +#define MAX11410_CTRL_UNIPOLAR_BIT BIT(6) +#define MAX11410_REG_MUX_CTRL0 0x0B +#define MAX11410_REG_PGA 0x0E +#define MAX11410_PGA_GAIN_MASK GENMASK(2, 0) +#define MAX11410_PGA_SIG_PATH_MASK GENMASK(5, 4) +#define MAX11410_PGA_SIG_PATH_BUFFERED 0x00 +#define MAX11410_PGA_SIG_PATH_BYPASS 0x01 +#define MAX11410_PGA_SIG_PATH_PGA 0x02 +#define MAX11410_REG_DATA0 0x30 +#define MAX11410_REG_STATUS 0x38 +#define MAX11410_STATUS_CONV_READY_BIT BIT(0) +#define MAX11410_STATUS_CAL_READY_BIT BIT(2) + +#define MAX11410_REFSEL_AVDD_AGND 0x03 +#define MAX11410_REFSEL_MAX 0x06 +#define MAX11410_SIG_PATH_MAX 0x02 +#define MAX11410_CHANNEL_INDEX_MAX 0x0A +#define MAX11410_AINP_AVDD 0x0A +#define MAX11410_AINN_GND 0x0A + +#define MAX11410_CONVERSION_TIMEOUT_MS 2000 +#define MAX11410_CALIB_TIMEOUT_MS 2000 + +#define MAX11410_SCALE_AVAIL_SIZE 8 + +enum max11410_filter { + MAX11410_FILTER_FIR5060, + MAX11410_FILTER_FIR50, + MAX11410_FILTER_FIR60, + MAX11410_FILTER_SINC4, +}; + +static const u8 max11410_sampling_len[] = { + [MAX11410_FILTER_FIR5060] = 5, + [MAX11410_FILTER_FIR50] = 6, + [MAX11410_FILTER_FIR60] = 6, + [MAX11410_FILTER_SINC4] = 10, +}; + +static const int max11410_sampling_rates[4][10][2] = { + [MAX11410_FILTER_FIR5060] = { + { 1, 100000 }, + { 2, 100000 }, + { 4, 200000 }, + { 8, 400000 }, + { 16, 800000 } + }, + [MAX11410_FILTER_FIR50] = { + { 1, 300000 }, + { 2, 700000 }, + { 5, 300000 }, + { 10, 700000 }, + { 21, 300000 }, + { 40 } + }, + [MAX11410_FILTER_FIR60] = { + { 1, 300000 }, + { 2, 700000 }, + { 5, 300000 }, + { 10, 700000 }, + { 21, 300000 }, + { 40 } + }, + [MAX11410_FILTER_SINC4] = { + { 4 }, + { 10 }, + { 20 }, + { 40 }, + { 60 }, + { 120 }, + { 240 }, + { 480 }, + { 960 }, + { 1920 } + } +}; + +struct max11410_channel_config { + u32 settling_time_us; + u32 *scale_avail; + u8 refsel; + u8 sig_path; + u8 gain; + bool bipolar; + bool buffered_vrefp; + bool buffered_vrefn; +}; + +struct max11410_state { + struct spi_device *spi_dev; + struct iio_trigger *trig; + struct completion completion; + struct mutex lock; /* Prevent changing channel config during sampling */ + struct regmap *regmap; + struct regulator *avdd; + struct regulator *vrefp[3]; + struct regulator *vrefn[3]; + struct max11410_channel_config *channels; + int irq; + struct { + u32 data __aligned(IIO_DMA_MINALIGN); + s64 ts __aligned(8); + } scan; +}; + +static const struct iio_chan_spec chanspec_template = { + .type = IIO_VOLTAGE, + .indexed = 1, + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | + BIT(IIO_CHAN_INFO_SCALE) | + BIT(IIO_CHAN_INFO_OFFSET), + .info_mask_shared_by_all = BIT(IIO_CHAN_INFO_SAMP_FREQ), + .info_mask_shared_by_all_available = BIT(IIO_CHAN_INFO_SAMP_FREQ), + .scan_type = { + .sign = 's', + .realbits = 24, + .storagebits = 32, + .endianness = IIO_LE, + }, +}; + +static unsigned int max11410_reg_size(unsigned int reg) +{ + /* Registers from 0x00 to 0x10 are 1 byte, the rest are 3 bytes long. */ + return reg <= 0x10 ? 1 : 3; +} + +static int max11410_write_reg(struct max11410_state *st, unsigned int reg, + unsigned int val) +{ + /* This driver only needs to write 8-bit registers */ + if (max11410_reg_size(reg) != 1) + return -EINVAL; + + return regmap_write(st->regmap, reg, val); +} + +static int max11410_read_reg(struct max11410_state *st, unsigned int reg, + int *val) +{ + int ret; + + if (max11410_reg_size(reg) == 3) { + ret = regmap_bulk_read(st->regmap, reg, &st->scan.data, 3); + if (ret) + return ret; + + *val = get_unaligned_be24(&st->scan.data); + return 0; + } + + return regmap_read(st->regmap, reg, val); +} + +static struct regulator *max11410_get_vrefp(struct max11410_state *st, + u8 refsel) +{ + refsel = refsel % 4; + if (refsel == 3) + return st->avdd; + + return st->vrefp[refsel]; +} + +static struct regulator *max11410_get_vrefn(struct max11410_state *st, + u8 refsel) +{ + if (refsel > 2) + return NULL; + + return st->vrefn[refsel]; +} + +static const struct regmap_config regmap_config = { + .reg_bits = 8, + .val_bits = 8, + .max_register = 0x39, +}; + +static ssize_t max11410_notch_en_show(struct device *dev, + struct device_attribute *devattr, + char *buf) +{ + struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct max11410_state *state = iio_priv(indio_dev); + struct iio_dev_attr *iio_attr = to_iio_dev_attr(devattr); + unsigned int val; + int ret; + + ret = max11410_read_reg(state, MAX11410_REG_FILTER, &val); + if (ret) + return ret; + + switch (iio_attr->address) { + case 0: + val = !FIELD_GET(MAX11410_FILTER_50HZ, val); + break; + case 1: + val = !FIELD_GET(MAX11410_FILTER_60HZ, val); + break; + case 2: + val = FIELD_GET(MAX11410_FILTER_LINEF_MASK, val) == 3; + break; + default: + return -EINVAL; + } + + return sysfs_emit(buf, "%d\n", val); +} + +static ssize_t max11410_notch_en_store(struct device *dev, + struct device_attribute *devattr, + const char *buf, size_t count) +{ + struct iio_dev_attr *iio_attr = to_iio_dev_attr(devattr); + struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct max11410_state *state = iio_priv(indio_dev); + unsigned int filter_bits; + bool enable; + int ret; + + ret = kstrtobool(buf, &enable); + if (ret) + return ret; + + switch (iio_attr->address) { + case 0: + filter_bits = MAX11410_FILTER_50HZ; + break; + case 1: + filter_bits = MAX11410_FILTER_60HZ; + break; + case 2: + default: + filter_bits = MAX11410_FILTER_50HZ | MAX11410_FILTER_60HZ; + enable = !enable; + break; + } + + if (enable) + ret = regmap_clear_bits(state->regmap, MAX11410_REG_FILTER, + filter_bits); + else + ret = regmap_set_bits(state->regmap, MAX11410_REG_FILTER, + filter_bits); + + if (ret) + return ret; + + return count; +} + +static ssize_t in_voltage_filter2_notch_center_show(struct device *dev, + struct device_attribute *devattr, + char *buf) +{ + struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct max11410_state *state = iio_priv(indio_dev); + int ret, reg, rate, filter; + + ret = regmap_read(state->regmap, MAX11410_REG_FILTER, ®); + if (ret) + return ret; + + rate = FIELD_GET(MAX11410_FILTER_RATE_MASK, reg); + rate = clamp_val(rate, 0, + max11410_sampling_len[MAX11410_FILTER_SINC4] - 1); + filter = max11410_sampling_rates[MAX11410_FILTER_SINC4][rate][0]; + + return sysfs_emit(buf, "%d\n", filter); +} + +static IIO_CONST_ATTR(in_voltage_filter0_notch_center, "50"); +static IIO_CONST_ATTR(in_voltage_filter1_notch_center, "60"); +static IIO_DEVICE_ATTR_RO(in_voltage_filter2_notch_center, 2); + +static IIO_DEVICE_ATTR(in_voltage_filter0_notch_en, 0644, + max11410_notch_en_show, max11410_notch_en_store, 0); +static IIO_DEVICE_ATTR(in_voltage_filter1_notch_en, 0644, + max11410_notch_en_show, max11410_notch_en_store, 1); +static IIO_DEVICE_ATTR(in_voltage_filter2_notch_en, 0644, + max11410_notch_en_show, max11410_notch_en_store, 2); + +static struct attribute *max11410_attributes[] = { + &iio_const_attr_in_voltage_filter0_notch_center.dev_attr.attr, + &iio_const_attr_in_voltage_filter1_notch_center.dev_attr.attr, + &iio_dev_attr_in_voltage_filter2_notch_center.dev_attr.attr, + &iio_dev_attr_in_voltage_filter0_notch_en.dev_attr.attr, + &iio_dev_attr_in_voltage_filter1_notch_en.dev_attr.attr, + &iio_dev_attr_in_voltage_filter2_notch_en.dev_attr.attr, + NULL +}; + +static const struct attribute_group max11410_attribute_group = { + .attrs = max11410_attributes, +}; + +static int max11410_set_input_mux(struct max11410_state *st, u8 ainp, u8 ainn) +{ + if (ainp > MAX11410_CHANNEL_INDEX_MAX || + ainn > MAX11410_CHANNEL_INDEX_MAX) + return -EINVAL; + + return max11410_write_reg(st, MAX11410_REG_MUX_CTRL0, + (ainp << 4) | ainn); +} + +static int max11410_configure_channel(struct max11410_state *st, + struct iio_chan_spec const *chan) +{ + struct max11410_channel_config cfg = st->channels[chan->address]; + unsigned int regval; + int ret; + + if (chan->differential) + ret = max11410_set_input_mux(st, chan->channel, chan->channel2); + else + ret = max11410_set_input_mux(st, chan->channel, + MAX11410_AINN_GND); + + if (ret) + return ret; + + regval = FIELD_PREP(MAX11410_CTRL_VREFP_BUF_BIT, cfg.buffered_vrefp) | + FIELD_PREP(MAX11410_CTRL_VREFN_BUF_BIT, cfg.buffered_vrefn) | + FIELD_PREP(MAX11410_CTRL_REFSEL_MASK, cfg.refsel) | + FIELD_PREP(MAX11410_CTRL_UNIPOLAR_BIT, cfg.bipolar ? 0 : 1); + ret = regmap_update_bits(st->regmap, MAX11410_REG_CTRL, + MAX11410_CTRL_REFSEL_MASK | + MAX11410_CTRL_VREFN_BUF_BIT | + MAX11410_CTRL_VREFN_BUF_BIT | + MAX11410_CTRL_UNIPOLAR_BIT, regval); + if (ret) + return ret; + + regval = FIELD_PREP(MAX11410_PGA_SIG_PATH_MASK, cfg.sig_path) | + FIELD_PREP(MAX11410_PGA_GAIN_MASK, cfg.gain); + ret = regmap_write(st->regmap, MAX11410_REG_PGA, regval); + if (ret) + return ret; + + if (cfg.settling_time_us) + fsleep(cfg.settling_time_us); + + return 0; +} + +static int max11410_sample(struct max11410_state *st, int *sample_raw, + struct iio_chan_spec const *chan) +{ + int val, ret; + + ret = max11410_configure_channel(st, chan); + if (ret) + return ret; + + if (st->irq > 0) + reinit_completion(&st->completion); + + /* Start Conversion */ + ret = max11410_write_reg(st, MAX11410_REG_CONV_START, + MAX11410_CONV_TYPE_SINGLE); + if (ret) + return ret; + + if (st->irq > 0) { + /* Wait for an interrupt. */ + ret = wait_for_completion_timeout(&st->completion, + msecs_to_jiffies(MAX11410_CONVERSION_TIMEOUT_MS)); + if (!ret) + return -ETIMEDOUT; + } else { + /* Wait for status register Conversion Ready flag */ + ret = read_poll_timeout(max11410_read_reg, ret, + ret || (val & MAX11410_STATUS_CONV_READY_BIT), + 5000, MAX11410_CONVERSION_TIMEOUT_MS * 1000, + true, st, MAX11410_REG_STATUS, &val); + if (ret) + return ret; + } + + /* Read ADC Data */ + return max11410_read_reg(st, MAX11410_REG_DATA0, sample_raw); +} + +static int max11410_get_scale(struct max11410_state *state, + struct max11410_channel_config cfg) +{ + struct regulator *vrefp, *vrefn; + int scale; + + vrefp = max11410_get_vrefp(state, cfg.refsel); + + scale = regulator_get_voltage(vrefp) / 1000; + vrefn = max11410_get_vrefn(state, cfg.refsel); + if (vrefn) + scale -= regulator_get_voltage(vrefn) / 1000; + + if (cfg.bipolar) + scale *= 2; + + return scale >> cfg.gain; +} + +static int max11410_read_raw(struct iio_dev *indio_dev, + struct iio_chan_spec const *chan, + int *val, int *val2, long info) +{ + struct max11410_state *state = iio_priv(indio_dev); + struct max11410_channel_config cfg = state->channels[chan->address]; + int ret, reg_val, filter, rate; + + switch (info) { + case IIO_CHAN_INFO_SCALE: + *val = max11410_get_scale(state, cfg); + *val2 = chan->scan_type.realbits; + return IIO_VAL_FRACTIONAL_LOG2; + case IIO_CHAN_INFO_OFFSET: + if (cfg.bipolar) + *val = -BIT(chan->scan_type.realbits - 1); + else + *val = 0; + + return IIO_VAL_INT; + case IIO_CHAN_INFO_RAW: + ret = iio_device_claim_direct_mode(indio_dev); + if (ret) + return ret; + + mutex_lock(&state->lock); + + ret = max11410_sample(state, ®_val, chan); + + mutex_unlock(&state->lock); + + iio_device_release_direct_mode(indio_dev); + + if (ret) + return ret; + + *val = reg_val; + + return IIO_VAL_INT; + case IIO_CHAN_INFO_SAMP_FREQ: + ret = regmap_read(state->regmap, MAX11410_REG_FILTER, ®_val); + if (ret) + return ret; + + filter = FIELD_GET(MAX11410_FILTER_LINEF_MASK, reg_val); + rate = reg_val & MAX11410_FILTER_RATE_MASK; + if (rate >= max11410_sampling_len[filter]) + rate = max11410_sampling_len[filter] - 1; + + *val = max11410_sampling_rates[filter][rate][0]; + *val2 = max11410_sampling_rates[filter][rate][1]; + + return IIO_VAL_INT_PLUS_MICRO; + } + return -EINVAL; +} + +static int max11410_write_raw(struct iio_dev *indio_dev, + struct iio_chan_spec const *chan, + int val, int val2, long mask) +{ + struct max11410_state *st = iio_priv(indio_dev); + int i, ret, reg_val, filter, gain; + u32 *scale_avail; + + switch (mask) { + case IIO_CHAN_INFO_SCALE: + scale_avail = st->channels[chan->address].scale_avail; + if (!scale_avail) + return -EOPNOTSUPP; + + /* Accept values in range 0.000001 <= scale < 1.000000 */ + if (val != 0 || val2 == 0) + return -EINVAL; + + ret = iio_device_claim_direct_mode(indio_dev); + if (ret) + return ret; + + /* Convert from INT_PLUS_MICRO to FRACTIONAL_LOG2 */ + val2 = val2 * DIV_ROUND_CLOSEST(BIT(24), 1000000); + val2 = DIV_ROUND_CLOSEST(scale_avail[0], val2); + gain = order_base_2(val2); + + st->channels[chan->address].gain = clamp_val(gain, 0, 7); + + iio_device_release_direct_mode(indio_dev); + + return 0; + case IIO_CHAN_INFO_SAMP_FREQ: + ret = iio_device_claim_direct_mode(indio_dev); + if (ret) + return ret; + + mutex_lock(&st->lock); + + ret = regmap_read(st->regmap, MAX11410_REG_FILTER, ®_val); + if (ret) + goto out; + + filter = FIELD_GET(MAX11410_FILTER_LINEF_MASK, reg_val); + + for (i = 0; i < max11410_sampling_len[filter]; ++i) { + if (val == max11410_sampling_rates[filter][i][0] && + val2 == max11410_sampling_rates[filter][i][1]) + break; + } + if (i == max11410_sampling_len[filter]) { + ret = -EINVAL; + goto out; + } + + ret = regmap_write_bits(st->regmap, MAX11410_REG_FILTER, + MAX11410_FILTER_RATE_MASK, i); + +out: + mutex_unlock(&st->lock); + iio_device_release_direct_mode(indio_dev); + + return ret; + default: + return -EINVAL; + } +} + +static int max11410_read_avail(struct iio_dev *indio_dev, + struct iio_chan_spec const *chan, + const int **vals, int *type, int *length, + long info) +{ + struct max11410_state *st = iio_priv(indio_dev); + struct max11410_channel_config cfg; + int ret, reg_val, filter; + + switch (info) { + case IIO_CHAN_INFO_SAMP_FREQ: + ret = regmap_read(st->regmap, MAX11410_REG_FILTER, ®_val); + if (ret) + return ret; + + filter = FIELD_GET(MAX11410_FILTER_LINEF_MASK, reg_val); + + *vals = (const int *)max11410_sampling_rates[filter]; + *length = max11410_sampling_len[filter] * 2; + *type = IIO_VAL_INT_PLUS_MICRO; + + return IIO_AVAIL_LIST; + case IIO_CHAN_INFO_SCALE: + cfg = st->channels[chan->address]; + + if (!cfg.scale_avail) + return -EINVAL; + + *vals = cfg.scale_avail; + *length = MAX11410_SCALE_AVAIL_SIZE * 2; + *type = IIO_VAL_FRACTIONAL_LOG2; + + return IIO_AVAIL_LIST; + } + return -EINVAL; +} + +static const struct iio_info max11410_info = { + .read_raw = max11410_read_raw, + .write_raw = max11410_write_raw, + .read_avail = max11410_read_avail, + .attrs = &max11410_attribute_group, +}; + +static irqreturn_t max11410_trigger_handler(int irq, void *p) +{ + struct iio_poll_func *pf = p; + struct iio_dev *indio_dev = pf->indio_dev; + struct max11410_state *st = iio_priv(indio_dev); + int ret; + + ret = max11410_read_reg(st, MAX11410_REG_DATA0, &st->scan.data); + if (ret) { + dev_err(&indio_dev->dev, "cannot read data\n"); + goto out; + } + + iio_push_to_buffers_with_timestamp(indio_dev, &st->scan, + iio_get_time_ns(indio_dev)); + +out: + iio_trigger_notify_done(indio_dev->trig); + + return IRQ_HANDLED; +} + +static int max11410_buffer_postenable(struct iio_dev *indio_dev) +{ + struct max11410_state *st = iio_priv(indio_dev); + int scan_ch, ret; + + scan_ch = ffs(*indio_dev->active_scan_mask) - 1; + + ret = max11410_configure_channel(st, &indio_dev->channels[scan_ch]); + if (ret) + return ret; + + /* Start continuous conversion. */ + return max11410_write_reg(st, MAX11410_REG_CONV_START, + MAX11410_CONV_TYPE_CONTINUOUS); +} + +static int max11410_buffer_predisable(struct iio_dev *indio_dev) +{ + struct max11410_state *st = iio_priv(indio_dev); + + /* Stop continuous conversion. */ + return max11410_write_reg(st, MAX11410_REG_CONV_START, + MAX11410_CONV_TYPE_SINGLE); +} + +static const struct iio_buffer_setup_ops max11410_buffer_ops = { + .postenable = &max11410_buffer_postenable, + .predisable = &max11410_buffer_predisable, + .validate_scan_mask = &iio_validate_scan_mask_onehot, +}; + +static const struct iio_trigger_ops max11410_trigger_ops = { + .validate_device = iio_trigger_validate_own_device, +}; + +static irqreturn_t max11410_interrupt(int irq, void *dev_id) +{ + struct iio_dev *indio_dev = dev_id; + struct max11410_state *st = iio_priv(indio_dev); + + if (iio_buffer_enabled(indio_dev)) + iio_trigger_poll_chained(st->trig); + else + complete(&st->completion); + + return IRQ_HANDLED; +}; + +static int max11410_parse_channels(struct max11410_state *st, + struct iio_dev *indio_dev) +{ + struct iio_chan_spec chanspec = chanspec_template; + struct device *dev = &st->spi_dev->dev; + struct max11410_channel_config *cfg; + struct iio_chan_spec *channels; + struct fwnode_handle *child; + u32 reference, sig_path; + const char *node_name; + u32 inputs[2], scale; + unsigned int num_ch; + int chan_idx = 0; + int ret, i; + + num_ch = device_get_child_node_count(dev); + if (num_ch == 0) + return dev_err_probe(&indio_dev->dev, -ENODEV, + "FW has no channels defined\n"); + + /* Reserve space for soft timestamp channel */ + num_ch++; + channels = devm_kcalloc(dev, num_ch, sizeof(*channels), GFP_KERNEL); + if (!channels) + return -ENOMEM; + + st->channels = devm_kcalloc(dev, num_ch, sizeof(*st->channels), + GFP_KERNEL); + if (!st->channels) + return -ENOMEM; + + device_for_each_child_node(dev, child) { + node_name = fwnode_get_name(child); + if (fwnode_property_present(child, "diff-channels")) { + ret = fwnode_property_read_u32_array(child, + "diff-channels", + inputs, + ARRAY_SIZE(inputs)); + + chanspec.differential = 1; + } else { + ret = fwnode_property_read_u32(child, "reg", &inputs[0]); + + inputs[1] = 0; + chanspec.differential = 0; + } + if (ret) { + fwnode_handle_put(child); + return ret; + } + + if (inputs[0] > MAX11410_CHANNEL_INDEX_MAX || + inputs[1] > MAX11410_CHANNEL_INDEX_MAX) { + fwnode_handle_put(child); + return dev_err_probe(&indio_dev->dev, -EINVAL, + "Invalid channel index for %s, should be less than %d\n", + node_name, + MAX11410_CHANNEL_INDEX_MAX + 1); + } + + cfg = &st->channels[chan_idx]; + + reference = MAX11410_REFSEL_AVDD_AGND; + fwnode_property_read_u32(child, "adi,reference", &reference); + if (reference > MAX11410_REFSEL_MAX) { + fwnode_handle_put(child); + return dev_err_probe(&indio_dev->dev, -EINVAL, + "Invalid adi,reference value for %s, should be less than %d.\n", + node_name, MAX11410_REFSEL_MAX + 1); + } + + if (!max11410_get_vrefp(st, reference) || + (!max11410_get_vrefn(st, reference) && reference <= 2)) { + fwnode_handle_put(child); + return dev_err_probe(&indio_dev->dev, -EINVAL, + "Invalid VREF configuration for %s, either specify corresponding VREF regulators or change adi,reference property.\n", + node_name); + } + + sig_path = MAX11410_PGA_SIG_PATH_BUFFERED; + fwnode_property_read_u32(child, "adi,input-mode", &sig_path); + if (sig_path > MAX11410_SIG_PATH_MAX) { + fwnode_handle_put(child); + return dev_err_probe(&indio_dev->dev, -EINVAL, + "Invalid adi,input-mode value for %s, should be less than %d.\n", + node_name, MAX11410_SIG_PATH_MAX + 1); + } + + fwnode_property_read_u32(child, "settling-time-us", + &cfg->settling_time_us); + cfg->bipolar = fwnode_property_read_bool(child, "bipolar"); + cfg->buffered_vrefp = fwnode_property_read_bool(child, "adi,buffered-vrefp"); + cfg->buffered_vrefn = fwnode_property_read_bool(child, "adi,buffered-vrefn"); + cfg->refsel = reference; + cfg->sig_path = sig_path; + cfg->gain = 0; + + /* Enable scale_available property if input mode is PGA */ + if (sig_path == MAX11410_PGA_SIG_PATH_PGA) { + __set_bit(IIO_CHAN_INFO_SCALE, + &chanspec.info_mask_separate_available); + cfg->scale_avail = devm_kcalloc(dev, MAX11410_SCALE_AVAIL_SIZE * 2, + sizeof(*cfg->scale_avail), + GFP_KERNEL); + if (!cfg->scale_avail) { + fwnode_handle_put(child); + return -ENOMEM; + } + + scale = max11410_get_scale(st, *cfg); + for (i = 0; i < MAX11410_SCALE_AVAIL_SIZE; i++) { + cfg->scale_avail[2 * i] = scale >> i; + cfg->scale_avail[2 * i + 1] = chanspec.scan_type.realbits; + } + } else { + __clear_bit(IIO_CHAN_INFO_SCALE, + &chanspec.info_mask_separate_available); + } + + chanspec.address = chan_idx; + chanspec.scan_index = chan_idx; + chanspec.channel = inputs[0]; + chanspec.channel2 = inputs[1]; + + channels[chan_idx] = chanspec; + chan_idx++; + } + + channels[chan_idx] = (struct iio_chan_spec)IIO_CHAN_SOFT_TIMESTAMP(chan_idx); + + indio_dev->num_channels = chan_idx + 1; + indio_dev->channels = channels; + + return 0; +} + +static void max11410_disable_reg(void *reg) +{ + regulator_disable(reg); +} + +static int max11410_init_vref(struct device *dev, + struct regulator **vref, + const char *id) +{ + struct regulator *reg; + int ret; + + reg = devm_regulator_get_optional(dev, id); + if (PTR_ERR(reg) == -ENODEV) { + *vref = NULL; + return 0; + } else if (IS_ERR(reg)) { + return PTR_ERR(reg); + } + ret = regulator_enable(reg); + if (ret) + return dev_err_probe(dev, ret, + "Failed to enable regulator %s\n", id); + + *vref = reg; + return devm_add_action_or_reset(dev, max11410_disable_reg, reg); +} + +static int max11410_calibrate(struct max11410_state *st, u32 cal_type) +{ + int ret, val; + + ret = max11410_write_reg(st, MAX11410_REG_CAL_START, cal_type); + if (ret) + return ret; + + /* Wait for status register Calibration Ready flag */ + return read_poll_timeout(max11410_read_reg, ret, + ret || (val & MAX11410_STATUS_CAL_READY_BIT), + 50000, MAX11410_CALIB_TIMEOUT_MS * 1000, true, + st, MAX11410_REG_STATUS, &val); +} + +static int max11410_self_calibrate(struct max11410_state *st) +{ + int ret, i; + + ret = regmap_write_bits(st->regmap, MAX11410_REG_FILTER, + MAX11410_FILTER_RATE_MASK, + FIELD_PREP(MAX11410_FILTER_RATE_MASK, + MAX11410_FILTER_RATE_MAX)); + if (ret) + return ret; + + ret = max11410_calibrate(st, MAX11410_CAL_START_SELF); + if (ret) + return ret; + + ret = regmap_write_bits(st->regmap, MAX11410_REG_PGA, + MAX11410_PGA_SIG_PATH_MASK, + FIELD_PREP(MAX11410_PGA_SIG_PATH_MASK, + MAX11410_PGA_SIG_PATH_PGA)); + if (ret) + return ret; + + /* PGA calibrations */ + for (i = 1; i < 8; ++i) { + ret = regmap_write_bits(st->regmap, MAX11410_REG_PGA, + MAX11410_PGA_GAIN_MASK, i); + if (ret) + return ret; + + ret = max11410_calibrate(st, MAX11410_CAL_START_PGA); + if (ret) + return ret; + } + + /* Cleanup */ + ret = regmap_write_bits(st->regmap, MAX11410_REG_PGA, + MAX11410_PGA_GAIN_MASK, 0); + if (ret) + return ret; + + ret = regmap_write_bits(st->regmap, MAX11410_REG_FILTER, + MAX11410_FILTER_RATE_MASK, 0); + if (ret) + return ret; + + return regmap_write_bits(st->regmap, MAX11410_REG_PGA, + MAX11410_PGA_SIG_PATH_MASK, + FIELD_PREP(MAX11410_PGA_SIG_PATH_MASK, + MAX11410_PGA_SIG_PATH_BUFFERED)); +} + +static int max11410_probe(struct spi_device *spi) +{ + const char *vrefp_regs[] = { "vref0p", "vref1p", "vref2p" }; + const char *vrefn_regs[] = { "vref0n", "vref1n", "vref2n" }; + struct device *dev = &spi->dev; + struct max11410_state *st; + struct iio_dev *indio_dev; + int ret, irqs[2]; + int i; + + indio_dev = devm_iio_device_alloc(dev, sizeof(*st)); + if (!indio_dev) + return -ENOMEM; + + st = iio_priv(indio_dev); + st->spi_dev = spi; + init_completion(&st->completion); + mutex_init(&st->lock); + + indio_dev->name = "max11410"; + indio_dev->modes = INDIO_DIRECT_MODE; + indio_dev->info = &max11410_info; + + st->regmap = devm_regmap_init_spi(spi, ®map_config); + if (IS_ERR(st->regmap)) + return dev_err_probe(dev, PTR_ERR(st->regmap), + "regmap initialization failed\n"); + + ret = max11410_init_vref(dev, &st->avdd, "avdd"); + if (ret) + return ret; + + for (i = 0; i < ARRAY_SIZE(vrefp_regs); i++) { + ret = max11410_init_vref(dev, &st->vrefp[i], vrefp_regs[i]); + if (ret) + return ret; + + ret = max11410_init_vref(dev, &st->vrefn[i], vrefn_regs[i]); + if (ret) + return ret; + } + + /* + * Regulators must be configured before parsing channels for + * validating "adi,reference" property of each channel. + */ + ret = max11410_parse_channels(st, indio_dev); + if (ret) + return ret; + + irqs[0] = fwnode_irq_get_byname(dev_fwnode(dev), "gpio0"); + irqs[1] = fwnode_irq_get_byname(dev_fwnode(dev), "gpio1"); + + if (irqs[0] > 0) { + st->irq = irqs[0]; + ret = regmap_write(st->regmap, MAX11410_REG_GPIO_CTRL(0), + MAX11410_GPIO_INTRB); + } else if (irqs[1] > 0) { + st->irq = irqs[1]; + ret = regmap_write(st->regmap, MAX11410_REG_GPIO_CTRL(1), + MAX11410_GPIO_INTRB); + } else if (spi->irq > 0) { + return dev_err_probe(dev, -ENODEV, + "no interrupt name specified"); + } + + if (ret) + return ret; + + ret = regmap_set_bits(st->regmap, MAX11410_REG_CTRL, + MAX11410_CTRL_FORMAT_BIT); + if (ret) + return ret; + + ret = devm_iio_triggered_buffer_setup(dev, indio_dev, NULL, + &max11410_trigger_handler, + &max11410_buffer_ops); + if (ret) + return ret; + + if (st->irq > 0) { + st->trig = devm_iio_trigger_alloc(dev, "%s-dev%d", + indio_dev->name, + iio_device_id(indio_dev)); + if (!st->trig) + return -ENOMEM; + + st->trig->ops = &max11410_trigger_ops; + ret = devm_iio_trigger_register(dev, st->trig); + if (ret) + return ret; + + ret = devm_request_threaded_irq(dev, st->irq, NULL, + &max11410_interrupt, + IRQF_ONESHOT, "max11410", + indio_dev); + if (ret) + return ret; + } + + ret = max11410_self_calibrate(st); + if (ret) + return dev_err_probe(dev, ret, + "cannot perform device self calibration\n"); + + return devm_iio_device_register(dev, indio_dev); +} + +static const struct of_device_id max11410_spi_of_id[] = { + { .compatible = "adi,max11410" }, + { } +}; +MODULE_DEVICE_TABLE(of, max11410_spi_of_id); + +static const struct spi_device_id max11410_id[] = { + { "max11410" }, + { } +}; +MODULE_DEVICE_TABLE(spi, max11410_id); + +static struct spi_driver max11410_driver = { + .driver = { + .name = "max11410", + .of_match_table = max11410_spi_of_id, + }, + .probe = max11410_probe, + .id_table = max11410_id, +}; +module_spi_driver(max11410_driver); + +MODULE_AUTHOR("David Jung "); +MODULE_AUTHOR("Ibrahim Tilki "); +MODULE_DESCRIPTION("Analog Devices MAX11410 ADC"); +MODULE_LICENSE("GPL"); -- cgit v1.2.3 From c1404d1b659fe3d7d13bdbd59e5161ab508dc101 Mon Sep 17 00:00:00 2001 From: ChiaEn Wu Date: Tue, 11 Oct 2022 12:05:45 +0800 Subject: iio: adc: mt6370: Add MediaTek MT6370 support MediaTek MT6370 is a SubPMIC consisting of a single cell battery charger with ADC monitoring, RGB LEDs, dual channel flashlight, WLED backlight driver, display bias voltage supply, one general purpose LDO, and the USB Type-C & PD controller complies with the latest USB Type-C and PD standards. Add support for the MT6370 ADC driver for system monitoring, including charger current, voltage, and temperature. Reviewed-by: AngeloGioacchino Del Regno Reviewed-by: Andy Shevchenko Signed-off-by: ChiaEn Wu Link: https://lore.kernel.org/r/81ec58ae89030e48508d6810396de2679c40d26c.1665488982.git.chiaen_wu@richtek.com Signed-off-by: Jonathan Cameron --- drivers/iio/adc/Kconfig | 12 ++ drivers/iio/adc/Makefile | 1 + drivers/iio/adc/mt6370-adc.c | 305 +++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 318 insertions(+) create mode 100644 drivers/iio/adc/mt6370-adc.c (limited to 'drivers/iio') diff --git a/drivers/iio/adc/Kconfig b/drivers/iio/adc/Kconfig index 544986fd456d..5386d862def9 100644 --- a/drivers/iio/adc/Kconfig +++ b/drivers/iio/adc/Kconfig @@ -765,6 +765,18 @@ config MEDIATEK_MT6360_ADC is used in smartphones and tablets and supports a 11 channel general purpose ADC. +config MEDIATEK_MT6370_ADC + tristate "MediaTek MT6370 ADC driver" + depends on MFD_MT6370 + help + Say yes here to enable MediaTek MT6370 ADC support. + + This ADC driver provides 9 channels for system monitoring (charger + current, voltage, and temperature). + + This driver can also be built as a module. If so, the module + will be called "mt6370-adc". + config MEDIATEK_MT6577_AUXADC tristate "MediaTek AUXADC driver" depends on ARCH_MEDIATEK || COMPILE_TEST diff --git a/drivers/iio/adc/Makefile b/drivers/iio/adc/Makefile index 4d803413425c..1571e891828e 100644 --- a/drivers/iio/adc/Makefile +++ b/drivers/iio/adc/Makefile @@ -70,6 +70,7 @@ obj-$(CONFIG_MCP320X) += mcp320x.o obj-$(CONFIG_MCP3422) += mcp3422.o obj-$(CONFIG_MCP3911) += mcp3911.o obj-$(CONFIG_MEDIATEK_MT6360_ADC) += mt6360-adc.o +obj-$(CONFIG_MEDIATEK_MT6370_ADC) += mt6370-adc.o obj-$(CONFIG_MEDIATEK_MT6577_AUXADC) += mt6577_auxadc.o obj-$(CONFIG_MEN_Z188_ADC) += men_z188_adc.o obj-$(CONFIG_MESON_SARADC) += meson_saradc.o diff --git a/drivers/iio/adc/mt6370-adc.c b/drivers/iio/adc/mt6370-adc.c new file mode 100644 index 000000000000..bc62e5a9d50d --- /dev/null +++ b/drivers/iio/adc/mt6370-adc.c @@ -0,0 +1,305 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (C) 2022 Richtek Technology Corp. + * + * Author: ChiaEn Wu + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#define MT6370_REG_CHG_CTRL3 0x113 +#define MT6370_REG_CHG_CTRL7 0x117 +#define MT6370_REG_CHG_ADC 0x121 +#define MT6370_REG_ADC_DATA_H 0x14C + +#define MT6370_ADC_START_MASK BIT(0) +#define MT6370_ADC_IN_SEL_MASK GENMASK(7, 4) +#define MT6370_AICR_ICHG_MASK GENMASK(7, 2) + +#define MT6370_AICR_100_mA 0x0 +#define MT6370_AICR_150_mA 0x1 +#define MT6370_AICR_200_mA 0x2 +#define MT6370_AICR_250_mA 0x3 +#define MT6370_AICR_300_mA 0x4 +#define MT6370_AICR_350_mA 0x5 + +#define MT6370_ICHG_100_mA 0x0 +#define MT6370_ICHG_200_mA 0x1 +#define MT6370_ICHG_300_mA 0x2 +#define MT6370_ICHG_400_mA 0x3 +#define MT6370_ICHG_500_mA 0x4 +#define MT6370_ICHG_600_mA 0x5 +#define MT6370_ICHG_700_mA 0x6 +#define MT6370_ICHG_800_mA 0x7 + +#define ADC_CONV_TIME_MS 35 +#define ADC_CONV_POLLING_TIME_US 1000 + +struct mt6370_adc_data { + struct device *dev; + struct regmap *regmap; + /* + * This mutex lock is for preventing the different ADC channels + * from being read at the same time. + */ + struct mutex adc_lock; +}; + +static int mt6370_adc_read_channel(struct mt6370_adc_data *priv, int chan, + unsigned long addr, int *val) +{ + unsigned int reg_val; + __be16 be_val; + int ret; + + mutex_lock(&priv->adc_lock); + + reg_val = MT6370_ADC_START_MASK | + FIELD_PREP(MT6370_ADC_IN_SEL_MASK, addr); + ret = regmap_write(priv->regmap, MT6370_REG_CHG_ADC, reg_val); + if (ret) + goto adc_unlock; + + msleep(ADC_CONV_TIME_MS); + + ret = regmap_read_poll_timeout(priv->regmap, + MT6370_REG_CHG_ADC, reg_val, + !(reg_val & MT6370_ADC_START_MASK), + ADC_CONV_POLLING_TIME_US, + ADC_CONV_TIME_MS * MILLI * 3); + if (ret) { + dev_err(priv->dev, "Failed to read ADC register (%d)\n", ret); + goto adc_unlock; + } + + ret = regmap_raw_read(priv->regmap, MT6370_REG_ADC_DATA_H, + &be_val, sizeof(be_val)); + if (ret) + goto adc_unlock; + + *val = be16_to_cpu(be_val); + ret = IIO_VAL_INT; + +adc_unlock: + mutex_unlock(&priv->adc_lock); + + return ret; +} + +static int mt6370_adc_read_scale(struct mt6370_adc_data *priv, + int chan, int *val1, int *val2) +{ + unsigned int reg_val; + int ret; + + switch (chan) { + case MT6370_CHAN_VBAT: + case MT6370_CHAN_VSYS: + case MT6370_CHAN_CHG_VDDP: + *val1 = 5; + return IIO_VAL_INT; + case MT6370_CHAN_IBUS: + ret = regmap_read(priv->regmap, MT6370_REG_CHG_CTRL3, ®_val); + if (ret) + return ret; + + reg_val = FIELD_GET(MT6370_AICR_ICHG_MASK, reg_val); + switch (reg_val) { + case MT6370_AICR_100_mA: + case MT6370_AICR_150_mA: + case MT6370_AICR_200_mA: + case MT6370_AICR_250_mA: + case MT6370_AICR_300_mA: + case MT6370_AICR_350_mA: + *val1 = 3350; + break; + default: + *val1 = 5000; + break; + } + + *val2 = 100; + + return IIO_VAL_FRACTIONAL; + case MT6370_CHAN_IBAT: + ret = regmap_read(priv->regmap, MT6370_REG_CHG_CTRL7, ®_val); + if (ret) + return ret; + + reg_val = FIELD_GET(MT6370_AICR_ICHG_MASK, reg_val); + switch (reg_val) { + case MT6370_ICHG_100_mA: + case MT6370_ICHG_200_mA: + case MT6370_ICHG_300_mA: + case MT6370_ICHG_400_mA: + *val1 = 2375; + break; + case MT6370_ICHG_500_mA: + case MT6370_ICHG_600_mA: + case MT6370_ICHG_700_mA: + case MT6370_ICHG_800_mA: + *val1 = 2680; + break; + default: + *val1 = 5000; + break; + } + + *val2 = 100; + + return IIO_VAL_FRACTIONAL; + case MT6370_CHAN_VBUSDIV5: + *val1 = 25; + return IIO_VAL_INT; + case MT6370_CHAN_VBUSDIV2: + *val1 = 10; + return IIO_VAL_INT; + case MT6370_CHAN_TS_BAT: + *val1 = 25; + *val2 = 10000; + return IIO_VAL_FRACTIONAL; + case MT6370_CHAN_TEMP_JC: + *val1 = 2000; + return IIO_VAL_INT; + default: + return -EINVAL; + } +} + +static int mt6370_adc_read_offset(struct mt6370_adc_data *priv, + int chan, int *val) +{ + *val = -20; + + return IIO_VAL_INT; +} + +static int mt6370_adc_read_raw(struct iio_dev *iio_dev, + const struct iio_chan_spec *chan, + int *val, int *val2, long mask) +{ + struct mt6370_adc_data *priv = iio_priv(iio_dev); + + switch (mask) { + case IIO_CHAN_INFO_RAW: + return mt6370_adc_read_channel(priv, chan->channel, + chan->address, val); + case IIO_CHAN_INFO_SCALE: + return mt6370_adc_read_scale(priv, chan->channel, val, val2); + case IIO_CHAN_INFO_OFFSET: + return mt6370_adc_read_offset(priv, chan->channel, val); + default: + return -EINVAL; + } +} + +static const char * const mt6370_channel_labels[MT6370_CHAN_MAX] = { + [MT6370_CHAN_VBUSDIV5] = "vbusdiv5", + [MT6370_CHAN_VBUSDIV2] = "vbusdiv2", + [MT6370_CHAN_VSYS] = "vsys", + [MT6370_CHAN_VBAT] = "vbat", + [MT6370_CHAN_TS_BAT] = "ts_bat", + [MT6370_CHAN_IBUS] = "ibus", + [MT6370_CHAN_IBAT] = "ibat", + [MT6370_CHAN_CHG_VDDP] = "chg_vddp", + [MT6370_CHAN_TEMP_JC] = "temp_jc", +}; + +static int mt6370_adc_read_label(struct iio_dev *iio_dev, + struct iio_chan_spec const *chan, char *label) +{ + return sysfs_emit(label, "%s\n", mt6370_channel_labels[chan->channel]); +} + +static const struct iio_info mt6370_adc_iio_info = { + .read_raw = mt6370_adc_read_raw, + .read_label = mt6370_adc_read_label, +}; + +#define MT6370_ADC_CHAN(_idx, _type, _addr, _extra_info) { \ + .type = _type, \ + .channel = MT6370_CHAN_##_idx, \ + .address = _addr, \ + .scan_index = MT6370_CHAN_##_idx, \ + .indexed = 1, \ + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | \ + BIT(IIO_CHAN_INFO_SCALE) | \ + _extra_info, \ +} + +static const struct iio_chan_spec mt6370_adc_channels[] = { + MT6370_ADC_CHAN(VBUSDIV5, IIO_VOLTAGE, 1, 0), + MT6370_ADC_CHAN(VBUSDIV2, IIO_VOLTAGE, 2, 0), + MT6370_ADC_CHAN(VSYS, IIO_VOLTAGE, 3, 0), + MT6370_ADC_CHAN(VBAT, IIO_VOLTAGE, 4, 0), + MT6370_ADC_CHAN(TS_BAT, IIO_VOLTAGE, 6, 0), + MT6370_ADC_CHAN(IBUS, IIO_CURRENT, 8, 0), + MT6370_ADC_CHAN(IBAT, IIO_CURRENT, 9, 0), + MT6370_ADC_CHAN(CHG_VDDP, IIO_VOLTAGE, 11, 0), + MT6370_ADC_CHAN(TEMP_JC, IIO_TEMP, 12, BIT(IIO_CHAN_INFO_OFFSET)), +}; + +static int mt6370_adc_probe(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + struct mt6370_adc_data *priv; + struct iio_dev *indio_dev; + struct regmap *regmap; + int ret; + + regmap = dev_get_regmap(pdev->dev.parent, NULL); + if (!regmap) + return dev_err_probe(dev, -ENODEV, "Failed to get regmap\n"); + + indio_dev = devm_iio_device_alloc(dev, sizeof(*priv)); + if (!indio_dev) + return -ENOMEM; + + priv = iio_priv(indio_dev); + priv->dev = dev; + priv->regmap = regmap; + mutex_init(&priv->adc_lock); + + ret = regmap_write(priv->regmap, MT6370_REG_CHG_ADC, 0); + if (ret) + return dev_err_probe(dev, ret, "Failed to reset ADC\n"); + + indio_dev->name = "mt6370-adc"; + indio_dev->info = &mt6370_adc_iio_info; + indio_dev->modes = INDIO_DIRECT_MODE; + indio_dev->channels = mt6370_adc_channels; + indio_dev->num_channels = ARRAY_SIZE(mt6370_adc_channels); + + return devm_iio_device_register(dev, indio_dev); +} + +static const struct of_device_id mt6370_adc_of_id[] = { + { .compatible = "mediatek,mt6370-adc", }, + {} +}; +MODULE_DEVICE_TABLE(of, mt6370_adc_of_id); + +static struct platform_driver mt6370_adc_driver = { + .driver = { + .name = "mt6370-adc", + .of_match_table = mt6370_adc_of_id, + }, + .probe = mt6370_adc_probe, +}; +module_platform_driver(mt6370_adc_driver); + +MODULE_AUTHOR("ChiaEn Wu "); +MODULE_DESCRIPTION("MT6370 ADC Driver"); +MODULE_LICENSE("GPL v2"); -- cgit v1.2.3 From cd83c5c10036a2a156d725725daf3409832c8a24 Mon Sep 17 00:00:00 2001 From: Lorenzo Bianconi Date: Mon, 10 Oct 2022 13:07:26 +0200 Subject: iio: imu: st_lsm6dsx: introduce st_lsm6dsx_device_set_enable routine Introduce st_lsm6dsx_device_set_enable utility routine and remove duplicated code used to enable/disable sensors Signed-off-by: Lorenzo Bianconi Link: https://lore.kernel.org/r/e3fbe5d4a3bed41130908669f745f78c8505cf47.1665399959.git.lorenzo@kernel.org Signed-off-by: Jonathan Cameron --- drivers/iio/imu/st_lsm6dsx/st_lsm6dsx.h | 11 +++++++++++ drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_buffer.c | 14 +++----------- drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c | 14 ++------------ 3 files changed, 16 insertions(+), 23 deletions(-) (limited to 'drivers/iio') diff --git a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx.h b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx.h index 6b57d47be69e..d3a4e21bc114 100644 --- a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx.h +++ b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx.h @@ -509,6 +509,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..48fe6a45671b 100644 --- a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_buffer.c +++ b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_buffer.c @@ -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..6af2e905c161 100644 --- a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c +++ b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c @@ -2317,12 +2317,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 +2348,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; -- cgit v1.2.3 From cf0fb80ae1675179620d964d629b43ca57219ced Mon Sep 17 00:00:00 2001 From: Olivier Moysan Date: Wed, 12 Oct 2022 16:22:00 +0200 Subject: iio: adc: stm32-adc: add stm32mp13 support Add STM32 ADC support for STM32MP13x SOCs family. On STM32MP13x, each ADC peripheral has a single ADC block. These ADC peripherals, ADC1 and ADC2, are fully independent. This introduces changes in common registers handling. Some features such as boost mode, channel preselection and linear calibration are not supported by the STM32MP13x ADC. Add diversity management for these features. The STM32MP13x ADC introduces registers and bitfield variants on existing features such as calibration factors and internal channels. Add register diversity management. Add also support for new internal channels VDDCPU and VDDQ_DDR. Signed-off-by: Olivier Moysan Reviewed-by: Fabrice Gasnier Reviewed-by: Andy Shevchenko Link: https://lore.kernel.org/r/20221012142205.13041-4-olivier.moysan@foss.st.com Signed-off-by: Jonathan Cameron --- drivers/iio/adc/stm32-adc-core.c | 30 +++++- drivers/iio/adc/stm32-adc-core.h | 30 ++++++ drivers/iio/adc/stm32-adc.c | 210 ++++++++++++++++++++++++++++++++++----- 3 files changed, 239 insertions(+), 31 deletions(-) (limited to 'drivers/iio') diff --git a/drivers/iio/adc/stm32-adc-core.c b/drivers/iio/adc/stm32-adc-core.c index 81d5db91c67b..48f02dcc81c1 100644 --- a/drivers/iio/adc/stm32-adc-core.c +++ b/drivers/iio/adc/stm32-adc-core.c @@ -22,6 +22,7 @@ #include #include #include +#include #include "stm32-adc-core.h" @@ -306,8 +307,8 @@ out: static const struct stm32_adc_common_regs stm32f4_adc_common_regs = { .csr = STM32F4_ADC_CSR, .ccr = STM32F4_ADC_CCR, - .eoc_msk = { STM32F4_EOC1, STM32F4_EOC2, STM32F4_EOC3}, - .ovr_msk = { STM32F4_OVR1, STM32F4_OVR2, STM32F4_OVR3}, + .eoc_msk = { STM32F4_EOC1, STM32F4_EOC2, STM32F4_EOC3 }, + .ovr_msk = { STM32F4_OVR1, STM32F4_OVR2, STM32F4_OVR3 }, .ier = STM32F4_ADC_CR1, .eocie_msk = STM32F4_EOCIE, }; @@ -316,8 +317,18 @@ static const struct stm32_adc_common_regs stm32f4_adc_common_regs = { static const struct stm32_adc_common_regs stm32h7_adc_common_regs = { .csr = STM32H7_ADC_CSR, .ccr = STM32H7_ADC_CCR, - .eoc_msk = { STM32H7_EOC_MST, STM32H7_EOC_SLV}, - .ovr_msk = { STM32H7_OVR_MST, STM32H7_OVR_SLV}, + .eoc_msk = { STM32H7_EOC_MST, STM32H7_EOC_SLV }, + .ovr_msk = { STM32H7_OVR_MST, STM32H7_OVR_SLV }, + .ier = STM32H7_ADC_IER, + .eocie_msk = STM32H7_EOCIE, +}; + +/* STM32MP13 common registers definitions */ +static const struct stm32_adc_common_regs stm32mp13_adc_common_regs = { + .csr = STM32H7_ADC_CSR, + .ccr = STM32H7_ADC_CCR, + .eoc_msk = { STM32H7_EOC_MST }, + .ovr_msk = { STM32H7_OVR_MST }, .ier = STM32H7_ADC_IER, .eocie_msk = STM32H7_EOCIE, }; @@ -868,6 +879,14 @@ static const struct stm32_adc_priv_cfg stm32mp1_adc_priv_cfg = { .num_irqs = 2, }; +static const struct stm32_adc_priv_cfg stm32mp13_adc_priv_cfg = { + .regs = &stm32mp13_adc_common_regs, + .clk_sel = stm32h7_adc_clk_sel, + .max_clk_rate_hz = 75 * HZ_PER_MHZ, + .ipid = STM32MP13_IPIDR_NUMBER, + .num_irqs = 1, +}; + static const struct of_device_id stm32_adc_of_match[] = { { .compatible = "st,stm32f4-adc-core", @@ -878,6 +897,9 @@ static const struct of_device_id stm32_adc_of_match[] = { }, { .compatible = "st,stm32mp1-adc-core", .data = (void *)&stm32mp1_adc_priv_cfg + }, { + .compatible = "st,stm32mp13-adc-core", + .data = (void *)&stm32mp13_adc_priv_cfg }, { }, }; diff --git a/drivers/iio/adc/stm32-adc-core.h b/drivers/iio/adc/stm32-adc-core.h index 2118ef63843d..9d6dfa1c03fa 100644 --- a/drivers/iio/adc/stm32-adc-core.h +++ b/drivers/iio/adc/stm32-adc-core.h @@ -112,6 +112,11 @@ #define STM32MP1_ADC_IPDR 0x3F8 #define STM32MP1_ADC_SIDR 0x3FC +/* STM32MP13 - Registers for each ADC instance */ +#define STM32MP13_ADC_DIFSEL 0xB0 +#define STM32MP13_ADC_CALFACT 0xB4 +#define STM32MP13_ADC2_OR 0xC8 + /* STM32H7 - common registers for all ADC instances */ #define STM32H7_ADC_CSR (STM32_ADCX_COMN_OFFSET + 0x00) #define STM32H7_ADC_CCR (STM32_ADCX_COMN_OFFSET + 0x08) @@ -161,6 +166,9 @@ enum stm32h7_adc_dmngt { STM32H7_DMNGT_DMA_CIRC, /* DMA circular mode */ }; +/* STM32H7_ADC_DIFSEL - bit fields */ +#define STM32H7_DIFSEL_MASK GENMASK(19, 0) + /* STM32H7_ADC_CALFACT - bit fields */ #define STM32H7_CALFACT_D_SHIFT 16 #define STM32H7_CALFACT_D_MASK GENMASK(26, 16) @@ -210,7 +218,29 @@ enum stm32h7_adc_dmngt { /* STM32MP1_ADC_SIDR - bit fields */ #define STM32MP1_SIDR_MASK GENMASK(31, 0) +/* STM32MP13_ADC_CFGR specific bit fields */ +#define STM32MP13_DMAEN BIT(0) +#define STM32MP13_DMACFG BIT(1) +#define STM32MP13_DFSDMCFG BIT(2) +#define STM32MP13_RES_SHIFT 3 +#define STM32MP13_RES_MASK GENMASK(4, 3) + +/* STM32MP13_ADC_DIFSEL - bit fields */ +#define STM32MP13_DIFSEL_MASK GENMASK(18, 0) + +/* STM32MP13_ADC_CALFACT - bit fields */ +#define STM32MP13_CALFACT_D_SHIFT 16 +#define STM32MP13_CALFACT_D_MASK GENMASK(22, 16) +#define STM32MP13_CALFACT_S_SHIFT 0 +#define STM32MP13_CALFACT_S_MASK GENMASK(6, 0) + +/* STM32MP13_ADC2_OR - bit fields */ +#define STM32MP13_OP2 BIT(2) +#define STM32MP13_OP1 BIT(1) +#define STM32MP13_OP0 BIT(0) + #define STM32MP15_IPIDR_NUMBER 0x00110005 +#define STM32MP13_IPIDR_NUMBER 0x00110006 /** * struct stm32_adc_common - stm32 ADC driver common data (for all instances) diff --git a/drivers/iio/adc/stm32-adc.c b/drivers/iio/adc/stm32-adc.c index 3cda529f081d..d36c024526f2 100644 --- a/drivers/iio/adc/stm32-adc.c +++ b/drivers/iio/adc/stm32-adc.c @@ -82,6 +82,8 @@ enum stm32_adc_extsel { enum stm32_adc_int_ch { STM32_ADC_INT_CH_NONE = -1, STM32_ADC_INT_CH_VDDCORE, + STM32_ADC_INT_CH_VDDCPU, + STM32_ADC_INT_CH_VDDQ_DDR, STM32_ADC_INT_CH_VREFINT, STM32_ADC_INT_CH_VBAT, STM32_ADC_INT_CH_NB, @@ -99,6 +101,8 @@ struct stm32_adc_ic { static const struct stm32_adc_ic stm32_adc_ic[STM32_ADC_INT_CH_NB] = { { "vddcore", STM32_ADC_INT_CH_VDDCORE }, + { "vddcpu", STM32_ADC_INT_CH_VDDCPU }, + { "vddq_ddr", STM32_ADC_INT_CH_VDDQ_DDR }, { "vrefint", STM32_ADC_INT_CH_VREFINT }, { "vbat", STM32_ADC_INT_CH_VBAT }, }; @@ -160,9 +164,14 @@ struct stm32_adc_vrefint { * @exten: trigger control register & bitfield * @extsel: trigger selection register & bitfield * @res: resolution selection register & bitfield + * @difsel: differential mode selection register & bitfield + * @calfact_s: single-ended calibration factors register & bitfield + * @calfact_d: differential calibration factors register & bitfield * @smpr: smpr1 & smpr2 registers offset array * @smp_bits: smpr1 & smpr2 index and bitfields - * @or_vdd: option register & vddcore bitfield + * @or_vddcore: option register & vddcore bitfield + * @or_vddcpu: option register & vddcpu bitfield + * @or_vddq_ddr: option register & vddq_ddr bitfield * @ccr_vbat: common register & vbat bitfield * @ccr_vref: common register & vrefint bitfield */ @@ -176,9 +185,14 @@ struct stm32_adc_regspec { const struct stm32_adc_regs exten; const struct stm32_adc_regs extsel; const struct stm32_adc_regs res; + const struct stm32_adc_regs difsel; + const struct stm32_adc_regs calfact_s; + const struct stm32_adc_regs calfact_d; const u32 smpr[2]; const struct stm32_adc_regs *smp_bits; - const struct stm32_adc_regs or_vdd; + const struct stm32_adc_regs or_vddcore; + const struct stm32_adc_regs or_vddcpu; + const struct stm32_adc_regs or_vddq_ddr; const struct stm32_adc_regs ccr_vbat; const struct stm32_adc_regs ccr_vref; }; @@ -192,6 +206,9 @@ struct stm32_adc; * @trigs: external trigger sources * @clk_required: clock is required * @has_vregready: vregready status flag presence + * @has_boostmode: boost mode support flag + * @has_linearcal: linear calibration support flag + * @has_presel: channel preselection support flag * @prepare: optional prepare routine (power-up, enable) * @start_conv: routine to start conversions * @stop_conv: routine to stop conversions @@ -206,6 +223,9 @@ struct stm32_adc_cfg { struct stm32_adc_trig_info *trigs; bool clk_required; bool has_vregready; + bool has_boostmode; + bool has_linearcal; + bool has_presel; int (*prepare)(struct iio_dev *); void (*start_conv)(struct iio_dev *, bool dma); void (*stop_conv)(struct iio_dev *); @@ -312,6 +332,13 @@ static const struct stm32_adc_info stm32h7_adc_info = { .num_res = ARRAY_SIZE(stm32h7_adc_resolutions), }; +/* stm32mp13 can have up to 19 channels */ +static const struct stm32_adc_info stm32mp13_adc_info = { + .max_channels = 19, + .resolutions = stm32f4_adc_resolutions, + .num_res = ARRAY_SIZE(stm32f4_adc_resolutions), +}; + /* * stm32f4_sq - describe regular sequence registers * - L: sequence len (register & bit field) @@ -497,10 +524,45 @@ static const struct stm32_adc_regspec stm32h7_adc_regspec = { .extsel = { STM32H7_ADC_CFGR, STM32H7_EXTSEL_MASK, STM32H7_EXTSEL_SHIFT }, .res = { STM32H7_ADC_CFGR, STM32H7_RES_MASK, STM32H7_RES_SHIFT }, + .difsel = { STM32H7_ADC_DIFSEL, STM32H7_DIFSEL_MASK}, + .calfact_s = { STM32H7_ADC_CALFACT, STM32H7_CALFACT_S_MASK, + STM32H7_CALFACT_S_SHIFT }, + .calfact_d = { STM32H7_ADC_CALFACT, STM32H7_CALFACT_D_MASK, + STM32H7_CALFACT_D_SHIFT }, .smpr = { STM32H7_ADC_SMPR1, STM32H7_ADC_SMPR2 }, .smp_bits = stm32h7_smp_bits, }; +/* STM32MP13 programmable sampling time (ADC clock cycles, rounded down) */ +static const unsigned int stm32mp13_adc_smp_cycles[STM32_ADC_MAX_SMP + 1] = { + 2, 6, 12, 24, 47, 92, 247, 640, +}; + +static const struct stm32_adc_regspec stm32mp13_adc_regspec = { + .dr = STM32H7_ADC_DR, + .ier_eoc = { STM32H7_ADC_IER, STM32H7_EOCIE }, + .ier_ovr = { STM32H7_ADC_IER, STM32H7_OVRIE }, + .isr_eoc = { STM32H7_ADC_ISR, STM32H7_EOC }, + .isr_ovr = { STM32H7_ADC_ISR, STM32H7_OVR }, + .sqr = stm32h7_sq, + .exten = { STM32H7_ADC_CFGR, STM32H7_EXTEN_MASK, STM32H7_EXTEN_SHIFT }, + .extsel = { STM32H7_ADC_CFGR, STM32H7_EXTSEL_MASK, + STM32H7_EXTSEL_SHIFT }, + .res = { STM32H7_ADC_CFGR, STM32MP13_RES_MASK, STM32MP13_RES_SHIFT }, + .difsel = { STM32MP13_ADC_DIFSEL, STM32MP13_DIFSEL_MASK}, + .calfact_s = { STM32MP13_ADC_CALFACT, STM32MP13_CALFACT_S_MASK, + STM32MP13_CALFACT_S_SHIFT }, + .calfact_d = { STM32MP13_ADC_CALFACT, STM32MP13_CALFACT_D_MASK, + STM32MP13_CALFACT_D_SHIFT }, + .smpr = { STM32H7_ADC_SMPR1, STM32H7_ADC_SMPR2 }, + .smp_bits = stm32h7_smp_bits, + .or_vddcore = { STM32MP13_ADC2_OR, STM32MP13_OP0 }, + .or_vddcpu = { STM32MP13_ADC2_OR, STM32MP13_OP1 }, + .or_vddq_ddr = { STM32MP13_ADC2_OR, STM32MP13_OP2 }, + .ccr_vbat = { STM32H7_ADC_CCR, STM32H7_VBATEN }, + .ccr_vref = { STM32H7_ADC_CCR, STM32H7_VREFEN }, +}; + static const struct stm32_adc_regspec stm32mp1_adc_regspec = { .dr = STM32H7_ADC_DR, .ier_eoc = { STM32H7_ADC_IER, STM32H7_EOCIE }, @@ -512,9 +574,14 @@ static const struct stm32_adc_regspec stm32mp1_adc_regspec = { .extsel = { STM32H7_ADC_CFGR, STM32H7_EXTSEL_MASK, STM32H7_EXTSEL_SHIFT }, .res = { STM32H7_ADC_CFGR, STM32H7_RES_MASK, STM32H7_RES_SHIFT }, + .difsel = { STM32H7_ADC_DIFSEL, STM32H7_DIFSEL_MASK}, + .calfact_s = { STM32H7_ADC_CALFACT, STM32H7_CALFACT_S_MASK, + STM32H7_CALFACT_S_SHIFT }, + .calfact_d = { STM32H7_ADC_CALFACT, STM32H7_CALFACT_D_MASK, + STM32H7_CALFACT_D_SHIFT }, .smpr = { STM32H7_ADC_SMPR1, STM32H7_ADC_SMPR2 }, .smp_bits = stm32h7_smp_bits, - .or_vdd = { STM32MP1_ADC2_OR, STM32MP1_VDDCOREEN }, + .or_vddcore = { STM32MP1_ADC2_OR, STM32MP1_VDDCOREEN }, .ccr_vbat = { STM32H7_ADC_CCR, STM32H7_VBATEN }, .ccr_vref = { STM32H7_ADC_CCR, STM32H7_VREFEN }, }; @@ -675,8 +742,18 @@ static void stm32_adc_int_ch_enable(struct iio_dev *indio_dev) switch (i) { case STM32_ADC_INT_CH_VDDCORE: dev_dbg(&indio_dev->dev, "Enable VDDCore\n"); - stm32_adc_set_bits(adc, adc->cfg->regs->or_vdd.reg, - adc->cfg->regs->or_vdd.mask); + stm32_adc_set_bits(adc, adc->cfg->regs->or_vddcore.reg, + adc->cfg->regs->or_vddcore.mask); + break; + case STM32_ADC_INT_CH_VDDCPU: + dev_dbg(&indio_dev->dev, "Enable VDDCPU\n"); + stm32_adc_set_bits(adc, adc->cfg->regs->or_vddcpu.reg, + adc->cfg->regs->or_vddcpu.mask); + break; + case STM32_ADC_INT_CH_VDDQ_DDR: + dev_dbg(&indio_dev->dev, "Enable VDDQ_DDR\n"); + stm32_adc_set_bits(adc, adc->cfg->regs->or_vddq_ddr.reg, + adc->cfg->regs->or_vddq_ddr.mask); break; case STM32_ADC_INT_CH_VREFINT: dev_dbg(&indio_dev->dev, "Enable VREFInt\n"); @@ -702,8 +779,16 @@ static void stm32_adc_int_ch_disable(struct stm32_adc *adc) switch (i) { case STM32_ADC_INT_CH_VDDCORE: - stm32_adc_clr_bits(adc, adc->cfg->regs->or_vdd.reg, - adc->cfg->regs->or_vdd.mask); + stm32_adc_clr_bits(adc, adc->cfg->regs->or_vddcore.reg, + adc->cfg->regs->or_vddcore.mask); + break; + case STM32_ADC_INT_CH_VDDCPU: + stm32_adc_clr_bits(adc, adc->cfg->regs->or_vddcpu.reg, + adc->cfg->regs->or_vddcpu.mask); + break; + case STM32_ADC_INT_CH_VDDQ_DDR: + stm32_adc_clr_bits(adc, adc->cfg->regs->or_vddq_ddr.reg, + adc->cfg->regs->or_vddq_ddr.mask); break; case STM32_ADC_INT_CH_VREFINT: stm32_adc_clr_bits_common(adc, adc->cfg->regs->ccr_vref.reg, @@ -801,6 +886,7 @@ static void stm32h7_adc_stop_conv(struct iio_dev *indio_dev) if (ret) dev_warn(&indio_dev->dev, "stop failed\n"); + /* STM32H7_DMNGT_MASK covers STM32MP13_DMAEN & STM32MP13_DMACFG */ stm32_adc_clr_bits(adc, STM32H7_ADC_CFGR, STM32H7_DMNGT_MASK); } @@ -811,6 +897,17 @@ static void stm32h7_adc_irq_clear(struct iio_dev *indio_dev, u32 msk) stm32_adc_set_bits(adc, adc->cfg->regs->isr_eoc.reg, msk); } +static void stm32mp13_adc_start_conv(struct iio_dev *indio_dev, bool dma) +{ + struct stm32_adc *adc = iio_priv(indio_dev); + + if (dma) + stm32_adc_set_bits(adc, STM32H7_ADC_CFGR, + STM32MP13_DMAEN | STM32MP13_DMACFG); + + stm32_adc_set_bits(adc, STM32H7_ADC_CR, STM32H7_ADSTART); +} + static int stm32h7_adc_exit_pwr_down(struct iio_dev *indio_dev) { struct stm32_adc *adc = iio_priv(indio_dev); @@ -821,7 +918,8 @@ static int stm32h7_adc_exit_pwr_down(struct iio_dev *indio_dev) stm32_adc_clr_bits(adc, STM32H7_ADC_CR, STM32H7_DEEPPWD); stm32_adc_set_bits(adc, STM32H7_ADC_CR, STM32H7_ADVREGEN); - if (adc->common->rate > STM32H7_BOOST_CLKRATE) + if (adc->cfg->has_boostmode && + adc->common->rate > STM32H7_BOOST_CLKRATE) stm32_adc_set_bits(adc, STM32H7_ADC_CR, STM32H7_BOOST); /* Wait for startup time */ @@ -843,7 +941,8 @@ static int stm32h7_adc_exit_pwr_down(struct iio_dev *indio_dev) static void stm32h7_adc_enter_pwr_down(struct stm32_adc *adc) { - stm32_adc_clr_bits(adc, STM32H7_ADC_CR, STM32H7_BOOST); + if (adc->cfg->has_boostmode) + stm32_adc_clr_bits(adc, STM32H7_ADC_CR, STM32H7_BOOST); /* Setting DEEPPWD disables ADC vreg and clears ADVREGEN */ stm32_adc_set_bits(adc, STM32H7_ADC_CR, STM32H7_DEEPPWD); @@ -901,6 +1000,9 @@ static int stm32h7_adc_read_selfcalib(struct iio_dev *indio_dev) int i, ret; u32 lincalrdyw_mask, val; + if (!adc->cfg->has_linearcal) + goto skip_linearcal; + /* Read linearity calibration */ lincalrdyw_mask = STM32H7_LINCALRDYW6; for (i = STM32H7_LINCALFACT_NUM - 1; i >= 0; i--) { @@ -923,12 +1025,13 @@ static int stm32h7_adc_read_selfcalib(struct iio_dev *indio_dev) lincalrdyw_mask >>= 1; } +skip_linearcal: /* Read offset calibration */ - val = stm32_adc_readl(adc, STM32H7_ADC_CALFACT); - adc->cal.calfact_s = (val & STM32H7_CALFACT_S_MASK); - adc->cal.calfact_s >>= STM32H7_CALFACT_S_SHIFT; - adc->cal.calfact_d = (val & STM32H7_CALFACT_D_MASK); - adc->cal.calfact_d >>= STM32H7_CALFACT_D_SHIFT; + val = stm32_adc_readl(adc, adc->cfg->regs->calfact_s.reg); + adc->cal.calfact_s = (val & adc->cfg->regs->calfact_s.mask); + adc->cal.calfact_s >>= adc->cfg->regs->calfact_s.shift; + adc->cal.calfact_d = (val & adc->cfg->regs->calfact_d.mask); + adc->cal.calfact_d >>= adc->cfg->regs->calfact_d.shift; adc->cal.calibrated = true; return 0; @@ -945,9 +1048,12 @@ static int stm32h7_adc_restore_selfcalib(struct iio_dev *indio_dev) int i, ret; u32 lincalrdyw_mask, val; - val = (adc->cal.calfact_s << STM32H7_CALFACT_S_SHIFT) | - (adc->cal.calfact_d << STM32H7_CALFACT_D_SHIFT); - stm32_adc_writel(adc, STM32H7_ADC_CALFACT, val); + val = (adc->cal.calfact_s << adc->cfg->regs->calfact_s.shift) | + (adc->cal.calfact_d << adc->cfg->regs->calfact_d.shift); + stm32_adc_writel(adc, adc->cfg->regs->calfact_s.reg, val); + + if (!adc->cfg->has_linearcal) + return 0; lincalrdyw_mask = STM32H7_LINCALRDYW6; for (i = STM32H7_LINCALFACT_NUM - 1; i >= 0; i--) { @@ -1016,11 +1122,14 @@ static int stm32h7_adc_selfcalib(struct iio_dev *indio_dev) { struct stm32_adc *adc = iio_priv(indio_dev); int ret; + u32 msk = STM32H7_ADCALDIF; u32 val; if (adc->cal.calibrated) return true; + if (adc->cfg->has_linearcal) + msk |= STM32H7_ADCALLIN; /* ADC must be disabled for calibration */ stm32h7_adc_disable(indio_dev); @@ -1029,8 +1138,7 @@ static int stm32h7_adc_selfcalib(struct iio_dev *indio_dev) * - Offset calibration for single ended inputs * - No linearity calibration (do it later, before reading it) */ - stm32_adc_clr_bits(adc, STM32H7_ADC_CR, STM32H7_ADCALDIF); - stm32_adc_clr_bits(adc, STM32H7_ADC_CR, STM32H7_ADCALLIN); + stm32_adc_clr_bits(adc, STM32H7_ADC_CR, msk); /* Start calibration, then wait for completion */ stm32_adc_set_bits(adc, STM32H7_ADC_CR, STM32H7_ADCAL); @@ -1048,8 +1156,7 @@ static int stm32h7_adc_selfcalib(struct iio_dev *indio_dev) * - Linearity calibration (needs to be done only once for single/diff) * will run simultaneously with offset calibration. */ - stm32_adc_set_bits(adc, STM32H7_ADC_CR, - STM32H7_ADCALDIF | STM32H7_ADCALLIN); + stm32_adc_set_bits(adc, STM32H7_ADC_CR, msk); stm32_adc_set_bits(adc, STM32H7_ADC_CR, STM32H7_ADCAL); ret = stm32_adc_readl_poll_timeout(STM32H7_ADC_CR, val, !(val & STM32H7_ADCAL), 100, @@ -1060,8 +1167,7 @@ static int stm32h7_adc_selfcalib(struct iio_dev *indio_dev) } out: - stm32_adc_clr_bits(adc, STM32H7_ADC_CR, - STM32H7_ADCALDIF | STM32H7_ADCALLIN); + stm32_adc_clr_bits(adc, STM32H7_ADC_CR, msk); return ret; } @@ -1093,7 +1199,7 @@ static int stm32h7_adc_prepare(struct iio_dev *indio_dev) stm32_adc_int_ch_enable(indio_dev); - stm32_adc_writel(adc, STM32H7_ADC_DIFSEL, adc->difsel); + stm32_adc_writel(adc, adc->cfg->regs->difsel.reg, adc->difsel); ret = stm32h7_adc_enable(indio_dev); if (ret) @@ -1107,7 +1213,8 @@ static int stm32h7_adc_prepare(struct iio_dev *indio_dev) if (ret) goto disable; - stm32_adc_writel(adc, STM32H7_ADC_PCSEL, adc->pcsel); + if (adc->cfg->has_presel) + stm32_adc_writel(adc, STM32H7_ADC_PCSEL, adc->pcsel); return 0; @@ -1125,7 +1232,8 @@ static void stm32h7_adc_unprepare(struct iio_dev *indio_dev) { struct stm32_adc *adc = iio_priv(indio_dev); - stm32_adc_writel(adc, STM32H7_ADC_PCSEL, 0); + if (adc->cfg->has_presel) + stm32_adc_writel(adc, STM32H7_ADC_PCSEL, 0); stm32h7_adc_disable(indio_dev); stm32_adc_int_ch_disable(adc); stm32h7_adc_enter_pwr_down(adc); @@ -1857,7 +1965,7 @@ static void stm32_adc_chan_init_one(struct iio_dev *indio_dev, adc->pcsel |= BIT(chan->channel); if (differential) { /* pre-build diff channels mask */ - adc->difsel |= BIT(chan->channel); + adc->difsel |= BIT(chan->channel) & adc->cfg->regs->difsel.mask; /* Also add negative input to pre-selected channels */ adc->pcsel |= BIT(chan->channel2); } @@ -1998,6 +2106,35 @@ static int stm32_adc_populate_int_ch(struct iio_dev *indio_dev, const char *ch_n for (i = 0; i < STM32_ADC_INT_CH_NB; i++) { if (!strncmp(stm32_adc_ic[i].name, ch_name, STM32_ADC_CH_SZ)) { + /* Check internal channel availability */ + switch (i) { + case STM32_ADC_INT_CH_VDDCORE: + if (!adc->cfg->regs->or_vddcore.reg) + dev_warn(&indio_dev->dev, + "%s channel not available\n", ch_name); + break; + case STM32_ADC_INT_CH_VDDCPU: + if (!adc->cfg->regs->or_vddcpu.reg) + dev_warn(&indio_dev->dev, + "%s channel not available\n", ch_name); + break; + case STM32_ADC_INT_CH_VDDQ_DDR: + if (!adc->cfg->regs->or_vddq_ddr.reg) + dev_warn(&indio_dev->dev, + "%s channel not available\n", ch_name); + break; + case STM32_ADC_INT_CH_VREFINT: + if (!adc->cfg->regs->ccr_vref.reg) + dev_warn(&indio_dev->dev, + "%s channel not available\n", ch_name); + break; + case STM32_ADC_INT_CH_VBAT: + if (!adc->cfg->regs->ccr_vbat.reg) + dev_warn(&indio_dev->dev, + "%s channel not available\n", ch_name); + break; + } + if (stm32_adc_ic[i].idx != STM32_ADC_INT_CH_VREFINT) { adc->int_ch[i] = chan; break; @@ -2435,6 +2572,9 @@ static const struct stm32_adc_cfg stm32h7_adc_cfg = { .regs = &stm32h7_adc_regspec, .adc_info = &stm32h7_adc_info, .trigs = stm32h7_adc_trigs, + .has_boostmode = true, + .has_linearcal = true, + .has_presel = true, .start_conv = stm32h7_adc_start_conv, .stop_conv = stm32h7_adc_stop_conv, .prepare = stm32h7_adc_prepare, @@ -2448,6 +2588,9 @@ static const struct stm32_adc_cfg stm32mp1_adc_cfg = { .adc_info = &stm32h7_adc_info, .trigs = stm32h7_adc_trigs, .has_vregready = true, + .has_boostmode = true, + .has_linearcal = true, + .has_presel = true, .start_conv = stm32h7_adc_start_conv, .stop_conv = stm32h7_adc_stop_conv, .prepare = stm32h7_adc_prepare, @@ -2457,10 +2600,23 @@ static const struct stm32_adc_cfg stm32mp1_adc_cfg = { .ts_vrefint_ns = 4300, }; +static const struct stm32_adc_cfg stm32mp13_adc_cfg = { + .regs = &stm32mp13_adc_regspec, + .adc_info = &stm32mp13_adc_info, + .trigs = stm32h7_adc_trigs, + .start_conv = stm32mp13_adc_start_conv, + .stop_conv = stm32h7_adc_stop_conv, + .prepare = stm32h7_adc_prepare, + .unprepare = stm32h7_adc_unprepare, + .smp_cycles = stm32mp13_adc_smp_cycles, + .irq_clear = stm32h7_adc_irq_clear, +}; + static const struct of_device_id stm32_adc_of_match[] = { { .compatible = "st,stm32f4-adc", .data = (void *)&stm32f4_adc_cfg }, { .compatible = "st,stm32h7-adc", .data = (void *)&stm32h7_adc_cfg }, { .compatible = "st,stm32mp1-adc", .data = (void *)&stm32mp1_adc_cfg }, + { .compatible = "st,stm32mp13-adc", .data = (void *)&stm32mp13_adc_cfg }, {}, }; MODULE_DEVICE_TABLE(of, stm32_adc_of_match); -- cgit v1.2.3 From 7cb2303dd02487cc18bc9ff0fc1338e8c78ae846 Mon Sep 17 00:00:00 2001 From: Olivier Moysan Date: Wed, 12 Oct 2022 16:22:01 +0200 Subject: iio: adc: stm32: manage min sampling time on all internal channels Force minimum sampling time for all internal channels according to datasheet requirement. This value can be increased through DT st,min-sample-time-ns property. Signed-off-by: Olivier Moysan Reviewed-by: Andy Shevchenko Reviewed-by: Fabrice Gasnier Link: https://lore.kernel.org/r/20221012142205.13041-5-olivier.moysan@foss.st.com Signed-off-by: Jonathan Cameron --- drivers/iio/adc/stm32-adc.c | 26 +++++++++++++++++++------- 1 file changed, 19 insertions(+), 7 deletions(-) (limited to 'drivers/iio') diff --git a/drivers/iio/adc/stm32-adc.c b/drivers/iio/adc/stm32-adc.c index d36c024526f2..8d03d21a33d6 100644 --- a/drivers/iio/adc/stm32-adc.c +++ b/drivers/iio/adc/stm32-adc.c @@ -215,7 +215,7 @@ struct stm32_adc; * @unprepare: optional unprepare routine (disable, power-down) * @irq_clear: routine to clear irqs * @smp_cycles: programmable sampling time (ADC clock cycles) - * @ts_vrefint_ns: vrefint minimum sampling time in ns + * @ts_int_ch: pointer to array of internal channels minimum sampling time in ns */ struct stm32_adc_cfg { const struct stm32_adc_regspec *regs; @@ -232,7 +232,7 @@ struct stm32_adc_cfg { void (*unprepare)(struct iio_dev *); void (*irq_clear)(struct iio_dev *indio_dev, u32 msk); const unsigned int *smp_cycles; - const unsigned int ts_vrefint_ns; + const unsigned int *ts_int_ch; }; /** @@ -1910,14 +1910,15 @@ static void stm32_adc_smpr_init(struct stm32_adc *adc, int channel, u32 smp_ns) { const struct stm32_adc_regs *smpr = &adc->cfg->regs->smp_bits[channel]; u32 period_ns, shift = smpr->shift, mask = smpr->mask; - unsigned int smp, r = smpr->reg; + unsigned int i, smp, r = smpr->reg; /* - * For vrefint channel, ensure that the sampling time cannot + * For internal channels, ensure that the sampling time cannot * be lower than the one specified in the datasheet */ - if (channel == adc->int_ch[STM32_ADC_INT_CH_VREFINT]) - smp_ns = max(smp_ns, adc->cfg->ts_vrefint_ns); + for (i = 0; i < STM32_ADC_INT_CH_NB; i++) + if (channel == adc->int_ch[i] && adc->int_ch[i] != STM32_ADC_INT_CH_NONE) + smp_ns = max(smp_ns, adc->cfg->ts_int_ch[i]); /* Determine sampling time (ADC clock cycles) */ period_ns = NSEC_PER_SEC / adc->common->rate; @@ -2568,6 +2569,9 @@ static const struct stm32_adc_cfg stm32f4_adc_cfg = { .irq_clear = stm32f4_adc_irq_clear, }; +const unsigned int stm32_adc_min_ts_h7[] = { 0, 0, 0, 4300, 9000 }; +static_assert(ARRAY_SIZE(stm32_adc_min_ts_h7) == STM32_ADC_INT_CH_NB); + static const struct stm32_adc_cfg stm32h7_adc_cfg = { .regs = &stm32h7_adc_regspec, .adc_info = &stm32h7_adc_info, @@ -2581,8 +2585,12 @@ static const struct stm32_adc_cfg stm32h7_adc_cfg = { .unprepare = stm32h7_adc_unprepare, .smp_cycles = stm32h7_adc_smp_cycles, .irq_clear = stm32h7_adc_irq_clear, + .ts_int_ch = stm32_adc_min_ts_h7, }; +const unsigned int stm32_adc_min_ts_mp1[] = { 100, 100, 100, 4300, 9800 }; +static_assert(ARRAY_SIZE(stm32_adc_min_ts_mp1) == STM32_ADC_INT_CH_NB); + static const struct stm32_adc_cfg stm32mp1_adc_cfg = { .regs = &stm32mp1_adc_regspec, .adc_info = &stm32h7_adc_info, @@ -2597,9 +2605,12 @@ static const struct stm32_adc_cfg stm32mp1_adc_cfg = { .unprepare = stm32h7_adc_unprepare, .smp_cycles = stm32h7_adc_smp_cycles, .irq_clear = stm32h7_adc_irq_clear, - .ts_vrefint_ns = 4300, + .ts_int_ch = stm32_adc_min_ts_mp1, }; +const unsigned int stm32_adc_min_ts_mp13[] = { 100, 0, 0, 4300, 9800 }; +static_assert(ARRAY_SIZE(stm32_adc_min_ts_mp13) == STM32_ADC_INT_CH_NB); + static const struct stm32_adc_cfg stm32mp13_adc_cfg = { .regs = &stm32mp13_adc_regspec, .adc_info = &stm32mp13_adc_info, @@ -2610,6 +2621,7 @@ static const struct stm32_adc_cfg stm32mp13_adc_cfg = { .unprepare = stm32h7_adc_unprepare, .smp_cycles = stm32mp13_adc_smp_cycles, .irq_clear = stm32h7_adc_irq_clear, + .ts_int_ch = stm32_adc_min_ts_mp13, }; static const struct of_device_id stm32_adc_of_match[] = { -- cgit v1.2.3 From 0a8565425afd8ba0e1a0ea73e21da119ee6dacea Mon Sep 17 00:00:00 2001 From: Nuno Sá Date: Wed, 12 Oct 2022 17:16:17 +0200 Subject: iio: core: introduce iio_device_{claim|release}_buffer_mode() APIs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit These APIs are analogous to iio_device_claim_direct_mode() and iio_device_release_direct_mode() but, as the name suggests, with the logic flipped. While this looks odd enough, it will have at least two users (in following changes) and it will be important to move the IIO mlock to the private struct. Signed-off-by: Nuno Sá Reviewed-by: Andy Shevchenko Link: https://lore.kernel.org/r/20221012151620.1725215-2-nuno.sa@analog.com Signed-off-by: Jonathan Cameron --- drivers/iio/industrialio-core.c | 38 ++++++++++++++++++++++++++++++++++++++ include/linux/iio/iio.h | 2 ++ 2 files changed, 40 insertions(+) (limited to 'drivers/iio') diff --git a/drivers/iio/industrialio-core.c b/drivers/iio/industrialio-core.c index 151ff3993354..b2b7bd27adc7 100644 --- a/drivers/iio/industrialio-core.c +++ b/drivers/iio/industrialio-core.c @@ -2083,6 +2083,44 @@ void iio_device_release_direct_mode(struct iio_dev *indio_dev) } EXPORT_SYMBOL_GPL(iio_device_release_direct_mode); +/** + * iio_device_claim_buffer_mode - Keep device in buffer mode + * @indio_dev: the iio_dev associated with the device + * + * If the device is in buffer mode it is guaranteed to stay + * that way until iio_device_release_buffer_mode() is called. + * + * Use with iio_device_release_buffer_mode(). + * + * Returns: 0 on success, -EBUSY on failure. + */ +int iio_device_claim_buffer_mode(struct iio_dev *indio_dev) +{ + mutex_lock(&indio_dev->mlock); + + if (iio_buffer_enabled(indio_dev)) + return 0; + + mutex_unlock(&indio_dev->mlock); + return -EBUSY; +} +EXPORT_SYMBOL_GPL(iio_device_claim_buffer_mode); + +/** + * iio_device_release_buffer_mode - releases claim on buffer mode + * @indio_dev: the iio_dev associated with the device + * + * Release the claim. Device is no longer guaranteed to stay + * in buffer mode. + * + * Use with iio_device_claim_buffer_mode(). + */ +void iio_device_release_buffer_mode(struct iio_dev *indio_dev) +{ + mutex_unlock(&indio_dev->mlock); +} +EXPORT_SYMBOL_GPL(iio_device_release_buffer_mode); + /** * iio_device_get_current_mode() - helper function providing read-only access to * the opaque @currentmode variable diff --git a/include/linux/iio/iio.h b/include/linux/iio/iio.h index f0ec8a5e5a7a..9d3bd6379eb8 100644 --- a/include/linux/iio/iio.h +++ b/include/linux/iio/iio.h @@ -629,6 +629,8 @@ int __devm_iio_device_register(struct device *dev, struct iio_dev *indio_dev, int iio_push_event(struct iio_dev *indio_dev, u64 ev_code, s64 timestamp); int iio_device_claim_direct_mode(struct iio_dev *indio_dev); void iio_device_release_direct_mode(struct iio_dev *indio_dev); +int iio_device_claim_buffer_mode(struct iio_dev *indio_dev); +void iio_device_release_buffer_mode(struct iio_dev *indio_dev); extern struct bus_type iio_bus_type; -- cgit v1.2.3 From 1555790c86286933dc674fffe9c1104250d093ce Mon Sep 17 00:00:00 2001 From: Nuno Sá Date: Wed, 12 Oct 2022 17:16:18 +0200 Subject: iio: health: max30100: do not use internal iio_dev lock MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The pattern used in this device does not quite fit in the iio_device_claim_direct_mode() typical usage. In this case, iio_buffer_enabled() was being used not to prevent the raw access but to allow it. Hence, let's make use of the new iio_device_claim_buffer_mode() API to make sure we stay in buffered mode during the complete read. Note that we are shadowing the error code returned by iio_device_claim_buffer_mode() so that we keep the original one (-EAGAIN). The reason is that some userspace stack might already be relying on this particular code so that we are not taking chances and leave it alone. Signed-off-by: Nuno Sá Link: https://lore.kernel.org/r/20221012151620.1725215-3-nuno.sa@analog.com Signed-off-by: Jonathan Cameron --- drivers/iio/health/max30100.c | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) (limited to 'drivers/iio') diff --git a/drivers/iio/health/max30100.c b/drivers/iio/health/max30100.c index 2cca5e0519f8..3aa5d037a1c3 100644 --- a/drivers/iio/health/max30100.c +++ b/drivers/iio/health/max30100.c @@ -387,18 +387,21 @@ static int max30100_read_raw(struct iio_dev *indio_dev, * Temperature reading can only be acquired while engine * is running */ - mutex_lock(&indio_dev->mlock); - - if (!iio_buffer_enabled(indio_dev)) + if (iio_device_claim_buffer_mode(indio_dev)) { + /* + * Replacing -EBUSY or other error code + * returned by iio_device_claim_buffer_mode() + * because user space may rely on the current + * one. + */ ret = -EAGAIN; - else { + } else { ret = max30100_get_temp(data, val); if (!ret) ret = IIO_VAL_INT; + iio_device_release_buffer_mode(indio_dev); } - - mutex_unlock(&indio_dev->mlock); break; case IIO_CHAN_INFO_SCALE: *val = 1; /* 0.0625 */ -- cgit v1.2.3 From 6b701cda3632c9cffaea6f79c5fe638800c8f7f1 Mon Sep 17 00:00:00 2001 From: Nuno Sá Date: Wed, 12 Oct 2022 17:16:19 +0200 Subject: iio: health: max30102: do not use internal iio_dev lock MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The pattern used in this device does not quite fit in the iio_device_claim_direct_mode() typical usage. In this case, we want to know if we are in buffered mode or not to know if the device is powered (buffer mode) or not. And depending on that max30102_get_temp() will power on the device if needed. Hence, in order to keep the same functionality, we try to: 1. Claim Buffered mode; 2: If 1) succeeds call max30102_get_temp() without powering on the device; 3: Release Buffered mode; 4: If 1) fails, Claim Direct mode; 5: If 4) succeeds call max30102_get_temp() with powering on the device; 6: Release Direct mode; 7: If 4) fails, goto to 1) and try again. This dance between buffered and direct mode is not particularly pretty (as well as the loop introduced by the goto statement) but it does allow us to get rid of the mlock usage while keeping the same behavior. Signed-off-by: Nuno Sá Reviewed-by: Andy Shevchenko Link: https://lore.kernel.org/r/20221012151620.1725215-4-nuno.sa@analog.com Signed-off-by: Jonathan Cameron --- drivers/iio/health/max30102.c | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) (limited to 'drivers/iio') diff --git a/drivers/iio/health/max30102.c b/drivers/iio/health/max30102.c index 437298a29f2d..66df4aaa31a7 100644 --- a/drivers/iio/health/max30102.c +++ b/drivers/iio/health/max30102.c @@ -477,12 +477,23 @@ static int max30102_read_raw(struct iio_dev *indio_dev, * Temperature reading can only be acquired when not in * shutdown; leave shutdown briefly when buffer not running */ - mutex_lock(&indio_dev->mlock); - if (!iio_buffer_enabled(indio_dev)) +any_mode_retry: + if (iio_device_claim_buffer_mode(indio_dev)) { + /* + * This one is a *bit* hacky. If we cannot claim buffer + * mode, then try direct mode so that we make sure + * things cannot concurrently change. And we just keep + * trying until we get one of the modes... + */ + if (iio_device_claim_direct_mode(indio_dev)) + goto any_mode_retry; + ret = max30102_get_temp(data, val, true); - else + iio_device_release_direct_mode(indio_dev); + } else { ret = max30102_get_temp(data, val, false); - mutex_unlock(&indio_dev->mlock); + iio_device_release_buffer_mode(indio_dev); + } if (ret) return ret; -- cgit v1.2.3 From 16afe125b53f88b855d2713c8ba253d905dcf3cc Mon Sep 17 00:00:00 2001 From: Nuno Sá Date: Wed, 12 Oct 2022 17:16:20 +0200 Subject: iio: core: move 'mlock' to 'struct iio_dev_opaque' MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Now that there are no more users accessing 'mlock' directly, we can move it to the iio_dev private structure. Hence, it's now explicit that new driver's should not directly use this lock. Signed-off-by: Nuno Sá Reviewed-by: Andy Shevchenko Link: https://lore.kernel.org/r/20221012151620.1725215-5-nuno.sa@analog.com Signed-off-by: Jonathan Cameron --- drivers/iio/TODO | 3 --- drivers/iio/industrialio-buffer.c | 29 +++++++++++++++++------------ drivers/iio/industrialio-core.c | 26 +++++++++++++++----------- drivers/iio/industrialio-event.c | 4 ++-- drivers/iio/industrialio-trigger.c | 12 ++++++------ include/linux/iio/iio-opaque.h | 2 ++ include/linux/iio/iio.h | 3 --- 7 files changed, 42 insertions(+), 37 deletions(-) (limited to 'drivers/iio') diff --git a/drivers/iio/TODO b/drivers/iio/TODO index 7d7326b7085a..2ace27d1ac62 100644 --- a/drivers/iio/TODO +++ b/drivers/iio/TODO @@ -7,9 +7,6 @@ tree - ABI Documentation - Audit driviers/iio/staging/Documentation -- Replace iio_dev->mlock by either a local lock or use -iio_claim_direct.(Requires analysis of the purpose of the lock.) - - Converting drivers from device tree centric to more generic property handlers. diff --git a/drivers/iio/industrialio-buffer.c b/drivers/iio/industrialio-buffer.c index 228598b82a2f..9cd7db549fcb 100644 --- a/drivers/iio/industrialio-buffer.c +++ b/drivers/iio/industrialio-buffer.c @@ -507,13 +507,14 @@ static ssize_t iio_scan_el_store(struct device *dev, int ret; bool state; struct iio_dev *indio_dev = dev_to_iio_dev(dev); + struct iio_dev_opaque *iio_dev_opaque = to_iio_dev_opaque(indio_dev); struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); struct iio_buffer *buffer = this_attr->buffer; ret = kstrtobool(buf, &state); if (ret < 0) return ret; - mutex_lock(&indio_dev->mlock); + mutex_lock(&iio_dev_opaque->mlock); if (iio_buffer_is_active(buffer)) { ret = -EBUSY; goto error_ret; @@ -532,7 +533,7 @@ static ssize_t iio_scan_el_store(struct device *dev, } error_ret: - mutex_unlock(&indio_dev->mlock); + mutex_unlock(&iio_dev_opaque->mlock); return ret < 0 ? ret : len; @@ -554,6 +555,7 @@ static ssize_t iio_scan_el_ts_store(struct device *dev, { int ret; struct iio_dev *indio_dev = dev_to_iio_dev(dev); + struct iio_dev_opaque *iio_dev_opaque = to_iio_dev_opaque(indio_dev); struct iio_buffer *buffer = to_iio_dev_attr(attr)->buffer; bool state; @@ -561,14 +563,14 @@ static ssize_t iio_scan_el_ts_store(struct device *dev, if (ret < 0) return ret; - mutex_lock(&indio_dev->mlock); + mutex_lock(&iio_dev_opaque->mlock); if (iio_buffer_is_active(buffer)) { ret = -EBUSY; goto error_ret; } buffer->scan_timestamp = state; error_ret: - mutex_unlock(&indio_dev->mlock); + mutex_unlock(&iio_dev_opaque->mlock); return ret ? ret : len; } @@ -642,6 +644,7 @@ static ssize_t length_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t len) { struct iio_dev *indio_dev = dev_to_iio_dev(dev); + struct iio_dev_opaque *iio_dev_opaque = to_iio_dev_opaque(indio_dev); struct iio_buffer *buffer = to_iio_dev_attr(attr)->buffer; unsigned int val; int ret; @@ -653,7 +656,7 @@ static ssize_t length_store(struct device *dev, struct device_attribute *attr, if (val == buffer->length) return len; - mutex_lock(&indio_dev->mlock); + mutex_lock(&iio_dev_opaque->mlock); if (iio_buffer_is_active(buffer)) { ret = -EBUSY; } else { @@ -665,7 +668,7 @@ static ssize_t length_store(struct device *dev, struct device_attribute *attr, if (buffer->length && buffer->length < buffer->watermark) buffer->watermark = buffer->length; out: - mutex_unlock(&indio_dev->mlock); + mutex_unlock(&iio_dev_opaque->mlock); return ret ? ret : len; } @@ -1256,7 +1259,7 @@ int iio_update_buffers(struct iio_dev *indio_dev, return -EINVAL; mutex_lock(&iio_dev_opaque->info_exist_lock); - mutex_lock(&indio_dev->mlock); + mutex_lock(&iio_dev_opaque->mlock); if (insert_buffer && iio_buffer_is_active(insert_buffer)) insert_buffer = NULL; @@ -1277,7 +1280,7 @@ int iio_update_buffers(struct iio_dev *indio_dev, ret = __iio_update_buffers(indio_dev, insert_buffer, remove_buffer); out_unlock: - mutex_unlock(&indio_dev->mlock); + mutex_unlock(&iio_dev_opaque->mlock); mutex_unlock(&iio_dev_opaque->info_exist_lock); return ret; @@ -1296,6 +1299,7 @@ static ssize_t enable_store(struct device *dev, struct device_attribute *attr, int ret; bool requested_state; struct iio_dev *indio_dev = dev_to_iio_dev(dev); + struct iio_dev_opaque *iio_dev_opaque = to_iio_dev_opaque(indio_dev); struct iio_buffer *buffer = to_iio_dev_attr(attr)->buffer; bool inlist; @@ -1303,7 +1307,7 @@ static ssize_t enable_store(struct device *dev, struct device_attribute *attr, if (ret < 0) return ret; - mutex_lock(&indio_dev->mlock); + mutex_lock(&iio_dev_opaque->mlock); /* Find out if it is in the list */ inlist = iio_buffer_is_active(buffer); @@ -1317,7 +1321,7 @@ static ssize_t enable_store(struct device *dev, struct device_attribute *attr, ret = __iio_update_buffers(indio_dev, NULL, buffer); done: - mutex_unlock(&indio_dev->mlock); + mutex_unlock(&iio_dev_opaque->mlock); return (ret < 0) ? ret : len; } @@ -1334,6 +1338,7 @@ static ssize_t watermark_store(struct device *dev, const char *buf, size_t len) { struct iio_dev *indio_dev = dev_to_iio_dev(dev); + struct iio_dev_opaque *iio_dev_opaque = to_iio_dev_opaque(indio_dev); struct iio_buffer *buffer = to_iio_dev_attr(attr)->buffer; unsigned int val; int ret; @@ -1344,7 +1349,7 @@ static ssize_t watermark_store(struct device *dev, if (!val) return -EINVAL; - mutex_lock(&indio_dev->mlock); + mutex_lock(&iio_dev_opaque->mlock); if (val > buffer->length) { ret = -EINVAL; @@ -1358,7 +1363,7 @@ static ssize_t watermark_store(struct device *dev, buffer->watermark = val; out: - mutex_unlock(&indio_dev->mlock); + mutex_unlock(&iio_dev_opaque->mlock); return ret ? ret : len; } diff --git a/drivers/iio/industrialio-core.c b/drivers/iio/industrialio-core.c index b2b7bd27adc7..52e690f031cb 100644 --- a/drivers/iio/industrialio-core.c +++ b/drivers/iio/industrialio-core.c @@ -285,16 +285,16 @@ int iio_device_set_clock(struct iio_dev *indio_dev, clockid_t clock_id) struct iio_dev_opaque *iio_dev_opaque = to_iio_dev_opaque(indio_dev); const struct iio_event_interface *ev_int = iio_dev_opaque->event_interface; - ret = mutex_lock_interruptible(&indio_dev->mlock); + ret = mutex_lock_interruptible(&iio_dev_opaque->mlock); if (ret) return ret; if ((ev_int && iio_event_enabled(ev_int)) || iio_buffer_enabled(indio_dev)) { - mutex_unlock(&indio_dev->mlock); + mutex_unlock(&iio_dev_opaque->mlock); return -EBUSY; } iio_dev_opaque->clock_id = clock_id; - mutex_unlock(&indio_dev->mlock); + mutex_unlock(&iio_dev_opaque->mlock); return 0; } @@ -1674,7 +1674,7 @@ struct iio_dev *iio_device_alloc(struct device *parent, int sizeof_priv) indio_dev->dev.type = &iio_device_type; indio_dev->dev.bus = &iio_bus_type; device_initialize(&indio_dev->dev); - mutex_init(&indio_dev->mlock); + mutex_init(&iio_dev_opaque->mlock); mutex_init(&iio_dev_opaque->info_exist_lock); INIT_LIST_HEAD(&iio_dev_opaque->channel_attr_list); @@ -1696,7 +1696,7 @@ struct iio_dev *iio_device_alloc(struct device *parent, int sizeof_priv) INIT_LIST_HEAD(&iio_dev_opaque->ioctl_handlers); lockdep_register_key(&iio_dev_opaque->mlock_key); - lockdep_set_class(&indio_dev->mlock, &iio_dev_opaque->mlock_key); + lockdep_set_class(&iio_dev_opaque->mlock, &iio_dev_opaque->mlock_key); return indio_dev; } @@ -2058,10 +2058,12 @@ EXPORT_SYMBOL_GPL(__devm_iio_device_register); */ int iio_device_claim_direct_mode(struct iio_dev *indio_dev) { - mutex_lock(&indio_dev->mlock); + struct iio_dev_opaque *iio_dev_opaque = to_iio_dev_opaque(indio_dev); + + mutex_lock(&iio_dev_opaque->mlock); if (iio_buffer_enabled(indio_dev)) { - mutex_unlock(&indio_dev->mlock); + mutex_unlock(&iio_dev_opaque->mlock); return -EBUSY; } return 0; @@ -2079,7 +2081,7 @@ EXPORT_SYMBOL_GPL(iio_device_claim_direct_mode); */ void iio_device_release_direct_mode(struct iio_dev *indio_dev) { - mutex_unlock(&indio_dev->mlock); + mutex_unlock(&to_iio_dev_opaque(indio_dev)->mlock); } EXPORT_SYMBOL_GPL(iio_device_release_direct_mode); @@ -2096,12 +2098,14 @@ EXPORT_SYMBOL_GPL(iio_device_release_direct_mode); */ int iio_device_claim_buffer_mode(struct iio_dev *indio_dev) { - mutex_lock(&indio_dev->mlock); + struct iio_dev_opaque *iio_dev_opaque = to_iio_dev_opaque(indio_dev); + + mutex_lock(&iio_dev_opaque->mlock); if (iio_buffer_enabled(indio_dev)) return 0; - mutex_unlock(&indio_dev->mlock); + mutex_unlock(&iio_dev_opaque->mlock); return -EBUSY; } EXPORT_SYMBOL_GPL(iio_device_claim_buffer_mode); @@ -2117,7 +2121,7 @@ EXPORT_SYMBOL_GPL(iio_device_claim_buffer_mode); */ void iio_device_release_buffer_mode(struct iio_dev *indio_dev) { - mutex_unlock(&indio_dev->mlock); + mutex_unlock(&to_iio_dev_opaque(indio_dev)->mlock); } EXPORT_SYMBOL_GPL(iio_device_release_buffer_mode); diff --git a/drivers/iio/industrialio-event.c b/drivers/iio/industrialio-event.c index 3d78da2531a9..1a26393a7c0c 100644 --- a/drivers/iio/industrialio-event.c +++ b/drivers/iio/industrialio-event.c @@ -198,7 +198,7 @@ static int iio_event_getfd(struct iio_dev *indio_dev) if (ev_int == NULL) return -ENODEV; - fd = mutex_lock_interruptible(&indio_dev->mlock); + fd = mutex_lock_interruptible(&iio_dev_opaque->mlock); if (fd) return fd; @@ -219,7 +219,7 @@ static int iio_event_getfd(struct iio_dev *indio_dev) } unlock: - mutex_unlock(&indio_dev->mlock); + mutex_unlock(&iio_dev_opaque->mlock); return fd; } diff --git a/drivers/iio/industrialio-trigger.c b/drivers/iio/industrialio-trigger.c index 6885a186fe27..a2f3cc2f65ef 100644 --- a/drivers/iio/industrialio-trigger.c +++ b/drivers/iio/industrialio-trigger.c @@ -120,12 +120,12 @@ int iio_trigger_set_immutable(struct iio_dev *indio_dev, struct iio_trigger *tri return -EINVAL; iio_dev_opaque = to_iio_dev_opaque(indio_dev); - mutex_lock(&indio_dev->mlock); + mutex_lock(&iio_dev_opaque->mlock); WARN_ON(iio_dev_opaque->trig_readonly); indio_dev->trig = iio_trigger_get(trig); iio_dev_opaque->trig_readonly = true; - mutex_unlock(&indio_dev->mlock); + mutex_unlock(&iio_dev_opaque->mlock); return 0; } @@ -438,16 +438,16 @@ static ssize_t current_trigger_store(struct device *dev, struct iio_trigger *trig; int ret; - mutex_lock(&indio_dev->mlock); + mutex_lock(&iio_dev_opaque->mlock); if (iio_dev_opaque->currentmode == INDIO_BUFFER_TRIGGERED) { - mutex_unlock(&indio_dev->mlock); + mutex_unlock(&iio_dev_opaque->mlock); return -EBUSY; } if (iio_dev_opaque->trig_readonly) { - mutex_unlock(&indio_dev->mlock); + mutex_unlock(&iio_dev_opaque->mlock); return -EPERM; } - mutex_unlock(&indio_dev->mlock); + mutex_unlock(&iio_dev_opaque->mlock); trig = iio_trigger_acquire_by_name(buf); if (oldtrig == trig) { diff --git a/include/linux/iio/iio-opaque.h b/include/linux/iio/iio-opaque.h index d1f8b30a7c8b..5aec3945555b 100644 --- a/include/linux/iio/iio-opaque.h +++ b/include/linux/iio/iio-opaque.h @@ -11,6 +11,7 @@ * checked by device drivers but should be considered * read-only as this is a core internal bit * @driver_module: used to make it harder to undercut users + * @mlock: lock used to prevent simultaneous device state changes * @mlock_key: lockdep class for iio_dev lock * @info_exist_lock: lock to prevent use during removal * @trig_readonly: mark the current trigger immutable @@ -43,6 +44,7 @@ struct iio_dev_opaque { int currentmode; int id; struct module *driver_module; + struct mutex mlock; struct lock_class_key mlock_key; struct mutex info_exist_lock; bool trig_readonly; diff --git a/include/linux/iio/iio.h b/include/linux/iio/iio.h index 9d3bd6379eb8..8e0afaaa3f75 100644 --- a/include/linux/iio/iio.h +++ b/include/linux/iio/iio.h @@ -548,8 +548,6 @@ struct iio_buffer_setup_ops { * and owner * @buffer: [DRIVER] any buffer present * @scan_bytes: [INTERN] num bytes captured to be fed to buffer demux - * @mlock: [INTERN] lock used to prevent simultaneous device state - * changes * @available_scan_masks: [DRIVER] optional array of allowed bitmasks * @masklength: [INTERN] the length of the mask established from * channels @@ -574,7 +572,6 @@ struct iio_dev { struct iio_buffer *buffer; int scan_bytes; - struct mutex mlock; const unsigned long *available_scan_masks; unsigned masklength; -- cgit v1.2.3 From 0c3a333524a3e5ba4b6c7b2638faef8420cfdb2a Mon Sep 17 00:00:00 2001 From: Rajat Khandelwal Date: Mon, 10 Oct 2022 23:07:20 +0530 Subject: iio: pressure: mpl115: Implementing low power mode by shutdown gpio MPL115 supports shutdown gpio which can be used to set the state to low power mode. Power from all internal circuits and registers is removed. This is done by pulling the SHDN pin to low. This patch enables runtime PM on MPL115 to increase power savings. According to spec., a wakeup time period of ~5 ms exists between waking up and actually communicating with the device. This is implemented using sleep delay. Signed-off-by: Rajat Khandelwal Link: https://lore.kernel.org/r/20221010173720.568916-1-rajat.khandelwal@linux.intel.com Signed-off-by: Jonathan Cameron --- drivers/iio/pressure/mpl115.c | 62 ++++++++++++++++++++++++++++++++++++++- drivers/iio/pressure/mpl115.h | 5 ++++ drivers/iio/pressure/mpl115_i2c.c | 1 + drivers/iio/pressure/mpl115_spi.c | 1 + 4 files changed, 68 insertions(+), 1 deletion(-) (limited to 'drivers/iio') diff --git a/drivers/iio/pressure/mpl115.c b/drivers/iio/pressure/mpl115.c index 5bf5b9abe6f1..02ea38c8a3e4 100644 --- a/drivers/iio/pressure/mpl115.c +++ b/drivers/iio/pressure/mpl115.c @@ -4,12 +4,13 @@ * * Copyright (c) 2014 Peter Meerwald * - * TODO: shutdown pin + * TODO: synchronization with system suspend */ #include #include #include +#include #include "mpl115.h" @@ -27,6 +28,7 @@ struct mpl115_data { s16 a0; s16 b1, b2; s16 c12; + struct gpio_desc *shutdown; const struct mpl115_ops *ops; }; @@ -102,16 +104,24 @@ static int mpl115_read_raw(struct iio_dev *indio_dev, switch (mask) { case IIO_CHAN_INFO_PROCESSED: + pm_runtime_get_sync(data->dev); ret = mpl115_comp_pressure(data, val, val2); if (ret < 0) return ret; + pm_runtime_mark_last_busy(data->dev); + pm_runtime_put_autosuspend(data->dev); + return IIO_VAL_INT_PLUS_MICRO; case IIO_CHAN_INFO_RAW: + pm_runtime_get_sync(data->dev); /* temperature -5.35 C / LSB, 472 LSB is 25 C */ ret = mpl115_read_temp(data); if (ret < 0) return ret; + pm_runtime_mark_last_busy(data->dev); + pm_runtime_put_autosuspend(data->dev); *val = ret >> 6; + return IIO_VAL_INT; case IIO_CHAN_INFO_OFFSET: *val = -605; @@ -168,6 +178,8 @@ int mpl115_probe(struct device *dev, const char *name, if (ret) return ret; + dev_set_drvdata(dev, indio_dev); + ret = data->ops->read(data->dev, MPL115_A0); if (ret < 0) return ret; @@ -185,10 +197,58 @@ int mpl115_probe(struct device *dev, const char *name, return ret; data->c12 = ret; + data->shutdown = devm_gpiod_get_optional(dev, "shutdown", + GPIOD_OUT_LOW); + if (IS_ERR(data->shutdown)) + return dev_err_probe(dev, PTR_ERR(data->shutdown), + "cannot get shutdown gpio\n"); + + if (data->shutdown) { + /* Enable runtime PM */ + pm_runtime_get_noresume(dev); + pm_runtime_set_active(dev); + pm_runtime_enable(dev); + + /* + * As the device takes 3 ms to come up with a fresh + * reading after power-on and 5 ms to actually power-on, + * do not shut it down unnecessarily. Set autosuspend to + * 2000 ms. + */ + pm_runtime_set_autosuspend_delay(dev, 2000); + pm_runtime_use_autosuspend(dev); + pm_runtime_put(dev); + + dev_dbg(dev, "low-power mode enabled"); + } else + dev_dbg(dev, "low-power mode disabled"); + return devm_iio_device_register(dev, indio_dev); } EXPORT_SYMBOL_NS_GPL(mpl115_probe, IIO_MPL115); +static int mpl115_runtime_suspend(struct device *dev) +{ + struct mpl115_data *data = iio_priv(dev_get_drvdata(dev)); + + gpiod_set_value(data->shutdown, 1); + + return 0; +} + +static int mpl115_runtime_resume(struct device *dev) +{ + struct mpl115_data *data = iio_priv(dev_get_drvdata(dev)); + + gpiod_set_value(data->shutdown, 0); + usleep_range(5000, 6000); + + return 0; +} + +EXPORT_NS_RUNTIME_DEV_PM_OPS(mpl115_dev_pm_ops, mpl115_runtime_suspend, + mpl115_runtime_resume, NULL, IIO_MPL115); + MODULE_AUTHOR("Peter Meerwald "); MODULE_DESCRIPTION("Freescale MPL115 pressure/temperature driver"); MODULE_LICENSE("GPL"); diff --git a/drivers/iio/pressure/mpl115.h b/drivers/iio/pressure/mpl115.h index 57d55eb8e661..78a0068a17bb 100644 --- a/drivers/iio/pressure/mpl115.h +++ b/drivers/iio/pressure/mpl115.h @@ -6,6 +6,8 @@ * Copyright (c) 2016 Akinobu Mita */ +#include + #ifndef _MPL115_H_ #define _MPL115_H_ @@ -18,4 +20,7 @@ struct mpl115_ops { int mpl115_probe(struct device *dev, const char *name, const struct mpl115_ops *ops); +/*PM ops */ +extern const struct dev_pm_ops mpl115_dev_pm_ops; + #endif diff --git a/drivers/iio/pressure/mpl115_i2c.c b/drivers/iio/pressure/mpl115_i2c.c index 099ab1c6832c..555bda1146fb 100644 --- a/drivers/iio/pressure/mpl115_i2c.c +++ b/drivers/iio/pressure/mpl115_i2c.c @@ -53,6 +53,7 @@ MODULE_DEVICE_TABLE(i2c, mpl115_i2c_id); static struct i2c_driver mpl115_i2c_driver = { .driver = { .name = "mpl115", + .pm = pm_ptr(&mpl115_dev_pm_ops), }, .probe = mpl115_i2c_probe, .id_table = mpl115_i2c_id, diff --git a/drivers/iio/pressure/mpl115_spi.c b/drivers/iio/pressure/mpl115_spi.c index 7feec87e2704..58d218fd90dc 100644 --- a/drivers/iio/pressure/mpl115_spi.c +++ b/drivers/iio/pressure/mpl115_spi.c @@ -92,6 +92,7 @@ MODULE_DEVICE_TABLE(spi, mpl115_spi_ids); static struct spi_driver mpl115_spi_driver = { .driver = { .name = "mpl115", + .pm = pm_ptr(&mpl115_dev_pm_ops), }, .probe = mpl115_spi_probe, .id_table = mpl115_spi_ids, -- cgit v1.2.3 From 687c8848c642c093c190bb182e4a6ac2ed86b4eb Mon Sep 17 00:00:00 2001 From: Jonathan Cameron Date: Sun, 25 Sep 2022 16:57:16 +0100 Subject: iio: accel: fxls8962af: Use new EXPORT_NS_GPL_DEV_PM_OPS() Using this macro allows the compiler to remove unused structures and callbacks if we are not building with CONFIG_PM* without needing __maybe_unused markings. Signed-off-by: Jonathan Cameron Cc: Sean Nyekjaer -- Switched to Paul Cercueil's more flexible implementation fo the macro. Dropped Sean's Ack given new form of macro being used. Acked-by: Sean Nyekjaer Link: https://lore.kernel.org/r/20220925155719.3316280-3-jic23@kernel.org Signed-off-by: Jonathan Cameron --- drivers/iio/accel/fxls8962af-core.c | 16 +++++++--------- drivers/iio/accel/fxls8962af-i2c.c | 2 +- drivers/iio/accel/fxls8962af-spi.c | 2 +- 3 files changed, 9 insertions(+), 11 deletions(-) (limited to 'drivers/iio') diff --git a/drivers/iio/accel/fxls8962af-core.c b/drivers/iio/accel/fxls8962af-core.c index 8874d6d61725..bf259db281f5 100644 --- a/drivers/iio/accel/fxls8962af-core.c +++ b/drivers/iio/accel/fxls8962af-core.c @@ -1241,7 +1241,7 @@ int fxls8962af_core_probe(struct device *dev, struct regmap *regmap, int irq) } EXPORT_SYMBOL_NS_GPL(fxls8962af_core_probe, IIO_FXLS8962AF); -static int __maybe_unused fxls8962af_runtime_suspend(struct device *dev) +static int fxls8962af_runtime_suspend(struct device *dev) { struct fxls8962af_data *data = iio_priv(dev_get_drvdata(dev)); int ret; @@ -1255,14 +1255,14 @@ static int __maybe_unused fxls8962af_runtime_suspend(struct device *dev) return 0; } -static int __maybe_unused fxls8962af_runtime_resume(struct device *dev) +static int fxls8962af_runtime_resume(struct device *dev) { struct fxls8962af_data *data = iio_priv(dev_get_drvdata(dev)); return fxls8962af_active(data); } -static int __maybe_unused fxls8962af_suspend(struct device *dev) +static int fxls8962af_suspend(struct device *dev) { struct iio_dev *indio_dev = dev_get_drvdata(dev); struct fxls8962af_data *data = iio_priv(indio_dev); @@ -1283,7 +1283,7 @@ static int __maybe_unused fxls8962af_suspend(struct device *dev) return 0; } -static int __maybe_unused fxls8962af_resume(struct device *dev) +static int fxls8962af_resume(struct device *dev) { struct iio_dev *indio_dev = dev_get_drvdata(dev); struct fxls8962af_data *data = iio_priv(indio_dev); @@ -1300,12 +1300,10 @@ static int __maybe_unused fxls8962af_resume(struct device *dev) return 0; } -const struct dev_pm_ops fxls8962af_pm_ops = { - SET_SYSTEM_SLEEP_PM_OPS(fxls8962af_suspend, fxls8962af_resume) - SET_RUNTIME_PM_OPS(fxls8962af_runtime_suspend, - fxls8962af_runtime_resume, NULL) +EXPORT_NS_GPL_DEV_PM_OPS(fxls8962af_pm_ops, IIO_FXLS8962AF) = { + SYSTEM_SLEEP_PM_OPS(fxls8962af_suspend, fxls8962af_resume) + RUNTIME_PM_OPS(fxls8962af_runtime_suspend, fxls8962af_runtime_resume, NULL) }; -EXPORT_SYMBOL_NS_GPL(fxls8962af_pm_ops, IIO_FXLS8962AF); MODULE_AUTHOR("Sean Nyekjaer "); MODULE_DESCRIPTION("NXP FXLS8962AF/FXLS8964AF accelerometer driver"); diff --git a/drivers/iio/accel/fxls8962af-i2c.c b/drivers/iio/accel/fxls8962af-i2c.c index 8fbadfea1620..22640eaebac7 100644 --- a/drivers/iio/accel/fxls8962af-i2c.c +++ b/drivers/iio/accel/fxls8962af-i2c.c @@ -45,7 +45,7 @@ static struct i2c_driver fxls8962af_driver = { .driver = { .name = "fxls8962af_i2c", .of_match_table = fxls8962af_of_match, - .pm = &fxls8962af_pm_ops, + .pm = pm_ptr(&fxls8962af_pm_ops), }, .probe_new = fxls8962af_probe, .id_table = fxls8962af_id, diff --git a/drivers/iio/accel/fxls8962af-spi.c b/drivers/iio/accel/fxls8962af-spi.c index 885b3ab7fcb5..a0d192211839 100644 --- a/drivers/iio/accel/fxls8962af-spi.c +++ b/drivers/iio/accel/fxls8962af-spi.c @@ -44,7 +44,7 @@ MODULE_DEVICE_TABLE(spi, fxls8962af_spi_id_table); static struct spi_driver fxls8962af_driver = { .driver = { .name = "fxls8962af_spi", - .pm = &fxls8962af_pm_ops, + .pm = pm_ptr(&fxls8962af_pm_ops), .of_match_table = fxls8962af_spi_of_match, }, .probe = fxls8962af_probe, -- cgit v1.2.3 From 02e082c433c65f06f4cb359688993377c1d7b6d1 Mon Sep 17 00:00:00 2001 From: Jonathan Cameron Date: Sun, 25 Sep 2022 16:57:17 +0100 Subject: iio: gyro: fxas210002c: Move exports to IIO_FXAS210002C namespace. Includes using EXPORT_NS_GPL_DEV_PM_OPS() and the simplifications that brings by allowing the compiler to remove unused struct dev_pm_ops and callbacks without needing explicit __maybe_unused markings. Signed-off-by: Jonathan Cameron Cc: Rui Miguel Silva Signed-off-by: Jonathan Cameron -- Dropped Rui's tag on basis this is rather different from v1 due to the different macro implementation. v2: Switch to Paul's more flexible approach to EXPORT_NS_GPL_DEV_PM_OPS() Acked-by: Rui Miguel Silva Link: https://lore.kernel.org/r/20220925155719.3316280-4-jic23@kernel.org Signed-off-by: Jonathan Cameron --- drivers/iio/gyro/fxas21002c_core.c | 21 ++++++++++----------- drivers/iio/gyro/fxas21002c_i2c.c | 3 ++- drivers/iio/gyro/fxas21002c_spi.c | 3 ++- 3 files changed, 14 insertions(+), 13 deletions(-) (limited to 'drivers/iio') diff --git a/drivers/iio/gyro/fxas21002c_core.c b/drivers/iio/gyro/fxas21002c_core.c index a36d71d9e3ea..3ea1d4613080 100644 --- a/drivers/iio/gyro/fxas21002c_core.c +++ b/drivers/iio/gyro/fxas21002c_core.c @@ -998,7 +998,7 @@ pm_disable: return ret; } -EXPORT_SYMBOL_GPL(fxas21002c_core_probe); +EXPORT_SYMBOL_NS_GPL(fxas21002c_core_probe, IIO_FXAS21002C); void fxas21002c_core_remove(struct device *dev) { @@ -1009,9 +1009,9 @@ void fxas21002c_core_remove(struct device *dev) pm_runtime_disable(dev); pm_runtime_set_suspended(dev); } -EXPORT_SYMBOL_GPL(fxas21002c_core_remove); +EXPORT_SYMBOL_NS_GPL(fxas21002c_core_remove, IIO_FXAS21002C); -static int __maybe_unused fxas21002c_suspend(struct device *dev) +static int fxas21002c_suspend(struct device *dev) { struct fxas21002c_data *data = iio_priv(dev_get_drvdata(dev)); @@ -1021,7 +1021,7 @@ static int __maybe_unused fxas21002c_suspend(struct device *dev) return 0; } -static int __maybe_unused fxas21002c_resume(struct device *dev) +static int fxas21002c_resume(struct device *dev) { struct fxas21002c_data *data = iio_priv(dev_get_drvdata(dev)); int ret; @@ -1033,26 +1033,25 @@ static int __maybe_unused fxas21002c_resume(struct device *dev) return fxas21002c_mode_set(data, data->prev_mode); } -static int __maybe_unused fxas21002c_runtime_suspend(struct device *dev) +static int fxas21002c_runtime_suspend(struct device *dev) { struct fxas21002c_data *data = iio_priv(dev_get_drvdata(dev)); return fxas21002c_mode_set(data, FXAS21002C_MODE_READY); } -static int __maybe_unused fxas21002c_runtime_resume(struct device *dev) +static int fxas21002c_runtime_resume(struct device *dev) { struct fxas21002c_data *data = iio_priv(dev_get_drvdata(dev)); return fxas21002c_mode_set(data, FXAS21002C_MODE_ACTIVE); } -const struct dev_pm_ops fxas21002c_pm_ops = { - SET_SYSTEM_SLEEP_PM_OPS(fxas21002c_suspend, fxas21002c_resume) - SET_RUNTIME_PM_OPS(fxas21002c_runtime_suspend, - fxas21002c_runtime_resume, NULL) +EXPORT_NS_GPL_DEV_PM_OPS(fxas21002c_pm_ops, IIO_FXAS21002C) = { + SYSTEM_SLEEP_PM_OPS(fxas21002c_suspend, fxas21002c_resume) + RUNTIME_PM_OPS(fxas21002c_runtime_suspend, fxas21002c_runtime_resume, + NULL) }; -EXPORT_SYMBOL_GPL(fxas21002c_pm_ops); MODULE_AUTHOR("Rui Miguel Silva "); MODULE_LICENSE("GPL v2"); diff --git a/drivers/iio/gyro/fxas21002c_i2c.c b/drivers/iio/gyro/fxas21002c_i2c.c index 13bb52c594d1..9e2d0f34a672 100644 --- a/drivers/iio/gyro/fxas21002c_i2c.c +++ b/drivers/iio/gyro/fxas21002c_i2c.c @@ -53,7 +53,7 @@ MODULE_DEVICE_TABLE(of, fxas21002c_i2c_of_match); static struct i2c_driver fxas21002c_i2c_driver = { .driver = { .name = "fxas21002c_i2c", - .pm = &fxas21002c_pm_ops, + .pm = pm_ptr(&fxas21002c_pm_ops), .of_match_table = fxas21002c_i2c_of_match, }, .probe_new = fxas21002c_i2c_probe, @@ -65,3 +65,4 @@ module_i2c_driver(fxas21002c_i2c_driver); MODULE_AUTHOR("Rui Miguel Silva "); MODULE_LICENSE("GPL v2"); MODULE_DESCRIPTION("FXAS21002C I2C Gyro driver"); +MODULE_IMPORT_NS(IIO_FXAS21002C); diff --git a/drivers/iio/gyro/fxas21002c_spi.c b/drivers/iio/gyro/fxas21002c_spi.c index c3ac169facf9..4f633826547c 100644 --- a/drivers/iio/gyro/fxas21002c_spi.c +++ b/drivers/iio/gyro/fxas21002c_spi.c @@ -54,7 +54,7 @@ MODULE_DEVICE_TABLE(of, fxas21002c_spi_of_match); static struct spi_driver fxas21002c_spi_driver = { .driver = { .name = "fxas21002c_spi", - .pm = &fxas21002c_pm_ops, + .pm = pm_ptr(&fxas21002c_pm_ops), .of_match_table = fxas21002c_spi_of_match, }, .probe = fxas21002c_spi_probe, @@ -66,3 +66,4 @@ module_spi_driver(fxas21002c_spi_driver); MODULE_AUTHOR("Rui Miguel Silva "); MODULE_LICENSE("GPL v2"); MODULE_DESCRIPTION("FXAS21002C SPI Gyro driver"); +MODULE_IMPORT_NS(IIO_FXAS21002C); -- cgit v1.2.3 From ef5a5ef29c8f70ca640d785b7173101417c78d24 Mon Sep 17 00:00:00 2001 From: Jonathan Cameron Date: Sun, 25 Sep 2022 16:57:18 +0100 Subject: iio: imu: inv_icm42600: Move exports to IIO_ICM42600 namespace As these exports are only relevant to core module and users in the bus specific modules, move them out of the main kernel namespace. Includes using EXPORT_NS_GPL_DEV_PM_OPS() and the simplifications that brings by allowing the compiler to remove unused struct dev_pm_ops and callbacks without needing explicit __maybe_unused markings. Signed-off-by: Jonathan Cameron Cc: Jean-Baptiste Maneyrol -- EXPORT_NS_GPL_DEV_PM_OPS() v2: Switch to Paul's more flexible version of the Acked-by: Jean-Baptiste Maneyrol Link: https://lore.kernel.org/r/20220925155719.3316280-5-jic23@kernel.org Signed-off-by: Jonathan Cameron --- drivers/iio/imu/inv_icm42600/inv_icm42600_core.c | 21 ++++++++++----------- drivers/iio/imu/inv_icm42600/inv_icm42600_i2c.c | 3 ++- drivers/iio/imu/inv_icm42600/inv_icm42600_spi.c | 3 ++- 3 files changed, 14 insertions(+), 13 deletions(-) (limited to 'drivers/iio') diff --git a/drivers/iio/imu/inv_icm42600/inv_icm42600_core.c b/drivers/iio/imu/inv_icm42600/inv_icm42600_core.c index ca85fccc9839..b63c5dab1a56 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; @@ -660,13 +660,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 +706,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 +739,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 +761,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 +774,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..4f96989ddf4a 100644 --- a/drivers/iio/imu/inv_icm42600/inv_icm42600_i2c.c +++ b/drivers/iio/imu/inv_icm42600/inv_icm42600_i2c.c @@ -93,7 +93,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 +102,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..486b46e53113 100644 --- a/drivers/iio/imu/inv_icm42600/inv_icm42600_spi.c +++ b/drivers/iio/imu/inv_icm42600/inv_icm42600_spi.c @@ -89,7 +89,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 +98,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); -- cgit v1.2.3 From 62bfa12c87ac7468a69e81ea870eb68b0adabf37 Mon Sep 17 00:00:00 2001 From: Jonathan Cameron Date: Sun, 25 Sep 2022 16:57:19 +0100 Subject: iio: imu: inv_mpu: Move exports to IIO_MPU6050 namespace As these exports are only relevant to core module and users in the bus specific modules, move them out of the main kernel namespace. Includes using EXPORT_NS_GPL_DEV_PM_OPS() and the simplifications that brings by allowing the compiler to remove unused struct dev_pm_ops and callbacks without needing explicit __maybe_unused markings. Signed-off-by: Jonathan Cameron Cc: Jean-Baptiste Maneyrol Cc: Linus Walleij -- Dropped Linus' tag as the new patch is significantly different. v2: Switch to more flexible version of EXPORT* macro from Paul. Acked-by: Jean-Baptiste Maneyrol Link: https://lore.kernel.org/r/20220925155719.3316280-6-jic23@kernel.org Signed-off-by: Jonathan Cameron --- drivers/iio/imu/inv_mpu6050/inv_mpu_core.c | 17 ++++++++--------- drivers/iio/imu/inv_mpu6050/inv_mpu_i2c.c | 3 ++- drivers/iio/imu/inv_mpu6050/inv_mpu_spi.c | 3 ++- 3 files changed, 12 insertions(+), 11 deletions(-) (limited to 'drivers/iio') 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..7a8d60a5afa9 100644 --- a/drivers/iio/imu/inv_mpu6050/inv_mpu_i2c.c +++ b/drivers/iio/imu/inv_mpu6050/inv_mpu_i2c.c @@ -267,7 +267,7 @@ static struct i2c_driver inv_mpu_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 +276,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 "); MODULE_DESCRIPTION("Invensense device MPU6000 driver"); MODULE_LICENSE("GPL"); +MODULE_IMPORT_NS(IIO_MPU6050); -- cgit v1.2.3 From 1ccef2e6e9205e209ad958d2e591bcca60981007 Mon Sep 17 00:00:00 2001 From: Matti Vaittinen Date: Fri, 19 Aug 2022 22:19:01 +0300 Subject: iio: adc: ad7192: Simplify using devm_regulator_get_enable() Use devm_regulator_get_enable() instead of open coded get, enable, add-action-to-disable-at-detach - pattern. Also drop the seemingly unused struct member 'dvdd'. Signed-off-by: Matti Vaittinen Link: https://lore.kernel.org/r/9719c445c095d3d308e2fc9f4f93294f5806c41c.1660934107.git.mazziesaccount@gmail.com Signed-off-by: Jonathan Cameron --- drivers/iio/adc/ad7192.c | 15 ++------------- 1 file changed, 2 insertions(+), 13 deletions(-) (limited to 'drivers/iio') diff --git a/drivers/iio/adc/ad7192.c b/drivers/iio/adc/ad7192.c index f5067173deb6..55a6ab591016 100644 --- a/drivers/iio/adc/ad7192.c +++ b/drivers/iio/adc/ad7192.c @@ -177,7 +177,6 @@ struct ad7192_chip_info { struct ad7192_state { const struct ad7192_chip_info *chip_info; struct regulator *avdd; - struct regulator *dvdd; struct clk *mclk; u16 int_vref_mv; u32 fclk; @@ -1015,19 +1014,9 @@ static int ad7192_probe(struct spi_device *spi) if (ret) return ret; - st->dvdd = devm_regulator_get(&spi->dev, "dvdd"); - if (IS_ERR(st->dvdd)) - return PTR_ERR(st->dvdd); - - ret = regulator_enable(st->dvdd); - if (ret) { - dev_err(&spi->dev, "Failed to enable specified DVdd supply\n"); - return ret; - } - - ret = devm_add_action_or_reset(&spi->dev, ad7192_reg_disable, st->dvdd); + ret = devm_regulator_get_enable(&spi->dev, "dvdd"); if (ret) - return ret; + return dev_err_probe(&spi->dev, ret, "Failed to enable specified DVdd supply\n"); ret = regulator_get_voltage(st->avdd); if (ret < 0) { -- cgit v1.2.3 From 08f75f180db06566d134b1cac1d8a4b8f266761e Mon Sep 17 00:00:00 2001 From: Matti Vaittinen Date: Fri, 19 Aug 2022 22:19:17 +0300 Subject: iio: dac: ltc2688: Simplify using devm_regulator_*get_enable() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Use devm_regulator_bulk_get_enable() instead of open coded bulk-get, bulk-enable, add-action-to-disable-at-detach - pattern. Signed-off-by: Matti Vaittinen Reviewed-by: Nuno Sá Link: https://lore.kernel.org/r/a29493f594c84b3bd852e462bbd3e591a8575a27.1660934107.git.mazziesaccount@gmail.com Signed-off-by: Jonathan Cameron --- drivers/iio/dac/ltc2688.c | 23 +++-------------------- 1 file changed, 3 insertions(+), 20 deletions(-) (limited to 'drivers/iio') diff --git a/drivers/iio/dac/ltc2688.c b/drivers/iio/dac/ltc2688.c index 28bdde2d3088..fc8eb53c65be 100644 --- a/drivers/iio/dac/ltc2688.c +++ b/drivers/iio/dac/ltc2688.c @@ -84,7 +84,6 @@ struct ltc2688_chan { struct ltc2688_state { struct spi_device *spi; struct regmap *regmap; - struct regulator_bulk_data regulators[2]; struct ltc2688_chan channels[LTC2688_DAC_CHANNELS]; struct iio_chan_spec *iio_chan; /* lock to protect against multiple access to the device and shared data */ @@ -902,13 +901,6 @@ static int ltc2688_setup(struct ltc2688_state *st, struct regulator *vref) LTC2688_CONFIG_EXT_REF); } -static void ltc2688_disable_regulators(void *data) -{ - struct ltc2688_state *st = data; - - regulator_bulk_disable(ARRAY_SIZE(st->regulators), st->regulators); -} - static void ltc2688_disable_regulator(void *regulator) { regulator_disable(regulator); @@ -965,6 +957,7 @@ static const struct iio_info ltc2688_info = { static int ltc2688_probe(struct spi_device *spi) { + static const char * const regulators[] = { "vcc", "iovcc" }; struct ltc2688_state *st; struct iio_dev *indio_dev; struct regulator *vref_reg; @@ -988,21 +981,11 @@ static int ltc2688_probe(struct spi_device *spi) return dev_err_probe(dev, PTR_ERR(st->regmap), "Failed to init regmap"); - st->regulators[0].supply = "vcc"; - st->regulators[1].supply = "iovcc"; - ret = devm_regulator_bulk_get(dev, ARRAY_SIZE(st->regulators), - st->regulators); - if (ret) - return dev_err_probe(dev, ret, "Failed to get regulators\n"); - - ret = regulator_bulk_enable(ARRAY_SIZE(st->regulators), st->regulators); + ret = devm_regulator_bulk_get_enable(dev, ARRAY_SIZE(regulators), + regulators); if (ret) return dev_err_probe(dev, ret, "Failed to enable regulators\n"); - ret = devm_add_action_or_reset(dev, ltc2688_disable_regulators, st); - if (ret) - return ret; - vref_reg = devm_regulator_get_optional(dev, "vref"); if (IS_ERR(vref_reg)) { if (PTR_ERR(vref_reg) != -ENODEV) -- cgit v1.2.3 From 2c620883a46b6e2299cf9e4b4683e5b3cc67a61e Mon Sep 17 00:00:00 2001 From: Matti Vaittinen Date: Fri, 19 Aug 2022 22:19:31 +0300 Subject: iio: gyro: bmg160_core: Simplify using devm_regulator_*get_enable() Use devm_regulator_bulk_get_enable() instead of open coded bulk-get, bulk-enable, add-action-to-disable-at-detach - pattern. Signed-off-by: Matti Vaittinen Link: https://lore.kernel.org/r/3fd11489356b1c73a3d7b4bd9dec7e12c9fe8788.1660934107.git.mazziesaccount@gmail.com Signed-off-by: Jonathan Cameron --- drivers/iio/gyro/bmg160_core.c | 24 +++--------------------- 1 file changed, 3 insertions(+), 21 deletions(-) (limited to 'drivers/iio') diff --git a/drivers/iio/gyro/bmg160_core.c b/drivers/iio/gyro/bmg160_core.c index cedd9f02ea21..0e2eb0e98235 100644 --- a/drivers/iio/gyro/bmg160_core.c +++ b/drivers/iio/gyro/bmg160_core.c @@ -93,7 +93,6 @@ struct bmg160_data { struct regmap *regmap; - struct regulator_bulk_data regulators[2]; struct iio_trigger *dready_trig; struct iio_trigger *motion_trig; struct iio_mount_matrix orientation; @@ -1067,16 +1066,10 @@ static const char *bmg160_match_acpi_device(struct device *dev) return dev_name(dev); } -static void bmg160_disable_regulators(void *d) -{ - struct bmg160_data *data = d; - - regulator_bulk_disable(ARRAY_SIZE(data->regulators), data->regulators); -} - int bmg160_core_probe(struct device *dev, struct regmap *regmap, int irq, const char *name) { + static const char * const regulators[] = { "vdd", "vddio" }; struct bmg160_data *data; struct iio_dev *indio_dev; int ret; @@ -1090,22 +1083,11 @@ int bmg160_core_probe(struct device *dev, struct regmap *regmap, int irq, data->irq = irq; data->regmap = regmap; - data->regulators[0].supply = "vdd"; - data->regulators[1].supply = "vddio"; - ret = devm_regulator_bulk_get(dev, ARRAY_SIZE(data->regulators), - data->regulators); + ret = devm_regulator_bulk_get_enable(dev, ARRAY_SIZE(regulators), + regulators); if (ret) return dev_err_probe(dev, ret, "Failed to get regulators\n"); - ret = regulator_bulk_enable(ARRAY_SIZE(data->regulators), - data->regulators); - if (ret) - return ret; - - ret = devm_add_action_or_reset(dev, bmg160_disable_regulators, data); - if (ret) - return ret; - ret = iio_read_mount_matrix(dev, &data->orientation); if (ret) return ret; -- cgit v1.2.3 From 6900cdbfb99e8600572da340576509297a684a3a Mon Sep 17 00:00:00 2001 From: Matti Vaittinen Date: Fri, 19 Aug 2022 22:19:46 +0300 Subject: iio: imu: st_lsm6dsx: Simplify using devm_regulator_*get_enable() Use devm_regulator_bulk_get_enable() instead of open coded bulk-get, bulk-enable, add-action-to-disable-at-detach - pattern. A functional change (which seems like a bugfix) is that if regulator_bulk_get fails, the enable is not attempted. Signed-off-by: Matti Vaittinen Link: https://lore.kernel.org/r/876e58428cec056d51070e49eff559e2d7c23b12.1660934107.git.mazziesaccount@gmail.com Signed-off-by: Jonathan Cameron --- drivers/iio/imu/st_lsm6dsx/st_lsm6dsx.h | 2 -- drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c | 30 +++++----------------------- 2 files changed, 5 insertions(+), 27 deletions(-) (limited to 'drivers/iio') diff --git a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx.h b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx.h index d3a4e21bc114..07ad8027de73 100644 --- a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx.h +++ b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx.h @@ -374,7 +374,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 +396,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; diff --git a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c index 6af2e905c161..fe5fa08b68ac 100644 --- a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c +++ b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c @@ -2177,36 +2177,20 @@ static int st_lsm6dsx_irq_setup(struct st_lsm6dsx_hw *hw) static int st_lsm6dsx_init_regulators(struct device *dev) { - struct st_lsm6dsx_hw *hw = dev_get_drvdata(dev); + /* vdd-vddio power regulators */ + static const char * const regulators[] = { "vdd", "vddio" }; int err; - /* 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); + err = devm_regulator_bulk_get_enable(dev, ARRAY_SIZE(regulators), + regulators); if (err) - return dev_err_probe(dev, err, "failed to get regulators\n"); - - err = regulator_bulk_enable(ARRAY_SIZE(hw->regulators), - hw->regulators); - if (err) { - dev_err(dev, "failed to enable regulators: %d\n", err); - return err; - } + return dev_err_probe(dev, err, "failed to enable regulators\n"); msleep(50); return 0; } -static void st_lsm6dsx_chip_uninit(void *data) -{ - struct st_lsm6dsx_hw *hw = data; - - regulator_bulk_disable(ARRAY_SIZE(hw->regulators), hw->regulators); -} - int st_lsm6dsx_probe(struct device *dev, int irq, int hw_id, struct regmap *regmap) { @@ -2230,10 +2214,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; -- cgit v1.2.3 From 7ff0ad35aa6f70fe32fee33bc6e0aa356af99f76 Mon Sep 17 00:00:00 2001 From: Matti Vaittinen Date: Fri, 19 Aug 2022 22:20:03 +0300 Subject: iio: adc: ad7476: simplify using devm_regulator_get_enable() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Drop open-coded pattern: 'devm_regulator_get(), regulator_enable(), add_action_or_reset(regulator_disable)' and use the devm_regulator_get_enable() Signed-off-by: Matti Vaittinen Acked-by: Nuno Sá Link: https://lore.kernel.org/r/33070d66b9b976acac1cee5570facef9278b6b61.1660934107.git.mazziesaccount@gmail.com Signed-off-by: Jonathan Cameron --- drivers/iio/adc/ad7476.c | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) (limited to 'drivers/iio') diff --git a/drivers/iio/adc/ad7476.c b/drivers/iio/adc/ad7476.c index 94776f696290..80aebed47d1f 100644 --- a/drivers/iio/adc/ad7476.c +++ b/drivers/iio/adc/ad7476.c @@ -368,16 +368,7 @@ static int ad7476_probe(struct spi_device *spi) } if (st->chip_info->has_vdrive) { - reg = devm_regulator_get(&spi->dev, "vdrive"); - if (IS_ERR(reg)) - return PTR_ERR(reg); - - ret = regulator_enable(reg); - if (ret) - return ret; - - ret = devm_add_action_or_reset(&spi->dev, ad7476_reg_disable, - reg); + ret = devm_regulator_get_enable(&spi->dev, "vdrive"); if (ret) return ret; } -- cgit v1.2.3 From fd5b6c48ec3345d5c243e283fbdb69618ada2be8 Mon Sep 17 00:00:00 2001 From: Matti Vaittinen Date: Fri, 19 Aug 2022 22:20:18 +0300 Subject: iio: adc: ad7606: simplify using devm_regulator_get_enable() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Drop open-coded pattern: 'devm_regulator_get(), regulator_enable(), add_action_or_reset(regulator_disable)' and use the devm_regulator_get_enable() and drop the pointer to the regulator. This simplifies code and makes it less tempting to add manual control for the regulator which is also controlled by devm. Whilst here also switch to dev_err_probe() to provide more information if a deferred probe occurs. Signed-off-by: Matti Vaittinen Acked-by: Nuno Sá Link: https://lore.kernel.org/r/521c52f5a9bdc2db04d5775b36df4b233ae338da.1660934107.git.mazziesaccount@gmail.com Signed-off-by: Jonathan Cameron --- drivers/iio/adc/ad7606.c | 22 +++------------------- drivers/iio/adc/ad7606.h | 2 -- 2 files changed, 3 insertions(+), 21 deletions(-) (limited to 'drivers/iio') diff --git a/drivers/iio/adc/ad7606.c b/drivers/iio/adc/ad7606.c index ba24f99523e0..dd6b603f65ea 100644 --- a/drivers/iio/adc/ad7606.c +++ b/drivers/iio/adc/ad7606.c @@ -557,13 +557,6 @@ static const struct iio_trigger_ops ad7606_trigger_ops = { .validate_device = iio_trigger_validate_own_device, }; -static void ad7606_regulator_disable(void *data) -{ - struct ad7606_state *st = data; - - regulator_disable(st->reg); -} - int ad7606_probe(struct device *dev, int irq, void __iomem *base_address, const char *name, unsigned int id, const struct ad7606_bus_ops *bops) @@ -589,19 +582,10 @@ int ad7606_probe(struct device *dev, int irq, void __iomem *base_address, st->scale_avail = ad7606_scale_avail; st->num_scales = ARRAY_SIZE(ad7606_scale_avail); - st->reg = devm_regulator_get(dev, "avcc"); - if (IS_ERR(st->reg)) - return PTR_ERR(st->reg); - - ret = regulator_enable(st->reg); - if (ret) { - dev_err(dev, "Failed to enable specified AVcc supply\n"); - return ret; - } - - ret = devm_add_action_or_reset(dev, ad7606_regulator_disable, st); + ret = devm_regulator_get_enable(dev, "avcc"); if (ret) - return ret; + return dev_err_probe(dev, ret, + "Failed to enable specified AVcc supply\n"); st->chip_info = &ad7606_chip_info_tbl[id]; diff --git a/drivers/iio/adc/ad7606.h b/drivers/iio/adc/ad7606.h index 2dc4f599f9df..0c6a88cc4695 100644 --- a/drivers/iio/adc/ad7606.h +++ b/drivers/iio/adc/ad7606.h @@ -62,7 +62,6 @@ struct ad7606_chip_info { * struct ad7606_state - driver instance specific data * @dev pointer to kernel device * @chip_info entry in the table of chips that describes this device - * @reg regulator info for the power supply of the device * @bops bus operations (SPI or parallel) * @range voltage range selection, selects which scale to apply * @oversampling oversampling selection @@ -92,7 +91,6 @@ struct ad7606_chip_info { struct ad7606_state { struct device *dev; const struct ad7606_chip_info *chip_info; - struct regulator *reg; const struct ad7606_bus_ops *bops; unsigned int range[16]; unsigned int oversampling; -- cgit v1.2.3 From f55c8e6696425ef22b7d08fc05b920d3a1a5dbf6 Mon Sep 17 00:00:00 2001 From: Matti Vaittinen Date: Fri, 19 Aug 2022 22:20:32 +0300 Subject: iio: adc: max1241: simplify using devm_regulator_get_enable() Drop open-coded pattern: 'devm_regulator_get(), regulator_enable(), add_action_or_reset(regulator_disable)' and use the devm_regulator_get_enable() and drop the pointer to the regulator. This simplifies code and makes it less tempting to add manual control for the regulator which is also controlled by devm. Signed-off-by: Matti Vaittinen Acked-by: Alexandru Lazar Link: https://lore.kernel.org/r/7c759bf6c06e72ae70bffeebc1939d9903427278.1660934107.git.mazziesaccount@gmail.com Signed-off-by: Jonathan Cameron --- drivers/iio/adc/max1241.c | 28 +++------------------------- 1 file changed, 3 insertions(+), 25 deletions(-) (limited to 'drivers/iio') diff --git a/drivers/iio/adc/max1241.c b/drivers/iio/adc/max1241.c index a815ad1f6913..500bb09ab19b 100644 --- a/drivers/iio/adc/max1241.c +++ b/drivers/iio/adc/max1241.c @@ -22,7 +22,6 @@ enum max1241_id { struct max1241 { struct spi_device *spi; struct mutex lock; - struct regulator *vdd; struct regulator *vref; struct gpio_desc *shutdown; @@ -110,17 +109,6 @@ static const struct iio_info max1241_info = { .read_raw = max1241_read_raw, }; -static void max1241_disable_vdd_action(void *data) -{ - struct max1241 *adc = data; - struct device *dev = &adc->spi->dev; - int err; - - err = regulator_disable(adc->vdd); - if (err) - dev_err(dev, "could not disable vdd regulator.\n"); -} - static void max1241_disable_vref_action(void *data) { struct max1241 *adc = data; @@ -147,20 +135,10 @@ static int max1241_probe(struct spi_device *spi) adc->spi = spi; mutex_init(&adc->lock); - adc->vdd = devm_regulator_get(dev, "vdd"); - if (IS_ERR(adc->vdd)) - return dev_err_probe(dev, PTR_ERR(adc->vdd), - "failed to get vdd regulator\n"); - - ret = regulator_enable(adc->vdd); + ret = devm_regulator_get_enable(dev, "vdd"); if (ret) - return ret; - - ret = devm_add_action_or_reset(dev, max1241_disable_vdd_action, adc); - if (ret) { - dev_err(dev, "could not set up vdd regulator cleanup action\n"); - return ret; - } + return dev_err_probe(dev, ret, + "failed to get/enable vdd regulator\n"); adc->vref = devm_regulator_get(dev, "vref"); if (IS_ERR(adc->vref)) -- cgit v1.2.3 From 3dfa1d4f63baf41774bbc77467729de39e0ac8a6 Mon Sep 17 00:00:00 2001 From: Matti Vaittinen Date: Fri, 19 Aug 2022 22:20:47 +0300 Subject: iio: adc: max1363: simplify using devm_regulator_get_enable() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Drop open-coded pattern: 'devm_regulator_get(), regulator_enable(), add_action_or_reset(regulator_disable)' and use the devm_regulator_get_enable() and drop the pointer to the regulator. This simplifies code and makes it less tempting to add manual control for the regulator which is also controlled by devm. Signed-off-by: Matti Vaittinen Acked-by: Nuno Sá Link: https://lore.kernel.org/r/1286ea127d190e5708a0aaff271819b2d3f8802d.1660934107.git.mazziesaccount@gmail.com Signed-off-by: Jonathan Cameron --- drivers/iio/adc/max1363.c | 12 +----------- 1 file changed, 1 insertion(+), 11 deletions(-) (limited to 'drivers/iio') diff --git a/drivers/iio/adc/max1363.c b/drivers/iio/adc/max1363.c index a28cf86cdce8..42d3479cefb7 100644 --- a/drivers/iio/adc/max1363.c +++ b/drivers/iio/adc/max1363.c @@ -148,7 +148,6 @@ struct max1363_chip_info { * @chip_info: chip model specific constants, available modes, etc. * @current_mode: the scan mode of this chip * @requestedmask: a valid requested set of channels - * @reg: supply regulator * @lock: lock to ensure state is consistent * @monitor_on: whether monitor mode is enabled * @monitor_speed: parameter corresponding to device monitor speed setting @@ -168,7 +167,6 @@ struct max1363_state { const struct max1363_chip_info *chip_info; const struct max1363_mode *current_mode; u32 requestedmask; - struct regulator *reg; struct mutex lock; /* Using monitor modes and buffer at the same time is @@ -1597,15 +1595,7 @@ static int max1363_probe(struct i2c_client *client, st = iio_priv(indio_dev); mutex_init(&st->lock); - st->reg = devm_regulator_get(&client->dev, "vcc"); - if (IS_ERR(st->reg)) - return PTR_ERR(st->reg); - - ret = regulator_enable(st->reg); - if (ret) - return ret; - - ret = devm_add_action_or_reset(&client->dev, max1363_reg_disable, st->reg); + ret = devm_regulator_get_enable(&client->dev, "vcc"); if (ret) return ret; -- cgit v1.2.3 From 563746c26db6c203d30bed2daa301416b27b77fb Mon Sep 17 00:00:00 2001 From: Matti Vaittinen Date: Fri, 19 Aug 2022 22:21:02 +0300 Subject: iio: amplifier: hmc425a: simplify using devm_regulator_get_enable() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Drop open-coded pattern: 'devm_regulator_get(), regulator_enable(), add_action_or_reset(regulator_disable)' and use the devm_regulator_get_enable() and drop the pointer to the regulator. This simplifies code and makes it less tempting to add manual control for the regulator which is also controlled by devm. Signed-off-by: Matti Vaittinen Acked-by: Nuno Sá Link: https://lore.kernel.org/r/8b1193fdefb231a6d721e2bded52c48e56039c20.1660934107.git.mazziesaccount@gmail.com Signed-off-by: Jonathan Cameron --- drivers/iio/amplifiers/hmc425a.c | 17 +---------------- 1 file changed, 1 insertion(+), 16 deletions(-) (limited to 'drivers/iio') diff --git a/drivers/iio/amplifiers/hmc425a.c b/drivers/iio/amplifiers/hmc425a.c index ce80e0c916f4..108f0f1685ef 100644 --- a/drivers/iio/amplifiers/hmc425a.c +++ b/drivers/iio/amplifiers/hmc425a.c @@ -34,7 +34,6 @@ struct hmc425a_chip_info { }; struct hmc425a_state { - struct regulator *reg; struct mutex lock; /* protect sensor state */ struct hmc425a_chip_info *chip_info; struct gpio_descs *gpios; @@ -162,13 +161,6 @@ static const struct of_device_id hmc425a_of_match[] = { }; MODULE_DEVICE_TABLE(of, hmc425a_of_match); -static void hmc425a_reg_disable(void *data) -{ - struct hmc425a_state *st = data; - - regulator_disable(st->reg); -} - static struct hmc425a_chip_info hmc425a_chip_info_tbl[] = { [ID_HMC425A] = { .name = "hmc425a", @@ -211,14 +203,7 @@ static int hmc425a_probe(struct platform_device *pdev) return -ENODEV; } - st->reg = devm_regulator_get(&pdev->dev, "vcc-supply"); - if (IS_ERR(st->reg)) - return PTR_ERR(st->reg); - - ret = regulator_enable(st->reg); - if (ret) - return ret; - ret = devm_add_action_or_reset(&pdev->dev, hmc425a_reg_disable, st); + ret = devm_regulator_get_enable(&pdev->dev, "vcc-supply"); if (ret) return ret; -- cgit v1.2.3 From 62094060cf3acaf52e277457d807ea753269b89e Mon Sep 17 00:00:00 2001 From: Cosmin Tanislav Date: Fri, 21 Oct 2022 13:41:15 +0300 Subject: iio: adc: ad4130: add AD4130 driver AD4130-8 is an ultra-low power, high precision, measurement solution for low bandwidth battery operated applications. The fully integrated AFE (Analog Front-End) includes a multiplexer for up to 16 single-ended or 8 differential inputs, PGA (Programmable Gain Amplifier), 24-bit Sigma-Delta ADC, on-chip reference and oscillator, selectable filter options, smart sequencer, sensor biasing and excitation options, diagnostics, and a FIFO buffer. Signed-off-by: Cosmin Tanislav Reviewed-by: Andy Shevchenko Link: https://lore.kernel.org/r/20221021104115.1812486-3-demonsingur@gmail.com Signed-off-by: Jonathan Cameron --- Documentation/ABI/testing/sysfs-bus-iio-adc-ad4130 | 36 + MAINTAINERS | 2 + drivers/iio/adc/Kconfig | 14 + drivers/iio/adc/Makefile | 1 + drivers/iio/adc/ad4130.c | 2100 ++++++++++++++++++++ 5 files changed, 2153 insertions(+) create mode 100644 Documentation/ABI/testing/sysfs-bus-iio-adc-ad4130 create mode 100644 drivers/iio/adc/ad4130.c (limited to 'drivers/iio') diff --git a/Documentation/ABI/testing/sysfs-bus-iio-adc-ad4130 b/Documentation/ABI/testing/sysfs-bus-iio-adc-ad4130 new file mode 100644 index 000000000000..d9555751d21c --- /dev/null +++ b/Documentation/ABI/testing/sysfs-bus-iio-adc-ad4130 @@ -0,0 +1,36 @@ +What: /sys/bus/iio/devices/iio:deviceX/in_voltage-voltage_filter_mode_available +KernelVersion: 6.2 +Contact: linux-iio@vger.kernel.org +Description: + Reading returns a list with the possible filter modes. + "sinc4" - Sinc 4. Excellent noise performance. Long 1st + conversion time. No natural 50/60Hz rejection. + "sinc4+sinc1" - Sinc4 + averaging by 8. Low 1st conversion time. + "sinc3" - Sinc3. Moderate 1st conversion time. Good noise + performance. + "sinc3+rej60" - Sinc3 + 60Hz rejection. At a sampling frequency + of 50Hz, achieves simultaneous 50Hz and 60Hz + rejection. + "sinc3+sinc1" - Sinc3 + averaging by 8. Low 1st conversion time. + Best used with a sampling frequency of at least + 216.19Hz. + "sinc3+pf1" - Sinc3 + Post Filter 1. + 53dB rejection @ 50Hz, 58dB rejection @ 60Hz. + "sinc3+pf2" - Sinc3 + Post Filter 2. + 70dB rejection @ 50Hz, 70dB rejection @ 60Hz. + "sinc3+pf3" - Sinc3 + Post Filter 3. + 99dB rejection @ 50Hz, 103dB rejection @ 60Hz. + "sinc3+pf4" - Sinc3 + Post Filter 4. + 103dB rejection @ 50Hz, 109dB rejection @ 60Hz. + +What: /sys/bus/iio/devices/iio:deviceX/in_voltageY-voltageZ_filter_mode +KernelVersion: 6.2 +Contact: linux-iio@vger.kernel.org +Description: + Set the filter mode of the differential channel. When the filter + mode changes, the in_voltageY-voltageZ_sampling_frequency and + in_voltageY-voltageZ_sampling_frequency_available attributes + might also change to accommodate the new filter mode. + If the current sampling frequency is out of range for the new + filter mode, the sampling frequency will be changed to the + closest valid one. diff --git a/MAINTAINERS b/MAINTAINERS index 5cb67803af96..ecec0bb6b09e 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -1122,7 +1122,9 @@ M: Cosmin Tanislav L: linux-iio@vger.kernel.org S: Supported W: http://ez.analog.com/community/linux-device-drivers +F: Documentation/ABI/testing/sysfs-bus-iio-adc-ad4130 F: Documentation/devicetree/bindings/iio/adc/adi,ad4130.yaml +F: drivers/iio/adc/ad4130.c ANALOG DEVICES INC AD7192 DRIVER M: Alexandru Tachici diff --git a/drivers/iio/adc/Kconfig b/drivers/iio/adc/Kconfig index 5386d862def9..8d719fbb6acc 100644 --- a/drivers/iio/adc/Kconfig +++ b/drivers/iio/adc/Kconfig @@ -21,6 +21,20 @@ config AD_SIGMA_DELTA select IIO_BUFFER select IIO_TRIGGERED_BUFFER +config AD4130 + tristate "Analog Device AD4130 ADC Driver" + depends on SPI + select IIO_BUFFER + select IIO_KFIFO_BUF + select REGMAP_SPI + depends on COMMON_CLK + help + Say yes here to build support for Analog Devices AD4130-8 SPI analog + to digital converters (ADC). + + To compile this driver as a module, choose M here: the module will be + called ad4130. + config AD7091R5 tristate "Analog Devices AD7091R5 ADC Driver" depends on I2C diff --git a/drivers/iio/adc/Makefile b/drivers/iio/adc/Makefile index 1571e891828e..4ef41a7dfac6 100644 --- a/drivers/iio/adc/Makefile +++ b/drivers/iio/adc/Makefile @@ -6,6 +6,7 @@ # When adding new entries keep the list in alphabetical order obj-$(CONFIG_AB8500_GPADC) += ab8500-gpadc.o obj-$(CONFIG_AD_SIGMA_DELTA) += ad_sigma_delta.o +obj-$(CONFIG_AD4130) += ad4130.o obj-$(CONFIG_AD7091R5) += ad7091r5.o ad7091r-base.o obj-$(CONFIG_AD7124) += ad7124.o obj-$(CONFIG_AD7192) += ad7192.o diff --git a/drivers/iio/adc/ad4130.c b/drivers/iio/adc/ad4130.c new file mode 100644 index 000000000000..9a4d0043d797 --- /dev/null +++ b/drivers/iio/adc/ad4130.c @@ -0,0 +1,2100 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (C) 2022 Analog Devices, Inc. + * Author: Cosmin Tanislav + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include +#include +#include +#include + +#define AD4130_NAME "ad4130" + +#define AD4130_COMMS_READ_MASK BIT(6) + +#define AD4130_STATUS_REG 0x00 + +#define AD4130_ADC_CONTROL_REG 0x01 +#define AD4130_ADC_CONTROL_BIPOLAR_MASK BIT(14) +#define AD4130_ADC_CONTROL_INT_REF_VAL_MASK BIT(13) +#define AD4130_INT_REF_2_5V 2500000 +#define AD4130_INT_REF_1_25V 1250000 +#define AD4130_ADC_CONTROL_CSB_EN_MASK BIT(9) +#define AD4130_ADC_CONTROL_INT_REF_EN_MASK BIT(8) +#define AD4130_ADC_CONTROL_MODE_MASK GENMASK(5, 2) +#define AD4130_ADC_CONTROL_MCLK_SEL_MASK GENMASK(1, 0) +#define AD4130_MCLK_FREQ_76_8KHZ 76800 +#define AD4130_MCLK_FREQ_153_6KHZ 153600 + +#define AD4130_DATA_REG 0x02 + +#define AD4130_IO_CONTROL_REG 0x03 +#define AD4130_IO_CONTROL_INT_PIN_SEL_MASK GENMASK(9, 8) +#define AD4130_IO_CONTROL_GPIO_DATA_MASK GENMASK(7, 4) +#define AD4130_IO_CONTROL_GPIO_CTRL_MASK GENMASK(3, 0) + +#define AD4130_VBIAS_REG 0x04 + +#define AD4130_ID_REG 0x05 + +#define AD4130_ERROR_REG 0x06 + +#define AD4130_ERROR_EN_REG 0x07 + +#define AD4130_MCLK_COUNT_REG 0x08 + +#define AD4130_CHANNEL_X_REG(x) (0x09 + (x)) +#define AD4130_CHANNEL_EN_MASK BIT(23) +#define AD4130_CHANNEL_SETUP_MASK GENMASK(22, 20) +#define AD4130_CHANNEL_AINP_MASK GENMASK(17, 13) +#define AD4130_CHANNEL_AINM_MASK GENMASK(12, 8) +#define AD4130_CHANNEL_IOUT1_MASK GENMASK(7, 4) +#define AD4130_CHANNEL_IOUT2_MASK GENMASK(3, 0) + +#define AD4130_CONFIG_X_REG(x) (0x19 + (x)) +#define AD4130_CONFIG_IOUT1_VAL_MASK GENMASK(15, 13) +#define AD4130_CONFIG_IOUT2_VAL_MASK GENMASK(12, 10) +#define AD4130_CONFIG_BURNOUT_MASK GENMASK(9, 8) +#define AD4130_CONFIG_REF_BUFP_MASK BIT(7) +#define AD4130_CONFIG_REF_BUFM_MASK BIT(6) +#define AD4130_CONFIG_REF_SEL_MASK GENMASK(5, 4) +#define AD4130_CONFIG_PGA_MASK GENMASK(3, 1) + +#define AD4130_FILTER_X_REG(x) (0x21 + (x)) +#define AD4130_FILTER_MODE_MASK GENMASK(15, 12) +#define AD4130_FILTER_SELECT_MASK GENMASK(10, 0) +#define AD4130_FILTER_SELECT_MIN 1 + +#define AD4130_OFFSET_X_REG(x) (0x29 + (x)) + +#define AD4130_GAIN_X_REG(x) (0x31 + (x)) + +#define AD4130_MISC_REG 0x39 + +#define AD4130_FIFO_CONTROL_REG 0x3a +#define AD4130_FIFO_CONTROL_HEADER_MASK BIT(18) +#define AD4130_FIFO_CONTROL_MODE_MASK GENMASK(17, 16) +#define AD4130_FIFO_CONTROL_WM_INT_EN_MASK BIT(9) +#define AD4130_FIFO_CONTROL_WM_MASK GENMASK(7, 0) +#define AD4130_WATERMARK_256 0 + +#define AD4130_FIFO_STATUS_REG 0x3b + +#define AD4130_FIFO_THRESHOLD_REG 0x3c + +#define AD4130_FIFO_DATA_REG 0x3d +#define AD4130_FIFO_SIZE 256 +#define AD4130_FIFO_MAX_SAMPLE_SIZE 3 + +#define AD4130_MAX_ANALOG_PINS 16 +#define AD4130_MAX_CHANNELS 16 +#define AD4130_MAX_DIFF_INPUTS 30 +#define AD4130_MAX_GPIOS 4 +#define AD4130_MAX_ODR 2400 +#define AD4130_MAX_PGA 8 +#define AD4130_MAX_SETUPS 8 + +#define AD4130_AIN2_P1 0x2 +#define AD4130_AIN3_P2 0x3 + +#define AD4130_RESET_BUF_SIZE 8 +#define AD4130_RESET_SLEEP_US (160 * MICRO / AD4130_MCLK_FREQ_76_8KHZ) + +#define AD4130_INVALID_SLOT -1 + +static const unsigned int ad4130_reg_size[] = { + [AD4130_STATUS_REG] = 1, + [AD4130_ADC_CONTROL_REG] = 2, + [AD4130_DATA_REG] = 3, + [AD4130_IO_CONTROL_REG] = 2, + [AD4130_VBIAS_REG] = 2, + [AD4130_ID_REG] = 1, + [AD4130_ERROR_REG] = 2, + [AD4130_ERROR_EN_REG] = 2, + [AD4130_MCLK_COUNT_REG] = 1, + [AD4130_CHANNEL_X_REG(0) ... AD4130_CHANNEL_X_REG(AD4130_MAX_CHANNELS - 1)] = 3, + [AD4130_CONFIG_X_REG(0) ... AD4130_CONFIG_X_REG(AD4130_MAX_SETUPS - 1)] = 2, + [AD4130_FILTER_X_REG(0) ... AD4130_FILTER_X_REG(AD4130_MAX_SETUPS - 1)] = 3, + [AD4130_OFFSET_X_REG(0) ... AD4130_OFFSET_X_REG(AD4130_MAX_SETUPS - 1)] = 3, + [AD4130_GAIN_X_REG(0) ... AD4130_GAIN_X_REG(AD4130_MAX_SETUPS - 1)] = 3, + [AD4130_MISC_REG] = 2, + [AD4130_FIFO_CONTROL_REG] = 3, + [AD4130_FIFO_STATUS_REG] = 1, + [AD4130_FIFO_THRESHOLD_REG] = 3, + [AD4130_FIFO_DATA_REG] = 3, +}; + +enum ad4130_int_ref_val { + AD4130_INT_REF_VAL_2_5V, + AD4130_INT_REF_VAL_1_25V, +}; + +enum ad4130_mclk_sel { + AD4130_MCLK_76_8KHZ, + AD4130_MCLK_76_8KHZ_OUT, + AD4130_MCLK_76_8KHZ_EXT, + AD4130_MCLK_153_6KHZ_EXT, +}; + +enum ad4130_int_pin_sel { + AD4130_INT_PIN_INT, + AD4130_INT_PIN_CLK, + AD4130_INT_PIN_P2, + AD4130_INT_PIN_DOUT, +}; + +enum ad4130_iout { + AD4130_IOUT_OFF, + AD4130_IOUT_10000NA, + AD4130_IOUT_20000NA, + AD4130_IOUT_50000NA, + AD4130_IOUT_100000NA, + AD4130_IOUT_150000NA, + AD4130_IOUT_200000NA, + AD4130_IOUT_100NA, + AD4130_IOUT_MAX +}; + +enum ad4130_burnout { + AD4130_BURNOUT_OFF, + AD4130_BURNOUT_500NA, + AD4130_BURNOUT_2000NA, + AD4130_BURNOUT_4000NA, + AD4130_BURNOUT_MAX +}; + +enum ad4130_ref_sel { + AD4130_REF_REFIN1, + AD4130_REF_REFIN2, + AD4130_REF_REFOUT_AVSS, + AD4130_REF_AVDD_AVSS, + AD4130_REF_SEL_MAX +}; + +enum ad4130_fifo_mode { + AD4130_FIFO_MODE_DISABLED = 0b00, + AD4130_FIFO_MODE_WM = 0b01, +}; + +enum ad4130_mode { + AD4130_MODE_CONTINUOUS = 0b0000, + AD4130_MODE_IDLE = 0b0100, +}; + +enum ad4130_filter_mode { + AD4130_FILTER_SINC4, + AD4130_FILTER_SINC4_SINC1, + AD4130_FILTER_SINC3, + AD4130_FILTER_SINC3_REJ60, + AD4130_FILTER_SINC3_SINC1, + AD4130_FILTER_SINC3_PF1, + AD4130_FILTER_SINC3_PF2, + AD4130_FILTER_SINC3_PF3, + AD4130_FILTER_SINC3_PF4, +}; + +enum ad4130_pin_function { + AD4130_PIN_FN_NONE, + AD4130_PIN_FN_SPECIAL = BIT(0), + AD4130_PIN_FN_DIFF = BIT(1), + AD4130_PIN_FN_EXCITATION = BIT(2), + AD4130_PIN_FN_VBIAS = BIT(3), +}; + +struct ad4130_setup_info { + unsigned int iout0_val; + unsigned int iout1_val; + unsigned int burnout; + unsigned int pga; + unsigned int fs; + u32 ref_sel; + enum ad4130_filter_mode filter_mode; + bool ref_bufp; + bool ref_bufm; +}; + +struct ad4130_slot_info { + struct ad4130_setup_info setup; + unsigned int enabled_channels; + unsigned int channels; +}; + +struct ad4130_chan_info { + struct ad4130_setup_info setup; + u32 iout0; + u32 iout1; + int slot; + bool enabled; + bool initialized; +}; + +struct ad4130_filter_config { + enum ad4130_filter_mode filter_mode; + unsigned int odr_div; + unsigned int fs_max; + enum iio_available_type samp_freq_avail_type; + int samp_freq_avail_len; + int samp_freq_avail[3][2]; +}; + +struct ad4130_state { + struct regmap *regmap; + struct spi_device *spi; + struct clk *mclk; + struct regulator_bulk_data regulators[4]; + u32 irq_trigger; + u32 inv_irq_trigger; + + /* + * Synchronize access to members the of driver state, and ensure + * atomicity of consecutive regmap operations. + */ + struct mutex lock; + struct completion completion; + + struct iio_chan_spec chans[AD4130_MAX_CHANNELS]; + struct ad4130_chan_info chans_info[AD4130_MAX_CHANNELS]; + struct ad4130_slot_info slots_info[AD4130_MAX_SETUPS]; + enum ad4130_pin_function pins_fn[AD4130_MAX_ANALOG_PINS]; + u32 vbias_pins[AD4130_MAX_ANALOG_PINS]; + u32 num_vbias_pins; + int scale_tbls[AD4130_REF_SEL_MAX][AD4130_MAX_PGA][2]; + struct gpio_chip gc; + struct clk_hw int_clk_hw; + + u32 int_pin_sel; + u32 int_ref_uv; + u32 mclk_sel; + bool int_ref_en; + bool bipolar; + + unsigned int num_enabled_channels; + unsigned int effective_watermark; + unsigned int watermark; + + struct spi_message fifo_msg; + struct spi_transfer fifo_xfer[2]; + + /* + * DMA (thus cache coherency maintenance) requires any transfer + * buffers to live in their own cache lines. As the use of these + * buffers is synchronous, all of the buffers used for DMA in this + * driver may share a cache line. + */ + u8 reset_buf[AD4130_RESET_BUF_SIZE] __aligned(IIO_DMA_MINALIGN); + u8 reg_write_tx_buf[4]; + u8 reg_read_tx_buf[1]; + u8 reg_read_rx_buf[3]; + u8 fifo_tx_buf[2]; + u8 fifo_rx_buf[AD4130_FIFO_SIZE * + AD4130_FIFO_MAX_SAMPLE_SIZE]; +}; + +static const char * const ad4130_int_pin_names[] = { + [AD4130_INT_PIN_INT] = "int", + [AD4130_INT_PIN_CLK] = "clk", + [AD4130_INT_PIN_P2] = "p2", + [AD4130_INT_PIN_DOUT] = "dout", +}; + +static const unsigned int ad4130_iout_current_na_tbl[AD4130_IOUT_MAX] = { + [AD4130_IOUT_OFF] = 0, + [AD4130_IOUT_100NA] = 100, + [AD4130_IOUT_10000NA] = 10000, + [AD4130_IOUT_20000NA] = 20000, + [AD4130_IOUT_50000NA] = 50000, + [AD4130_IOUT_100000NA] = 100000, + [AD4130_IOUT_150000NA] = 150000, + [AD4130_IOUT_200000NA] = 200000, +}; + +static const unsigned int ad4130_burnout_current_na_tbl[AD4130_BURNOUT_MAX] = { + [AD4130_BURNOUT_OFF] = 0, + [AD4130_BURNOUT_500NA] = 500, + [AD4130_BURNOUT_2000NA] = 2000, + [AD4130_BURNOUT_4000NA] = 4000, +}; + +#define AD4130_VARIABLE_ODR_CONFIG(_filter_mode, _odr_div, _fs_max) \ +{ \ + .filter_mode = (_filter_mode), \ + .odr_div = (_odr_div), \ + .fs_max = (_fs_max), \ + .samp_freq_avail_type = IIO_AVAIL_RANGE, \ + .samp_freq_avail = { \ + { AD4130_MAX_ODR, (_odr_div) * (_fs_max) }, \ + { AD4130_MAX_ODR, (_odr_div) * (_fs_max) }, \ + { AD4130_MAX_ODR, (_odr_div) }, \ + }, \ +} + +#define AD4130_FIXED_ODR_CONFIG(_filter_mode, _odr_div) \ +{ \ + .filter_mode = (_filter_mode), \ + .odr_div = (_odr_div), \ + .fs_max = AD4130_FILTER_SELECT_MIN, \ + .samp_freq_avail_type = IIO_AVAIL_LIST, \ + .samp_freq_avail_len = 1, \ + .samp_freq_avail = { \ + { AD4130_MAX_ODR, (_odr_div) }, \ + }, \ +} + +static const struct ad4130_filter_config ad4130_filter_configs[] = { + AD4130_VARIABLE_ODR_CONFIG(AD4130_FILTER_SINC4, 1, 10), + AD4130_VARIABLE_ODR_CONFIG(AD4130_FILTER_SINC4_SINC1, 11, 10), + AD4130_VARIABLE_ODR_CONFIG(AD4130_FILTER_SINC3, 1, 2047), + AD4130_VARIABLE_ODR_CONFIG(AD4130_FILTER_SINC3_REJ60, 1, 2047), + AD4130_VARIABLE_ODR_CONFIG(AD4130_FILTER_SINC3_SINC1, 10, 2047), + AD4130_FIXED_ODR_CONFIG(AD4130_FILTER_SINC3_PF1, 92), + AD4130_FIXED_ODR_CONFIG(AD4130_FILTER_SINC3_PF2, 100), + AD4130_FIXED_ODR_CONFIG(AD4130_FILTER_SINC3_PF3, 124), + AD4130_FIXED_ODR_CONFIG(AD4130_FILTER_SINC3_PF4, 148), +}; + +static const char * const ad4130_filter_modes_str[] = { + [AD4130_FILTER_SINC4] = "sinc4", + [AD4130_FILTER_SINC4_SINC1] = "sinc4+sinc1", + [AD4130_FILTER_SINC3] = "sinc3", + [AD4130_FILTER_SINC3_REJ60] = "sinc3+rej60", + [AD4130_FILTER_SINC3_SINC1] = "sinc3+sinc1", + [AD4130_FILTER_SINC3_PF1] = "sinc3+pf1", + [AD4130_FILTER_SINC3_PF2] = "sinc3+pf2", + [AD4130_FILTER_SINC3_PF3] = "sinc3+pf3", + [AD4130_FILTER_SINC3_PF4] = "sinc3+pf4", +}; + +static int ad4130_get_reg_size(struct ad4130_state *st, unsigned int reg, + unsigned int *size) +{ + if (reg >= ARRAY_SIZE(ad4130_reg_size)) + return -EINVAL; + + *size = ad4130_reg_size[reg]; + + return 0; +} + +static unsigned int ad4130_data_reg_size(struct ad4130_state *st) +{ + unsigned int data_reg_size; + int ret; + + ret = ad4130_get_reg_size(st, AD4130_DATA_REG, &data_reg_size); + if (ret) + return 0; + + return data_reg_size; +} + +static unsigned int ad4130_resolution(struct ad4130_state *st) +{ + return ad4130_data_reg_size(st) * BITS_PER_BYTE; +} + +static int ad4130_reg_write(void *context, unsigned int reg, unsigned int val) +{ + struct ad4130_state *st = context; + unsigned int size; + int ret; + + ret = ad4130_get_reg_size(st, reg, &size); + if (ret) + return ret; + + st->reg_write_tx_buf[0] = reg; + + switch (size) { + case 3: + put_unaligned_be24(val, &st->reg_write_tx_buf[1]); + break; + case 2: + put_unaligned_be16(val, &st->reg_write_tx_buf[1]); + break; + case 1: + st->reg_write_tx_buf[1] = val; + break; + default: + return -EINVAL; + } + + return spi_write(st->spi, st->reg_write_tx_buf, size + 1); +} + +static int ad4130_reg_read(void *context, unsigned int reg, unsigned int *val) +{ + struct ad4130_state *st = context; + struct spi_transfer t[] = { + { + .tx_buf = st->reg_read_tx_buf, + .len = sizeof(st->reg_read_tx_buf), + }, + { + .rx_buf = st->reg_read_rx_buf, + }, + }; + unsigned int size; + int ret; + + ret = ad4130_get_reg_size(st, reg, &size); + if (ret) + return ret; + + st->reg_read_tx_buf[0] = AD4130_COMMS_READ_MASK | reg; + t[1].len = size; + + ret = spi_sync_transfer(st->spi, t, ARRAY_SIZE(t)); + if (ret) + return ret; + + switch (size) { + case 3: + *val = get_unaligned_be24(st->reg_read_rx_buf); + break; + case 2: + *val = get_unaligned_be16(st->reg_read_rx_buf); + break; + case 1: + *val = st->reg_read_rx_buf[0]; + break; + default: + return -EINVAL; + } + + return 0; +} + +static const struct regmap_config ad4130_regmap_config = { + .reg_read = ad4130_reg_read, + .reg_write = ad4130_reg_write, +}; + +static int ad4130_gpio_init_valid_mask(struct gpio_chip *gc, + unsigned long *valid_mask, + unsigned int ngpios) +{ + struct ad4130_state *st = gpiochip_get_data(gc); + unsigned int i; + + /* + * Output-only GPIO functionality is available on pins AIN2 through + * AIN5. If these pins are used for anything else, do not expose them. + */ + for (i = 0; i < ngpios; i++) { + unsigned int pin = i + AD4130_AIN2_P1; + bool valid = st->pins_fn[pin] == AD4130_PIN_FN_NONE; + + __assign_bit(i, valid_mask, valid); + } + + return 0; +} + +static int ad4130_gpio_get_direction(struct gpio_chip *gc, unsigned int offset) +{ + return GPIO_LINE_DIRECTION_OUT; +} + +static void ad4130_gpio_set(struct gpio_chip *gc, unsigned int offset, + int value) +{ + struct ad4130_state *st = gpiochip_get_data(gc); + unsigned int mask = FIELD_PREP(AD4130_IO_CONTROL_GPIO_DATA_MASK, + BIT(offset)); + + regmap_update_bits(st->regmap, AD4130_IO_CONTROL_REG, mask, + value ? mask : 0); +} + +static int ad4130_set_mode(struct ad4130_state *st, enum ad4130_mode mode) +{ + return regmap_update_bits(st->regmap, AD4130_ADC_CONTROL_REG, + AD4130_ADC_CONTROL_MODE_MASK, + FIELD_PREP(AD4130_ADC_CONTROL_MODE_MASK, mode)); +} + +static int ad4130_set_watermark_interrupt_en(struct ad4130_state *st, bool en) +{ + return regmap_update_bits(st->regmap, AD4130_FIFO_CONTROL_REG, + AD4130_FIFO_CONTROL_WM_INT_EN_MASK, + FIELD_PREP(AD4130_FIFO_CONTROL_WM_INT_EN_MASK, en)); +} + +static unsigned int ad4130_watermark_reg_val(unsigned int val) +{ + if (val == AD4130_FIFO_SIZE) + val = AD4130_WATERMARK_256; + + return val; +} + +static int ad4130_set_fifo_mode(struct ad4130_state *st, + enum ad4130_fifo_mode mode) +{ + return regmap_update_bits(st->regmap, AD4130_FIFO_CONTROL_REG, + AD4130_FIFO_CONTROL_MODE_MASK, + FIELD_PREP(AD4130_FIFO_CONTROL_MODE_MASK, mode)); +} + +static void ad4130_push_fifo_data(struct iio_dev *indio_dev) +{ + struct ad4130_state *st = iio_priv(indio_dev); + unsigned int data_reg_size = ad4130_data_reg_size(st); + unsigned int transfer_len = st->effective_watermark * data_reg_size; + unsigned int set_size = st->num_enabled_channels * data_reg_size; + unsigned int i; + int ret; + + st->fifo_tx_buf[1] = ad4130_watermark_reg_val(st->effective_watermark); + st->fifo_xfer[1].len = transfer_len; + + ret = spi_sync(st->spi, &st->fifo_msg); + if (ret) + return; + + for (i = 0; i < transfer_len; i += set_size) + iio_push_to_buffers(indio_dev, &st->fifo_rx_buf[i]); +} + +static irqreturn_t ad4130_irq_handler(int irq, void *private) +{ + struct iio_dev *indio_dev = private; + struct ad4130_state *st = iio_priv(indio_dev); + + if (iio_buffer_enabled(indio_dev)) + ad4130_push_fifo_data(indio_dev); + else + complete(&st->completion); + + return IRQ_HANDLED; +} + +static int ad4130_find_slot(struct ad4130_state *st, + struct ad4130_setup_info *target_setup_info, + unsigned int *slot, bool *overwrite) +{ + unsigned int i; + + *slot = AD4130_INVALID_SLOT; + *overwrite = false; + + for (i = 0; i < AD4130_MAX_SETUPS; i++) { + struct ad4130_slot_info *slot_info = &st->slots_info[i]; + + /* Immediately accept a matching setup info. */ + if (!memcmp(target_setup_info, &slot_info->setup, + sizeof(*target_setup_info))) { + *slot = i; + return 0; + } + + /* Ignore all setups which are used by enabled channels. */ + if (slot_info->enabled_channels) + continue; + + /* Find the least used slot. */ + if (*slot == AD4130_INVALID_SLOT || + slot_info->channels < st->slots_info[*slot].channels) + *slot = i; + } + + if (*slot == AD4130_INVALID_SLOT) + return -EINVAL; + + *overwrite = true; + + return 0; +} + +static void ad4130_unlink_channel(struct ad4130_state *st, unsigned int channel) +{ + struct ad4130_chan_info *chan_info = &st->chans_info[channel]; + struct ad4130_slot_info *slot_info = &st->slots_info[chan_info->slot]; + + chan_info->slot = AD4130_INVALID_SLOT; + slot_info->channels--; +} + +static int ad4130_unlink_slot(struct ad4130_state *st, unsigned int slot) +{ + unsigned int i; + + for (i = 0; i < AD4130_MAX_CHANNELS; i++) { + struct ad4130_chan_info *chan_info = &st->chans_info[i]; + + if (!chan_info->initialized || chan_info->slot != slot) + continue; + + ad4130_unlink_channel(st, i); + } + + return 0; +} + +static int ad4130_link_channel_slot(struct ad4130_state *st, + unsigned int channel, unsigned int slot) +{ + struct ad4130_slot_info *slot_info = &st->slots_info[slot]; + struct ad4130_chan_info *chan_info = &st->chans_info[channel]; + int ret; + + ret = regmap_update_bits(st->regmap, AD4130_CHANNEL_X_REG(channel), + AD4130_CHANNEL_SETUP_MASK, + FIELD_PREP(AD4130_CHANNEL_SETUP_MASK, slot)); + if (ret) + return ret; + + chan_info->slot = slot; + slot_info->channels++; + + return 0; +} + +static int ad4130_write_slot_setup(struct ad4130_state *st, + unsigned int slot, + struct ad4130_setup_info *setup_info) +{ + unsigned int val; + int ret; + + val = FIELD_PREP(AD4130_CONFIG_IOUT1_VAL_MASK, setup_info->iout0_val) | + FIELD_PREP(AD4130_CONFIG_IOUT1_VAL_MASK, setup_info->iout1_val) | + FIELD_PREP(AD4130_CONFIG_BURNOUT_MASK, setup_info->burnout) | + FIELD_PREP(AD4130_CONFIG_REF_BUFP_MASK, setup_info->ref_bufp) | + FIELD_PREP(AD4130_CONFIG_REF_BUFM_MASK, setup_info->ref_bufm) | + FIELD_PREP(AD4130_CONFIG_REF_SEL_MASK, setup_info->ref_sel) | + FIELD_PREP(AD4130_CONFIG_PGA_MASK, setup_info->pga); + + ret = regmap_write(st->regmap, AD4130_CONFIG_X_REG(slot), val); + if (ret) + return ret; + + val = FIELD_PREP(AD4130_FILTER_MODE_MASK, setup_info->filter_mode) | + FIELD_PREP(AD4130_FILTER_SELECT_MASK, setup_info->fs); + + ret = regmap_write(st->regmap, AD4130_FILTER_X_REG(slot), val); + if (ret) + return ret; + + memcpy(&st->slots_info[slot].setup, setup_info, sizeof(*setup_info)); + + return 0; +} + +static int ad4130_write_channel_setup(struct ad4130_state *st, + unsigned int channel, bool on_enable) +{ + struct ad4130_chan_info *chan_info = &st->chans_info[channel]; + struct ad4130_setup_info *setup_info = &chan_info->setup; + bool overwrite; + int slot; + int ret; + + /* + * The following cases need to be handled. + * + * 1. Enabled and linked channel with setup changes: + * - Find a slot. If not possible, return error. + * - Unlink channel from current slot. + * - If the slot has channels linked to it, unlink all channels, and + * write the new setup to it. + * - Link channel to new slot. + * + * 2. Soon to be enabled and unlinked channel: + * - Find a slot. If not possible, return error. + * - If the slot has channels linked to it, unlink all channels, and + * write the new setup to it. + * - Link channel to the slot. + * + * 3. Disabled and linked channel with setup changes: + * - Unlink channel from current slot. + * + * 4. Soon to be enabled and linked channel: + * 5. Disabled and unlinked channel with setup changes: + * - Do nothing. + */ + + /* Case 4 */ + if (on_enable && chan_info->slot != AD4130_INVALID_SLOT) + return 0; + + if (!on_enable && !chan_info->enabled) { + if (chan_info->slot != AD4130_INVALID_SLOT) + /* Case 3 */ + ad4130_unlink_channel(st, channel); + + /* Cases 3 & 5 */ + return 0; + } + + /* Cases 1 & 2 */ + ret = ad4130_find_slot(st, setup_info, &slot, &overwrite); + if (ret) + return ret; + + if (chan_info->slot != AD4130_INVALID_SLOT) + /* Case 1 */ + ad4130_unlink_channel(st, channel); + + if (overwrite) { + ret = ad4130_unlink_slot(st, slot); + if (ret) + return ret; + + ret = ad4130_write_slot_setup(st, slot, setup_info); + if (ret) + return ret; + } + + return ad4130_link_channel_slot(st, channel, slot); +} + +static int ad4130_set_channel_enable(struct ad4130_state *st, + unsigned int channel, bool status) +{ + struct ad4130_chan_info *chan_info = &st->chans_info[channel]; + struct ad4130_slot_info *slot_info; + int ret; + + if (chan_info->enabled == status) + return 0; + + if (status) { + ret = ad4130_write_channel_setup(st, channel, true); + if (ret) + return ret; + } + + slot_info = &st->slots_info[chan_info->slot]; + + ret = regmap_update_bits(st->regmap, AD4130_CHANNEL_X_REG(channel), + AD4130_CHANNEL_EN_MASK, + FIELD_PREP(AD4130_CHANNEL_EN_MASK, status)); + if (ret) + return ret; + + slot_info->enabled_channels += status ? 1 : -1; + chan_info->enabled = status; + + return 0; +} + +/* + * Table 58. FILTER_MODE_n bits and Filter Types of the datasheet describes + * the relation between filter mode, ODR and FS. + * + * Notice that the max ODR of each filter mode is not necessarily the + * absolute max ODR supported by the chip. + * + * The ODR divider is not explicitly specified, but it can be deduced based + * on the ODR range of each filter mode. + * + * For example, for Sinc4+Sinc1, max ODR is 218.18. That means that the + * absolute max ODR is divided by 11 to achieve the max ODR of this filter + * mode. + * + * The formulas for converting between ODR and FS for a specific filter + * mode can be deduced from the same table. + * + * Notice that FS = 1 actually means max ODR, and that ODR decreases by + * (maximum ODR / maximum FS) for each increment of FS. + * + * odr = MAX_ODR / odr_div * (1 - (fs - 1) / fs_max) <=> + * odr = MAX_ODR * (1 - (fs - 1) / fs_max) / odr_div <=> + * odr = MAX_ODR * (1 - (fs - 1) / fs_max) / odr_div <=> + * odr = MAX_ODR * (fs_max - fs + 1) / (fs_max * odr_div) + * (used in ad4130_fs_to_freq) + * + * For the opposite formula, FS can be extracted from the last one. + * + * MAX_ODR * (fs_max - fs + 1) = fs_max * odr_div * odr <=> + * fs_max - fs + 1 = fs_max * odr_div * odr / MAX_ODR <=> + * fs = 1 + fs_max - fs_max * odr_div * odr / MAX_ODR + * (used in ad4130_fs_to_freq) + */ + +static void ad4130_freq_to_fs(enum ad4130_filter_mode filter_mode, + int val, int val2, unsigned int *fs) +{ + const struct ad4130_filter_config *filter_config = + &ad4130_filter_configs[filter_mode]; + u64 dividend, divisor; + int temp; + + dividend = filter_config->fs_max * filter_config->odr_div * + ((u64)val * NANO + val2); + divisor = (u64)AD4130_MAX_ODR * NANO; + + temp = AD4130_FILTER_SELECT_MIN + filter_config->fs_max - + DIV64_U64_ROUND_CLOSEST(dividend, divisor); + + if (temp < AD4130_FILTER_SELECT_MIN) + temp = AD4130_FILTER_SELECT_MIN; + else if (temp > filter_config->fs_max) + temp = filter_config->fs_max; + + *fs = temp; +} + +static void ad4130_fs_to_freq(enum ad4130_filter_mode filter_mode, + unsigned int fs, int *val, int *val2) +{ + const struct ad4130_filter_config *filter_config = + &ad4130_filter_configs[filter_mode]; + unsigned int dividend, divisor; + u64 temp; + + dividend = (filter_config->fs_max - fs + AD4130_FILTER_SELECT_MIN) * + AD4130_MAX_ODR; + divisor = filter_config->fs_max * filter_config->odr_div; + + temp = div_u64((u64)dividend * NANO, divisor); + *val = div_u64_rem(temp, NANO, val2); +} + +static int ad4130_set_filter_mode(struct iio_dev *indio_dev, + const struct iio_chan_spec *chan, + unsigned int val) +{ + struct ad4130_state *st = iio_priv(indio_dev); + unsigned int channel = chan->scan_index; + struct ad4130_chan_info *chan_info = &st->chans_info[channel]; + struct ad4130_setup_info *setup_info = &chan_info->setup; + enum ad4130_filter_mode old_filter_mode; + int freq_val, freq_val2; + unsigned int old_fs; + int ret = 0; + + mutex_lock(&st->lock); + if (setup_info->filter_mode == val) + goto out; + + old_fs = setup_info->fs; + old_filter_mode = setup_info->filter_mode; + + /* + * When switching between filter modes, try to match the ODR as + * close as possible. To do this, convert the current FS into ODR + * using the old filter mode, then convert it back into FS using + * the new filter mode. + */ + ad4130_fs_to_freq(setup_info->filter_mode, setup_info->fs, + &freq_val, &freq_val2); + + ad4130_freq_to_fs(val, freq_val, freq_val2, &setup_info->fs); + + setup_info->filter_mode = val; + + ret = ad4130_write_channel_setup(st, channel, false); + if (ret) { + setup_info->fs = old_fs; + setup_info->filter_mode = old_filter_mode; + } + + out: + mutex_unlock(&st->lock); + + return ret; +} + +static int ad4130_get_filter_mode(struct iio_dev *indio_dev, + const struct iio_chan_spec *chan) +{ + struct ad4130_state *st = iio_priv(indio_dev); + unsigned int channel = chan->scan_index; + struct ad4130_setup_info *setup_info = &st->chans_info[channel].setup; + enum ad4130_filter_mode filter_mode; + + mutex_lock(&st->lock); + filter_mode = setup_info->filter_mode; + mutex_unlock(&st->lock); + + return filter_mode; +} + +static const struct iio_enum ad4130_filter_mode_enum = { + .items = ad4130_filter_modes_str, + .num_items = ARRAY_SIZE(ad4130_filter_modes_str), + .set = ad4130_set_filter_mode, + .get = ad4130_get_filter_mode, +}; + +static const struct iio_chan_spec_ext_info ad4130_filter_mode_ext_info[] = { + IIO_ENUM("filter_mode", IIO_SEPARATE, &ad4130_filter_mode_enum), + IIO_ENUM_AVAILABLE("filter_mode", IIO_SHARED_BY_TYPE, + &ad4130_filter_mode_enum), + { } +}; + +static const struct iio_chan_spec ad4130_channel_template = { + .type = IIO_VOLTAGE, + .indexed = 1, + .differential = 1, + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | + BIT(IIO_CHAN_INFO_SCALE) | + BIT(IIO_CHAN_INFO_OFFSET) | + BIT(IIO_CHAN_INFO_SAMP_FREQ), + .info_mask_separate_available = BIT(IIO_CHAN_INFO_SCALE) | + BIT(IIO_CHAN_INFO_SAMP_FREQ), + .ext_info = ad4130_filter_mode_ext_info, + .scan_type = { + .sign = 'u', + .endianness = IIO_BE, + }, +}; + +static int ad4130_set_channel_pga(struct ad4130_state *st, unsigned int channel, + int val, int val2) +{ + struct ad4130_chan_info *chan_info = &st->chans_info[channel]; + struct ad4130_setup_info *setup_info = &chan_info->setup; + unsigned int pga, old_pga; + int ret = 0; + + for (pga = 0; pga < AD4130_MAX_PGA; pga++) + if (val == st->scale_tbls[setup_info->ref_sel][pga][0] && + val2 == st->scale_tbls[setup_info->ref_sel][pga][1]) + break; + + if (pga == AD4130_MAX_PGA) + return -EINVAL; + + mutex_lock(&st->lock); + if (pga == setup_info->pga) + goto out; + + old_pga = setup_info->pga; + setup_info->pga = pga; + + ret = ad4130_write_channel_setup(st, channel, false); + if (ret) + setup_info->pga = old_pga; + +out: + mutex_unlock(&st->lock); + + return ret; +} + +static int ad4130_set_channel_freq(struct ad4130_state *st, + unsigned int channel, int val, int val2) +{ + struct ad4130_chan_info *chan_info = &st->chans_info[channel]; + struct ad4130_setup_info *setup_info = &chan_info->setup; + unsigned int fs, old_fs; + int ret = 0; + + mutex_lock(&st->lock); + old_fs = setup_info->fs; + + ad4130_freq_to_fs(setup_info->filter_mode, val, val2, &fs); + + if (fs == setup_info->fs) + goto out; + + setup_info->fs = fs; + + ret = ad4130_write_channel_setup(st, channel, false); + if (ret) + setup_info->fs = old_fs; + +out: + mutex_unlock(&st->lock); + + return ret; +} + +static int _ad4130_read_sample(struct iio_dev *indio_dev, unsigned int channel, + int *val) +{ + struct ad4130_state *st = iio_priv(indio_dev); + int ret; + + ret = ad4130_set_channel_enable(st, channel, true); + if (ret) + return ret; + + reinit_completion(&st->completion); + + ret = ad4130_set_mode(st, AD4130_MODE_CONTINUOUS); + if (ret) + return ret; + + ret = wait_for_completion_timeout(&st->completion, + msecs_to_jiffies(1000)); + if (!ret) + return -ETIMEDOUT; + + ret = ad4130_set_mode(st, AD4130_MODE_IDLE); + if (ret) + return ret; + + ret = regmap_read(st->regmap, AD4130_DATA_REG, val); + if (ret) + return ret; + + ret = ad4130_set_channel_enable(st, channel, false); + if (ret) + return ret; + + return IIO_VAL_INT; +} + +static int ad4130_read_sample(struct iio_dev *indio_dev, unsigned int channel, + int *val) +{ + struct ad4130_state *st = iio_priv(indio_dev); + int ret; + + ret = iio_device_claim_direct_mode(indio_dev); + if (ret) + return ret; + + mutex_lock(&st->lock); + ret = _ad4130_read_sample(indio_dev, channel, val); + mutex_unlock(&st->lock); + + iio_device_release_direct_mode(indio_dev); + + return ret; +} + +static int ad4130_read_raw(struct iio_dev *indio_dev, + struct iio_chan_spec const *chan, + int *val, int *val2, long info) +{ + struct ad4130_state *st = iio_priv(indio_dev); + unsigned int channel = chan->scan_index; + struct ad4130_setup_info *setup_info = &st->chans_info[channel].setup; + + switch (info) { + case IIO_CHAN_INFO_RAW: + return ad4130_read_sample(indio_dev, channel, val); + case IIO_CHAN_INFO_SCALE: + mutex_lock(&st->lock); + *val = st->scale_tbls[setup_info->ref_sel][setup_info->pga][0]; + *val2 = st->scale_tbls[setup_info->ref_sel][setup_info->pga][1]; + mutex_unlock(&st->lock); + + return IIO_VAL_INT_PLUS_NANO; + case IIO_CHAN_INFO_OFFSET: + *val = st->bipolar ? -BIT(chan->scan_type.realbits - 1) : 0; + + return IIO_VAL_INT; + case IIO_CHAN_INFO_SAMP_FREQ: + mutex_lock(&st->lock); + ad4130_fs_to_freq(setup_info->filter_mode, setup_info->fs, + val, val2); + mutex_unlock(&st->lock); + + return IIO_VAL_INT_PLUS_NANO; + default: + return -EINVAL; + } +} + +static int ad4130_read_avail(struct iio_dev *indio_dev, + struct iio_chan_spec const *chan, + const int **vals, int *type, int *length, + long info) +{ + struct ad4130_state *st = iio_priv(indio_dev); + unsigned int channel = chan->scan_index; + struct ad4130_setup_info *setup_info = &st->chans_info[channel].setup; + const struct ad4130_filter_config *filter_config; + + switch (info) { + case IIO_CHAN_INFO_SCALE: + *vals = (int *)st->scale_tbls[setup_info->ref_sel]; + *length = ARRAY_SIZE(st->scale_tbls[setup_info->ref_sel]) * 2; + + *type = IIO_VAL_INT_PLUS_NANO; + + return IIO_AVAIL_LIST; + case IIO_CHAN_INFO_SAMP_FREQ: + mutex_lock(&st->lock); + filter_config = &ad4130_filter_configs[setup_info->filter_mode]; + mutex_unlock(&st->lock); + + *vals = (int *)filter_config->samp_freq_avail; + *length = filter_config->samp_freq_avail_len * 2; + *type = IIO_VAL_FRACTIONAL; + + return filter_config->samp_freq_avail_type; + default: + return -EINVAL; + } +} + +static int ad4130_write_raw_get_fmt(struct iio_dev *indio_dev, + struct iio_chan_spec const *chan, + long info) +{ + switch (info) { + case IIO_CHAN_INFO_SCALE: + case IIO_CHAN_INFO_SAMP_FREQ: + return IIO_VAL_INT_PLUS_NANO; + default: + return -EINVAL; + } +} + +static int ad4130_write_raw(struct iio_dev *indio_dev, + struct iio_chan_spec const *chan, + int val, int val2, long info) +{ + struct ad4130_state *st = iio_priv(indio_dev); + unsigned int channel = chan->scan_index; + + switch (info) { + case IIO_CHAN_INFO_SCALE: + return ad4130_set_channel_pga(st, channel, val, val2); + case IIO_CHAN_INFO_SAMP_FREQ: + return ad4130_set_channel_freq(st, channel, val, val2); + default: + return -EINVAL; + } +} + +static int ad4130_reg_access(struct iio_dev *indio_dev, unsigned int reg, + unsigned int writeval, unsigned int *readval) +{ + struct ad4130_state *st = iio_priv(indio_dev); + + if (readval) + return regmap_read(st->regmap, reg, readval); + + return regmap_write(st->regmap, reg, writeval); +} + +static int ad4130_update_scan_mode(struct iio_dev *indio_dev, + const unsigned long *scan_mask) +{ + struct ad4130_state *st = iio_priv(indio_dev); + unsigned int channel; + unsigned int val = 0; + int ret; + + mutex_lock(&st->lock); + + for_each_set_bit(channel, scan_mask, indio_dev->num_channels) { + ret = ad4130_set_channel_enable(st, channel, true); + if (ret) + goto out; + + val++; + } + + st->num_enabled_channels = val; + +out: + mutex_unlock(&st->lock); + + return 0; +} + +static int ad4130_set_fifo_watermark(struct iio_dev *indio_dev, unsigned int val) +{ + struct ad4130_state *st = iio_priv(indio_dev); + unsigned int eff; + int ret; + + if (val > AD4130_FIFO_SIZE) + return -EINVAL; + + eff = val * st->num_enabled_channels; + if (eff > AD4130_FIFO_SIZE) + /* + * Always set watermark to a multiple of the number of + * enabled channels to avoid making the FIFO unaligned. + */ + eff = rounddown(AD4130_FIFO_SIZE, st->num_enabled_channels); + + mutex_lock(&st->lock); + + ret = regmap_update_bits(st->regmap, AD4130_FIFO_CONTROL_REG, + AD4130_FIFO_CONTROL_WM_MASK, + FIELD_PREP(AD4130_FIFO_CONTROL_WM_MASK, + ad4130_watermark_reg_val(eff))); + if (ret) + goto out; + + st->effective_watermark = eff; + st->watermark = val; + +out: + mutex_unlock(&st->lock); + + return ret; +} + +static const struct iio_info ad4130_info = { + .read_raw = ad4130_read_raw, + .read_avail = ad4130_read_avail, + .write_raw_get_fmt = ad4130_write_raw_get_fmt, + .write_raw = ad4130_write_raw, + .update_scan_mode = ad4130_update_scan_mode, + .hwfifo_set_watermark = ad4130_set_fifo_watermark, + .debugfs_reg_access = ad4130_reg_access, +}; + +static int ad4130_buffer_postenable(struct iio_dev *indio_dev) +{ + struct ad4130_state *st = iio_priv(indio_dev); + int ret; + + mutex_lock(&st->lock); + + ret = ad4130_set_watermark_interrupt_en(st, true); + if (ret) + goto out; + + ret = irq_set_irq_type(st->spi->irq, st->inv_irq_trigger); + if (ret) + goto out; + + ret = ad4130_set_fifo_mode(st, AD4130_FIFO_MODE_WM); + if (ret) + goto out; + + ret = ad4130_set_mode(st, AD4130_MODE_CONTINUOUS); + +out: + mutex_unlock(&st->lock); + + return ret; +} + +static int ad4130_buffer_predisable(struct iio_dev *indio_dev) +{ + struct ad4130_state *st = iio_priv(indio_dev); + unsigned int i; + int ret; + + mutex_lock(&st->lock); + + ret = ad4130_set_mode(st, AD4130_MODE_IDLE); + if (ret) + goto out; + + ret = irq_set_irq_type(st->spi->irq, st->irq_trigger); + if (ret) + goto out; + + ret = ad4130_set_fifo_mode(st, AD4130_FIFO_MODE_DISABLED); + if (ret) + goto out; + + ret = ad4130_set_watermark_interrupt_en(st, false); + if (ret) + goto out; + + /* + * update_scan_mode() is not called in the disable path, disable all + * channels here. + */ + for (i = 0; i < indio_dev->num_channels; i++) { + ret = ad4130_set_channel_enable(st, i, false); + if (ret) + goto out; + } + +out: + mutex_unlock(&st->lock); + + return ret; +} + +static const struct iio_buffer_setup_ops ad4130_buffer_ops = { + .postenable = ad4130_buffer_postenable, + .predisable = ad4130_buffer_predisable, +}; + +static ssize_t hwfifo_watermark_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct ad4130_state *st = iio_priv(dev_to_iio_dev(dev)); + unsigned int val; + + mutex_lock(&st->lock); + val = st->watermark; + mutex_unlock(&st->lock); + + return sysfs_emit(buf, "%d\n", val); +} + +static ssize_t hwfifo_enabled_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct ad4130_state *st = iio_priv(dev_to_iio_dev(dev)); + unsigned int val; + int ret; + + ret = regmap_read(st->regmap, AD4130_FIFO_CONTROL_REG, &val); + if (ret) + return ret; + + val = FIELD_GET(AD4130_FIFO_CONTROL_MODE_MASK, val); + + return sysfs_emit(buf, "%d\n", val != AD4130_FIFO_MODE_DISABLED); +} + +static ssize_t hwfifo_watermark_min_show(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + return sysfs_emit(buf, "%s\n", "1"); +} + +static ssize_t hwfifo_watermark_max_show(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + return sysfs_emit(buf, "%s\n", __stringify(AD4130_FIFO_SIZE)); +} + +static IIO_DEVICE_ATTR_RO(hwfifo_watermark_min, 0); +static IIO_DEVICE_ATTR_RO(hwfifo_watermark_max, 0); +static IIO_DEVICE_ATTR_RO(hwfifo_watermark, 0); +static IIO_DEVICE_ATTR_RO(hwfifo_enabled, 0); + +static const struct attribute *ad4130_fifo_attributes[] = { + &iio_dev_attr_hwfifo_watermark_min.dev_attr.attr, + &iio_dev_attr_hwfifo_watermark_max.dev_attr.attr, + &iio_dev_attr_hwfifo_watermark.dev_attr.attr, + &iio_dev_attr_hwfifo_enabled.dev_attr.attr, + NULL +}; + +static int _ad4130_find_table_index(const unsigned int *tbl, size_t len, + unsigned int val) +{ + unsigned int i; + + for (i = 0; i < len; i++) + if (tbl[i] == val) + return i; + + return -EINVAL; +} + +#define ad4130_find_table_index(table, val) \ + _ad4130_find_table_index(table, ARRAY_SIZE(table), val) + +static int ad4130_get_ref_voltage(struct ad4130_state *st, + enum ad4130_ref_sel ref_sel) +{ + switch (ref_sel) { + case AD4130_REF_REFIN1: + return regulator_get_voltage(st->regulators[2].consumer); + case AD4130_REF_REFIN2: + return regulator_get_voltage(st->regulators[3].consumer); + case AD4130_REF_AVDD_AVSS: + return regulator_get_voltage(st->regulators[0].consumer); + case AD4130_REF_REFOUT_AVSS: + return st->int_ref_uv; + default: + return -EINVAL; + } +} + +static int ad4130_parse_fw_setup(struct ad4130_state *st, + struct fwnode_handle *child, + struct ad4130_setup_info *setup_info) +{ + struct device *dev = &st->spi->dev; + u32 tmp; + int ret; + + tmp = 0; + fwnode_property_read_u32(child, "adi,excitation-current-0-nanoamp", &tmp); + ret = ad4130_find_table_index(ad4130_iout_current_na_tbl, tmp); + if (ret < 0) + return dev_err_probe(dev, ret, + "Invalid excitation current %unA\n", tmp); + setup_info->iout0_val = ret; + + tmp = 0; + fwnode_property_read_u32(child, "adi,excitation-current-1-nanoamp", &tmp); + ret = ad4130_find_table_index(ad4130_iout_current_na_tbl, tmp); + if (ret < 0) + return dev_err_probe(dev, ret, + "Invalid excitation current %unA\n", tmp); + setup_info->iout1_val = ret; + + tmp = 0; + fwnode_property_read_u32(child, "adi,burnout-current-nanoamp", &tmp); + ret = ad4130_find_table_index(ad4130_burnout_current_na_tbl, tmp); + if (ret < 0) + return dev_err_probe(dev, ret, + "Invalid burnout current %unA\n", tmp); + setup_info->burnout = ret; + + setup_info->ref_bufp = fwnode_property_read_bool(child, "adi,buffered-positive"); + setup_info->ref_bufm = fwnode_property_read_bool(child, "adi,buffered-negative"); + + setup_info->ref_sel = AD4130_REF_REFIN1; + fwnode_property_read_u32(child, "adi,reference-select", + &setup_info->ref_sel); + if (setup_info->ref_sel >= AD4130_REF_SEL_MAX) + return dev_err_probe(dev, -EINVAL, + "Invalid reference selected %u\n", + setup_info->ref_sel); + + if (setup_info->ref_sel == AD4130_REF_REFOUT_AVSS) + st->int_ref_en = true; + + ret = ad4130_get_ref_voltage(st, setup_info->ref_sel); + if (ret < 0) + return dev_err_probe(dev, ret, "Cannot use reference %u\n", + setup_info->ref_sel); + + return 0; +} + +static int ad4130_validate_diff_channel(struct ad4130_state *st, u32 pin) +{ + struct device *dev = &st->spi->dev; + + if (pin >= AD4130_MAX_DIFF_INPUTS) + return dev_err_probe(dev, -EINVAL, + "Invalid diffreential channel %u\n", pin); + + if (pin >= AD4130_MAX_ANALOG_PINS) + return 0; + + if (st->pins_fn[pin] == AD4130_PIN_FN_SPECIAL) + return dev_err_probe(dev, -EINVAL, + "Pin %u already used with fn %u\n", pin, + st->pins_fn[pin]); + + st->pins_fn[pin] |= AD4130_PIN_FN_DIFF; + + return 0; +} + +static int ad4130_validate_diff_channels(struct ad4130_state *st, + u32 *pins, unsigned int len) +{ + unsigned int i; + int ret; + + for (i = 0; i < len; i++) { + ret = ad4130_validate_diff_channel(st, pins[i]); + if (ret) + return ret; + } + + return 0; +} + +static int ad4130_validate_excitation_pin(struct ad4130_state *st, u32 pin) +{ + struct device *dev = &st->spi->dev; + + if (pin >= AD4130_MAX_ANALOG_PINS) + return dev_err_probe(dev, -EINVAL, + "Invalid excitation pin %u\n", pin); + + if (st->pins_fn[pin] == AD4130_PIN_FN_SPECIAL) + return dev_err_probe(dev, -EINVAL, + "Pin %u already used with fn %u\n", pin, + st->pins_fn[pin]); + + st->pins_fn[pin] |= AD4130_PIN_FN_EXCITATION; + + return 0; +} + +static int ad4130_validate_vbias_pin(struct ad4130_state *st, u32 pin) +{ + struct device *dev = &st->spi->dev; + + if (pin >= AD4130_MAX_ANALOG_PINS) + return dev_err_probe(dev, -EINVAL, "Invalid vbias pin %u\n", + pin); + + if (st->pins_fn[pin] == AD4130_PIN_FN_SPECIAL) + return dev_err_probe(dev, -EINVAL, + "Pin %u already used with fn %u\n", pin, + st->pins_fn[pin]); + + st->pins_fn[pin] |= AD4130_PIN_FN_VBIAS; + + return 0; +} + +static int ad4130_validate_vbias_pins(struct ad4130_state *st, + u32 *pins, unsigned int len) +{ + unsigned int i; + int ret; + + for (i = 0; i < st->num_vbias_pins; i++) { + ret = ad4130_validate_vbias_pin(st, pins[i]); + if (ret) + return ret; + } + + return 0; +} + +static int ad4130_parse_fw_channel(struct iio_dev *indio_dev, + struct fwnode_handle *child) +{ + struct ad4130_state *st = iio_priv(indio_dev); + unsigned int resolution = ad4130_resolution(st); + unsigned int index = indio_dev->num_channels++; + struct device *dev = &st->spi->dev; + struct ad4130_chan_info *chan_info; + struct iio_chan_spec *chan; + u32 pins[2]; + int ret; + + if (index >= AD4130_MAX_CHANNELS) + return dev_err_probe(dev, -EINVAL, "Too many channels\n"); + + chan = &st->chans[index]; + chan_info = &st->chans_info[index]; + + *chan = ad4130_channel_template; + chan->scan_type.realbits = resolution; + chan->scan_type.storagebits = resolution; + chan->scan_index = index; + + chan_info->slot = AD4130_INVALID_SLOT; + chan_info->setup.fs = AD4130_FILTER_SELECT_MIN; + chan_info->initialized = true; + + ret = fwnode_property_read_u32_array(child, "diff-channels", pins, + ARRAY_SIZE(pins)); + if (ret) + return ret; + + ret = ad4130_validate_diff_channels(st, pins, ARRAY_SIZE(pins)); + if (ret) + return ret; + + chan->channel = pins[0]; + chan->channel2 = pins[1]; + + ret = ad4130_parse_fw_setup(st, child, &chan_info->setup); + if (ret) + return ret; + + fwnode_property_read_u32(child, "adi,excitation-pin-0", + &chan_info->iout0); + if (chan_info->setup.iout0_val != AD4130_IOUT_OFF) { + ret = ad4130_validate_excitation_pin(st, chan_info->iout0); + if (ret) + return ret; + } + + fwnode_property_read_u32(child, "adi,excitation-pin-1", + &chan_info->iout1); + if (chan_info->setup.iout1_val != AD4130_IOUT_OFF) { + ret = ad4130_validate_excitation_pin(st, chan_info->iout1); + if (ret) + return ret; + } + + return 0; +} + +static int ad4130_parse_fw_children(struct iio_dev *indio_dev) +{ + struct ad4130_state *st = iio_priv(indio_dev); + struct device *dev = &st->spi->dev; + struct fwnode_handle *child; + int ret; + + indio_dev->channels = st->chans; + + device_for_each_child_node(dev, child) { + ret = ad4130_parse_fw_channel(indio_dev, child); + if (ret) { + fwnode_handle_put(child); + return ret; + } + } + + return 0; +} + +static int ad4310_parse_fw(struct iio_dev *indio_dev) +{ + struct ad4130_state *st = iio_priv(indio_dev); + struct device *dev = &st->spi->dev; + u32 ext_clk_freq = AD4130_MCLK_FREQ_76_8KHZ; + unsigned int i; + int avdd_uv; + int irq; + int ret; + + st->mclk = devm_clk_get_optional(dev, "mclk"); + if (IS_ERR(st->mclk)) + return dev_err_probe(dev, PTR_ERR(st->mclk), + "Failed to get mclk\n"); + + st->int_pin_sel = AD4130_INT_PIN_INT; + + for (i = 0; i < ARRAY_SIZE(ad4130_int_pin_names); i++) { + irq = fwnode_irq_get_byname(dev_fwnode(dev), + ad4130_int_pin_names[i]); + if (irq > 0) { + st->int_pin_sel = i; + break; + } + } + + if (st->int_pin_sel == AD4130_INT_PIN_DOUT) + return dev_err_probe(dev, -EINVAL, + "Cannot use DOUT as interrupt pin\n"); + + if (st->int_pin_sel == AD4130_INT_PIN_P2) + st->pins_fn[AD4130_AIN3_P2] = AD4130_PIN_FN_SPECIAL; + + device_property_read_u32(dev, "adi,ext-clk-freq-hz", &ext_clk_freq); + if (ext_clk_freq != AD4130_MCLK_FREQ_153_6KHZ && + ext_clk_freq != AD4130_MCLK_FREQ_76_8KHZ) + return dev_err_probe(dev, -EINVAL, + "Invalid external clock frequency %u\n", + ext_clk_freq); + + if (st->mclk && ext_clk_freq == AD4130_MCLK_FREQ_153_6KHZ) + st->mclk_sel = AD4130_MCLK_153_6KHZ_EXT; + else if (st->mclk) + st->mclk_sel = AD4130_MCLK_76_8KHZ_EXT; + else + st->mclk_sel = AD4130_MCLK_76_8KHZ; + + if (st->int_pin_sel == AD4130_INT_PIN_CLK && + st->mclk_sel != AD4130_MCLK_76_8KHZ) + return dev_err_probe(dev, -EINVAL, + "Invalid clock %u for interrupt pin %u\n", + st->mclk_sel, st->int_pin_sel); + + st->int_ref_uv = AD4130_INT_REF_2_5V; + + /* + * When the AVDD supply is set to below 2.5V the internal reference of + * 1.25V should be selected. + * See datasheet page 37, section ADC REFERENCE. + */ + avdd_uv = regulator_get_voltage(st->regulators[0].consumer); + if (avdd_uv > 0 && avdd_uv < AD4130_INT_REF_2_5V) + st->int_ref_uv = AD4130_INT_REF_1_25V; + + st->bipolar = device_property_read_bool(dev, "adi,bipolar"); + + ret = device_property_count_u32(dev, "adi,vbias-pins"); + if (ret > 0) { + if (ret > AD4130_MAX_ANALOG_PINS) + return dev_err_probe(dev, -EINVAL, + "Too many vbias pins %u\n", ret); + + st->num_vbias_pins = ret; + + ret = device_property_read_u32_array(dev, "adi,vbias-pins", + st->vbias_pins, + st->num_vbias_pins); + if (ret) + return dev_err_probe(dev, ret, + "Failed to read vbias pins\n"); + + ret = ad4130_validate_vbias_pins(st, st->vbias_pins, + st->num_vbias_pins); + if (ret) + return ret; + } + + ret = ad4130_parse_fw_children(indio_dev); + if (ret) + return ret; + + return 0; +} + +static void ad4130_fill_scale_tbls(struct ad4130_state *st) +{ + unsigned int pow = ad4130_resolution(st) - st->bipolar; + unsigned int i, j; + + for (i = 0; i < AD4130_REF_SEL_MAX; i++) { + int ret; + u64 nv; + + ret = ad4130_get_ref_voltage(st, i); + if (ret < 0) + continue; + + nv = (u64)ret * NANO; + + for (j = 0; j < AD4130_MAX_PGA; j++) + st->scale_tbls[i][j][1] = div_u64(nv >> (pow + j), MILLI); + } +} + +static void ad4130_clk_disable_unprepare(void *clk) +{ + clk_disable_unprepare(clk); +} + +static int ad4130_set_mclk_sel(struct ad4130_state *st, + enum ad4130_mclk_sel mclk_sel) +{ + return regmap_update_bits(st->regmap, AD4130_ADC_CONTROL_REG, + AD4130_ADC_CONTROL_MCLK_SEL_MASK, + FIELD_PREP(AD4130_ADC_CONTROL_MCLK_SEL_MASK, + mclk_sel)); +} + +static unsigned long ad4130_int_clk_recalc_rate(struct clk_hw *hw, + unsigned long parent_rate) +{ + return AD4130_MCLK_FREQ_76_8KHZ; +} + +static int ad4130_int_clk_is_enabled(struct clk_hw *hw) +{ + struct ad4130_state *st = container_of(hw, struct ad4130_state, int_clk_hw); + + return st->mclk_sel == AD4130_MCLK_76_8KHZ_OUT; +} + +static int ad4130_int_clk_prepare(struct clk_hw *hw) +{ + struct ad4130_state *st = container_of(hw, struct ad4130_state, int_clk_hw); + int ret; + + ret = ad4130_set_mclk_sel(st, AD4130_MCLK_76_8KHZ_OUT); + if (ret) + return ret; + + st->mclk_sel = AD4130_MCLK_76_8KHZ_OUT; + + return 0; +} + +static void ad4130_int_clk_unprepare(struct clk_hw *hw) +{ + struct ad4130_state *st = container_of(hw, struct ad4130_state, int_clk_hw); + int ret; + + ret = ad4130_set_mclk_sel(st, AD4130_MCLK_76_8KHZ); + if (ret) + return; + + st->mclk_sel = AD4130_MCLK_76_8KHZ; +} + +static const struct clk_ops ad4130_int_clk_ops = { + .recalc_rate = ad4130_int_clk_recalc_rate, + .is_enabled = ad4130_int_clk_is_enabled, + .prepare = ad4130_int_clk_prepare, + .unprepare = ad4130_int_clk_unprepare, +}; + +static int ad4130_setup_int_clk(struct ad4130_state *st) +{ + struct device *dev = &st->spi->dev; + struct device_node *of_node = dev_of_node(dev); + struct clk_init_data init; + const char *clk_name; + struct clk *clk; + + if (st->int_pin_sel == AD4130_INT_PIN_CLK || + st->mclk_sel != AD4130_MCLK_76_8KHZ) + return 0; + + if (!of_node) + return 0; + + clk_name = of_node->name; + of_property_read_string(of_node, "clock-output-names", &clk_name); + + init.name = clk_name; + init.ops = &ad4130_int_clk_ops; + + st->int_clk_hw.init = &init; + clk = devm_clk_register(dev, &st->int_clk_hw); + if (IS_ERR(clk)) + return PTR_ERR(clk); + + return of_clk_add_provider(of_node, of_clk_src_simple_get, clk); +} + +static int ad4130_setup(struct iio_dev *indio_dev) +{ + struct ad4130_state *st = iio_priv(indio_dev); + struct device *dev = &st->spi->dev; + unsigned int int_ref_val; + unsigned long rate = AD4130_MCLK_FREQ_76_8KHZ; + unsigned int val; + unsigned int i; + int ret; + + if (st->mclk_sel == AD4130_MCLK_153_6KHZ_EXT) + rate = AD4130_MCLK_FREQ_153_6KHZ; + + ret = clk_set_rate(st->mclk, rate); + if (ret) + return ret; + + ret = clk_prepare_enable(st->mclk); + if (ret) + return ret; + + ret = devm_add_action_or_reset(dev, ad4130_clk_disable_unprepare, + st->mclk); + if (ret) + return ret; + + if (st->int_ref_uv == AD4130_INT_REF_2_5V) + int_ref_val = AD4130_INT_REF_VAL_2_5V; + else + int_ref_val = AD4130_INT_REF_VAL_1_25V; + + /* Switch to SPI 4-wire mode. */ + val = FIELD_PREP(AD4130_ADC_CONTROL_CSB_EN_MASK, 1); + val |= FIELD_PREP(AD4130_ADC_CONTROL_BIPOLAR_MASK, st->bipolar); + val |= FIELD_PREP(AD4130_ADC_CONTROL_INT_REF_EN_MASK, st->int_ref_en); + val |= FIELD_PREP(AD4130_ADC_CONTROL_MODE_MASK, AD4130_MODE_IDLE); + val |= FIELD_PREP(AD4130_ADC_CONTROL_MCLK_SEL_MASK, st->mclk_sel); + val |= FIELD_PREP(AD4130_ADC_CONTROL_INT_REF_VAL_MASK, int_ref_val); + + ret = regmap_write(st->regmap, AD4130_ADC_CONTROL_REG, val); + if (ret) + return ret; + + /* + * Configure all GPIOs for output. If configured, the interrupt function + * of P2 takes priority over the GPIO out function. + */ + val = AD4130_IO_CONTROL_GPIO_CTRL_MASK; + val |= FIELD_PREP(AD4130_IO_CONTROL_INT_PIN_SEL_MASK, st->int_pin_sel); + + ret = regmap_write(st->regmap, AD4130_IO_CONTROL_REG, val); + if (ret) + return ret; + + val = 0; + for (i = 0; i < st->num_vbias_pins; i++) + val |= BIT(st->vbias_pins[i]); + + ret = regmap_write(st->regmap, AD4130_VBIAS_REG, val); + if (ret) + return ret; + + ret = regmap_update_bits(st->regmap, AD4130_FIFO_CONTROL_REG, + AD4130_FIFO_CONTROL_HEADER_MASK, 0); + if (ret) + return ret; + + /* FIFO watermark interrupt starts out as enabled, disable it. */ + ret = ad4130_set_watermark_interrupt_en(st, false); + if (ret) + return ret; + + /* Setup channels. */ + for (i = 0; i < indio_dev->num_channels; i++) { + struct ad4130_chan_info *chan_info = &st->chans_info[i]; + struct iio_chan_spec *chan = &st->chans[i]; + unsigned int val; + + val = FIELD_PREP(AD4130_CHANNEL_AINP_MASK, chan->channel) | + FIELD_PREP(AD4130_CHANNEL_AINM_MASK, chan->channel2) | + FIELD_PREP(AD4130_CHANNEL_IOUT1_MASK, chan_info->iout0) | + FIELD_PREP(AD4130_CHANNEL_IOUT2_MASK, chan_info->iout1); + + ret = regmap_write(st->regmap, AD4130_CHANNEL_X_REG(i), val); + if (ret) + return ret; + } + + return 0; +} + +static int ad4130_soft_reset(struct ad4130_state *st) +{ + int ret; + + ret = spi_write(st->spi, st->reset_buf, sizeof(st->reset_buf)); + if (ret) + return ret; + + fsleep(AD4130_RESET_SLEEP_US); + + return 0; +} + +static void ad4130_disable_regulators(void *data) +{ + struct ad4130_state *st = data; + + regulator_bulk_disable(ARRAY_SIZE(st->regulators), st->regulators); +} + +static int ad4130_probe(struct spi_device *spi) +{ + struct device *dev = &spi->dev; + struct iio_dev *indio_dev; + struct ad4130_state *st; + int ret; + + indio_dev = devm_iio_device_alloc(dev, sizeof(*st)); + if (!indio_dev) + return -ENOMEM; + + st = iio_priv(indio_dev); + + memset(st->reset_buf, 0xff, sizeof(st->reset_buf)); + init_completion(&st->completion); + mutex_init(&st->lock); + st->spi = spi; + + /* + * Xfer: [ XFR1 ] [ XFR2 ] + * Master: 0x7D N ...................... + * Slave: ...... DATA1 DATA2 ... DATAN + */ + st->fifo_tx_buf[0] = AD4130_COMMS_READ_MASK | AD4130_FIFO_DATA_REG; + st->fifo_xfer[0].tx_buf = st->fifo_tx_buf; + st->fifo_xfer[0].len = sizeof(st->fifo_tx_buf); + st->fifo_xfer[1].rx_buf = st->fifo_rx_buf; + spi_message_init_with_transfers(&st->fifo_msg, st->fifo_xfer, + ARRAY_SIZE(st->fifo_xfer)); + + indio_dev->name = AD4130_NAME; + indio_dev->modes = INDIO_DIRECT_MODE; + indio_dev->info = &ad4130_info; + + st->regmap = devm_regmap_init(dev, NULL, st, &ad4130_regmap_config); + if (IS_ERR(st->regmap)) + return PTR_ERR(st->regmap); + + st->regulators[0].supply = "avdd"; + st->regulators[1].supply = "iovdd"; + st->regulators[2].supply = "refin1"; + st->regulators[3].supply = "refin2"; + + ret = devm_regulator_bulk_get(dev, ARRAY_SIZE(st->regulators), + st->regulators); + if (ret) + return dev_err_probe(dev, ret, "Failed to get regulators\n"); + + ret = regulator_bulk_enable(ARRAY_SIZE(st->regulators), st->regulators); + if (ret) + return dev_err_probe(dev, ret, "Failed to enable regulators\n"); + + ret = devm_add_action_or_reset(dev, ad4130_disable_regulators, st); + if (ret) + return dev_err_probe(dev, ret, + "Failed to add regulators disable action\n"); + + ret = ad4130_soft_reset(st); + if (ret) + return ret; + + ret = ad4310_parse_fw(indio_dev); + if (ret) + return ret; + + ret = ad4130_setup(indio_dev); + if (ret) + return ret; + + ret = ad4130_setup_int_clk(st); + if (ret) + return ret; + + ad4130_fill_scale_tbls(st); + + st->gc.owner = THIS_MODULE; + st->gc.label = AD4130_NAME; + st->gc.base = -1; + st->gc.ngpio = AD4130_MAX_GPIOS; + st->gc.parent = dev; + st->gc.can_sleep = true; + st->gc.init_valid_mask = ad4130_gpio_init_valid_mask; + st->gc.get_direction = ad4130_gpio_get_direction; + st->gc.set = ad4130_gpio_set; + + ret = devm_gpiochip_add_data(dev, &st->gc, st); + if (ret) + return ret; + + ret = devm_iio_kfifo_buffer_setup_ext(dev, indio_dev, + &ad4130_buffer_ops, + ad4130_fifo_attributes); + if (ret) + return ret; + + ret = devm_request_threaded_irq(dev, spi->irq, NULL, + ad4130_irq_handler, IRQF_ONESHOT, + indio_dev->name, indio_dev); + if (ret) + return dev_err_probe(dev, ret, "Failed to request irq\n"); + + /* + * When the chip enters FIFO mode, IRQ polarity is inverted. + * When the chip exits FIFO mode, IRQ polarity returns to normal. + * See datasheet pages: 65, FIFO Watermark Interrupt section, + * and 71, Bit Descriptions for STATUS Register, RDYB. + * Cache the normal and inverted IRQ triggers to set them when + * entering and exiting FIFO mode. + */ + st->irq_trigger = irq_get_trigger_type(spi->irq); + if (st->irq_trigger & IRQF_TRIGGER_RISING) + st->inv_irq_trigger = IRQF_TRIGGER_FALLING; + else if (st->irq_trigger & IRQF_TRIGGER_FALLING) + st->inv_irq_trigger = IRQF_TRIGGER_RISING; + else + return dev_err_probe(dev, -EINVAL, "Invalid irq flags: %u\n", + st->irq_trigger); + + return devm_iio_device_register(dev, indio_dev); +} + +static const struct of_device_id ad4130_of_match[] = { + { + .compatible = "adi,ad4130", + }, + { } +}; +MODULE_DEVICE_TABLE(of, ad4130_of_match); + +static struct spi_driver ad4130_driver = { + .driver = { + .name = AD4130_NAME, + .of_match_table = ad4130_of_match, + }, + .probe = ad4130_probe, +}; +module_spi_driver(ad4130_driver); + +MODULE_AUTHOR("Cosmin Tanislav "); +MODULE_DESCRIPTION("Analog Devices AD4130 SPI driver"); +MODULE_LICENSE("GPL"); -- cgit v1.2.3 From e9b96e18cf47133e51f4cb67d9dd9d163abc5f6d Mon Sep 17 00:00:00 2001 From: Jonathan Cameron Date: Sun, 16 Oct 2022 17:33:56 +0100 Subject: iio: accel: adxl367: Use devm_regulator_bulk_get_enable() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This driver only turns the power on at probe and off via a custom devm_add_action_or_reset() callback. The new devm_regulator_bulk_get_enable() replaces this boilerplate code. Signed-off-by: Jonathan Cameron Cc: Cosmin Tanislav Reviewed-by: Matti Vaittinen Reviewed-by: Nuno Sá Link: https://lore.kernel.org/r/20221016163409.320197-2-jic23@kernel.org --- drivers/iio/accel/adxl367.c | 28 ++++------------------------ 1 file changed, 4 insertions(+), 24 deletions(-) (limited to 'drivers/iio') diff --git a/drivers/iio/accel/adxl367.c b/drivers/iio/accel/adxl367.c index 7c7d78040793..d7af3a006a44 100644 --- a/drivers/iio/accel/adxl367.c +++ b/drivers/iio/accel/adxl367.c @@ -160,8 +160,6 @@ struct adxl367_state { struct device *dev; struct regmap *regmap; - struct regulator_bulk_data regulators[2]; - /* * Synchronize access to members of driver state, and ensure atomicity * of consecutive regmap operations. @@ -1487,16 +1485,10 @@ static int adxl367_setup(struct adxl367_state *st) return adxl367_set_measure_en(st, true); } -static void adxl367_disable_regulators(void *data) -{ - struct adxl367_state *st = data; - - regulator_bulk_disable(ARRAY_SIZE(st->regulators), st->regulators); -} - int adxl367_probe(struct device *dev, const struct adxl367_ops *ops, void *context, struct regmap *regmap, int irq) { + static const char * const regulator_names[] = { "vdd", "vddio" }; struct iio_dev *indio_dev; struct adxl367_state *st; int ret; @@ -1520,25 +1512,13 @@ int adxl367_probe(struct device *dev, const struct adxl367_ops *ops, indio_dev->info = &adxl367_info; indio_dev->modes = INDIO_DIRECT_MODE; - st->regulators[0].supply = "vdd"; - st->regulators[1].supply = "vddio"; - - ret = devm_regulator_bulk_get(st->dev, ARRAY_SIZE(st->regulators), - st->regulators); + ret = devm_regulator_bulk_get_enable(st->dev, + ARRAY_SIZE(regulator_names), + regulator_names); if (ret) return dev_err_probe(st->dev, ret, "Failed to get regulators\n"); - ret = regulator_bulk_enable(ARRAY_SIZE(st->regulators), st->regulators); - if (ret) - return dev_err_probe(st->dev, ret, - "Failed to enable regulators\n"); - - ret = devm_add_action_or_reset(st->dev, adxl367_disable_regulators, st); - if (ret) - return dev_err_probe(st->dev, ret, - "Failed to add regulators disable action\n"); - ret = regmap_write(st->regmap, ADXL367_REG_RESET, ADXL367_RESET_CODE); if (ret) return ret; -- cgit v1.2.3 From 5b30e739ceaf37aa5817195a20cd1fa7a4607623 Mon Sep 17 00:00:00 2001 From: Jonathan Cameron Date: Sun, 16 Oct 2022 17:33:58 +0100 Subject: iio: accel: fxls8962af: Use devm_regulator_get_enable() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This driver only turns the power on at probe and off via a custom devm_add_action_or_reset() callback. The new devm_regulator_get_enable() replaces this boilerplate code. Signed-off-by: Jonathan Cameron Cc: Sean Nyekjaer Reviewed-by: Sean Nyekjaer Reviewed-by: Matti Vaittinen Reviewed-by: Nuno Sá Link: https://lore.kernel.org/r/20221016163409.320197-4-jic23@kernel.org --- drivers/iio/accel/fxls8962af-core.c | 24 +++--------------------- 1 file changed, 3 insertions(+), 21 deletions(-) (limited to 'drivers/iio') diff --git a/drivers/iio/accel/fxls8962af-core.c b/drivers/iio/accel/fxls8962af-core.c index bf259db281f5..0d672b1469e8 100644 --- a/drivers/iio/accel/fxls8962af-core.c +++ b/drivers/iio/accel/fxls8962af-core.c @@ -159,7 +159,6 @@ struct fxls8962af_chip_info { struct fxls8962af_data { struct regmap *regmap; const struct fxls8962af_chip_info *chip_info; - struct regulator *vdd_reg; struct { __le16 channels[3]; s64 ts __aligned(8); @@ -1051,13 +1050,6 @@ static irqreturn_t fxls8962af_interrupt(int irq, void *p) return IRQ_NONE; } -static void fxls8962af_regulator_disable(void *data_ptr) -{ - struct fxls8962af_data *data = data_ptr; - - regulator_disable(data->vdd_reg); -} - static void fxls8962af_pm_disable(void *dev_ptr) { struct device *dev = dev_ptr; @@ -1171,20 +1163,10 @@ int fxls8962af_core_probe(struct device *dev, struct regmap *regmap, int irq) if (ret) return ret; - data->vdd_reg = devm_regulator_get(dev, "vdd"); - if (IS_ERR(data->vdd_reg)) - return dev_err_probe(dev, PTR_ERR(data->vdd_reg), - "Failed to get vdd regulator\n"); - - ret = regulator_enable(data->vdd_reg); - if (ret) { - dev_err(dev, "Failed to enable vdd regulator: %d\n", ret); - return ret; - } - - ret = devm_add_action_or_reset(dev, fxls8962af_regulator_disable, data); + ret = devm_regulator_get_enable(dev, "vdd"); if (ret) - return ret; + return dev_err_probe(dev, ret, + "Failed to get vdd regulator\n"); ret = regmap_read(data->regmap, FXLS8962AF_WHO_AM_I, ®); if (ret) -- cgit v1.2.3 From 1fa4ff1f249983b38394ee79379e028c1c501ae5 Mon Sep 17 00:00:00 2001 From: Jonathan Cameron Date: Sun, 16 Oct 2022 17:33:59 +0100 Subject: iio: accel: kxcjk-1013: Use devm_regulator_bulk_get_enable() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This driver only turns the power on at probe and off via a custom devm_add_action_or_reset() callback. The new devm_regulator_bulk_get_enable() replaces this boilerplate code. Signed-off-by: Jonathan Cameron Reviewed-by: Matti Vaittinen Reviewed-by: Nuno Sá Link: https://lore.kernel.org/r/20221016163409.320197-5-jic23@kernel.org --- drivers/iio/accel/kxcjk-1013.c | 25 ++++--------------------- 1 file changed, 4 insertions(+), 21 deletions(-) (limited to 'drivers/iio') diff --git a/drivers/iio/accel/kxcjk-1013.c b/drivers/iio/accel/kxcjk-1013.c index adc66b3615c0..e626b6fa8a36 100644 --- a/drivers/iio/accel/kxcjk-1013.c +++ b/drivers/iio/accel/kxcjk-1013.c @@ -241,7 +241,6 @@ enum kxcjk1013_axis { }; struct kxcjk1013_data { - struct regulator_bulk_data regulators[2]; struct i2c_client *client; struct iio_trigger *dready_trig; struct iio_trigger *motion_trig; @@ -1425,16 +1424,10 @@ static const char *kxcjk1013_match_acpi_device(struct device *dev, return dev_name(dev); } -static void kxcjk1013_disable_regulators(void *d) -{ - struct kxcjk1013_data *data = d; - - regulator_bulk_disable(ARRAY_SIZE(data->regulators), data->regulators); -} - static int kxcjk1013_probe(struct i2c_client *client, const struct i2c_device_id *id) { + static const char * const regulator_names[] = { "vdd", "vddio" }; struct kxcjk1013_data *data; struct iio_dev *indio_dev; struct kxcjk_1013_platform_data *pdata; @@ -1461,22 +1454,12 @@ static int kxcjk1013_probe(struct i2c_client *client, return ret; } - data->regulators[0].supply = "vdd"; - data->regulators[1].supply = "vddio"; - ret = devm_regulator_bulk_get(&client->dev, ARRAY_SIZE(data->regulators), - data->regulators); + ret = devm_regulator_bulk_get_enable(&client->dev, + ARRAY_SIZE(regulator_names), + regulator_names); if (ret) return dev_err_probe(&client->dev, ret, "Failed to get regulators\n"); - ret = regulator_bulk_enable(ARRAY_SIZE(data->regulators), - data->regulators); - if (ret) - return ret; - - ret = devm_add_action_or_reset(&client->dev, kxcjk1013_disable_regulators, data); - if (ret) - return ret; - /* * A typical delay of 10ms is required for powering up * according to the data sheets of supported chips. -- cgit v1.2.3 From eefa008b1677244d73ba47920172be36570c87c1 Mon Sep 17 00:00:00 2001 From: Jonathan Cameron Date: Sun, 16 Oct 2022 17:34:00 +0100 Subject: iio: accel: msa311: Use devm_regulator_get_enable() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This driver only turns the power on at probe and off via a custom devm_add_action_or_reset() callback. The new devm_regulator_get_enable() replaces this boilerplate code. Signed-off-by: Jonathan Cameron Cc: Dmitry Rokosov Reviewed-by: Dmitry Rokosov Reviewed-by: Nuno Sá Link: https://lore.kernel.org/r/20221016163409.320197-6-jic23@kernel.org --- drivers/iio/accel/msa311.c | 21 ++------------------- 1 file changed, 2 insertions(+), 19 deletions(-) (limited to 'drivers/iio') diff --git a/drivers/iio/accel/msa311.c b/drivers/iio/accel/msa311.c index 2fded3759171..af94d3adf6d8 100644 --- a/drivers/iio/accel/msa311.c +++ b/drivers/iio/accel/msa311.c @@ -351,7 +351,6 @@ static const struct regmap_config msa311_regmap_config = { * @chip_name: Chip name in the format "msa311-%02x" % partid * @new_data_trig: Optional NEW_DATA interrupt driven trigger used * to notify external consumers a new sample is ready - * @vdd: Optional external voltage regulator for the device power supply */ struct msa311_priv { struct regmap *regs; @@ -362,7 +361,6 @@ struct msa311_priv { char *chip_name; struct iio_trigger *new_data_trig; - struct regulator *vdd; }; enum msa311_si { @@ -1146,11 +1144,6 @@ static void msa311_powerdown(void *msa311) msa311_set_pwr_mode(msa311, MSA311_PWR_MODE_SUSPEND); } -static void msa311_vdd_disable(void *vdd) -{ - regulator_disable(vdd); -} - static int msa311_probe(struct i2c_client *i2c) { struct device *dev = &i2c->dev; @@ -1173,19 +1166,9 @@ static int msa311_probe(struct i2c_client *i2c) mutex_init(&msa311->lock); - msa311->vdd = devm_regulator_get(dev, "vdd"); - if (IS_ERR(msa311->vdd)) - return dev_err_probe(dev, PTR_ERR(msa311->vdd), - "can't get vdd supply\n"); - - err = regulator_enable(msa311->vdd); + err = devm_regulator_get_enable(dev, "vdd"); if (err) - return dev_err_probe(dev, err, "can't enable vdd supply\n"); - - err = devm_add_action_or_reset(dev, msa311_vdd_disable, msa311->vdd); - if (err) - return dev_err_probe(dev, err, - "can't add vdd disable action\n"); + return dev_err_probe(dev, err, "can't get vdd supply\n"); err = msa311_check_partid(msa311); if (err) -- cgit v1.2.3 From 72ce527c7bb599ac1d64ec5393f66a673b75de6b Mon Sep 17 00:00:00 2001 From: Jonathan Cameron Date: Sun, 16 Oct 2022 17:34:01 +0100 Subject: iio: cdc: ad7150: Use devm_regulator_get_enable() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This driver only turns the power on at probe and off via a custom devm_add_action_or_reset() callback. The new devm_regulator_get_enable() replaces this boilerplate code. Signed-off-by: Jonathan Cameron Reviewed-by: Matti Vaittinen Reviewed-by: Nuno Sá Link: https://lore.kernel.org/r/20221016163409.320197-7-jic23@kernel.org --- drivers/iio/cdc/ad7150.c | 18 +----------------- 1 file changed, 1 insertion(+), 17 deletions(-) (limited to 'drivers/iio') diff --git a/drivers/iio/cdc/ad7150.c b/drivers/iio/cdc/ad7150.c index ebe112b4618b..1113745890ca 100644 --- a/drivers/iio/cdc/ad7150.c +++ b/drivers/iio/cdc/ad7150.c @@ -536,19 +536,11 @@ static const struct iio_info ad7150_info_no_irq = { .read_raw = &ad7150_read_raw, }; -static void ad7150_reg_disable(void *data) -{ - struct regulator *reg = data; - - regulator_disable(reg); -} - static int ad7150_probe(struct i2c_client *client, const struct i2c_device_id *id) { struct ad7150_chip_info *chip; struct iio_dev *indio_dev; - struct regulator *reg; int ret; indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*chip)); @@ -563,15 +555,7 @@ static int ad7150_probe(struct i2c_client *client, indio_dev->modes = INDIO_DIRECT_MODE; - reg = devm_regulator_get(&client->dev, "vdd"); - if (IS_ERR(reg)) - return PTR_ERR(reg); - - ret = regulator_enable(reg); - if (ret) - return ret; - - ret = devm_add_action_or_reset(&client->dev, ad7150_reg_disable, reg); + ret = devm_regulator_get_enable(&client->dev, "vdd"); if (ret) return ret; -- cgit v1.2.3 From 9e855d77b1ec57704d23e25761a97e6e64abed66 Mon Sep 17 00:00:00 2001 From: Jonathan Cameron Date: Sun, 16 Oct 2022 17:34:02 +0100 Subject: iio: st_sensors: core and lsm9ds0 switch to devm_regulator_bulk_get_enable() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit These drivers only turns the power on at probe and off via a custom devm_add_action_or_reset() callback. The two regulators were handled separately so also switch to bulk registration. The new devm_regulator_bulk_get_enable() replaces all this boilerplate code. Signed-off-by: Jonathan Cameron Cc: Linus Walleij Cc: Andy Shevchenko Reviewed-by: Matti Vaittinen Reviewed-by: Nuno Sá Link: https://lore.kernel.org/r/20221016163409.320197-8-jic23@kernel.org --- drivers/iio/common/st_sensors/st_sensors_core.c | 39 +++------------ drivers/iio/imu/st_lsm9ds0/st_lsm9ds0_core.c | 65 +++---------------------- include/linux/iio/common/st_sensors.h | 4 -- 3 files changed, 14 insertions(+), 94 deletions(-) (limited to 'drivers/iio') diff --git a/drivers/iio/common/st_sensors/st_sensors_core.c b/drivers/iio/common/st_sensors/st_sensors_core.c index 35720c64fea8..c77d7bdcc121 100644 --- a/drivers/iio/common/st_sensors/st_sensors_core.c +++ b/drivers/iio/common/st_sensors/st_sensors_core.c @@ -219,47 +219,22 @@ int st_sensors_set_axis_enable(struct iio_dev *indio_dev, u8 axis_enable) } EXPORT_SYMBOL_NS(st_sensors_set_axis_enable, IIO_ST_SENSORS); -static void st_reg_disable(void *reg) -{ - regulator_disable(reg); -} int st_sensors_power_enable(struct iio_dev *indio_dev) { - struct st_sensor_data *pdata = iio_priv(indio_dev); + static const char * const regulator_names[] = { "vdd", "vddio" }; struct device *parent = indio_dev->dev.parent; int err; /* Regulators not mandatory, but if requested we should enable them. */ - pdata->vdd = devm_regulator_get(parent, "vdd"); - if (IS_ERR(pdata->vdd)) - return dev_err_probe(&indio_dev->dev, PTR_ERR(pdata->vdd), - "unable to get Vdd supply\n"); - - err = regulator_enable(pdata->vdd); - if (err != 0) { - dev_warn(&indio_dev->dev, - "Failed to enable specified Vdd supply\n"); - return err; - } - - err = devm_add_action_or_reset(parent, st_reg_disable, pdata->vdd); + err = devm_regulator_bulk_get_enable(parent, + ARRAY_SIZE(regulator_names), + regulator_names); if (err) - return err; + return dev_err_probe(&indio_dev->dev, err, + "unable to enable supplies\n"); - pdata->vdd_io = devm_regulator_get(parent, "vddio"); - if (IS_ERR(pdata->vdd_io)) - return dev_err_probe(&indio_dev->dev, PTR_ERR(pdata->vdd_io), - "unable to get Vdd_IO supply\n"); - - err = regulator_enable(pdata->vdd_io); - if (err != 0) { - dev_warn(&indio_dev->dev, - "Failed to enable specified Vdd_IO supply\n"); - return err; - } - - return devm_add_action_or_reset(parent, st_reg_disable, pdata->vdd_io); + return 0; } EXPORT_SYMBOL_NS(st_sensors_power_enable, IIO_ST_SENSORS); 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); diff --git a/include/linux/iio/common/st_sensors.h b/include/linux/iio/common/st_sensors.h index db4a1b260348..f5f3ee57bc70 100644 --- a/include/linux/iio/common/st_sensors.h +++ b/include/linux/iio/common/st_sensors.h @@ -224,8 +224,6 @@ struct st_sensor_settings { * @mount_matrix: The mounting matrix of the sensor. * @sensor_settings: Pointer to the specific sensor settings in use. * @current_fullscale: Maximum range of measure by the sensor. - * @vdd: Pointer to sensor's Vdd power supply - * @vdd_io: Pointer to sensor's Vdd-IO power supply * @regmap: Pointer to specific sensor regmap configuration. * @enabled: Status of the sensor (false->off, true->on). * @odr: Output data rate of the sensor [Hz]. @@ -244,8 +242,6 @@ struct st_sensor_data { struct iio_mount_matrix mount_matrix; struct st_sensor_settings *sensor_settings; struct st_sensor_fullscale_avl *current_fullscale; - struct regulator *vdd; - struct regulator *vdd_io; struct regmap *regmap; bool enabled; -- cgit v1.2.3 From d86186a6e0247394c70239713994df5e2c66220c Mon Sep 17 00:00:00 2001 From: Jonathan Cameron Date: Sun, 16 Oct 2022 17:34:03 +0100 Subject: iio: frequency: ad9523: Use devm_regulator_get_enable() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This driver only turns the power on at probe and off via a custom devm_add_action_or_reset() callback. The new devm_regulator_get_enable() replaces this boilerplate code. Note that in event of an error on the devm_regulator_get() the driver would have continued without enabling the regulator which is probably not a good idea. So here we handle any error as a reason to fail the probe(). In theory this may expose breakage on a platform that was previously papered over but it seems low risk. Signed-off-by: Jonathan Cameron Cc: Michael Hennerich Reviewed-by: Matti Vaittinen Reviewed-by: Nuno Sá Link: https://lore.kernel.org/r/20221016163409.320197-9-jic23@kernel.org --- drivers/iio/frequency/ad9523.c | 22 +++------------------- 1 file changed, 3 insertions(+), 19 deletions(-) (limited to 'drivers/iio') diff --git a/drivers/iio/frequency/ad9523.c b/drivers/iio/frequency/ad9523.c index 97662ca1ca96..b391c6e27ab0 100644 --- a/drivers/iio/frequency/ad9523.c +++ b/drivers/iio/frequency/ad9523.c @@ -265,7 +265,6 @@ enum { struct ad9523_state { struct spi_device *spi; - struct regulator *reg; struct ad9523_platform_data *pdata; struct iio_chan_spec ad9523_channels[AD9523_NUM_CHAN]; struct gpio_desc *pwrdown_gpio; @@ -969,13 +968,6 @@ static int ad9523_setup(struct iio_dev *indio_dev) return 0; } -static void ad9523_reg_disable(void *data) -{ - struct regulator *reg = data; - - regulator_disable(reg); -} - static int ad9523_probe(struct spi_device *spi) { struct ad9523_platform_data *pdata = spi->dev.platform_data; @@ -996,17 +988,9 @@ static int ad9523_probe(struct spi_device *spi) mutex_init(&st->lock); - st->reg = devm_regulator_get(&spi->dev, "vcc"); - if (!IS_ERR(st->reg)) { - ret = regulator_enable(st->reg); - if (ret) - return ret; - - ret = devm_add_action_or_reset(&spi->dev, ad9523_reg_disable, - st->reg); - if (ret) - return ret; - } + ret = devm_regulator_get_enable(&spi->dev, "vcc"); + if (ret) + return ret; st->pwrdown_gpio = devm_gpiod_get_optional(&spi->dev, "powerdown", GPIOD_OUT_HIGH); -- cgit v1.2.3 From 2c97f7b404b8610ebca645d60a6ed1e68d08fbe3 Mon Sep 17 00:00:00 2001 From: Jonathan Cameron Date: Sun, 16 Oct 2022 17:34:04 +0100 Subject: iio: humidity: hts211: Use devm_regulator_get_enable() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This driver only turns the power on at probe and off via a custom devm_add_action_or_reset() callback. The new devm_regulator_get_enable() replaces this boilerplate code. Signed-off-by: Jonathan Cameron Acked-by: Lorenzo Bianconi Reviewed-by: Matti Vaittinen Reviewed-by: Nuno Sá Link: https://lore.kernel.org/r/20221016163409.320197-10-jic23@kernel.org --- drivers/iio/humidity/hts221.h | 2 -- drivers/iio/humidity/hts221_core.c | 27 ++++----------------------- 2 files changed, 4 insertions(+), 25 deletions(-) (limited to 'drivers/iio') diff --git a/drivers/iio/humidity/hts221.h b/drivers/iio/humidity/hts221.h index cf3d8d2dccd6..721359e226cb 100644 --- a/drivers/iio/humidity/hts221.h +++ b/drivers/iio/humidity/hts221.h @@ -13,7 +13,6 @@ #define HTS221_DEV_NAME "hts221" #include -#include enum hts221_sensor_type { HTS221_SENSOR_H, @@ -30,7 +29,6 @@ struct hts221_hw { const char *name; struct device *dev; struct regmap *regmap; - struct regulator *vdd; struct iio_trigger *trig; int irq; diff --git a/drivers/iio/humidity/hts221_core.c b/drivers/iio/humidity/hts221_core.c index 517158307d8c..2a413da87b76 100644 --- a/drivers/iio/humidity/hts221_core.c +++ b/drivers/iio/humidity/hts221_core.c @@ -14,6 +14,7 @@ #include #include #include +#include #include #include "hts221.h" @@ -549,33 +550,17 @@ static const unsigned long hts221_scan_masks[] = {0x3, 0x0}; static int hts221_init_regulators(struct device *dev) { - struct iio_dev *iio_dev = dev_get_drvdata(dev); - struct hts221_hw *hw = iio_priv(iio_dev); int err; - hw->vdd = devm_regulator_get(dev, "vdd"); - if (IS_ERR(hw->vdd)) - return dev_err_probe(dev, PTR_ERR(hw->vdd), - "failed to get vdd regulator\n"); - - err = regulator_enable(hw->vdd); - if (err) { - dev_err(dev, "failed to enable vdd regulator: %d\n", err); - return err; - } + err = devm_regulator_get_enable(dev, "vdd"); + if (err) + return dev_err_probe(dev, err, "failed to get vdd regulator\n"); msleep(50); return 0; } -static void hts221_chip_uninit(void *data) -{ - struct hts221_hw *hw = data; - - regulator_disable(hw->vdd); -} - int hts221_probe(struct device *dev, int irq, const char *name, struct regmap *regmap) { @@ -600,10 +585,6 @@ int hts221_probe(struct device *dev, int irq, const char *name, if (err) return err; - err = devm_add_action_or_reset(dev, hts221_chip_uninit, hw); - if (err) - return err; - err = hts221_check_whoami(hw); if (err < 0) return err; -- cgit v1.2.3 From c437c977c1d2116e0f3667de7222544f348032e4 Mon Sep 17 00:00:00 2001 From: Jonathan Cameron Date: Sun, 16 Oct 2022 17:34:05 +0100 Subject: iio: light: ltr501: Use devm_regulator_bulk_get_enable() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This driver only turns the power for some regulators on at probe and off via a custom devm_add_action_or_reset() callback. The new devm_regulator_bulk_get_enable() replaces all this boilerplate code. Signed-off-by: Jonathan Cameron Reviewed-by: Matti Vaittinen Reviewed-by: Nuno Sá Link: https://lore.kernel.org/r/20221016163409.320197-11-jic23@kernel.org --- drivers/iio/light/ltr501.c | 27 ++++----------------------- 1 file changed, 4 insertions(+), 23 deletions(-) (limited to 'drivers/iio') diff --git a/drivers/iio/light/ltr501.c b/drivers/iio/light/ltr501.c index 74a1ccda8b9c..453b845ef265 100644 --- a/drivers/iio/light/ltr501.c +++ b/drivers/iio/light/ltr501.c @@ -153,7 +153,6 @@ struct ltr501_chip_info { struct ltr501_data { struct i2c_client *client; - struct regulator_bulk_data regulators[2]; struct mutex lock_als, lock_ps; const struct ltr501_chip_info *chip_info; u8 als_contr, ps_contr; @@ -1415,13 +1414,6 @@ static const struct regmap_config ltr501_regmap_config = { .volatile_reg = ltr501_is_volatile_reg, }; -static void ltr501_disable_regulators(void *d) -{ - struct ltr501_data *data = d; - - regulator_bulk_disable(ARRAY_SIZE(data->regulators), data->regulators); -} - static int ltr501_powerdown(struct ltr501_data *data) { return ltr501_write_contr(data, data->als_contr & @@ -1443,6 +1435,7 @@ static const char *ltr501_match_acpi_device(struct device *dev, int *chip_idx) static int ltr501_probe(struct i2c_client *client, const struct i2c_device_id *id) { + static const char * const regulator_names[] = { "vdd", "vddio" }; struct ltr501_data *data; struct iio_dev *indio_dev; struct regmap *regmap; @@ -1466,25 +1459,13 @@ static int ltr501_probe(struct i2c_client *client, mutex_init(&data->lock_als); mutex_init(&data->lock_ps); - data->regulators[0].supply = "vdd"; - data->regulators[1].supply = "vddio"; - ret = devm_regulator_bulk_get(&client->dev, - ARRAY_SIZE(data->regulators), - data->regulators); + ret = devm_regulator_bulk_get_enable(&client->dev, + ARRAY_SIZE(regulator_names), + regulator_names); if (ret) return dev_err_probe(&client->dev, ret, "Failed to get regulators\n"); - ret = regulator_bulk_enable(ARRAY_SIZE(data->regulators), - data->regulators); - if (ret) - return ret; - - ret = devm_add_action_or_reset(&client->dev, - ltr501_disable_regulators, data); - if (ret) - return ret; - data->reg_it = devm_regmap_field_alloc(&client->dev, regmap, reg_field_it); if (IS_ERR(data->reg_it)) { -- cgit v1.2.3 From b620be5f32621b953313056c396894818d5a2ed9 Mon Sep 17 00:00:00 2001 From: Jonathan Cameron Date: Sun, 16 Oct 2022 17:34:06 +0100 Subject: iio: light: noa1305: Use devm_regulator_get_enable() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This driver only turns the power on at probe and off via a custom devm_add_action_or_reset() callback. The new devm_regulator_get_enable() replaces this boilerplate code. Signed-off-by: Jonathan Cameron Cc: Martyn Welch Reviewed-by: Matti Vaittinen Reviewed-by: Nuno Sá Link: https://lore.kernel.org/r/20221016163409.320197-12-jic23@kernel.org --- drivers/iio/light/noa1305.c | 26 +++----------------------- 1 file changed, 3 insertions(+), 23 deletions(-) (limited to 'drivers/iio') diff --git a/drivers/iio/light/noa1305.c b/drivers/iio/light/noa1305.c index ee81fe083e4c..be3536b390fc 100644 --- a/drivers/iio/light/noa1305.c +++ b/drivers/iio/light/noa1305.c @@ -46,7 +46,6 @@ struct noa1305_priv { struct i2c_client *client; struct regmap *regmap; - struct regulator *vin_reg; }; static int noa1305_measure(struct noa1305_priv *priv) @@ -187,13 +186,6 @@ static const struct regmap_config noa1305_regmap_config = { .writeable_reg = noa1305_writable_reg, }; -static void noa1305_reg_remove(void *data) -{ - struct noa1305_priv *priv = data; - - regulator_disable(priv->vin_reg); -} - static int noa1305_probe(struct i2c_client *client, const struct i2c_device_id *id) { @@ -216,23 +208,11 @@ static int noa1305_probe(struct i2c_client *client, priv = iio_priv(indio_dev); - priv->vin_reg = devm_regulator_get(&client->dev, "vin"); - if (IS_ERR(priv->vin_reg)) - return dev_err_probe(&client->dev, PTR_ERR(priv->vin_reg), + ret = devm_regulator_get_enable(&client->dev, "vin"); + if (ret) + return dev_err_probe(&client->dev, ret, "get regulator vin failed\n"); - ret = regulator_enable(priv->vin_reg); - if (ret) { - dev_err(&client->dev, "enable regulator vin failed\n"); - return ret; - } - - ret = devm_add_action_or_reset(&client->dev, noa1305_reg_remove, priv); - if (ret) { - dev_err(&client->dev, "addition of devm action failed\n"); - return ret; - } - i2c_set_clientdata(client, indio_dev); priv->client = client; priv->regmap = regmap; -- cgit v1.2.3 From 1db96143df6b81a402e9b88d08f04374f1353ed0 Mon Sep 17 00:00:00 2001 From: Jonathan Cameron Date: Sun, 16 Oct 2022 17:34:07 +0100 Subject: iio: proximity: sx_common: Use devm_regulator_bulk_get_enable() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This driver only turns the power for some regulators on at probe and off via a custom devm_add_action_or_reset() callback. The new devm_regulator_bulk_get_enable() replaces all this boilerplate code. Signed-off-by: Jonathan Cameron Cc: Gwendal Grignou Reviewed-by: Stephen Boyd Reviewed-by: Matti Vaittinen Reviewed-by: Nuno Sá Link: https://lore.kernel.org/r/20221016163409.320197-13-jic23@kernel.org --- drivers/iio/proximity/sx_common.c | 23 +++-------------------- drivers/iio/proximity/sx_common.h | 2 -- 2 files changed, 3 insertions(+), 22 deletions(-) (limited to 'drivers/iio') diff --git a/drivers/iio/proximity/sx_common.c b/drivers/iio/proximity/sx_common.c index d70a6b4f0bf8..eba9256730ec 100644 --- a/drivers/iio/proximity/sx_common.c +++ b/drivers/iio/proximity/sx_common.c @@ -424,13 +424,6 @@ static const struct iio_buffer_setup_ops sx_common_buffer_setup_ops = { .postdisable = sx_common_buffer_postdisable, }; -static void sx_common_regulator_disable(void *_data) -{ - struct sx_common_data *data = _data; - - regulator_bulk_disable(ARRAY_SIZE(data->supplies), data->supplies); -} - #define SX_COMMON_SOFT_RESET 0xde static int sx_common_init_device(struct device *dev, struct iio_dev *indio_dev) @@ -474,6 +467,7 @@ int sx_common_probe(struct i2c_client *client, const struct sx_common_chip_info *chip_info, const struct regmap_config *regmap_config) { + static const char * const regulator_names[] = { "vdd", "svdd" }; struct device *dev = &client->dev; struct iio_dev *indio_dev; struct sx_common_data *data; @@ -487,8 +481,6 @@ int sx_common_probe(struct i2c_client *client, data->chip_info = chip_info; data->client = client; - data->supplies[0].supply = "vdd"; - data->supplies[1].supply = "svdd"; mutex_init(&data->mutex); init_completion(&data->completion); @@ -497,23 +489,14 @@ int sx_common_probe(struct i2c_client *client, return dev_err_probe(dev, PTR_ERR(data->regmap), "Could init register map\n"); - ret = devm_regulator_bulk_get(dev, ARRAY_SIZE(data->supplies), - data->supplies); + ret = devm_regulator_bulk_get_enable(dev, ARRAY_SIZE(regulator_names), + regulator_names); if (ret) return dev_err_probe(dev, ret, "Unable to get regulators\n"); - ret = regulator_bulk_enable(ARRAY_SIZE(data->supplies), data->supplies); - if (ret) - return dev_err_probe(dev, ret, "Unable to enable regulators\n"); - /* Must wait for Tpor time after initial power up */ usleep_range(1000, 1100); - ret = devm_add_action_or_reset(dev, sx_common_regulator_disable, data); - if (ret) - return dev_err_probe(dev, ret, - "Unable to register regulators deleter\n"); - ret = data->chip_info->ops.check_whoami(dev, indio_dev); if (ret) return dev_err_probe(dev, ret, "error reading WHOAMI\n"); diff --git a/drivers/iio/proximity/sx_common.h b/drivers/iio/proximity/sx_common.h index 5d3edeb75f4e..49d4517103b0 100644 --- a/drivers/iio/proximity/sx_common.h +++ b/drivers/iio/proximity/sx_common.h @@ -102,7 +102,6 @@ struct sx_common_chip_info { * @trig: IIO trigger object. * @regmap: Register map. * @num_default_regs: Number of default registers to set at init. - * @supplies: Power supplies object. * @chan_prox_stat: Last reading of the proximity status for each channel. * We only send an event to user space when this changes. * @trigger_enabled: True when the device trigger is enabled. @@ -120,7 +119,6 @@ struct sx_common_data { struct iio_trigger *trig; struct regmap *regmap; - struct regulator_bulk_data supplies[2]; unsigned long chan_prox_stat; bool trigger_enabled; -- cgit v1.2.3 From ecff5cb471b5dc20b996378c0533bd5f34e85c89 Mon Sep 17 00:00:00 2001 From: Uwe Kleine-König Date: Sun, 23 Oct 2022 15:22:40 +0200 Subject: iio: accel: adxl367: Convert to i2c's .probe_new() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The probe function doesn't make use of the i2c_device_id * parameter so it can be trivially converted. Signed-off-by: Uwe Kleine-König Link: https://lore.kernel.org/r/20221023132302.911644-2-u.kleine-koenig@pengutronix.de Signed-off-by: Jonathan Cameron --- drivers/iio/accel/adxl367_i2c.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'drivers/iio') diff --git a/drivers/iio/accel/adxl367_i2c.c b/drivers/iio/accel/adxl367_i2c.c index 3606efa25835..070aad724abd 100644 --- a/drivers/iio/accel/adxl367_i2c.c +++ b/drivers/iio/accel/adxl367_i2c.c @@ -41,8 +41,7 @@ static const struct adxl367_ops adxl367_i2c_ops = { .read_fifo = adxl367_i2c_read_fifo, }; -static int adxl367_i2c_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int adxl367_i2c_probe(struct i2c_client *client) { struct adxl367_i2c_state *st; struct regmap *regmap; @@ -78,7 +77,7 @@ static struct i2c_driver adxl367_i2c_driver = { .name = "adxl367_i2c", .of_match_table = adxl367_of_match, }, - .probe = adxl367_i2c_probe, + .probe_new = adxl367_i2c_probe, .id_table = adxl367_i2c_id, }; -- cgit v1.2.3 From a9e38f1ecc461c43aa26849394c552e38593ad38 Mon Sep 17 00:00:00 2001 From: Uwe Kleine-König Date: Sun, 23 Oct 2022 15:22:45 +0200 Subject: iio: accel: da311: Convert to i2c's .probe_new() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The probe function doesn't make use of the i2c_device_id * parameter so it can be trivially converted. Signed-off-by: Uwe Kleine-König Link: https://lore.kernel.org/r/20221023132302.911644-7-u.kleine-koenig@pengutronix.de Signed-off-by: Jonathan Cameron --- drivers/iio/accel/da311.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'drivers/iio') diff --git a/drivers/iio/accel/da311.c b/drivers/iio/accel/da311.c index ec4e29d260f7..080335fa2ad6 100644 --- a/drivers/iio/accel/da311.c +++ b/drivers/iio/accel/da311.c @@ -217,8 +217,7 @@ static void da311_disable(void *client) da311_enable(client, false); } -static int da311_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int da311_probe(struct i2c_client *client) { int ret; struct iio_dev *indio_dev; @@ -279,7 +278,7 @@ static struct i2c_driver da311_driver = { .name = "da311", .pm = pm_sleep_ptr(&da311_pm_ops), }, - .probe = da311_probe, + .probe_new = da311_probe, .id_table = da311_i2c_id, }; -- cgit v1.2.3 From 72907238b193be0fc18f2859b7f4c6741b73aedc Mon Sep 17 00:00:00 2001 From: Uwe Kleine-König Date: Sun, 23 Oct 2022 15:22:46 +0200 Subject: iio: accel: dmard06: Convert to i2c's .probe_new() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The probe function doesn't make use of the i2c_device_id * parameter so it can be trivially converted. Signed-off-by: Uwe Kleine-König Link: https://lore.kernel.org/r/20221023132302.911644-8-u.kleine-koenig@pengutronix.de Signed-off-by: Jonathan Cameron --- drivers/iio/accel/dmard06.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'drivers/iio') diff --git a/drivers/iio/accel/dmard06.c b/drivers/iio/accel/dmard06.c index 4b69c8530f5e..7390509aaac0 100644 --- a/drivers/iio/accel/dmard06.c +++ b/drivers/iio/accel/dmard06.c @@ -125,8 +125,7 @@ static const struct iio_info dmard06_info = { .read_raw = dmard06_read_raw, }; -static int dmard06_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int dmard06_probe(struct i2c_client *client) { int ret; struct iio_dev *indio_dev; @@ -218,7 +217,7 @@ static const struct of_device_id dmard06_of_match[] = { MODULE_DEVICE_TABLE(of, dmard06_of_match); static struct i2c_driver dmard06_driver = { - .probe = dmard06_probe, + .probe_new = dmard06_probe, .id_table = dmard06_id, .driver = { .name = DMARD06_DRV_NAME, -- cgit v1.2.3 From d61f79d383f548df8b3b9da58ab687c7db1a93c7 Mon Sep 17 00:00:00 2001 From: Uwe Kleine-König Date: Sun, 23 Oct 2022 15:22:47 +0200 Subject: iio: accel: dmard09: Convert to i2c's .probe_new() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The probe function doesn't make use of the i2c_device_id * parameter so it can be trivially converted. Signed-off-by: Uwe Kleine-König Link: https://lore.kernel.org/r/20221023132302.911644-9-u.kleine-koenig@pengutronix.de Signed-off-by: Jonathan Cameron --- drivers/iio/accel/dmard09.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'drivers/iio') diff --git a/drivers/iio/accel/dmard09.c b/drivers/iio/accel/dmard09.c index cb0246ca72f3..4b7a537f617d 100644 --- a/drivers/iio/accel/dmard09.c +++ b/drivers/iio/accel/dmard09.c @@ -88,8 +88,7 @@ static const struct iio_info dmard09_info = { .read_raw = dmard09_read_raw, }; -static int dmard09_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int dmard09_probe(struct i2c_client *client) { int ret; struct iio_dev *indio_dev; @@ -136,7 +135,7 @@ static struct i2c_driver dmard09_driver = { .driver = { .name = DMARD09_DRV_NAME }, - .probe = dmard09_probe, + .probe_new = dmard09_probe, .id_table = dmard09_id, }; -- cgit v1.2.3 From 5019025fc3a9869c438ad33ab18a4fdad46a996d Mon Sep 17 00:00:00 2001 From: Uwe Kleine-König Date: Sun, 23 Oct 2022 15:22:48 +0200 Subject: iio: accel: dmard10: Convert to i2c's .probe_new() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The probe function doesn't make use of the i2c_device_id * parameter so it can be trivially converted. Signed-off-by: Uwe Kleine-König Link: https://lore.kernel.org/r/20221023132302.911644-10-u.kleine-koenig@pengutronix.de Signed-off-by: Jonathan Cameron --- drivers/iio/accel/dmard10.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'drivers/iio') diff --git a/drivers/iio/accel/dmard10.c b/drivers/iio/accel/dmard10.c index 8ac62ec0a04a..07e68aed8a13 100644 --- a/drivers/iio/accel/dmard10.c +++ b/drivers/iio/accel/dmard10.c @@ -175,8 +175,7 @@ static void dmard10_shutdown_cleanup(void *client) dmard10_shutdown(client); } -static int dmard10_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int dmard10_probe(struct i2c_client *client) { int ret; struct iio_dev *indio_dev; @@ -242,7 +241,7 @@ static struct i2c_driver dmard10_driver = { .name = "dmard10", .pm = pm_sleep_ptr(&dmard10_pm_ops), }, - .probe = dmard10_probe, + .probe_new = dmard10_probe, .id_table = dmard10_i2c_id, }; -- cgit v1.2.3 From 2ba423fefb1c87d080e3a7964ccfa7e929ed6f07 Mon Sep 17 00:00:00 2001 From: Uwe Kleine-König Date: Sun, 23 Oct 2022 15:22:50 +0200 Subject: iio: accel: kxsd9: Convert to i2c's .probe_new() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The probe function doesn't make use of the i2c_device_id * parameter so it can be trivially converted. Signed-off-by: Uwe Kleine-König Link: https://lore.kernel.org/r/20221023132302.911644-12-u.kleine-koenig@pengutronix.de Signed-off-by: Jonathan Cameron --- drivers/iio/accel/kxsd9-i2c.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'drivers/iio') diff --git a/drivers/iio/accel/kxsd9-i2c.c b/drivers/iio/accel/kxsd9-i2c.c index 61346ea8ef19..6b3683ddce36 100644 --- a/drivers/iio/accel/kxsd9-i2c.c +++ b/drivers/iio/accel/kxsd9-i2c.c @@ -10,8 +10,7 @@ #include "kxsd9.h" -static int kxsd9_i2c_probe(struct i2c_client *i2c, - const struct i2c_device_id *id) +static int kxsd9_i2c_probe(struct i2c_client *i2c) { static const struct regmap_config config = { .reg_bits = 8, @@ -55,7 +54,7 @@ static struct i2c_driver kxsd9_i2c_driver = { .of_match_table = kxsd9_of_match, .pm = pm_ptr(&kxsd9_dev_pm_ops), }, - .probe = kxsd9_i2c_probe, + .probe_new = kxsd9_i2c_probe, .remove = kxsd9_i2c_remove, .id_table = kxsd9_i2c_id, }; -- cgit v1.2.3 From ded7a4f8f90286e63eefcd32443ac911d926e118 Mon Sep 17 00:00:00 2001 From: Uwe Kleine-König Date: Sun, 23 Oct 2022 15:22:51 +0200 Subject: iio: accel: mc3230: Convert to i2c's .probe_new() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The probe function doesn't make use of the i2c_device_id * parameter so it can be trivially converted. Signed-off-by: Uwe Kleine-König Link: https://lore.kernel.org/r/20221023132302.911644-13-u.kleine-koenig@pengutronix.de Signed-off-by: Jonathan Cameron --- drivers/iio/accel/mc3230.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'drivers/iio') diff --git a/drivers/iio/accel/mc3230.c b/drivers/iio/accel/mc3230.c index 2462000e0519..efc21871de42 100644 --- a/drivers/iio/accel/mc3230.c +++ b/drivers/iio/accel/mc3230.c @@ -106,8 +106,7 @@ static const struct iio_info mc3230_info = { .read_raw = mc3230_read_raw, }; -static int mc3230_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int mc3230_probe(struct i2c_client *client) { int ret; struct iio_dev *indio_dev; @@ -191,7 +190,7 @@ static struct i2c_driver mc3230_driver = { .name = "mc3230", .pm = pm_sleep_ptr(&mc3230_pm_ops), }, - .probe = mc3230_probe, + .probe_new = mc3230_probe, .remove = mc3230_remove, .id_table = mc3230_i2c_id, }; -- cgit v1.2.3 From 76403ea698adffb6661e083545f21e50fef5b3ac Mon Sep 17 00:00:00 2001 From: Uwe Kleine-König Date: Sun, 23 Oct 2022 15:22:53 +0200 Subject: iio: accel: mma7660: Convert to i2c's .probe_new() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The probe function doesn't make use of the i2c_device_id * parameter so it can be trivially converted. Signed-off-by: Uwe Kleine-König Link: https://lore.kernel.org/r/20221023132302.911644-15-u.kleine-koenig@pengutronix.de Signed-off-by: Jonathan Cameron --- drivers/iio/accel/mma7660.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'drivers/iio') diff --git a/drivers/iio/accel/mma7660.c b/drivers/iio/accel/mma7660.c index 85829990bbad..b279ca4dcdc0 100644 --- a/drivers/iio/accel/mma7660.c +++ b/drivers/iio/accel/mma7660.c @@ -169,8 +169,7 @@ static const struct iio_info mma7660_info = { .attrs = &mma7660_attribute_group, }; -static int mma7660_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int mma7660_probe(struct i2c_client *client) { int ret; struct iio_dev *indio_dev; @@ -267,7 +266,7 @@ static struct i2c_driver mma7660_driver = { .of_match_table = mma7660_of_match, .acpi_match_table = mma7660_acpi_id, }, - .probe = mma7660_probe, + .probe_new = mma7660_probe, .remove = mma7660_remove, .id_table = mma7660_i2c_id, }; -- cgit v1.2.3 From a97d9d95a188d21f5d1cbedbbc7c990b00bf5744 Mon Sep 17 00:00:00 2001 From: Uwe Kleine-König Date: Sun, 23 Oct 2022 15:22:57 +0200 Subject: iio: accel: mxc4005: Convert to i2c's .probe_new() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The probe function doesn't make use of the i2c_device_id * parameter so it can be trivially converted. Signed-off-by: Uwe Kleine-König Link: https://lore.kernel.org/r/20221023132302.911644-19-u.kleine-koenig@pengutronix.de Signed-off-by: Jonathan Cameron --- drivers/iio/accel/mxc4005.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'drivers/iio') diff --git a/drivers/iio/accel/mxc4005.c b/drivers/iio/accel/mxc4005.c index df600d2917c0..b146fc82738f 100644 --- a/drivers/iio/accel/mxc4005.c +++ b/drivers/iio/accel/mxc4005.c @@ -385,8 +385,7 @@ static int mxc4005_chip_init(struct mxc4005_data *data) return 0; } -static int mxc4005_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int mxc4005_probe(struct i2c_client *client) { struct mxc4005_data *data; struct iio_dev *indio_dev; @@ -489,7 +488,7 @@ static struct i2c_driver mxc4005_driver = { .name = MXC4005_DRV_NAME, .acpi_match_table = ACPI_PTR(mxc4005_acpi_match), }, - .probe = mxc4005_probe, + .probe_new = mxc4005_probe, .id_table = mxc4005_id, }; -- cgit v1.2.3 From 76e4a118c85a7e93ff5264ff8d92f76f675be352 Mon Sep 17 00:00:00 2001 From: Uwe Kleine-König Date: Sun, 23 Oct 2022 15:22:58 +0200 Subject: iio: accel: mxc6255: Convert to i2c's .probe_new() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The probe function doesn't make use of the i2c_device_id * parameter so it can be trivially converted. Signed-off-by: Uwe Kleine-König Link: https://lore.kernel.org/r/20221023132302.911644-20-u.kleine-koenig@pengutronix.de Signed-off-by: Jonathan Cameron --- drivers/iio/accel/mxc6255.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'drivers/iio') diff --git a/drivers/iio/accel/mxc6255.c b/drivers/iio/accel/mxc6255.c index 9aeeadc420d3..aa2e660545f8 100644 --- a/drivers/iio/accel/mxc6255.c +++ b/drivers/iio/accel/mxc6255.c @@ -113,8 +113,7 @@ static const struct regmap_config mxc6255_regmap_config = { .readable_reg = mxc6255_is_readable_reg, }; -static int mxc6255_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int mxc6255_probe(struct i2c_client *client) { struct mxc6255_data *data; struct iio_dev *indio_dev; @@ -184,7 +183,7 @@ static struct i2c_driver mxc6255_driver = { .name = MXC6255_DRV_NAME, .acpi_match_table = ACPI_PTR(mxc6255_acpi_match), }, - .probe = mxc6255_probe, + .probe_new = mxc6255_probe, .id_table = mxc6255_id, }; -- cgit v1.2.3 From 3d8a49ebd6576b7803181e0a9fa4e7930f011f1b Mon Sep 17 00:00:00 2001 From: Uwe Kleine-König Date: Sun, 23 Oct 2022 15:22:59 +0200 Subject: iio: accel: stk8312: Convert to i2c's .probe_new() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The probe function doesn't make use of the i2c_device_id * parameter so it can be trivially converted. Signed-off-by: Uwe Kleine-König Link: https://lore.kernel.org/r/20221023132302.911644-21-u.kleine-koenig@pengutronix.de Signed-off-by: Jonathan Cameron --- drivers/iio/accel/stk8312.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'drivers/iio') diff --git a/drivers/iio/accel/stk8312.c b/drivers/iio/accel/stk8312.c index 7b1d6fb692b3..68f680db7505 100644 --- a/drivers/iio/accel/stk8312.c +++ b/drivers/iio/accel/stk8312.c @@ -498,8 +498,7 @@ static const struct iio_buffer_setup_ops stk8312_buffer_setup_ops = { .postdisable = stk8312_buffer_postdisable, }; -static int stk8312_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int stk8312_probe(struct i2c_client *client) { int ret; struct iio_dev *indio_dev; @@ -645,7 +644,7 @@ static struct i2c_driver stk8312_driver = { .name = STK8312_DRIVER_NAME, .pm = pm_sleep_ptr(&stk8312_pm_ops), }, - .probe = stk8312_probe, + .probe_new = stk8312_probe, .remove = stk8312_remove, .id_table = stk8312_i2c_id, }; -- cgit v1.2.3 From d18e70608e01a5845fd75e7ec1956ce422b07184 Mon Sep 17 00:00:00 2001 From: Uwe Kleine-König Date: Sun, 23 Oct 2022 15:23:00 +0200 Subject: iio: accel: stk8ba50: Convert to i2c's .probe_new() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The probe function doesn't make use of the i2c_device_id * parameter so it can be trivially converted. Signed-off-by: Uwe Kleine-König Link: https://lore.kernel.org/r/20221023132302.911644-22-u.kleine-koenig@pengutronix.de Signed-off-by: Jonathan Cameron --- drivers/iio/accel/stk8ba50.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'drivers/iio') diff --git a/drivers/iio/accel/stk8ba50.c b/drivers/iio/accel/stk8ba50.c index 2f5e4ab2a6e7..44f6e0fbdfcc 100644 --- a/drivers/iio/accel/stk8ba50.c +++ b/drivers/iio/accel/stk8ba50.c @@ -379,8 +379,7 @@ static const struct iio_buffer_setup_ops stk8ba50_buffer_setup_ops = { .postdisable = stk8ba50_buffer_postdisable, }; -static int stk8ba50_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int stk8ba50_probe(struct i2c_client *client) { int ret; struct iio_dev *indio_dev; @@ -544,7 +543,7 @@ static struct i2c_driver stk8ba50_driver = { .pm = pm_sleep_ptr(&stk8ba50_pm_ops), .acpi_match_table = ACPI_PTR(stk8ba50_acpi_id), }, - .probe = stk8ba50_probe, + .probe_new = stk8ba50_probe, .remove = stk8ba50_remove, .id_table = stk8ba50_i2c_id, }; -- cgit v1.2.3 From 9492c00d83ee8b2b141e29acbcd3e56dd11aa436 Mon Sep 17 00:00:00 2001 From: Uwe Kleine-König Date: Sun, 23 Oct 2022 15:23:01 +0200 Subject: iio: accel: st_magn: Convert to i2c's .probe_new() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The probe function doesn't make use of the i2c_device_id * parameter so it can be trivially converted. Signed-off-by: Uwe Kleine-König Link: https://lore.kernel.org/r/20221023132302.911644-23-u.kleine-koenig@pengutronix.de Signed-off-by: Jonathan Cameron --- drivers/iio/magnetometer/st_magn_i2c.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'drivers/iio') diff --git a/drivers/iio/magnetometer/st_magn_i2c.c b/drivers/iio/magnetometer/st_magn_i2c.c index c5d8c303db4e..b4098d3b3813 100644 --- a/drivers/iio/magnetometer/st_magn_i2c.c +++ b/drivers/iio/magnetometer/st_magn_i2c.c @@ -54,8 +54,7 @@ static const struct of_device_id st_magn_of_match[] = { }; MODULE_DEVICE_TABLE(of, st_magn_of_match); -static int st_magn_i2c_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int st_magn_i2c_probe(struct i2c_client *client) { const struct st_sensor_settings *settings; struct st_sensor_data *mdata; @@ -107,7 +106,7 @@ static struct i2c_driver st_magn_driver = { .name = "st-magn-i2c", .of_match_table = st_magn_of_match, }, - .probe = st_magn_i2c_probe, + .probe_new = st_magn_i2c_probe, .id_table = st_magn_id_table, }; module_i2c_driver(st_magn_driver); -- cgit v1.2.3 From 2ca0b16f6ce23cf586c27a9139cf426b3f64d242 Mon Sep 17 00:00:00 2001 From: Uwe Kleine-König Date: Sun, 23 Oct 2022 15:23:02 +0200 Subject: iio: accel: vl6180: Convert to i2c's .probe_new() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The probe function doesn't make use of the i2c_device_id * parameter so it can be trivially converted. Signed-off-by: Uwe Kleine-König Link: https://lore.kernel.org/r/20221023132302.911644-24-u.kleine-koenig@pengutronix.de Signed-off-by: Jonathan Cameron --- drivers/iio/light/vl6180.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'drivers/iio') diff --git a/drivers/iio/light/vl6180.c b/drivers/iio/light/vl6180.c index d47a4f6f4e87..8b56df26c59e 100644 --- a/drivers/iio/light/vl6180.c +++ b/drivers/iio/light/vl6180.c @@ -493,8 +493,7 @@ static int vl6180_init(struct vl6180_data *data) return vl6180_hold(data, false); } -static int vl6180_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int vl6180_probe(struct i2c_client *client) { struct vl6180_data *data; struct iio_dev *indio_dev; @@ -539,7 +538,7 @@ static struct i2c_driver vl6180_driver = { .name = VL6180_DRV_NAME, .of_match_table = vl6180_of_match, }, - .probe = vl6180_probe, + .probe_new = vl6180_probe, .id_table = vl6180_id, }; -- cgit v1.2.3 From a95ccebde759f1f6a6070819cd43dce1ad06750d Mon Sep 17 00:00:00 2001 From: Crt Mori Date: Mon, 24 Oct 2022 12:22:05 +0200 Subject: iio: temperature: mlx90632 Style alignment for the driver Changing and aligning the overall style of the driver with the recent reviews. There is no functional change, only type generalization and moving to the reverse Christmas tree for variable declarations. Reviewed-by: Andy Shevchenko Signed-off-by: Crt Mori Link: https://lore.kernel.org/r/d59aad00891c1a64e044a0f5bc7d40e42d47e9c7.1666606912.git.cmo@melexis.com Signed-off-by: Jonathan Cameron --- drivers/iio/temperature/mlx90632.c | 65 +++++++++++++++++++++----------------- 1 file changed, 36 insertions(+), 29 deletions(-) (limited to 'drivers/iio') diff --git a/drivers/iio/temperature/mlx90632.c b/drivers/iio/temperature/mlx90632.c index 224db7513baa..a17fe5f4967a 100644 --- a/drivers/iio/temperature/mlx90632.c +++ b/drivers/iio/temperature/mlx90632.c @@ -219,11 +219,11 @@ static const struct regmap_config mlx90632_regmap = { .cache_type = REGCACHE_RBTREE, }; -static s32 mlx90632_pwr_set_sleep_step(struct regmap *regmap) +static int mlx90632_pwr_set_sleep_step(struct regmap *regmap) { struct mlx90632_data *data = iio_priv(dev_get_drvdata(regmap_get_device(regmap))); - s32 ret; + int ret; if (data->powerstatus == MLX90632_PWR_STATUS_SLEEP_STEP) return 0; @@ -234,14 +234,14 @@ static s32 mlx90632_pwr_set_sleep_step(struct regmap *regmap) return ret; data->powerstatus = MLX90632_PWR_STATUS_SLEEP_STEP; - return ret; + return 0; } -static s32 mlx90632_pwr_continuous(struct regmap *regmap) +static int mlx90632_pwr_continuous(struct regmap *regmap) { struct mlx90632_data *data = iio_priv(dev_get_drvdata(regmap_get_device(regmap))); - s32 ret; + int ret; if (data->powerstatus == MLX90632_PWR_STATUS_CONTINUOUS) return 0; @@ -252,7 +252,7 @@ static s32 mlx90632_pwr_continuous(struct regmap *regmap) return ret; data->powerstatus = MLX90632_PWR_STATUS_CONTINUOUS; - return ret; + return 0; } /** @@ -444,8 +444,8 @@ static int mlx90632_channel_new_select(int perform_ret, uint8_t *channel_new, static int mlx90632_read_ambient_raw(struct regmap *regmap, s16 *ambient_new_raw, s16 *ambient_old_raw) { - int ret; unsigned int read_tmp; + int ret; ret = regmap_read(regmap, MLX90632_RAM_3(1), &read_tmp); if (ret < 0) @@ -464,11 +464,11 @@ static int mlx90632_read_object_raw(struct regmap *regmap, int perform_measurement_ret, s16 *object_new_raw, s16 *object_old_raw) { - int ret; unsigned int read_tmp; - s16 read; - u8 channel = 0; u8 channel_old = 0; + u8 channel = 0; + s16 read; + int ret; ret = mlx90632_channel_new_select(perform_measurement_ret, &channel, &channel_old); @@ -503,7 +503,8 @@ static int mlx90632_read_all_channel(struct mlx90632_data *data, s16 *ambient_new_raw, s16 *ambient_old_raw, s16 *object_new_raw, s16 *object_old_raw) { - s32 ret, measurement; + s32 measurement; + int ret; mutex_lock(&data->lock); ret = mlx90632_set_meas_type(data, MLX90632_MTYP_MEDICAL); @@ -512,24 +513,24 @@ static int mlx90632_read_all_channel(struct mlx90632_data *data, switch (data->powerstatus) { case MLX90632_PWR_STATUS_CONTINUOUS: - measurement = mlx90632_perform_measurement(data); - if (measurement < 0) { - ret = measurement; + ret = mlx90632_perform_measurement(data); + if (ret < 0) goto read_unlock; - } + break; case MLX90632_PWR_STATUS_SLEEP_STEP: - measurement = mlx90632_perform_measurement_burst(data); - if (measurement < 0) { - ret = measurement; + ret = mlx90632_perform_measurement_burst(data); + if (ret < 0) goto read_unlock; - } + break; default: ret = -EOPNOTSUPP; goto read_unlock; } + measurement = ret; /* If we came here ret holds the measurement position */ + ret = mlx90632_read_ambient_raw(data->regmap, ambient_new_raw, ambient_old_raw); if (ret < 0) @@ -615,15 +616,21 @@ static int mlx90632_read_all_channel_extended(struct mlx90632_data *data, s16 *o if (ret < 0) goto read_unlock; - if (data->powerstatus == MLX90632_PWR_STATUS_CONTINUOUS) { + switch (data->powerstatus) { + case MLX90632_PWR_STATUS_CONTINUOUS: ret = read_poll_timeout(mlx90632_perform_measurement, meas, meas == 19, 50000, 800000, false, data); if (ret) goto read_unlock; - } else if (data->powerstatus == MLX90632_PWR_STATUS_SLEEP_STEP) { + break; + case MLX90632_PWR_STATUS_SLEEP_STEP: ret = mlx90632_perform_measurement_burst(data); if (ret < 0) goto read_unlock; + break; + default: + ret = -EOPNOTSUPP; + goto read_unlock; } ret = mlx90632_read_object_raw_extended(data->regmap, object_new_raw); @@ -640,9 +647,9 @@ read_unlock: static int mlx90632_read_ee_register(struct regmap *regmap, u16 reg_lsb, s32 *reg_value) { - s32 ret; unsigned int read; u32 value; + int ret; ret = regmap_read(regmap, reg_lsb, &read); if (ret < 0) @@ -806,12 +813,12 @@ static s32 mlx90632_calc_temp_object_extended(s64 object, s64 ambient, s64 refle static int mlx90632_calc_object_dsp105(struct mlx90632_data *data, int *val) { - s32 ret; + s16 ambient_new_raw, ambient_old_raw, object_new_raw, object_old_raw; s32 Ea, Eb, Fa, Fb, Ga; unsigned int read_tmp; - s16 Ha, Hb, Gb, Ka; - s16 ambient_new_raw, ambient_old_raw, object_new_raw, object_old_raw; s64 object, ambient; + s16 Ha, Hb, Gb, Ka; + int ret; ret = mlx90632_read_ee_register(data->regmap, MLX90632_EE_Ea, &Ea); if (ret < 0) @@ -885,11 +892,11 @@ static int mlx90632_calc_object_dsp105(struct mlx90632_data *data, int *val) static int mlx90632_calc_ambient_dsp105(struct mlx90632_data *data, int *val) { - s32 ret; + s16 ambient_new_raw, ambient_old_raw; unsigned int read_tmp; s32 PT, PR, PG, PO; + int ret; s16 Gb; - s16 ambient_new_raw, ambient_old_raw; ret = mlx90632_read_ee_register(data->regmap, MLX90632_EE_P_R, &PR); if (ret < 0) @@ -1164,11 +1171,11 @@ static int mlx90632_enable_regulator(struct mlx90632_data *data) static int mlx90632_probe(struct i2c_client *client, const struct i2c_device_id *id) { - struct iio_dev *indio_dev; struct mlx90632_data *mlx90632; + struct iio_dev *indio_dev; struct regmap *regmap; - int ret; unsigned int read; + int ret; indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*mlx90632)); if (!indio_dev) { -- cgit v1.2.3 From f7626504432a6d30178bc6946d50a9d4a1bb4e31 Mon Sep 17 00:00:00 2001 From: Yang Yingliang Date: Mon, 24 Oct 2022 18:52:50 +0800 Subject: iio: trigger: sysfs: rename error label in iio_sysfs_trigger_probe() Rename error label in iio_sysfs_trigger_probe() to make more readable. Signed-off-by: Yang Yingliang Link: https://lore.kernel.org/r/20221024105250.873394-1-yangyingliang@huawei.com Signed-off-by: Jonathan Cameron --- drivers/iio/trigger/iio-trig-sysfs.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'drivers/iio') diff --git a/drivers/iio/trigger/iio-trig-sysfs.c b/drivers/iio/trigger/iio-trig-sysfs.c index d6c5e9644738..63ce01ac2036 100644 --- a/drivers/iio/trigger/iio-trig-sysfs.c +++ b/drivers/iio/trigger/iio-trig-sysfs.c @@ -138,18 +138,18 @@ static int iio_sysfs_trigger_probe(int id) } if (foundit) { ret = -EINVAL; - goto out1; + goto err_unlock; } t = kmalloc(sizeof(*t), GFP_KERNEL); if (t == NULL) { ret = -ENOMEM; - goto out1; + goto err_unlock; } t->id = id; t->trig = iio_trigger_alloc(&iio_sysfs_trig_dev, "sysfstrig%d", id); if (!t->trig) { ret = -ENOMEM; - goto free_t; + goto err_free_sys_trig; } t->trig->dev.groups = iio_sysfs_trigger_attr_groups; @@ -159,17 +159,17 @@ static int iio_sysfs_trigger_probe(int id) ret = iio_trigger_register(t->trig); if (ret) - goto out2; + goto err_free_trig; list_add(&t->l, &iio_sysfs_trig_list); __module_get(THIS_MODULE); mutex_unlock(&iio_sysfs_trig_list_mut); return 0; -out2: +err_free_trig: iio_trigger_free(t->trig); -free_t: +err_free_sys_trig: kfree(t); -out1: +err_unlock: mutex_unlock(&iio_sysfs_trig_list_mut); return ret; } -- cgit v1.2.3 From 7c1d1677b3227c6b18ac999f2b84778baa280b8f Mon Sep 17 00:00:00 2001 From: Matti Vaittinen Date: Mon, 24 Oct 2022 15:40:29 +0300 Subject: iio: accel: Support Kionix/ROHM KX022A accelerometer KX022A is a 3-axis accelerometer from ROHM/Kionix. The sensor features include variable ODRs, I2C and SPI control, FIFO/LIFO with watermark IRQ, tap/motion detection, wake-up & back-to-sleep events, four acceleration ranges (2, 4, 8 and 16g), and probably some other cool features. Add support for the basic accelerometer features such as getting the acceleration data via IIO. (raw reads, triggered buffer [data-ready] or using the WMI IRQ). Important things to be added include the double-tap, motion detection and wake-up as well as the runtime power management. Signed-off-by: Matti Vaittinen Reviewed-by: Andy Shevchenko Link: https://lore.kernel.org/r/758b00d6aea0a6431a5a3a78d557d449c113b21e.1666614295.git.mazziesaccount@gmail.com Signed-off-by: Jonathan Cameron --- drivers/iio/accel/Kconfig | 21 + drivers/iio/accel/Makefile | 3 + drivers/iio/accel/kionix-kx022a-i2c.c | 51 ++ drivers/iio/accel/kionix-kx022a-spi.c | 58 ++ drivers/iio/accel/kionix-kx022a.c | 1142 +++++++++++++++++++++++++++++++++ drivers/iio/accel/kionix-kx022a.h | 82 +++ 6 files changed, 1357 insertions(+) create mode 100644 drivers/iio/accel/kionix-kx022a-i2c.c create mode 100644 drivers/iio/accel/kionix-kx022a-spi.c create mode 100644 drivers/iio/accel/kionix-kx022a.c create mode 100644 drivers/iio/accel/kionix-kx022a.h (limited to 'drivers/iio') diff --git a/drivers/iio/accel/Kconfig b/drivers/iio/accel/Kconfig index ffac66db7ac9..03ac410c162e 100644 --- a/drivers/iio/accel/Kconfig +++ b/drivers/iio/accel/Kconfig @@ -409,6 +409,27 @@ config IIO_ST_ACCEL_SPI_3AXIS To compile this driver as a module, choose M here. The module will be called st_accel_spi. +config IIO_KX022A + tristate + +config IIO_KX022A_SPI + tristate "Kionix KX022A tri-axis digital accelerometer SPI interface" + depends on SPI + select IIO_KX022A + select REGMAP_SPI + help + Enable support for the Kionix KX022A digital tri-axis + accelerometer connected to I2C interface. + +config IIO_KX022A_I2C + tristate "Kionix KX022A tri-axis digital accelerometer I2C interface" + depends on I2C + select IIO_KX022A + select REGMAP_I2C + help + Enable support for the Kionix KX022A digital tri-axis + accelerometer connected to I2C interface. + config KXSD9 tristate "Kionix KXSD9 Accelerometer Driver" select IIO_BUFFER diff --git a/drivers/iio/accel/Makefile b/drivers/iio/accel/Makefile index 5e45b5fa5ab5..311ead9c3ef1 100644 --- a/drivers/iio/accel/Makefile +++ b/drivers/iio/accel/Makefile @@ -40,6 +40,9 @@ obj-$(CONFIG_FXLS8962AF) += fxls8962af-core.o obj-$(CONFIG_FXLS8962AF_I2C) += fxls8962af-i2c.o obj-$(CONFIG_FXLS8962AF_SPI) += fxls8962af-spi.o obj-$(CONFIG_HID_SENSOR_ACCEL_3D) += hid-sensor-accel-3d.o +obj-$(CONFIG_IIO_KX022A) += kionix-kx022a.o +obj-$(CONFIG_IIO_KX022A_I2C) += kionix-kx022a-i2c.o +obj-$(CONFIG_IIO_KX022A_SPI) += kionix-kx022a-spi.o obj-$(CONFIG_KXCJK1013) += kxcjk-1013.o obj-$(CONFIG_KXSD9) += kxsd9.o obj-$(CONFIG_KXSD9_SPI) += kxsd9-spi.o diff --git a/drivers/iio/accel/kionix-kx022a-i2c.c b/drivers/iio/accel/kionix-kx022a-i2c.c new file mode 100644 index 000000000000..e6fd02d931b6 --- /dev/null +++ b/drivers/iio/accel/kionix-kx022a-i2c.c @@ -0,0 +1,51 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (C) 2022 ROHM Semiconductors + * + * ROHM/KIONIX KX022A accelerometer driver + */ + +#include +#include +#include +#include + +#include "kionix-kx022a.h" + +static int kx022a_i2c_probe(struct i2c_client *i2c) +{ + struct device *dev = &i2c->dev; + struct regmap *regmap; + + if (!i2c->irq) { + dev_err(dev, "No IRQ configured\n"); + return -EINVAL; + } + + regmap = devm_regmap_init_i2c(i2c, &kx022a_regmap); + if (IS_ERR(regmap)) + return dev_err_probe(dev, PTR_ERR(regmap), + "Failed to initialize Regmap\n"); + + return kx022a_probe_internal(dev); +} + +static const struct of_device_id kx022a_of_match[] = { + { .compatible = "kionix,kx022a", }, + { } +}; +MODULE_DEVICE_TABLE(of, kx022a_of_match); + +static struct i2c_driver kx022a_i2c_driver = { + .driver = { + .name = "kx022a-i2c", + .of_match_table = kx022a_of_match, + }, + .probe_new = kx022a_i2c_probe, +}; +module_i2c_driver(kx022a_i2c_driver); + +MODULE_DESCRIPTION("ROHM/Kionix KX022A accelerometer driver"); +MODULE_AUTHOR("Matti Vaittinen "); +MODULE_LICENSE("GPL"); +MODULE_IMPORT_NS(IIO_KX022A); diff --git a/drivers/iio/accel/kionix-kx022a-spi.c b/drivers/iio/accel/kionix-kx022a-spi.c new file mode 100644 index 000000000000..9cd047f7b346 --- /dev/null +++ b/drivers/iio/accel/kionix-kx022a-spi.c @@ -0,0 +1,58 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (C) 2022 ROHM Semiconductors + * + * ROHM/KIONIX KX022A accelerometer driver + */ + +#include +#include +#include +#include + +#include "kionix-kx022a.h" + +static int kx022a_spi_probe(struct spi_device *spi) +{ + struct device *dev = &spi->dev; + struct regmap *regmap; + + if (!spi->irq) { + dev_err(dev, "No IRQ configured\n"); + return -EINVAL; + } + + regmap = devm_regmap_init_spi(spi, &kx022a_regmap); + if (IS_ERR(regmap)) + return dev_err_probe(dev, PTR_ERR(regmap), + "Failed to initialize Regmap\n"); + + return kx022a_probe_internal(dev); +} + +static const struct spi_device_id kx022a_id[] = { + { "kx022a" }, + { } +}; +MODULE_DEVICE_TABLE(spi, kx022a_id); + +static const struct of_device_id kx022a_of_match[] = { + { .compatible = "kionix,kx022a", }, + { } +}; +MODULE_DEVICE_TABLE(of, kx022a_of_match); + +static struct spi_driver kx022a_spi_driver = { + .driver = { + .name = "kx022a-spi", + .of_match_table = kx022a_of_match, + }, + .probe = kx022a_spi_probe, + .id_table = kx022a_id, +}; +module_spi_driver(kx022a_spi_driver); + +MODULE_DESCRIPTION("ROHM/Kionix kx022A accelerometer driver"); +MODULE_AUTHOR("Matti Vaittinen "); +MODULE_LICENSE("GPL"); +MODULE_IMPORT_NS(IIO_KX022A); diff --git a/drivers/iio/accel/kionix-kx022a.c b/drivers/iio/accel/kionix-kx022a.c new file mode 100644 index 000000000000..50de7f9a1cc7 --- /dev/null +++ b/drivers/iio/accel/kionix-kx022a.c @@ -0,0 +1,1142 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (C) 2022 ROHM Semiconductors + * + * ROHM/KIONIX KX022A accelerometer driver + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include "kionix-kx022a.h" + +/* + * The KX022A has FIFO which can store 43 samples of HiRes data from 2 + * channels. This equals to 43 (samples) * 3 (channels) * 2 (bytes/sample) to + * 258 bytes of sample data. The quirk to know is that the amount of bytes in + * the FIFO is advertised via 8 bit register (max value 255). The thing to note + * is that full 258 bytes of data is indicated using the max value 255. + */ +#define KX022A_FIFO_LENGTH 43 +#define KX022A_FIFO_FULL_VALUE 255 +#define KX022A_SOFT_RESET_WAIT_TIME_US (5 * USEC_PER_MSEC) +#define KX022A_SOFT_RESET_TOTAL_WAIT_TIME_US (500 * USEC_PER_MSEC) + +/* 3 axis, 2 bytes of data for each of the axis */ +#define KX022A_FIFO_SAMPLES_SIZE_BYTES 6 +#define KX022A_FIFO_MAX_BYTES \ + (KX022A_FIFO_LENGTH * KX022A_FIFO_SAMPLES_SIZE_BYTES) + +enum { + KX022A_STATE_SAMPLE, + KX022A_STATE_FIFO, +}; + +/* Regmap configs */ +static const struct regmap_range kx022a_volatile_ranges[] = { + { + .range_min = KX022A_REG_XHP_L, + .range_max = KX022A_REG_COTR, + }, { + .range_min = KX022A_REG_TSCP, + .range_max = KX022A_REG_INT_REL, + }, { + /* The reset bit will be cleared by sensor */ + .range_min = KX022A_REG_CNTL2, + .range_max = KX022A_REG_CNTL2, + }, { + .range_min = KX022A_REG_BUF_STATUS_1, + .range_max = KX022A_REG_BUF_READ, + }, +}; + +static const struct regmap_access_table kx022a_volatile_regs = { + .yes_ranges = &kx022a_volatile_ranges[0], + .n_yes_ranges = ARRAY_SIZE(kx022a_volatile_ranges), +}; + +static const struct regmap_range kx022a_precious_ranges[] = { + { + .range_min = KX022A_REG_INT_REL, + .range_max = KX022A_REG_INT_REL, + }, +}; + +static const struct regmap_access_table kx022a_precious_regs = { + .yes_ranges = &kx022a_precious_ranges[0], + .n_yes_ranges = ARRAY_SIZE(kx022a_precious_ranges), +}; + +/* + * The HW does not set WHO_AM_I reg as read-only but we don't want to write it + * so we still include it in the read-only ranges. + */ +static const struct regmap_range kx022a_read_only_ranges[] = { + { + .range_min = KX022A_REG_XHP_L, + .range_max = KX022A_REG_INT_REL, + }, { + .range_min = KX022A_REG_BUF_STATUS_1, + .range_max = KX022A_REG_BUF_STATUS_2, + }, { + .range_min = KX022A_REG_BUF_READ, + .range_max = KX022A_REG_BUF_READ, + }, +}; + +static const struct regmap_access_table kx022a_ro_regs = { + .no_ranges = &kx022a_read_only_ranges[0], + .n_no_ranges = ARRAY_SIZE(kx022a_read_only_ranges), +}; + +static const struct regmap_range kx022a_write_only_ranges[] = { + { + .range_min = KX022A_REG_BTS_WUF_TH, + .range_max = KX022A_REG_BTS_WUF_TH, + }, { + .range_min = KX022A_REG_MAN_WAKE, + .range_max = KX022A_REG_MAN_WAKE, + }, { + .range_min = KX022A_REG_SELF_TEST, + .range_max = KX022A_REG_SELF_TEST, + }, { + .range_min = KX022A_REG_BUF_CLEAR, + .range_max = KX022A_REG_BUF_CLEAR, + }, +}; + +static const struct regmap_access_table kx022a_wo_regs = { + .no_ranges = &kx022a_write_only_ranges[0], + .n_no_ranges = ARRAY_SIZE(kx022a_write_only_ranges), +}; + +static const struct regmap_range kx022a_noinc_read_ranges[] = { + { + .range_min = KX022A_REG_BUF_READ, + .range_max = KX022A_REG_BUF_READ, + }, +}; + +static const struct regmap_access_table kx022a_nir_regs = { + .yes_ranges = &kx022a_noinc_read_ranges[0], + .n_yes_ranges = ARRAY_SIZE(kx022a_noinc_read_ranges), +}; + +const struct regmap_config kx022a_regmap = { + .reg_bits = 8, + .val_bits = 8, + .volatile_table = &kx022a_volatile_regs, + .rd_table = &kx022a_wo_regs, + .wr_table = &kx022a_ro_regs, + .rd_noinc_table = &kx022a_nir_regs, + .precious_table = &kx022a_precious_regs, + .max_register = KX022A_MAX_REGISTER, + .cache_type = REGCACHE_RBTREE, +}; +EXPORT_SYMBOL_NS_GPL(kx022a_regmap, IIO_KX022A); + +struct kx022a_data { + struct regmap *regmap; + struct iio_trigger *trig; + struct device *dev; + struct iio_mount_matrix orientation; + int64_t timestamp, old_timestamp; + + int irq; + int inc_reg; + int ien_reg; + + unsigned int g_range; + unsigned int state; + unsigned int odr_ns; + + bool trigger_enabled; + /* + * Prevent toggling the sensor stby/active state (PC1 bit) in the + * middle of a configuration, or when the fifo is enabled. Also, + * protect the data stored/retrieved from this structure from + * concurrent accesses. + */ + struct mutex mutex; + u8 watermark; + + /* 3 x 16bit accel data + timestamp */ + __le16 buffer[8] __aligned(IIO_DMA_MINALIGN); + struct { + __le16 channels[3]; + s64 ts __aligned(8); + } scan; +}; + +static const struct iio_mount_matrix * +kx022a_get_mount_matrix(const struct iio_dev *idev, + const struct iio_chan_spec *chan) +{ + struct kx022a_data *data = iio_priv(idev); + + return &data->orientation; +} + +enum { + AXIS_X, + AXIS_Y, + AXIS_Z, + AXIS_MAX +}; + +static const unsigned long kx022a_scan_masks[] = { + BIT(AXIS_X) | BIT(AXIS_Y) | BIT(AXIS_Z), 0 +}; + +static const struct iio_chan_spec_ext_info kx022a_ext_info[] = { + IIO_MOUNT_MATRIX(IIO_SHARED_BY_TYPE, kx022a_get_mount_matrix), + { } +}; + +#define KX022A_ACCEL_CHAN(axis, index) \ +{ \ + .type = IIO_ACCEL, \ + .modified = 1, \ + .channel2 = IIO_MOD_##axis, \ + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \ + .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE) | \ + BIT(IIO_CHAN_INFO_SAMP_FREQ), \ + .info_mask_shared_by_type_available = \ + BIT(IIO_CHAN_INFO_SCALE) | \ + BIT(IIO_CHAN_INFO_SAMP_FREQ), \ + .ext_info = kx022a_ext_info, \ + .address = KX022A_REG_##axis##OUT_L, \ + .scan_index = index, \ + .scan_type = { \ + .sign = 's', \ + .realbits = 16, \ + .storagebits = 16, \ + .endianness = IIO_LE, \ + }, \ +} + +static const struct iio_chan_spec kx022a_channels[] = { + KX022A_ACCEL_CHAN(X, 0), + KX022A_ACCEL_CHAN(Y, 1), + KX022A_ACCEL_CHAN(Z, 2), + IIO_CHAN_SOFT_TIMESTAMP(3), +}; + +/* + * The sensor HW can support ODR up to 1600 Hz, which is beyond what most of the + * Linux CPUs can handle without dropping samples. Also, the low power mode is + * not available for higher sample rates. Thus, the driver only supports 200 Hz + * and slower ODRs. The slowest is 0.78 Hz. + */ +static const int kx022a_accel_samp_freq_table[][2] = { + { 0, 780000 }, + { 1, 563000 }, + { 3, 125000 }, + { 6, 250000 }, + { 12, 500000 }, + { 25, 0 }, + { 50, 0 }, + { 100, 0 }, + { 200, 0 }, +}; + +static const unsigned int kx022a_odrs[] = { + 1282051282, + 639795266, + 320 * MEGA, + 160 * MEGA, + 80 * MEGA, + 40 * MEGA, + 20 * MEGA, + 10 * MEGA, + 5 * MEGA, +}; + +/* + * range is typically +-2G/4G/8G/16G, distributed over the amount of bits. + * The scale table can be calculated using + * (range / 2^bits) * g = (range / 2^bits) * 9.80665 m/s^2 + * => KX022A uses 16 bit (HiRes mode - assume the low 8 bits are zeroed + * in low-power mode(?) ) + * => +/-2G => 4 / 2^16 * 9,80665 * 10^6 (to scale to micro) + * => +/-2G - 598.550415 + * +/-4G - 1197.10083 + * +/-8G - 2394.20166 + * +/-16G - 4788.40332 + */ +static const int kx022a_scale_table[][2] = { + { 598, 550415 }, + { 1197, 100830 }, + { 2394, 201660 }, + { 4788, 403320 }, +}; + +static int kx022a_read_avail(struct iio_dev *indio_dev, + struct iio_chan_spec const *chan, + const int **vals, int *type, int *length, + long mask) +{ + switch (mask) { + case IIO_CHAN_INFO_SAMP_FREQ: + *vals = (const int *)kx022a_accel_samp_freq_table; + *length = ARRAY_SIZE(kx022a_accel_samp_freq_table) * + ARRAY_SIZE(kx022a_accel_samp_freq_table[0]); + *type = IIO_VAL_INT_PLUS_MICRO; + return IIO_AVAIL_LIST; + case IIO_CHAN_INFO_SCALE: + *vals = (const int *)kx022a_scale_table; + *length = ARRAY_SIZE(kx022a_scale_table) * + ARRAY_SIZE(kx022a_scale_table[0]); + *type = IIO_VAL_INT_PLUS_MICRO; + return IIO_AVAIL_LIST; + default: + return -EINVAL; + } +} + +#define KX022A_DEFAULT_PERIOD_NS (20 * NSEC_PER_MSEC) + +static void kx022a_reg2freq(unsigned int val, int *val1, int *val2) +{ + *val1 = kx022a_accel_samp_freq_table[val & KX022A_MASK_ODR][0]; + *val2 = kx022a_accel_samp_freq_table[val & KX022A_MASK_ODR][1]; +} + +static void kx022a_reg2scale(unsigned int val, unsigned int *val1, + unsigned int *val2) +{ + val &= KX022A_MASK_GSEL; + val >>= KX022A_GSEL_SHIFT; + + *val1 = kx022a_scale_table[val][0]; + *val2 = kx022a_scale_table[val][1]; +} + +static int kx022a_turn_on_off_unlocked(struct kx022a_data *data, bool on) +{ + int ret; + + if (on) + ret = regmap_set_bits(data->regmap, KX022A_REG_CNTL, + KX022A_MASK_PC1); + else + ret = regmap_clear_bits(data->regmap, KX022A_REG_CNTL, + KX022A_MASK_PC1); + if (ret) + dev_err(data->dev, "Turn %s fail %d\n", str_on_off(on), ret); + + return ret; + +} + +static int kx022a_turn_off_lock(struct kx022a_data *data) +{ + int ret; + + mutex_lock(&data->mutex); + ret = kx022a_turn_on_off_unlocked(data, false); + if (ret) + mutex_unlock(&data->mutex); + + return ret; +} + +static int kx022a_turn_on_unlock(struct kx022a_data *data) +{ + int ret; + + ret = kx022a_turn_on_off_unlocked(data, true); + mutex_unlock(&data->mutex); + + return ret; +} + +static int kx022a_write_raw(struct iio_dev *idev, + struct iio_chan_spec const *chan, + int val, int val2, long mask) +{ + struct kx022a_data *data = iio_priv(idev); + int ret, n; + + /* + * We should not allow changing scale or frequency when FIFO is running + * as it will mess the timestamp/scale for samples existing in the + * buffer. If this turns out to be an issue we can later change logic + * to internally flush the fifo before reconfiguring so the samples in + * fifo keep matching the freq/scale settings. (Such setup could cause + * issues if users trust the watermark to be reached within known + * time-limit). + */ + ret = iio_device_claim_direct_mode(idev); + if (ret) + return ret; + + switch (mask) { + case IIO_CHAN_INFO_SAMP_FREQ: + n = ARRAY_SIZE(kx022a_accel_samp_freq_table); + + while (n--) + if (val == kx022a_accel_samp_freq_table[n][0] && + val2 == kx022a_accel_samp_freq_table[n][1]) + break; + if (n < 0) { + ret = -EINVAL; + goto unlock_out; + } + ret = kx022a_turn_off_lock(data); + if (ret) + break; + + ret = regmap_update_bits(data->regmap, + KX022A_REG_ODCNTL, + KX022A_MASK_ODR, n); + data->odr_ns = kx022a_odrs[n]; + kx022a_turn_on_unlock(data); + break; + case IIO_CHAN_INFO_SCALE: + n = ARRAY_SIZE(kx022a_scale_table); + + while (n-- > 0) + if (val == kx022a_scale_table[n][0] && + val2 == kx022a_scale_table[n][1]) + break; + if (n < 0) { + ret = -EINVAL; + goto unlock_out; + } + + ret = kx022a_turn_off_lock(data); + if (ret) + break; + + ret = regmap_update_bits(data->regmap, KX022A_REG_CNTL, + KX022A_MASK_GSEL, + n << KX022A_GSEL_SHIFT); + kx022a_turn_on_unlock(data); + break; + default: + ret = -EINVAL; + break; + } + +unlock_out: + iio_device_release_direct_mode(idev); + + return ret; +} + +static int kx022a_fifo_set_wmi(struct kx022a_data *data) +{ + u8 threshold; + + threshold = data->watermark; + + return regmap_update_bits(data->regmap, KX022A_REG_BUF_CNTL1, + KX022A_MASK_WM_TH, threshold); +} + +static int kx022a_get_axis(struct kx022a_data *data, + struct iio_chan_spec const *chan, + int *val) +{ + int ret; + + ret = regmap_bulk_read(data->regmap, chan->address, &data->buffer[0], + sizeof(__le16)); + if (ret) + return ret; + + *val = le16_to_cpu(data->buffer[0]); + + return IIO_VAL_INT; +} + +static int kx022a_read_raw(struct iio_dev *idev, + struct iio_chan_spec const *chan, + int *val, int *val2, long mask) +{ + struct kx022a_data *data = iio_priv(idev); + unsigned int regval; + int ret; + + switch (mask) { + case IIO_CHAN_INFO_RAW: + ret = iio_device_claim_direct_mode(idev); + if (ret) + return ret; + + mutex_lock(&data->mutex); + ret = kx022a_get_axis(data, chan, val); + mutex_unlock(&data->mutex); + + iio_device_release_direct_mode(idev); + + return ret; + + case IIO_CHAN_INFO_SAMP_FREQ: + ret = regmap_read(data->regmap, KX022A_REG_ODCNTL, ®val); + if (ret) + return ret; + + if ((regval & KX022A_MASK_ODR) > + ARRAY_SIZE(kx022a_accel_samp_freq_table)) { + dev_err(data->dev, "Invalid ODR\n"); + return -EINVAL; + } + + kx022a_reg2freq(regval, val, val2); + + return IIO_VAL_INT_PLUS_MICRO; + + case IIO_CHAN_INFO_SCALE: + ret = regmap_read(data->regmap, KX022A_REG_CNTL, ®val); + if (ret < 0) + return ret; + + kx022a_reg2scale(regval, val, val2); + + return IIO_VAL_INT_PLUS_MICRO; + } + + return -EINVAL; +}; + +static int kx022a_validate_trigger(struct iio_dev *idev, + struct iio_trigger *trig) +{ + struct kx022a_data *data = iio_priv(idev); + + if (data->trig != trig) + return -EINVAL; + + return 0; +} + +static int kx022a_set_watermark(struct iio_dev *idev, unsigned int val) +{ + struct kx022a_data *data = iio_priv(idev); + + if (val > KX022A_FIFO_LENGTH) + val = KX022A_FIFO_LENGTH; + + mutex_lock(&data->mutex); + data->watermark = val; + mutex_unlock(&data->mutex); + + return 0; +} + +static ssize_t hwfifo_enabled_show(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct iio_dev *idev = dev_to_iio_dev(dev); + struct kx022a_data *data = iio_priv(idev); + bool state; + + mutex_lock(&data->mutex); + state = data->state; + mutex_unlock(&data->mutex); + + return sysfs_emit(buf, "%d\n", state); +} + +static ssize_t hwfifo_watermark_show(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct iio_dev *idev = dev_to_iio_dev(dev); + struct kx022a_data *data = iio_priv(idev); + int wm; + + mutex_lock(&data->mutex); + wm = data->watermark; + mutex_unlock(&data->mutex); + + return sysfs_emit(buf, "%d\n", wm); +} + +static IIO_DEVICE_ATTR_RO(hwfifo_enabled, 0); +static IIO_DEVICE_ATTR_RO(hwfifo_watermark, 0); + +static const struct attribute *kx022a_fifo_attributes[] = { + &iio_dev_attr_hwfifo_watermark.dev_attr.attr, + &iio_dev_attr_hwfifo_enabled.dev_attr.attr, + NULL +}; + +static int kx022a_drop_fifo_contents(struct kx022a_data *data) +{ + /* + * We must clear the old time-stamp to avoid computing the timestamps + * based on samples acquired when buffer was last enabled. + * + * We don't need to protect the timestamp as long as we are only + * called from fifo-disable where we can guarantee the sensor is not + * triggering interrupts and where the mutex is locked to prevent the + * user-space access. + */ + data->timestamp = 0; + + return regmap_write(data->regmap, KX022A_REG_BUF_CLEAR, 0x0); +} + +static int __kx022a_fifo_flush(struct iio_dev *idev, unsigned int samples, + bool irq) +{ + struct kx022a_data *data = iio_priv(idev); + struct device *dev = regmap_get_device(data->regmap); + __le16 buffer[KX022A_FIFO_LENGTH * 3]; + uint64_t sample_period; + int count, fifo_bytes; + bool renable = false; + int64_t tstamp; + int ret, i; + + ret = regmap_read(data->regmap, KX022A_REG_BUF_STATUS_1, &fifo_bytes); + if (ret) { + dev_err(dev, "Error reading buffer status\n"); + return ret; + } + + /* Let's not overflow if we for some reason get bogus value from i2c */ + if (fifo_bytes == KX022A_FIFO_FULL_VALUE) + fifo_bytes = KX022A_FIFO_MAX_BYTES; + + if (fifo_bytes % KX022A_FIFO_SAMPLES_SIZE_BYTES) + dev_warn(data->dev, "Bad FIFO alignment. Data may be corrupt\n"); + + count = fifo_bytes / KX022A_FIFO_SAMPLES_SIZE_BYTES; + if (!count) + return 0; + + /* + * If we are being called from IRQ handler we know the stored timestamp + * is fairly accurate for the last stored sample. Otherwise, if we are + * called as a result of a read operation from userspace and hence + * before the watermark interrupt was triggered, take a timestamp + * now. We can fall anywhere in between two samples so the error in this + * case is at most one sample period. + */ + if (!irq) { + /* + * We need to have the IRQ disabled or we risk of messing-up + * the timestamps. If we are ran from IRQ, then the + * IRQF_ONESHOT has us covered - but if we are ran by the + * user-space read we need to disable the IRQ to be on a safe + * side. We do this usng synchronous disable so that if the + * IRQ thread is being ran on other CPU we wait for it to be + * finished. + */ + disable_irq(data->irq); + renable = true; + + data->old_timestamp = data->timestamp; + data->timestamp = iio_get_time_ns(idev); + } + + /* + * Approximate timestamps for each of the sample based on the sampling + * frequency, timestamp for last sample and number of samples. + * + * We'd better not use the current bandwidth settings to compute the + * sample period. The real sample rate varies with the device and + * small variation adds when we store a large number of samples. + * + * To avoid this issue we compute the actual sample period ourselves + * based on the timestamp delta between the last two flush operations. + */ + if (data->old_timestamp) { + sample_period = data->timestamp - data->old_timestamp; + do_div(sample_period, count); + } else { + sample_period = data->odr_ns; + } + tstamp = data->timestamp - (count - 1) * sample_period; + + if (samples && count > samples) { + /* + * Here we leave some old samples to the buffer. We need to + * adjust the timestamp to match the first sample in the buffer + * or we will miscalculate the sample_period at next round. + */ + data->timestamp -= (count - samples) * sample_period; + count = samples; + } + + fifo_bytes = count * KX022A_FIFO_SAMPLES_SIZE_BYTES; + ret = regmap_noinc_read(data->regmap, KX022A_REG_BUF_READ, + &buffer[0], fifo_bytes); + if (ret) + goto renable_out; + + for (i = 0; i < count; i++) { + __le16 *sam = &buffer[i * 3]; + __le16 *chs; + int bit; + + chs = &data->scan.channels[0]; + for_each_set_bit(bit, idev->active_scan_mask, AXIS_MAX) + chs[bit] = sam[bit]; + + iio_push_to_buffers_with_timestamp(idev, &data->scan, tstamp); + + tstamp += sample_period; + } + + ret = count; + +renable_out: + if (renable) + enable_irq(data->irq); + + return ret; +} + +static int kx022a_fifo_flush(struct iio_dev *idev, unsigned int samples) +{ + struct kx022a_data *data = iio_priv(idev); + int ret; + + mutex_lock(&data->mutex); + ret = __kx022a_fifo_flush(idev, samples, false); + mutex_unlock(&data->mutex); + + return ret; +} + +static const struct iio_info kx022a_info = { + .read_raw = &kx022a_read_raw, + .write_raw = &kx022a_write_raw, + .read_avail = &kx022a_read_avail, + + .validate_trigger = kx022a_validate_trigger, + .hwfifo_set_watermark = kx022a_set_watermark, + .hwfifo_flush_to_buffer = kx022a_fifo_flush, +}; + +static int kx022a_set_drdy_irq(struct kx022a_data *data, bool en) +{ + if (en) + return regmap_set_bits(data->regmap, KX022A_REG_CNTL, + KX022A_MASK_DRDY); + + return regmap_clear_bits(data->regmap, KX022A_REG_CNTL, + KX022A_MASK_DRDY); +} + +static int kx022a_prepare_irq_pin(struct kx022a_data *data) +{ + /* Enable IRQ1 pin. Set polarity to active low */ + int mask = KX022A_MASK_IEN | KX022A_MASK_IPOL | + KX022A_MASK_ITYP; + int val = KX022A_MASK_IEN | KX022A_IPOL_LOW | + KX022A_ITYP_LEVEL; + int ret; + + ret = regmap_update_bits(data->regmap, data->inc_reg, mask, val); + if (ret) + return ret; + + /* We enable WMI to IRQ pin only at buffer_enable */ + mask = KX022A_MASK_INS2_DRDY; + + return regmap_set_bits(data->regmap, data->ien_reg, mask); +} + +static int kx022a_fifo_disable(struct kx022a_data *data) +{ + int ret = 0; + + ret = kx022a_turn_off_lock(data); + if (ret) + return ret; + + ret = regmap_clear_bits(data->regmap, data->ien_reg, KX022A_MASK_WMI); + if (ret) + goto unlock_out; + + ret = regmap_clear_bits(data->regmap, KX022A_REG_BUF_CNTL2, + KX022A_MASK_BUF_EN); + if (ret) + goto unlock_out; + + data->state &= ~KX022A_STATE_FIFO; + + kx022a_drop_fifo_contents(data); + + return kx022a_turn_on_unlock(data); + +unlock_out: + mutex_unlock(&data->mutex); + + return ret; +} + +static int kx022a_buffer_predisable(struct iio_dev *idev) +{ + struct kx022a_data *data = iio_priv(idev); + + if (iio_device_get_current_mode(idev) == INDIO_BUFFER_TRIGGERED) + return 0; + + return kx022a_fifo_disable(data); +} + +static int kx022a_fifo_enable(struct kx022a_data *data) +{ + int ret; + + ret = kx022a_turn_off_lock(data); + if (ret) + return ret; + + /* Update watermark to HW */ + ret = kx022a_fifo_set_wmi(data); + if (ret) + goto unlock_out; + + /* Enable buffer */ + ret = regmap_set_bits(data->regmap, KX022A_REG_BUF_CNTL2, + KX022A_MASK_BUF_EN); + if (ret) + goto unlock_out; + + data->state |= KX022A_STATE_FIFO; + ret = regmap_set_bits(data->regmap, data->ien_reg, + KX022A_MASK_WMI); + if (ret) + goto unlock_out; + + return kx022a_turn_on_unlock(data); + +unlock_out: + mutex_unlock(&data->mutex); + + return ret; +} + +static int kx022a_buffer_postenable(struct iio_dev *idev) +{ + struct kx022a_data *data = iio_priv(idev); + + /* + * If we use data-ready trigger, then the IRQ masks should be handled by + * trigger enable and the hardware buffer is not used but we just update + * results to the IIO fifo when data-ready triggers. + */ + if (iio_device_get_current_mode(idev) == INDIO_BUFFER_TRIGGERED) + return 0; + + return kx022a_fifo_enable(data); +} + +static const struct iio_buffer_setup_ops kx022a_buffer_ops = { + .postenable = kx022a_buffer_postenable, + .predisable = kx022a_buffer_predisable, +}; + +static irqreturn_t kx022a_trigger_handler(int irq, void *p) +{ + struct iio_poll_func *pf = p; + struct iio_dev *idev = pf->indio_dev; + struct kx022a_data *data = iio_priv(idev); + int ret; + + ret = regmap_bulk_read(data->regmap, KX022A_REG_XOUT_L, data->buffer, + KX022A_FIFO_SAMPLES_SIZE_BYTES); + if (ret < 0) + goto err_read; + + iio_push_to_buffers_with_timestamp(idev, data->buffer, pf->timestamp); +err_read: + iio_trigger_notify_done(idev->trig); + + return IRQ_HANDLED; +} + +/* Get timestamps and wake the thread if we need to read data */ +static irqreturn_t kx022a_irq_handler(int irq, void *private) +{ + struct iio_dev *idev = private; + struct kx022a_data *data = iio_priv(idev); + + data->old_timestamp = data->timestamp; + data->timestamp = iio_get_time_ns(idev); + + if (data->state & KX022A_STATE_FIFO || data->trigger_enabled) + return IRQ_WAKE_THREAD; + + return IRQ_NONE; +} + +/* + * WMI and data-ready IRQs are acked when results are read. If we add + * TILT/WAKE or other IRQs - then we may need to implement the acking + * (which is racy). + */ +static irqreturn_t kx022a_irq_thread_handler(int irq, void *private) +{ + struct iio_dev *idev = private; + struct kx022a_data *data = iio_priv(idev); + irqreturn_t ret = IRQ_NONE; + + mutex_lock(&data->mutex); + + if (data->trigger_enabled) { + iio_trigger_poll_chained(data->trig); + ret = IRQ_HANDLED; + } + + if (data->state & KX022A_STATE_FIFO) { + int ok; + + ok = __kx022a_fifo_flush(idev, KX022A_FIFO_LENGTH, true); + if (ok > 0) + ret = IRQ_HANDLED; + } + + mutex_unlock(&data->mutex); + + return ret; +} + +static int kx022a_trigger_set_state(struct iio_trigger *trig, + bool state) +{ + struct kx022a_data *data = iio_trigger_get_drvdata(trig); + int ret = 0; + + mutex_lock(&data->mutex); + + if (data->trigger_enabled == state) + goto unlock_out; + + if (data->state & KX022A_STATE_FIFO) { + dev_warn(data->dev, "Can't set trigger when FIFO enabled\n"); + ret = -EBUSY; + goto unlock_out; + } + + ret = kx022a_turn_on_off_unlocked(data, false); + if (ret) + goto unlock_out; + + data->trigger_enabled = state; + ret = kx022a_set_drdy_irq(data, state); + if (ret) + goto unlock_out; + + ret = kx022a_turn_on_off_unlocked(data, true); + +unlock_out: + mutex_unlock(&data->mutex); + + return ret; +} + +static const struct iio_trigger_ops kx022a_trigger_ops = { + .set_trigger_state = kx022a_trigger_set_state, +}; + +static int kx022a_chip_init(struct kx022a_data *data) +{ + int ret, val; + + /* Reset the senor */ + ret = regmap_write(data->regmap, KX022A_REG_CNTL2, KX022A_MASK_SRST); + if (ret) + return ret; + + /* + * I've seen I2C read failures if we poll too fast after the sensor + * reset. Slight delay gives I2C block the time to recover. + */ + msleep(1); + + ret = regmap_read_poll_timeout(data->regmap, KX022A_REG_CNTL2, val, + !(val & KX022A_MASK_SRST), + KX022A_SOFT_RESET_WAIT_TIME_US, + KX022A_SOFT_RESET_TOTAL_WAIT_TIME_US); + if (ret) { + dev_err(data->dev, "Sensor reset %s\n", + val & KX022A_MASK_SRST ? "timeout" : "fail#"); + return ret; + } + + ret = regmap_reinit_cache(data->regmap, &kx022a_regmap); + if (ret) { + dev_err(data->dev, "Failed to reinit reg cache\n"); + return ret; + } + + /* set data res 16bit */ + ret = regmap_set_bits(data->regmap, KX022A_REG_BUF_CNTL2, + KX022A_MASK_BRES16); + if (ret) { + dev_err(data->dev, "Failed to set data resolution\n"); + return ret; + } + + return kx022a_prepare_irq_pin(data); +} + +int kx022a_probe_internal(struct device *dev) +{ + static const char * const regulator_names[] = {"io-vdd", "vdd"}; + struct iio_trigger *indio_trig; + struct fwnode_handle *fwnode; + struct kx022a_data *data; + struct regmap *regmap; + unsigned int chip_id; + struct iio_dev *idev; + int ret, irq; + char *name; + + regmap = dev_get_regmap(dev, NULL); + if (!regmap) { + dev_err(dev, "no regmap\n"); + return -EINVAL; + } + + fwnode = dev_fwnode(dev); + if (!fwnode) + return -ENODEV; + + idev = devm_iio_device_alloc(dev, sizeof(*data)); + if (!idev) + return -ENOMEM; + + data = iio_priv(idev); + + /* + * VDD is the analog and digital domain voltage supply and + * IO_VDD is the digital I/O voltage supply. + */ + ret = devm_regulator_bulk_get_enable(dev, ARRAY_SIZE(regulator_names), + regulator_names); + if (ret && ret != -ENODEV) + return dev_err_probe(dev, ret, "failed to enable regulator\n"); + + ret = regmap_read(regmap, KX022A_REG_WHO, &chip_id); + if (ret) + return dev_err_probe(dev, ret, "Failed to access sensor\n"); + + if (chip_id != KX022A_ID) { + dev_err(dev, "unsupported device 0x%x\n", chip_id); + return -EINVAL; + } + + irq = fwnode_irq_get_byname(fwnode, "INT1"); + if (irq > 0) { + data->inc_reg = KX022A_REG_INC1; + data->ien_reg = KX022A_REG_INC4; + } else { + irq = fwnode_irq_get_byname(fwnode, "INT2"); + if (irq <= 0) + return dev_err_probe(dev, irq, "No suitable IRQ\n"); + + data->inc_reg = KX022A_REG_INC5; + data->ien_reg = KX022A_REG_INC6; + } + + data->regmap = regmap; + data->dev = dev; + data->irq = irq; + data->odr_ns = KX022A_DEFAULT_PERIOD_NS; + mutex_init(&data->mutex); + + idev->channels = kx022a_channels; + idev->num_channels = ARRAY_SIZE(kx022a_channels); + idev->name = "kx022-accel"; + idev->info = &kx022a_info; + idev->modes = INDIO_DIRECT_MODE | INDIO_BUFFER_SOFTWARE; + idev->available_scan_masks = kx022a_scan_masks; + + /* Read the mounting matrix, if present */ + ret = iio_read_mount_matrix(dev, &data->orientation); + if (ret) + return ret; + + /* The sensor must be turned off for configuration */ + ret = kx022a_turn_off_lock(data); + if (ret) + return ret; + + ret = kx022a_chip_init(data); + if (ret) { + mutex_unlock(&data->mutex); + return ret; + } + + ret = kx022a_turn_on_unlock(data); + if (ret) + return ret; + + ret = devm_iio_triggered_buffer_setup_ext(dev, idev, + &iio_pollfunc_store_time, + kx022a_trigger_handler, + IIO_BUFFER_DIRECTION_IN, + &kx022a_buffer_ops, + kx022a_fifo_attributes); + + if (ret) + return dev_err_probe(data->dev, ret, + "iio_triggered_buffer_setup_ext FAIL\n"); + indio_trig = devm_iio_trigger_alloc(dev, "%sdata-rdy-dev%d", idev->name, + iio_device_id(idev)); + if (!indio_trig) + return -ENOMEM; + + data->trig = indio_trig; + + indio_trig->ops = &kx022a_trigger_ops; + iio_trigger_set_drvdata(indio_trig, data); + + /* + * No need to check for NULL. request_threaded_irq() defaults to + * dev_name() should the alloc fail. + */ + name = devm_kasprintf(data->dev, GFP_KERNEL, "%s-kx022a", + dev_name(data->dev)); + + ret = devm_request_threaded_irq(data->dev, irq, kx022a_irq_handler, + &kx022a_irq_thread_handler, + IRQF_ONESHOT, name, idev); + if (ret) + return dev_err_probe(data->dev, ret, "Could not request IRQ\n"); + + + ret = devm_iio_trigger_register(dev, indio_trig); + if (ret) + return dev_err_probe(data->dev, ret, + "Trigger registration failed\n"); + + ret = devm_iio_device_register(data->dev, idev); + if (ret < 0) + return dev_err_probe(dev, ret, + "Unable to register iio device\n"); + + return ret; +} +EXPORT_SYMBOL_NS_GPL(kx022a_probe_internal, IIO_KX022A); + +MODULE_DESCRIPTION("ROHM/Kionix KX022A accelerometer driver"); +MODULE_AUTHOR("Matti Vaittinen "); +MODULE_LICENSE("GPL"); diff --git a/drivers/iio/accel/kionix-kx022a.h b/drivers/iio/accel/kionix-kx022a.h new file mode 100644 index 000000000000..12424649d438 --- /dev/null +++ b/drivers/iio/accel/kionix-kx022a.h @@ -0,0 +1,82 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* + * Copyright (C) 2022 ROHM Semiconductors + * + * ROHM/KIONIX KX022A accelerometer driver + */ + +#ifndef _KX022A_H_ +#define _KX022A_H_ + +#include +#include + +#define KX022A_REG_WHO 0x0f +#define KX022A_ID 0xc8 + +#define KX022A_REG_CNTL2 0x19 +#define KX022A_MASK_SRST BIT(7) +#define KX022A_REG_CNTL 0x18 +#define KX022A_MASK_PC1 BIT(7) +#define KX022A_MASK_RES BIT(6) +#define KX022A_MASK_DRDY BIT(5) +#define KX022A_MASK_GSEL GENMASK(4, 3) +#define KX022A_GSEL_SHIFT 3 +#define KX022A_GSEL_2 0x0 +#define KX022A_GSEL_4 BIT(3) +#define KX022A_GSEL_8 BIT(4) +#define KX022A_GSEL_16 GENMASK(4, 3) + +#define KX022A_REG_INS2 0x13 +#define KX022A_MASK_INS2_DRDY BIT(4) +#define KX122_MASK_INS2_WMI BIT(5) + +#define KX022A_REG_XHP_L 0x0 +#define KX022A_REG_XOUT_L 0x06 +#define KX022A_REG_YOUT_L 0x08 +#define KX022A_REG_ZOUT_L 0x0a +#define KX022A_REG_COTR 0x0c +#define KX022A_REG_TSCP 0x10 +#define KX022A_REG_INT_REL 0x17 + +#define KX022A_REG_ODCNTL 0x1b + +#define KX022A_REG_BTS_WUF_TH 0x31 +#define KX022A_REG_MAN_WAKE 0x2c + +#define KX022A_REG_BUF_CNTL1 0x3a +#define KX022A_MASK_WM_TH GENMASK(6, 0) +#define KX022A_REG_BUF_CNTL2 0x3b +#define KX022A_MASK_BUF_EN BIT(7) +#define KX022A_MASK_BRES16 BIT(6) +#define KX022A_REG_BUF_STATUS_1 0x3c +#define KX022A_REG_BUF_STATUS_2 0x3d +#define KX022A_REG_BUF_CLEAR 0x3e +#define KX022A_REG_BUF_READ 0x3f +#define KX022A_MASK_ODR GENMASK(3, 0) +#define KX022A_ODR_SHIFT 3 +#define KX022A_FIFO_MAX_WMI_TH 41 + +#define KX022A_REG_INC1 0x1c +#define KX022A_REG_INC5 0x20 +#define KX022A_REG_INC6 0x21 +#define KX022A_MASK_IEN BIT(5) +#define KX022A_MASK_IPOL BIT(4) +#define KX022A_IPOL_LOW 0 +#define KX022A_IPOL_HIGH KX022A_MASK_IPOL1 +#define KX022A_MASK_ITYP BIT(3) +#define KX022A_ITYP_PULSE KX022A_MASK_ITYP +#define KX022A_ITYP_LEVEL 0 + +#define KX022A_REG_INC4 0x1f +#define KX022A_MASK_WMI BIT(5) + +#define KX022A_REG_SELF_TEST 0x60 +#define KX022A_MAX_REGISTER 0x60 + +struct device; + +int kx022a_probe_internal(struct device *dev); +extern const struct regmap_config kx022a_regmap; + +#endif -- cgit v1.2.3 From 6abcb19e0a6a371b5dafe4473ea886a6891a5cd5 Mon Sep 17 00:00:00 2001 From: Colin Ian King Date: Fri, 4 Nov 2022 09:31:48 +0000 Subject: iio: adc: ad4130: Fix spelling mistake "diffreential" -> "differential" There is a spelling mistake in an error message. Fix it. Signed-off-by: Colin Ian King Link: https://lore.kernel.org/r/20221104093148.167765-1-colin.i.king@gmail.com Signed-off-by: Jonathan Cameron --- drivers/iio/adc/ad4130.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/iio') diff --git a/drivers/iio/adc/ad4130.c b/drivers/iio/adc/ad4130.c index 9a4d0043d797..ae1a4dd5c40a 100644 --- a/drivers/iio/adc/ad4130.c +++ b/drivers/iio/adc/ad4130.c @@ -1480,7 +1480,7 @@ static int ad4130_validate_diff_channel(struct ad4130_state *st, u32 pin) if (pin >= AD4130_MAX_DIFF_INPUTS) return dev_err_probe(dev, -EINVAL, - "Invalid diffreential channel %u\n", pin); + "Invalid differential channel %u\n", pin); if (pin >= AD4130_MAX_ANALOG_PINS) return 0; -- cgit v1.2.3 From f0ab171b80d49a2a47b88f79de38ca64c7d641d4 Mon Sep 17 00:00:00 2001 From: Matti Vaittinen Date: Mon, 3 Oct 2022 11:12:25 +0300 Subject: iio: adxl367: Use IIO_STATIC_CONST_DEVICE_ATTR() Slightly simplify by dropping open-coded constant data iio_dev_attr functions and using the IIO_STATIC_CONST_DEVICE_ATTR() instead. Signed-off-by: Matti Vaittinen Link: https://lore.kernel.org/r/c96c55363b8f36017ef7f18fdfe810cd3990e2a4.1664782676.git.mazziesaccount@gmail.com Signed-off-by: Jonathan Cameron --- drivers/iio/accel/adxl367.c | 19 +++---------------- 1 file changed, 3 insertions(+), 16 deletions(-) (limited to 'drivers/iio') diff --git a/drivers/iio/accel/adxl367.c b/drivers/iio/accel/adxl367.c index d7af3a006a44..d8e98f65f25d 100644 --- a/drivers/iio/accel/adxl367.c +++ b/drivers/iio/accel/adxl367.c @@ -1183,22 +1183,9 @@ static ssize_t adxl367_get_fifo_watermark(struct device *dev, return sysfs_emit(buf, "%d\n", fifo_watermark); } -static ssize_t hwfifo_watermark_min_show(struct device *dev, - struct device_attribute *attr, - char *buf) -{ - return sysfs_emit(buf, "%s\n", "1"); -} - -static ssize_t hwfifo_watermark_max_show(struct device *dev, - struct device_attribute *attr, - char *buf) -{ - return sysfs_emit(buf, "%s\n", __stringify(ADXL367_FIFO_MAX_WATERMARK)); -} - -static IIO_DEVICE_ATTR_RO(hwfifo_watermark_min, 0); -static IIO_DEVICE_ATTR_RO(hwfifo_watermark_max, 0); +IIO_STATIC_CONST_DEVICE_ATTR(hwfifo_watermark_min, "1"); +IIO_STATIC_CONST_DEVICE_ATTR(hwfifo_watermark_max, + __stringify(ADXL367_FIFO_MAX_WATERMARK)); static IIO_DEVICE_ATTR(hwfifo_watermark, 0444, adxl367_get_fifo_watermark, NULL, 0); static IIO_DEVICE_ATTR(hwfifo_enabled, 0444, -- cgit v1.2.3 From f7e6804509eeb27accc6625150db3f02d0b93ad7 Mon Sep 17 00:00:00 2001 From: Matti Vaittinen Date: Mon, 3 Oct 2022 11:12:48 +0300 Subject: iio: adxl372: Use IIO_STATIC_CONST_DEVICE_ATTR() Slightly simplify by dropping open-coded constant data iio_dev_attr functions and using the IIO_STATIC_CONST_DEVICE_ATTR() instead. Signed-off-by: Matti Vaittinen Link: https://lore.kernel.org/r/3632af8849ef101c54ec1f739596f22c773b067c.1664782676.git.mazziesaccount@gmail.com Signed-off-by: Jonathan Cameron --- drivers/iio/accel/adxl372.c | 19 +++---------------- 1 file changed, 3 insertions(+), 16 deletions(-) (limited to 'drivers/iio') diff --git a/drivers/iio/accel/adxl372.c b/drivers/iio/accel/adxl372.c index bc53af809d5d..90e1d726b9c5 100644 --- a/drivers/iio/accel/adxl372.c +++ b/drivers/iio/accel/adxl372.c @@ -998,22 +998,9 @@ static ssize_t adxl372_get_fifo_watermark(struct device *dev, return sprintf(buf, "%d\n", st->watermark); } -static ssize_t hwfifo_watermark_min_show(struct device *dev, - struct device_attribute *attr, - char *buf) -{ - return sysfs_emit(buf, "%s\n", "1"); -} - -static ssize_t hwfifo_watermark_max_show(struct device *dev, - struct device_attribute *attr, - char *buf) -{ - return sysfs_emit(buf, "%s\n", __stringify(ADXL372_FIFO_SIZE)); -} - -static IIO_DEVICE_ATTR_RO(hwfifo_watermark_min, 0); -static IIO_DEVICE_ATTR_RO(hwfifo_watermark_max, 0); +IIO_STATIC_CONST_DEVICE_ATTR(hwfifo_watermark_min, "1"); +IIO_STATIC_CONST_DEVICE_ATTR(hwfifo_watermark_max, + __stringify(ADXL372_FIFO_SIZE)); static IIO_DEVICE_ATTR(hwfifo_watermark, 0444, adxl372_get_fifo_watermark, NULL, 0); static IIO_DEVICE_ATTR(hwfifo_enabled, 0444, -- cgit v1.2.3 From c02b2a5166a58823e8a335c486ee71ce4f22f2b7 Mon Sep 17 00:00:00 2001 From: Matti Vaittinen Date: Mon, 3 Oct 2022 11:13:10 +0300 Subject: iio: bmc150-accel-core: Use IIO_STATIC_CONST_DEVICE_ATTR() Slightly simplify by dropping open-coded constant data iio_dev_attr functions and using the IIO_STATIC_CONST_DEVICE_ATTR() instead. Signed-off-by: Matti Vaittinen Link: https://lore.kernel.org/r/b1b0d662705b43d68594639fb7719bc431101f79.1664782676.git.mazziesaccount@gmail.com Signed-off-by: Jonathan Cameron --- drivers/iio/accel/bmc150-accel-core.c | 19 +++---------------- 1 file changed, 3 insertions(+), 16 deletions(-) (limited to 'drivers/iio') diff --git a/drivers/iio/accel/bmc150-accel-core.c b/drivers/iio/accel/bmc150-accel-core.c index 92f8b139acce..b4a077944896 100644 --- a/drivers/iio/accel/bmc150-accel-core.c +++ b/drivers/iio/accel/bmc150-accel-core.c @@ -925,22 +925,9 @@ static const struct iio_chan_spec_ext_info bmc150_accel_ext_info[] = { { } }; -static ssize_t hwfifo_watermark_min_show(struct device *dev, - struct device_attribute *attr, - char *buf) -{ - return sysfs_emit(buf, "%s\n", "1"); -} - -static ssize_t hwfifo_watermark_max_show(struct device *dev, - struct device_attribute *attr, - char *buf) -{ - return sysfs_emit(buf, "%s\n", __stringify(BMC150_ACCEL_FIFO_LENGTH)); -} - -static IIO_DEVICE_ATTR_RO(hwfifo_watermark_min, 0); -static IIO_DEVICE_ATTR_RO(hwfifo_watermark_max, 0); +IIO_STATIC_CONST_DEVICE_ATTR(hwfifo_watermark_min, "1"); +IIO_STATIC_CONST_DEVICE_ATTR(hwfifo_watermark_max, + __stringify(BMC150_ACCEL_FIFO_LENGTH)); static IIO_DEVICE_ATTR(hwfifo_enabled, S_IRUGO, bmc150_accel_get_fifo_state, NULL, 0); static IIO_DEVICE_ATTR(hwfifo_watermark, S_IRUGO, -- cgit v1.2.3 From c1531e3ad43f5e66cd04ae19644343b9222204d2 Mon Sep 17 00:00:00 2001 From: Matti Vaittinen Date: Mon, 3 Oct 2022 11:13:31 +0300 Subject: iio: at91-sama5d2_adc: Use IIO_STATIC_CONST_DEVICE_ATTR() Slightly simplify by dropping open-coded constant data iio_dev_attr functions and using the IIO_STATIC_CONST_DEVICE_ATTR() instead. Signed-off-by: Matti Vaittinen Tested-by: Claudiu Beznea Link: https://lore.kernel.org/r/4476a4ce852febb3eb863878e66751c787195b18.1664782676.git.mazziesaccount@gmail.com Signed-off-by: Jonathan Cameron --- drivers/iio/adc/at91-sama5d2_adc.c | 19 +++---------------- 1 file changed, 3 insertions(+), 16 deletions(-) (limited to 'drivers/iio') diff --git a/drivers/iio/adc/at91-sama5d2_adc.c b/drivers/iio/adc/at91-sama5d2_adc.c index 33e251552214..aa2e1640c4a3 100644 --- a/drivers/iio/adc/at91-sama5d2_adc.c +++ b/drivers/iio/adc/at91-sama5d2_adc.c @@ -2193,26 +2193,13 @@ static ssize_t at91_adc_get_watermark(struct device *dev, return scnprintf(buf, PAGE_SIZE, "%d\n", st->dma_st.watermark); } -static ssize_t hwfifo_watermark_min_show(struct device *dev, - struct device_attribute *attr, - char *buf) -{ - return sysfs_emit(buf, "%s\n", "2"); -} - -static ssize_t hwfifo_watermark_max_show(struct device *dev, - struct device_attribute *attr, - char *buf) -{ - return sysfs_emit(buf, "%s\n", AT91_HWFIFO_MAX_SIZE_STR); -} - static IIO_DEVICE_ATTR(hwfifo_enabled, 0444, at91_adc_get_fifo_state, NULL, 0); static IIO_DEVICE_ATTR(hwfifo_watermark, 0444, at91_adc_get_watermark, NULL, 0); -static IIO_DEVICE_ATTR_RO(hwfifo_watermark_min, 0); -static IIO_DEVICE_ATTR_RO(hwfifo_watermark_max, 0); + +IIO_STATIC_CONST_DEVICE_ATTR(hwfifo_watermark_min, "2"); +IIO_STATIC_CONST_DEVICE_ATTR(hwfifo_watermark_max, AT91_HWFIFO_MAX_SIZE_STR); static const struct attribute *at91_adc_fifo_attributes[] = { &iio_dev_attr_hwfifo_watermark_min.dev_attr.attr, -- cgit v1.2.3 From 0a33755c4b01ed62a6d025cb585928304f9653d7 Mon Sep 17 00:00:00 2001 From: Matti Vaittinen Date: Mon, 3 Oct 2022 11:13:53 +0300 Subject: iio: Don't silently expect attribute types The iio_triggered_buffer_setup_ext() and the devm_iio_kfifo_buffer_setup_ext() were changed by commit 15097c7a1adc ("iio: buffer: wrap all buffer attributes into iio_dev_attr") to silently expect that all attributes given in buffer_attrs array are device-attributes. This expectation was not forced by the API - and some drivers did register attributes created by IIO_CONST_ATTR(). When using IIO_CONST_ATTRs the added attribute "wrapping" does not copy the pointer to stored string constant and when the sysfs file is read the kernel will access to invalid location. Change the function signatures to expect an array of iio_dev_attrs to avoid similar errors in the future. Merge conflict resolved whilst applying due to patch crossing with two new drivers (kx022a accelerometer and ad4130 ADC). Signed-off-by: Matti Vaittinen Tested-by: Claudiu Beznea Link: https://lore.kernel.org/r/63f54787a684eb1232f1c5d275a09c786987fe4a.1664782676.git.mazziesaccount@gmail.com Signed-off-by: Jonathan Cameron --- drivers/iio/accel/adxl367.c | 10 +++++----- drivers/iio/accel/adxl372.c | 10 +++++----- drivers/iio/accel/bmc150-accel-core.c | 12 ++++++------ drivers/iio/accel/kionix-kx022a.c | 6 +++--- drivers/iio/adc/ad4130.c | 10 +++++----- drivers/iio/adc/at91-sama5d2_adc.c | 12 ++++++------ drivers/iio/buffer/industrialio-buffer-dmaengine.c | 4 ++-- drivers/iio/buffer/industrialio-triggered-buffer.c | 4 ++-- drivers/iio/buffer/kfifo_buf.c | 2 +- drivers/iio/common/cros_ec_sensors/cros_ec_sensors_core.c | 6 +++--- drivers/iio/common/hid-sensors/hid-sensor-trigger.c | 8 ++++---- drivers/iio/industrialio-buffer.c | 11 +++++++---- include/linux/iio/buffer_impl.h | 2 +- include/linux/iio/kfifo_buf.h | 3 ++- include/linux/iio/triggered_buffer.h | 6 +++--- 15 files changed, 55 insertions(+), 51 deletions(-) (limited to 'drivers/iio') diff --git a/drivers/iio/accel/adxl367.c b/drivers/iio/accel/adxl367.c index d8e98f65f25d..90b7ae6d42b7 100644 --- a/drivers/iio/accel/adxl367.c +++ b/drivers/iio/accel/adxl367.c @@ -1191,11 +1191,11 @@ static IIO_DEVICE_ATTR(hwfifo_watermark, 0444, static IIO_DEVICE_ATTR(hwfifo_enabled, 0444, adxl367_get_fifo_enabled, NULL, 0); -static const struct attribute *adxl367_fifo_attributes[] = { - &iio_dev_attr_hwfifo_watermark_min.dev_attr.attr, - &iio_dev_attr_hwfifo_watermark_max.dev_attr.attr, - &iio_dev_attr_hwfifo_watermark.dev_attr.attr, - &iio_dev_attr_hwfifo_enabled.dev_attr.attr, +static const struct iio_dev_attr *adxl367_fifo_attributes[] = { + &iio_dev_attr_hwfifo_watermark_min, + &iio_dev_attr_hwfifo_watermark_max, + &iio_dev_attr_hwfifo_watermark, + &iio_dev_attr_hwfifo_enabled, NULL, }; diff --git a/drivers/iio/accel/adxl372.c b/drivers/iio/accel/adxl372.c index 90e1d726b9c5..c4193286eb05 100644 --- a/drivers/iio/accel/adxl372.c +++ b/drivers/iio/accel/adxl372.c @@ -1006,11 +1006,11 @@ static IIO_DEVICE_ATTR(hwfifo_watermark, 0444, static IIO_DEVICE_ATTR(hwfifo_enabled, 0444, adxl372_get_fifo_enabled, NULL, 0); -static const struct attribute *adxl372_fifo_attributes[] = { - &iio_dev_attr_hwfifo_watermark_min.dev_attr.attr, - &iio_dev_attr_hwfifo_watermark_max.dev_attr.attr, - &iio_dev_attr_hwfifo_watermark.dev_attr.attr, - &iio_dev_attr_hwfifo_enabled.dev_attr.attr, +static const struct iio_dev_attr *adxl372_fifo_attributes[] = { + &iio_dev_attr_hwfifo_watermark_min, + &iio_dev_attr_hwfifo_watermark_max, + &iio_dev_attr_hwfifo_watermark, + &iio_dev_attr_hwfifo_enabled, NULL, }; diff --git a/drivers/iio/accel/bmc150-accel-core.c b/drivers/iio/accel/bmc150-accel-core.c index b4a077944896..110591804b4c 100644 --- a/drivers/iio/accel/bmc150-accel-core.c +++ b/drivers/iio/accel/bmc150-accel-core.c @@ -933,11 +933,11 @@ static IIO_DEVICE_ATTR(hwfifo_enabled, S_IRUGO, static IIO_DEVICE_ATTR(hwfifo_watermark, S_IRUGO, bmc150_accel_get_fifo_watermark, NULL, 0); -static const struct attribute *bmc150_accel_fifo_attributes[] = { - &iio_dev_attr_hwfifo_watermark_min.dev_attr.attr, - &iio_dev_attr_hwfifo_watermark_max.dev_attr.attr, - &iio_dev_attr_hwfifo_watermark.dev_attr.attr, - &iio_dev_attr_hwfifo_enabled.dev_attr.attr, +static const struct iio_dev_attr *bmc150_accel_fifo_attributes[] = { + &iio_dev_attr_hwfifo_watermark_min, + &iio_dev_attr_hwfifo_watermark_max, + &iio_dev_attr_hwfifo_watermark, + &iio_dev_attr_hwfifo_enabled, NULL, }; @@ -1665,7 +1665,7 @@ int bmc150_accel_core_probe(struct device *dev, struct regmap *regmap, int irq, enum bmc150_type type, const char *name, bool block_supported) { - const struct attribute **fifo_attrs; + const struct iio_dev_attr **fifo_attrs; struct bmc150_accel_data *data; struct iio_dev *indio_dev; int ret; diff --git a/drivers/iio/accel/kionix-kx022a.c b/drivers/iio/accel/kionix-kx022a.c index 50de7f9a1cc7..f866859855cd 100644 --- a/drivers/iio/accel/kionix-kx022a.c +++ b/drivers/iio/accel/kionix-kx022a.c @@ -575,9 +575,9 @@ static ssize_t hwfifo_watermark_show(struct device *dev, static IIO_DEVICE_ATTR_RO(hwfifo_enabled, 0); static IIO_DEVICE_ATTR_RO(hwfifo_watermark, 0); -static const struct attribute *kx022a_fifo_attributes[] = { - &iio_dev_attr_hwfifo_watermark.dev_attr.attr, - &iio_dev_attr_hwfifo_enabled.dev_attr.attr, +static const struct iio_dev_attr *kx022a_fifo_attributes[] = { + &iio_dev_attr_hwfifo_watermark, + &iio_dev_attr_hwfifo_enabled, NULL }; diff --git a/drivers/iio/adc/ad4130.c b/drivers/iio/adc/ad4130.c index ae1a4dd5c40a..38394341fd6e 100644 --- a/drivers/iio/adc/ad4130.c +++ b/drivers/iio/adc/ad4130.c @@ -1380,11 +1380,11 @@ static IIO_DEVICE_ATTR_RO(hwfifo_watermark_max, 0); static IIO_DEVICE_ATTR_RO(hwfifo_watermark, 0); static IIO_DEVICE_ATTR_RO(hwfifo_enabled, 0); -static const struct attribute *ad4130_fifo_attributes[] = { - &iio_dev_attr_hwfifo_watermark_min.dev_attr.attr, - &iio_dev_attr_hwfifo_watermark_max.dev_attr.attr, - &iio_dev_attr_hwfifo_watermark.dev_attr.attr, - &iio_dev_attr_hwfifo_enabled.dev_attr.attr, +static const struct iio_dev_attr *ad4130_fifo_attributes[] = { + &iio_dev_attr_hwfifo_watermark_min, + &iio_dev_attr_hwfifo_watermark_max, + &iio_dev_attr_hwfifo_watermark, + &iio_dev_attr_hwfifo_enabled, NULL }; diff --git a/drivers/iio/adc/at91-sama5d2_adc.c b/drivers/iio/adc/at91-sama5d2_adc.c index aa2e1640c4a3..a00b8316a12f 100644 --- a/drivers/iio/adc/at91-sama5d2_adc.c +++ b/drivers/iio/adc/at91-sama5d2_adc.c @@ -2201,11 +2201,11 @@ static IIO_DEVICE_ATTR(hwfifo_watermark, 0444, IIO_STATIC_CONST_DEVICE_ATTR(hwfifo_watermark_min, "2"); IIO_STATIC_CONST_DEVICE_ATTR(hwfifo_watermark_max, AT91_HWFIFO_MAX_SIZE_STR); -static const struct attribute *at91_adc_fifo_attributes[] = { - &iio_dev_attr_hwfifo_watermark_min.dev_attr.attr, - &iio_dev_attr_hwfifo_watermark_max.dev_attr.attr, - &iio_dev_attr_hwfifo_watermark.dev_attr.attr, - &iio_dev_attr_hwfifo_enabled.dev_attr.attr, +static const struct iio_dev_attr *at91_adc_fifo_attributes[] = { + &iio_dev_attr_hwfifo_watermark_min, + &iio_dev_attr_hwfifo_watermark_max, + &iio_dev_attr_hwfifo_watermark, + &iio_dev_attr_hwfifo_enabled, NULL, }; @@ -2222,7 +2222,7 @@ static int at91_adc_buffer_and_trigger_init(struct device *dev, struct iio_dev *indio) { struct at91_adc_state *st = iio_priv(indio); - const struct attribute **fifo_attrs; + const struct iio_dev_attr **fifo_attrs; int ret; if (st->selected_trig->hw_trig) diff --git a/drivers/iio/buffer/industrialio-buffer-dmaengine.c b/drivers/iio/buffer/industrialio-buffer-dmaengine.c index f744b62a636a..5f85ba38e6f6 100644 --- a/drivers/iio/buffer/industrialio-buffer-dmaengine.c +++ b/drivers/iio/buffer/industrialio-buffer-dmaengine.c @@ -142,8 +142,8 @@ static ssize_t iio_dmaengine_buffer_get_length_align(struct device *dev, static IIO_DEVICE_ATTR(length_align_bytes, 0444, iio_dmaengine_buffer_get_length_align, NULL, 0); -static const struct attribute *iio_dmaengine_buffer_attrs[] = { - &iio_dev_attr_length_align_bytes.dev_attr.attr, +static const struct iio_dev_attr *iio_dmaengine_buffer_attrs[] = { + &iio_dev_attr_length_align_bytes, NULL, }; diff --git a/drivers/iio/buffer/industrialio-triggered-buffer.c b/drivers/iio/buffer/industrialio-triggered-buffer.c index 8d4fc97d1005..c7671b1f5ead 100644 --- a/drivers/iio/buffer/industrialio-triggered-buffer.c +++ b/drivers/iio/buffer/industrialio-triggered-buffer.c @@ -41,7 +41,7 @@ int iio_triggered_buffer_setup_ext(struct iio_dev *indio_dev, irqreturn_t (*thread)(int irq, void *p), enum iio_buffer_direction direction, const struct iio_buffer_setup_ops *setup_ops, - const struct attribute **buffer_attrs) + const struct iio_dev_attr **buffer_attrs) { struct iio_buffer *buffer; int ret; @@ -110,7 +110,7 @@ int devm_iio_triggered_buffer_setup_ext(struct device *dev, irqreturn_t (*thread)(int irq, void *p), enum iio_buffer_direction direction, const struct iio_buffer_setup_ops *ops, - const struct attribute **buffer_attrs) + const struct iio_dev_attr **buffer_attrs) { int ret; diff --git a/drivers/iio/buffer/kfifo_buf.c b/drivers/iio/buffer/kfifo_buf.c index 35d8b4077376..05b285f0eb22 100644 --- a/drivers/iio/buffer/kfifo_buf.c +++ b/drivers/iio/buffer/kfifo_buf.c @@ -270,7 +270,7 @@ static struct iio_buffer *devm_iio_kfifo_allocate(struct device *dev) int devm_iio_kfifo_buffer_setup_ext(struct device *dev, struct iio_dev *indio_dev, const struct iio_buffer_setup_ops *setup_ops, - const struct attribute **buffer_attrs) + const struct iio_dev_attr **buffer_attrs) { struct iio_buffer *buffer; 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 05a28d353e34..943e9e14d1e9 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 @@ -172,9 +172,9 @@ static ssize_t hwfifo_watermark_max_show(struct device *dev, static IIO_DEVICE_ATTR_RO(hwfifo_watermark_max, 0); -static const struct attribute *cros_ec_sensor_fifo_attributes[] = { - &iio_dev_attr_hwfifo_timeout.dev_attr.attr, - &iio_dev_attr_hwfifo_watermark_max.dev_attr.attr, +static const struct iio_dev_attr *cros_ec_sensor_fifo_attributes[] = { + &iio_dev_attr_hwfifo_timeout, + &iio_dev_attr_hwfifo_watermark_max, NULL, }; diff --git a/drivers/iio/common/hid-sensors/hid-sensor-trigger.c b/drivers/iio/common/hid-sensors/hid-sensor-trigger.c index 1151434038d4..ad8910e6ad59 100644 --- a/drivers/iio/common/hid-sensors/hid-sensor-trigger.c +++ b/drivers/iio/common/hid-sensors/hid-sensor-trigger.c @@ -75,9 +75,9 @@ static IIO_DEVICE_ATTR(hwfifo_timeout, 0644, static IIO_DEVICE_ATTR(hwfifo_enabled, 0444, _hid_sensor_get_fifo_state, NULL, 0); -static const struct attribute *hid_sensor_fifo_attributes[] = { - &iio_dev_attr_hwfifo_timeout.dev_attr.attr, - &iio_dev_attr_hwfifo_enabled.dev_attr.attr, +static const struct iio_dev_attr *hid_sensor_fifo_attributes[] = { + &iio_dev_attr_hwfifo_timeout, + &iio_dev_attr_hwfifo_enabled, NULL, }; @@ -231,7 +231,7 @@ static const struct iio_trigger_ops hid_sensor_trigger_ops = { int hid_sensor_setup_trigger(struct iio_dev *indio_dev, const char *name, struct hid_sensor_common *attrb) { - const struct attribute **fifo_attrs; + const struct iio_dev_attr **fifo_attrs; int ret; struct iio_trigger *trig; diff --git a/drivers/iio/industrialio-buffer.c b/drivers/iio/industrialio-buffer.c index 9cd7db549fcb..80c78bd6bbef 100644 --- a/drivers/iio/industrialio-buffer.c +++ b/drivers/iio/industrialio-buffer.c @@ -1605,6 +1605,7 @@ static int __iio_buffer_alloc_sysfs_and_mask(struct iio_buffer *buffer, { struct iio_dev_opaque *iio_dev_opaque = to_iio_dev_opaque(indio_dev); struct iio_dev_attr *p; + const struct iio_dev_attr *id_attr; struct attribute **attr; int ret, i, attrn, scan_el_attrcount, buffer_attrcount; const struct iio_chan_spec *channels; @@ -1614,6 +1615,7 @@ static int __iio_buffer_alloc_sysfs_and_mask(struct iio_buffer *buffer, while (buffer->attrs[buffer_attrcount] != NULL) buffer_attrcount++; } + buffer_attrcount += ARRAY_SIZE(iio_buffer_attrs); scan_el_attrcount = 0; INIT_LIST_HEAD(&buffer->buffer_attr_list); @@ -1656,7 +1658,7 @@ static int __iio_buffer_alloc_sysfs_and_mask(struct iio_buffer *buffer, } } - attrn = buffer_attrcount + scan_el_attrcount + ARRAY_SIZE(iio_buffer_attrs); + attrn = buffer_attrcount + scan_el_attrcount; attr = kcalloc(attrn + 1, sizeof(*attr), GFP_KERNEL); if (!attr) { ret = -ENOMEM; @@ -1671,10 +1673,11 @@ static int __iio_buffer_alloc_sysfs_and_mask(struct iio_buffer *buffer, attr[2] = &dev_attr_watermark_ro.attr; if (buffer->attrs) - memcpy(&attr[ARRAY_SIZE(iio_buffer_attrs)], buffer->attrs, - sizeof(struct attribute *) * buffer_attrcount); + for (i = 0, id_attr = buffer->attrs[i]; + (id_attr = buffer->attrs[i]); i++) + attr[ARRAY_SIZE(iio_buffer_attrs) + i] = + (struct attribute *)&id_attr->dev_attr.attr; - buffer_attrcount += ARRAY_SIZE(iio_buffer_attrs); buffer->buffer_group.attrs = attr; for (i = 0; i < buffer_attrcount; i++) { diff --git a/include/linux/iio/buffer_impl.h b/include/linux/iio/buffer_impl.h index e2ca8ea23e19..89c3fd7c29ca 100644 --- a/include/linux/iio/buffer_impl.h +++ b/include/linux/iio/buffer_impl.h @@ -123,7 +123,7 @@ struct iio_buffer { struct attribute_group buffer_group; /* @attrs: Standard attributes of the buffer. */ - const struct attribute **attrs; + const struct iio_dev_attr **attrs; /* @demux_bounce: Buffer for doing gather from incoming scan. */ void *demux_bounce; diff --git a/include/linux/iio/kfifo_buf.h b/include/linux/iio/kfifo_buf.h index 8a83fb58232d..22874da0c8be 100644 --- a/include/linux/iio/kfifo_buf.h +++ b/include/linux/iio/kfifo_buf.h @@ -5,6 +5,7 @@ struct iio_buffer; struct iio_buffer_setup_ops; struct iio_dev; +struct iio_dev_attr; struct device; struct iio_buffer *iio_kfifo_allocate(void); @@ -13,7 +14,7 @@ void iio_kfifo_free(struct iio_buffer *r); int devm_iio_kfifo_buffer_setup_ext(struct device *dev, struct iio_dev *indio_dev, const struct iio_buffer_setup_ops *setup_ops, - const struct attribute **buffer_attrs); + const struct iio_dev_attr **buffer_attrs); #define devm_iio_kfifo_buffer_setup(dev, indio_dev, setup_ops) \ devm_iio_kfifo_buffer_setup_ext((dev), (indio_dev), (setup_ops), NULL) diff --git a/include/linux/iio/triggered_buffer.h b/include/linux/iio/triggered_buffer.h index 7490b05fc5b2..29e1fe146879 100644 --- a/include/linux/iio/triggered_buffer.h +++ b/include/linux/iio/triggered_buffer.h @@ -5,8 +5,8 @@ #include #include -struct attribute; struct iio_dev; +struct iio_dev_attr; struct iio_buffer_setup_ops; int iio_triggered_buffer_setup_ext(struct iio_dev *indio_dev, @@ -14,7 +14,7 @@ int iio_triggered_buffer_setup_ext(struct iio_dev *indio_dev, irqreturn_t (*thread)(int irq, void *p), enum iio_buffer_direction direction, const struct iio_buffer_setup_ops *setup_ops, - const struct attribute **buffer_attrs); + const struct iio_dev_attr **buffer_attrs); void iio_triggered_buffer_cleanup(struct iio_dev *indio_dev); #define iio_triggered_buffer_setup(indio_dev, h, thread, setup_ops) \ @@ -28,7 +28,7 @@ int devm_iio_triggered_buffer_setup_ext(struct device *dev, irqreturn_t (*thread)(int irq, void *p), enum iio_buffer_direction direction, const struct iio_buffer_setup_ops *ops, - const struct attribute **buffer_attrs); + const struct iio_dev_attr **buffer_attrs); #define devm_iio_triggered_buffer_setup(dev, indio_dev, h, thread, setup_ops) \ devm_iio_triggered_buffer_setup_ext((dev), (indio_dev), (h), (thread), \ -- cgit v1.2.3 From 26bfb581931a020eaf560612f01009b3e179db0a Mon Sep 17 00:00:00 2001 From: Jonathan Cameron Date: Sun, 16 Oct 2022 18:09:46 +0100 Subject: iio: adc: cc10001: Add local struct device *dev variable to avoid repitition MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit There are lots of uses of this in probe() and we are about to introduce some more, so add a local variable to simplify this. Signed-off-by: Jonathan Cameron Reviewed-by: Nuno Sá Link: https://lore.kernel.org/r/20221016170950.387751-2-jic23@kernel.org --- drivers/iio/adc/cc10001_adc.c | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) (limited to 'drivers/iio') diff --git a/drivers/iio/adc/cc10001_adc.c b/drivers/iio/adc/cc10001_adc.c index e16ac935693b..eeaea1362ed1 100644 --- a/drivers/iio/adc/cc10001_adc.c +++ b/drivers/iio/adc/cc10001_adc.c @@ -307,14 +307,15 @@ static int cc10001_adc_channel_init(struct iio_dev *indio_dev, static int cc10001_adc_probe(struct platform_device *pdev) { - struct device_node *node = pdev->dev.of_node; + struct device *dev = &pdev->dev; + struct device_node *node = dev->of_node; struct cc10001_adc_device *adc_dev; unsigned long adc_clk_rate; struct iio_dev *indio_dev; unsigned long channel_map; int ret; - indio_dev = devm_iio_device_alloc(&pdev->dev, sizeof(*adc_dev)); + indio_dev = devm_iio_device_alloc(dev, sizeof(*adc_dev)); if (indio_dev == NULL) return -ENOMEM; @@ -326,7 +327,7 @@ static int cc10001_adc_probe(struct platform_device *pdev) channel_map &= ~ret; } - adc_dev->reg = devm_regulator_get(&pdev->dev, "vref"); + adc_dev->reg = devm_regulator_get(dev, "vref"); if (IS_ERR(adc_dev->reg)) return PTR_ERR(adc_dev->reg); @@ -334,7 +335,7 @@ static int cc10001_adc_probe(struct platform_device *pdev) if (ret) return ret; - indio_dev->name = dev_name(&pdev->dev); + indio_dev->name = dev_name(dev); indio_dev->info = &cc10001_adc_info; indio_dev->modes = INDIO_DIRECT_MODE; @@ -344,23 +345,23 @@ static int cc10001_adc_probe(struct platform_device *pdev) goto err_disable_reg; } - adc_dev->adc_clk = devm_clk_get(&pdev->dev, "adc"); + adc_dev->adc_clk = devm_clk_get(dev, "adc"); if (IS_ERR(adc_dev->adc_clk)) { - dev_err(&pdev->dev, "failed to get the clock\n"); + dev_err(dev, "failed to get the clock\n"); ret = PTR_ERR(adc_dev->adc_clk); goto err_disable_reg; } ret = clk_prepare_enable(adc_dev->adc_clk); if (ret) { - dev_err(&pdev->dev, "failed to enable the clock\n"); + dev_err(dev, "failed to enable the clock\n"); goto err_disable_reg; } adc_clk_rate = clk_get_rate(adc_dev->adc_clk); if (!adc_clk_rate) { ret = -EINVAL; - dev_err(&pdev->dev, "null clock rate!\n"); + dev_err(dev, "null clock rate!\n"); goto err_disable_clk; } -- cgit v1.2.3 From dc0ba516d103532b7f289b20119374fe3797f81b Mon Sep 17 00:00:00 2001 From: Jonathan Cameron Date: Sun, 16 Oct 2022 18:09:47 +0100 Subject: iio: adc: cc10001: Add devm_add_action_or_reset() to disable regulator. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit As the voltage of this regulator is queried, we cannot use the devm_regulator_get_enable() call and have to role our own disable. Signed-off-by: Jonathan Cameron Reviewed-by: Nuno Sá Link: https://lore.kernel.org/r/20221016170950.387751-3-jic23@kernel.org --- drivers/iio/adc/cc10001_adc.c | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) (limited to 'drivers/iio') diff --git a/drivers/iio/adc/cc10001_adc.c b/drivers/iio/adc/cc10001_adc.c index eeaea1362ed1..4f42ceb40ded 100644 --- a/drivers/iio/adc/cc10001_adc.c +++ b/drivers/iio/adc/cc10001_adc.c @@ -305,6 +305,11 @@ static int cc10001_adc_channel_init(struct iio_dev *indio_dev, return 0; } +static void cc10001_reg_disable(void *priv) +{ + regulator_disable(priv); +} + static int cc10001_adc_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; @@ -335,27 +340,28 @@ static int cc10001_adc_probe(struct platform_device *pdev) if (ret) return ret; + ret = devm_add_action_or_reset(dev, cc10001_reg_disable, adc_dev->reg); + if (ret) + return ret; + indio_dev->name = dev_name(dev); indio_dev->info = &cc10001_adc_info; indio_dev->modes = INDIO_DIRECT_MODE; adc_dev->reg_base = devm_platform_ioremap_resource(pdev, 0); - if (IS_ERR(adc_dev->reg_base)) { - ret = PTR_ERR(adc_dev->reg_base); - goto err_disable_reg; - } + if (IS_ERR(adc_dev->reg_base)) + return PTR_ERR(adc_dev->reg_base); adc_dev->adc_clk = devm_clk_get(dev, "adc"); if (IS_ERR(adc_dev->adc_clk)) { dev_err(dev, "failed to get the clock\n"); - ret = PTR_ERR(adc_dev->adc_clk); - goto err_disable_reg; + return PTR_ERR(adc_dev->adc_clk); } ret = clk_prepare_enable(adc_dev->adc_clk); if (ret) { dev_err(dev, "failed to enable the clock\n"); - goto err_disable_reg; + return ret; } adc_clk_rate = clk_get_rate(adc_dev->adc_clk); @@ -400,8 +406,6 @@ err_cleanup_buffer: iio_triggered_buffer_cleanup(indio_dev); err_disable_clk: clk_disable_unprepare(adc_dev->adc_clk); -err_disable_reg: - regulator_disable(adc_dev->reg); return ret; } @@ -414,7 +418,6 @@ static int cc10001_adc_remove(struct platform_device *pdev) iio_device_unregister(indio_dev); iio_triggered_buffer_cleanup(indio_dev); clk_disable_unprepare(adc_dev->adc_clk); - regulator_disable(adc_dev->reg); return 0; } -- cgit v1.2.3 From c247e0d8c0d50793f459d2a7997d2f8f2105c973 Mon Sep 17 00:00:00 2001 From: Jonathan Cameron Date: Sun, 16 Oct 2022 18:09:48 +0100 Subject: iio: adc: cc10001: Use devm_clk_get_enabled() to avoid boilerplate. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit As this driver just enables clock in probe() and disables in remove() we can use this new function to replace boilerplate and simplify error paths. Signed-off-by: Jonathan Cameron Reviewed-by: Nuno Sá Link: https://lore.kernel.org/r/20221016170950.387751-4-jic23@kernel.org --- drivers/iio/adc/cc10001_adc.c | 20 +++++--------------- 1 file changed, 5 insertions(+), 15 deletions(-) (limited to 'drivers/iio') diff --git a/drivers/iio/adc/cc10001_adc.c b/drivers/iio/adc/cc10001_adc.c index 4f42ceb40ded..1a3a5e0a52f7 100644 --- a/drivers/iio/adc/cc10001_adc.c +++ b/drivers/iio/adc/cc10001_adc.c @@ -352,23 +352,16 @@ static int cc10001_adc_probe(struct platform_device *pdev) if (IS_ERR(adc_dev->reg_base)) return PTR_ERR(adc_dev->reg_base); - adc_dev->adc_clk = devm_clk_get(dev, "adc"); + adc_dev->adc_clk = devm_clk_get_enabled(dev, "adc"); if (IS_ERR(adc_dev->adc_clk)) { - dev_err(dev, "failed to get the clock\n"); + dev_err(dev, "failed to get/enable the clock\n"); return PTR_ERR(adc_dev->adc_clk); } - ret = clk_prepare_enable(adc_dev->adc_clk); - if (ret) { - dev_err(dev, "failed to enable the clock\n"); - return ret; - } - adc_clk_rate = clk_get_rate(adc_dev->adc_clk); if (!adc_clk_rate) { - ret = -EINVAL; dev_err(dev, "null clock rate!\n"); - goto err_disable_clk; + return -EINVAL; } adc_dev->eoc_delay_ns = NSEC_PER_SEC / adc_clk_rate; @@ -385,14 +378,14 @@ static int cc10001_adc_probe(struct platform_device *pdev) /* Setup the ADC channels available on the device */ ret = cc10001_adc_channel_init(indio_dev, channel_map); if (ret < 0) - goto err_disable_clk; + return ret; mutex_init(&adc_dev->lock); ret = iio_triggered_buffer_setup(indio_dev, NULL, &cc10001_adc_trigger_h, NULL); if (ret < 0) - goto err_disable_clk; + return ret; ret = iio_device_register(indio_dev); if (ret < 0) @@ -404,8 +397,6 @@ static int cc10001_adc_probe(struct platform_device *pdev) err_cleanup_buffer: iio_triggered_buffer_cleanup(indio_dev); -err_disable_clk: - clk_disable_unprepare(adc_dev->adc_clk); return ret; } @@ -417,7 +408,6 @@ static int cc10001_adc_remove(struct platform_device *pdev) cc10001_adc_power_down(adc_dev); iio_device_unregister(indio_dev); iio_triggered_buffer_cleanup(indio_dev); - clk_disable_unprepare(adc_dev->adc_clk); return 0; } -- cgit v1.2.3 From a43d5155b9455d38c4b3e4656131d79af61a2978 Mon Sep 17 00:00:00 2001 From: Jonathan Cameron Date: Sun, 16 Oct 2022 18:09:49 +0100 Subject: iio: adc: cc10001: Use devm_ to call device power down. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit It is presumably safe to call the powerdown whether or not we are in the commented shared state (the driver always did this). The power down was previously out of order wrt to the probe() function so move using devm_ will ensure it occurs after the userspace interfaces are removed. Signed-off-by: Jonathan Cameron Reviewed-by: Nuno Sá Link: https://lore.kernel.org/r/20221016170950.387751-5-jic23@kernel.org --- drivers/iio/adc/cc10001_adc.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) (limited to 'drivers/iio') diff --git a/drivers/iio/adc/cc10001_adc.c b/drivers/iio/adc/cc10001_adc.c index 1a3a5e0a52f7..aecad89c00ff 100644 --- a/drivers/iio/adc/cc10001_adc.c +++ b/drivers/iio/adc/cc10001_adc.c @@ -310,6 +310,11 @@ static void cc10001_reg_disable(void *priv) regulator_disable(priv); } +static void cc10001_pd_cb(void *priv) +{ + cc10001_adc_power_down(priv); +} + static int cc10001_adc_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; @@ -375,6 +380,9 @@ static int cc10001_adc_probe(struct platform_device *pdev) if (adc_dev->shared) cc10001_adc_power_up(adc_dev); + ret = devm_add_action_or_reset(dev, cc10001_pd_cb, adc_dev); + if (ret) + return ret; /* Setup the ADC channels available on the device */ ret = cc10001_adc_channel_init(indio_dev, channel_map); if (ret < 0) @@ -405,7 +413,6 @@ static int cc10001_adc_remove(struct platform_device *pdev) struct iio_dev *indio_dev = platform_get_drvdata(pdev); struct cc10001_adc_device *adc_dev = iio_priv(indio_dev); - cc10001_adc_power_down(adc_dev); iio_device_unregister(indio_dev); iio_triggered_buffer_cleanup(indio_dev); -- cgit v1.2.3 From c5269fe908635c67c1eb4876df625efcfb156827 Mon Sep 17 00:00:00 2001 From: Jonathan Cameron Date: Sun, 16 Oct 2022 18:09:50 +0100 Subject: iio: adc: cc10001: Switch remaining IIO calls in probe to devm_ forms. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit As everything else is now handled by devm managed releases the triggered buffer setup and IIO device registration can also be moved over to their devm forms allowing dropping of remove(). Only user of drvdata associated with the struct device was the remove function, so also drop the platform_set_drvdata() call. Signed-off-by: Jonathan Cameron Reviewed-by: Nuno Sá Link: https://lore.kernel.org/r/20221016170950.387751-6-jic23@kernel.org --- drivers/iio/adc/cc10001_adc.c | 28 +++------------------------- 1 file changed, 3 insertions(+), 25 deletions(-) (limited to 'drivers/iio') diff --git a/drivers/iio/adc/cc10001_adc.c b/drivers/iio/adc/cc10001_adc.c index aecad89c00ff..2cde4b44fc6e 100644 --- a/drivers/iio/adc/cc10001_adc.c +++ b/drivers/iio/adc/cc10001_adc.c @@ -390,33 +390,12 @@ static int cc10001_adc_probe(struct platform_device *pdev) mutex_init(&adc_dev->lock); - ret = iio_triggered_buffer_setup(indio_dev, NULL, - &cc10001_adc_trigger_h, NULL); + ret = devm_iio_triggered_buffer_setup(dev, indio_dev, NULL, + &cc10001_adc_trigger_h, NULL); if (ret < 0) return ret; - ret = iio_device_register(indio_dev); - if (ret < 0) - goto err_cleanup_buffer; - - platform_set_drvdata(pdev, indio_dev); - - return 0; - -err_cleanup_buffer: - iio_triggered_buffer_cleanup(indio_dev); - return ret; -} - -static int cc10001_adc_remove(struct platform_device *pdev) -{ - struct iio_dev *indio_dev = platform_get_drvdata(pdev); - struct cc10001_adc_device *adc_dev = iio_priv(indio_dev); - - iio_device_unregister(indio_dev); - iio_triggered_buffer_cleanup(indio_dev); - - return 0; + return devm_iio_device_register(dev, indio_dev); } static const struct of_device_id cc10001_adc_dt_ids[] = { @@ -431,7 +410,6 @@ static struct platform_driver cc10001_adc_driver = { .of_match_table = cc10001_adc_dt_ids, }, .probe = cc10001_adc_probe, - .remove = cc10001_adc_remove, }; module_platform_driver(cc10001_adc_driver); -- cgit v1.2.3 From 2cfb2180c3e8002719234c43b88b040e4f89396f Mon Sep 17 00:00:00 2001 From: Lorenzo Bianconi Date: Fri, 28 Oct 2022 13:23:42 +0200 Subject: iio: imu: st_lsm6dsx: introduce sw trigger support There are some hw configuration where irq0 and/or irq1 pins are not connected to the SPI or I2C/I3C controller. In order to avoid polling the output register introduce iio-sw trigger support when irq line is not available (or hw FIFO is not supported). Suggested-by: Mario Tesi Signed-off-by: Lorenzo Bianconi Link: https://lore.kernel.org/r/93ae6ff1150b531a9d7a4d3d1b1adb8383613717.1666955685.git.lorenzo@kernel.org Signed-off-by: Jonathan Cameron --- drivers/iio/imu/st_lsm6dsx/st_lsm6dsx.h | 3 +- drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c | 78 ++++++++++++++++++++++++++++ drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_shub.c | 4 +- 3 files changed, 81 insertions(+), 4 deletions(-) (limited to 'drivers/iio') diff --git a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx.h b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx.h index 07ad8027de73..6399b0bb6f67 100644 --- a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx.h +++ b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx.h @@ -424,7 +424,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 = { @@ -456,6 +456,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 diff --git a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c index fe5fa08b68ac..73fd5f038375 100644 --- a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c +++ b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c @@ -53,6 +53,8 @@ #include #include #include +#include +#include #include #include #include @@ -2117,6 +2119,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,6 +2203,46 @@ static int st_lsm6dsx_irq_setup(struct st_lsm6dsx_hw *hw) return 0; } +static int st_lsm6dsx_sw_buffer_preenable(struct iio_dev *iio_dev) +{ + struct st_lsm6dsx_sensor *sensor = iio_priv(iio_dev); + + return st_lsm6dsx_device_set_enable(sensor, true); +} + +static int st_lsm6dsx_sw_buffer_postdisable(struct iio_dev *iio_dev) +{ + struct st_lsm6dsx_sensor *sensor = iio_priv(iio_dev); + + 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 int st_lsm6dsx_init_regulators(struct device *dev) { /* vdd-vddio power regulators */ @@ -2255,6 +2323,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; 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; -- cgit v1.2.3 From a1c6d631ff12cd41201c3ab824f3c4db66621c13 Mon Sep 17 00:00:00 2001 From: Lorenzo Bianconi Date: Mon, 31 Oct 2022 12:41:25 +0100 Subject: iio: imu: st_lsm6dsx: add support to LSM6DSV Add support to STM LSM6DSV (accelerometer and gyroscope) Mems sensor. Datasheet: https://www.st.com/resource/en/datasheet/lsm6dsv.pdf Signed-off-by: Lorenzo Bianconi Link: https://lore.kernel.org/r/aad879e7af0fe583bbf043a2b93e32fade79fa19.1667216004.git.lorenzo@kernel.org Signed-off-by: Jonathan Cameron --- drivers/iio/imu/st_lsm6dsx/Kconfig | 2 +- drivers/iio/imu/st_lsm6dsx/st_lsm6dsx.h | 2 + drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_buffer.c | 2 +- drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c | 202 +++++++++++++++++++++++++ drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_i2c.c | 5 + drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_spi.c | 5 + 6 files changed, 216 insertions(+), 2 deletions(-) (limited to 'drivers/iio') diff --git a/drivers/iio/imu/st_lsm6dsx/Kconfig b/drivers/iio/imu/st_lsm6dsx/Kconfig index 2ed2b3f40c0b..1c68bac94bce 100644 --- a/drivers/iio/imu/st_lsm6dsx/Kconfig +++ b/drivers/iio/imu/st_lsm6dsx/Kconfig @@ -13,7 +13,7 @@ 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, the accelerometer/gyroscope of lsm9ds1 and lsm6dst. 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 6399b0bb6f67..ab61895cf072 100644 --- a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx.h +++ b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx.h @@ -33,6 +33,7 @@ #define ST_LSM6DSOP_DEV_NAME "lsm6dsop" #define ST_ASM330LHHX_DEV_NAME "asm330lhhx" #define ST_LSM6DSTX_DEV_NAME "lsm6dstx" +#define ST_LSM6DSV_DEV_NAME "lsm6dsv" enum st_lsm6dsx_hw_id { ST_LSM6DS3_ID, @@ -53,6 +54,7 @@ enum st_lsm6dsx_hw_id { ST_LSM6DSOP_ID, ST_ASM330LHHX_ID, ST_LSM6DSTX_ID, + ST_LSM6DSV_ID, ST_LSM6DSX_MAX_ID, }; diff --git a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_buffer.c b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_buffer.c index 48fe6a45671b..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). diff --git a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c index 73fd5f038375..5e716a5071fd 100644 --- a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c +++ b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c @@ -1162,6 +1162,208 @@ 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, + }, + }, + .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), + }, + }, }; int st_lsm6dsx_set_page(struct st_lsm6dsx_hw *hw, bool enable) diff --git a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_i2c.c b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_i2c.c index 307c8c436862..239c8920a31f 100644 --- a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_i2c.c +++ b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_i2c.c @@ -109,6 +109,10 @@ 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, + }, {}, }; MODULE_DEVICE_TABLE(of, st_lsm6dsx_i2c_of_match); @@ -132,6 +136,7 @@ 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 }, {}, }; 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 6a4eecf4bb05..66705ef16ed0 100644 --- a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_spi.c +++ b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_spi.c @@ -109,6 +109,10 @@ 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, + }, {}, }; MODULE_DEVICE_TABLE(of, st_lsm6dsx_spi_of_match); @@ -132,6 +136,7 @@ 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 }, {}, }; MODULE_DEVICE_TABLE(spi, st_lsm6dsx_spi_id_table); -- cgit v1.2.3 From 75347e30f142521c140ba1f5011d4fb175c1406b Mon Sep 17 00:00:00 2001 From: Ramona Bolboaca Date: Mon, 31 Oct 2022 12:51:27 +0200 Subject: drivers: iio: accel: Use warning if invalid device id is detected Use warning instead of failing driver probe if invalid device id is detected for ADXL355 device. Signed-off-by: Ramona Bolboaca Link: https://lore.kernel.org/r/20221031105129.47740-2-ramona.bolboaca@analog.com Signed-off-by: Jonathan Cameron --- drivers/iio/accel/adxl355_core.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) (limited to 'drivers/iio') diff --git a/drivers/iio/accel/adxl355_core.c b/drivers/iio/accel/adxl355_core.c index 4bc648eac8b2..dd08253d66d0 100644 --- a/drivers/iio/accel/adxl355_core.c +++ b/drivers/iio/accel/adxl355_core.c @@ -262,10 +262,8 @@ static int adxl355_setup(struct adxl355_data *data) if (ret) return ret; - if (regval != ADXL355_PARTID_VAL) { - dev_err(data->dev, "Invalid DEV ID 0x%02x\n", regval); - return -ENODEV; - } + if (regval != ADXL355_PARTID_VAL) + dev_warn(data->dev, "Invalid DEV ID 0x%02x\n", regval); /* * Perform a software reset to make sure the device is in a consistent -- cgit v1.2.3 From d3532d69757f9c6a73155d73bd9b94b64b12ef72 Mon Sep 17 00:00:00 2001 From: Ramona Bolboaca Date: Mon, 31 Oct 2022 12:51:29 +0200 Subject: drivers: iio: accel: Add support for ADXL359 device Add support for ADXL359 device in already existing ADXL355 driver. Datasheet: https://www.analog.com/media/en/technical-documentation/data-sheets/adxl359.pdf Signed-off-by: Ramona Bolboaca Link: https://lore.kernel.org/r/20221031105129.47740-4-ramona.bolboaca@analog.com Signed-off-by: Jonathan Cameron --- drivers/iio/accel/adxl355.h | 20 ++++++++- drivers/iio/accel/adxl355_core.c | 87 +++++++++++++++++++++++++++++++--------- drivers/iio/accel/adxl355_i2c.c | 22 ++++++++-- drivers/iio/accel/adxl355_spi.c | 19 +++++++-- 4 files changed, 121 insertions(+), 27 deletions(-) (limited to 'drivers/iio') diff --git a/drivers/iio/accel/adxl355.h b/drivers/iio/accel/adxl355.h index 6dd49b13e4fd..061e66dc7057 100644 --- a/drivers/iio/accel/adxl355.h +++ b/drivers/iio/accel/adxl355.h @@ -10,12 +10,30 @@ #include +enum adxl355_device_type { + ADXL355, + ADXL359, +}; + +struct adxl355_fractional_type { + int integer; + int decimal; +}; + struct device; +struct adxl355_chip_info { + const char *name; + u8 part_id; + struct adxl355_fractional_type accel_scale; + struct adxl355_fractional_type temp_offset; +}; + extern const struct regmap_access_table adxl355_readable_regs_tbl; extern const struct regmap_access_table adxl355_writeable_regs_tbl; +extern const struct adxl355_chip_info adxl35x_chip_info[]; int adxl355_core_probe(struct device *dev, struct regmap *regmap, - const char *name); + const struct adxl355_chip_info *chip_info); #endif /* _ADXL355_H_ */ diff --git a/drivers/iio/accel/adxl355_core.c b/drivers/iio/accel/adxl355_core.c index dd08253d66d0..0c9225d18fb2 100644 --- a/drivers/iio/accel/adxl355_core.c +++ b/drivers/iio/accel/adxl355_core.c @@ -60,6 +60,7 @@ #define ADXL355_DEVID_AD_VAL 0xAD #define ADXL355_DEVID_MST_VAL 0x1D #define ADXL355_PARTID_VAL 0xED +#define ADXL359_PARTID_VAL 0xE9 #define ADXL355_RESET_CODE 0x52 static const struct regmap_range adxl355_read_reg_range[] = { @@ -83,6 +84,60 @@ const struct regmap_access_table adxl355_writeable_regs_tbl = { }; EXPORT_SYMBOL_NS_GPL(adxl355_writeable_regs_tbl, IIO_ADXL355); +const struct adxl355_chip_info adxl35x_chip_info[] = { + [ADXL355] = { + .name = "adxl355", + .part_id = ADXL355_PARTID_VAL, + /* + * At +/- 2g with 20-bit resolution, scale is given in datasheet + * as 3.9ug/LSB = 0.0000039 * 9.80665 = 0.00003824593 m/s^2. + */ + .accel_scale = { + .integer = 0, + .decimal = 38245, + }, + /* + * The datasheet defines an intercept of 1885 LSB at 25 degC + * and a slope of -9.05 LSB/C. The following formula can be used + * to find the temperature: + * Temp = ((RAW - 1885)/(-9.05)) + 25 but this doesn't follow + * the format of the IIO which is Temp = (RAW + OFFSET) * SCALE. + * Hence using some rearranging we get the scale as -110.497238 + * and offset as -2111.25. + */ + .temp_offset = { + .integer = -2111, + .decimal = 250000, + }, + }, + [ADXL359] = { + .name = "adxl359", + .part_id = ADXL359_PARTID_VAL, + /* + * At +/- 10g with 20-bit resolution, scale is given in datasheet + * as 19.5ug/LSB = 0.0000195 * 9.80665 = 0.0.00019122967 m/s^2. + */ + .accel_scale = { + .integer = 0, + .decimal = 191229, + }, + /* + * The datasheet defines an intercept of 1852 LSB at 25 degC + * and a slope of -9.05 LSB/C. The following formula can be used + * to find the temperature: + * Temp = ((RAW - 1852)/(-9.05)) + 25 but this doesn't follow + * the format of the IIO which is Temp = (RAW + OFFSET) * SCALE. + * Hence using some rearranging we get the scale as -110.497238 + * and offset as -2079.25. + */ + .temp_offset = { + .integer = -2079, + .decimal = 250000, + }, + }, +}; +EXPORT_SYMBOL_NS_GPL(adxl35x_chip_info, IIO_ADXL355); + enum adxl355_op_mode { ADXL355_MEASUREMENT, ADXL355_STANDBY, @@ -162,6 +217,7 @@ static const struct adxl355_chan_info adxl355_chans[] = { }; struct adxl355_data { + const struct adxl355_chip_info *chip_info; struct regmap *regmap; struct device *dev; struct mutex lock; /* lock to protect op_mode */ @@ -456,33 +512,25 @@ static int adxl355_read_raw(struct iio_dev *indio_dev, case IIO_CHAN_INFO_SCALE: switch (chan->type) { - /* - * The datasheet defines an intercept of 1885 LSB at 25 degC - * and a slope of -9.05 LSB/C. The following formula can be used - * to find the temperature: - * Temp = ((RAW - 1885)/(-9.05)) + 25 but this doesn't follow - * the format of the IIO which is Temp = (RAW + OFFSET) * SCALE. - * Hence using some rearranging we get the scale as -110.497238 - * and offset as -2111.25. - */ case IIO_TEMP: + /* + * Temperature scale is -110.497238. + * See the detailed explanation in adxl35x_chip_info + * definition above. + */ *val = -110; *val2 = 497238; return IIO_VAL_INT_PLUS_MICRO; - /* - * At +/- 2g with 20-bit resolution, scale is given in datasheet - * as 3.9ug/LSB = 0.0000039 * 9.80665 = 0.00003824593 m/s^2. - */ case IIO_ACCEL: - *val = 0; - *val2 = 38245; + *val = data->chip_info->accel_scale.integer; + *val2 = data->chip_info->accel_scale.decimal; return IIO_VAL_INT_PLUS_NANO; default: return -EINVAL; } case IIO_CHAN_INFO_OFFSET: - *val = -2111; - *val2 = 250000; + *val = data->chip_info->temp_offset.integer; + *val2 = data->chip_info->temp_offset.decimal; return IIO_VAL_INT_PLUS_MICRO; case IIO_CHAN_INFO_CALIBBIAS: *val = sign_extend32(data->calibbias[chan->address], 15); @@ -705,7 +753,7 @@ static int adxl355_probe_trigger(struct iio_dev *indio_dev, int irq) } int adxl355_core_probe(struct device *dev, struct regmap *regmap, - const char *name) + const struct adxl355_chip_info *chip_info) { struct adxl355_data *data; struct iio_dev *indio_dev; @@ -720,9 +768,10 @@ int adxl355_core_probe(struct device *dev, struct regmap *regmap, data->regmap = regmap; data->dev = dev; data->op_mode = ADXL355_STANDBY; + data->chip_info = chip_info; mutex_init(&data->lock); - indio_dev->name = name; + indio_dev->name = chip_info->name; indio_dev->info = &adxl355_info; indio_dev->modes = INDIO_DIRECT_MODE; indio_dev->channels = adxl355_channels; diff --git a/drivers/iio/accel/adxl355_i2c.c b/drivers/iio/accel/adxl355_i2c.c index f67d57921c81..6cde5ccac06b 100644 --- a/drivers/iio/accel/adxl355_i2c.c +++ b/drivers/iio/accel/adxl355_i2c.c @@ -23,6 +23,20 @@ static const struct regmap_config adxl355_i2c_regmap_config = { static int adxl355_i2c_probe(struct i2c_client *client) { struct regmap *regmap; + const struct adxl355_chip_info *chip_data; + const struct i2c_device_id *adxl355; + + chip_data = device_get_match_data(&client->dev); + if (!chip_data) { + adxl355 = to_i2c_driver(client->dev.driver)->id_table; + if (!adxl355) + return -EINVAL; + + chip_data = (void *)i2c_match_id(adxl355, client)->driver_data; + + if (!chip_data) + return -EINVAL; + } regmap = devm_regmap_init_i2c(client, &adxl355_i2c_regmap_config); if (IS_ERR(regmap)) { @@ -32,17 +46,19 @@ static int adxl355_i2c_probe(struct i2c_client *client) return PTR_ERR(regmap); } - return adxl355_core_probe(&client->dev, regmap, client->name); + return adxl355_core_probe(&client->dev, regmap, chip_data); } static const struct i2c_device_id adxl355_i2c_id[] = { - { "adxl355", 0 }, + { "adxl355", (kernel_ulong_t)&adxl35x_chip_info[ADXL355] }, + { "adxl359", (kernel_ulong_t)&adxl35x_chip_info[ADXL359] }, { } }; MODULE_DEVICE_TABLE(i2c, adxl355_i2c_id); static const struct of_device_id adxl355_of_match[] = { - { .compatible = "adi,adxl355" }, + { .compatible = "adi,adxl355", .data = &adxl35x_chip_info[ADXL355] }, + { .compatible = "adi,adxl359", .data = &adxl35x_chip_info[ADXL359] }, { } }; MODULE_DEVICE_TABLE(of, adxl355_of_match); diff --git a/drivers/iio/accel/adxl355_spi.c b/drivers/iio/accel/adxl355_spi.c index 5fe986ae03f6..fc99534d91ff 100644 --- a/drivers/iio/accel/adxl355_spi.c +++ b/drivers/iio/accel/adxl355_spi.c @@ -9,6 +9,7 @@ #include #include #include +#include #include "adxl355.h" @@ -24,9 +25,17 @@ static const struct regmap_config adxl355_spi_regmap_config = { static int adxl355_spi_probe(struct spi_device *spi) { - const struct spi_device_id *id = spi_get_device_id(spi); + const struct adxl355_chip_info *chip_data; struct regmap *regmap; + chip_data = device_get_match_data(&spi->dev); + if (!chip_data) { + chip_data = (void *)spi_get_device_id(spi)->driver_data; + + if (!chip_data) + return -EINVAL; + } + regmap = devm_regmap_init_spi(spi, &adxl355_spi_regmap_config); if (IS_ERR(regmap)) { dev_err(&spi->dev, "Error initializing spi regmap: %ld\n", @@ -35,17 +44,19 @@ static int adxl355_spi_probe(struct spi_device *spi) return PTR_ERR(regmap); } - return adxl355_core_probe(&spi->dev, regmap, id->name); + return adxl355_core_probe(&spi->dev, regmap, chip_data); } static const struct spi_device_id adxl355_spi_id[] = { - { "adxl355", 0 }, + { "adxl355", (kernel_ulong_t)&adxl35x_chip_info[ADXL355] }, + { "adxl359", (kernel_ulong_t)&adxl35x_chip_info[ADXL359] }, { } }; MODULE_DEVICE_TABLE(spi, adxl355_spi_id); static const struct of_device_id adxl355_of_match[] = { - { .compatible = "adi,adxl355" }, + { .compatible = "adi,adxl355", .data = &adxl35x_chip_info[ADXL355] }, + { .compatible = "adi,adxl359", .data = &adxl35x_chip_info[ADXL359] }, { } }; MODULE_DEVICE_TABLE(of, adxl355_of_match); -- cgit v1.2.3 From 5e0176213949724fbe9a8e4a39817edce337b8a0 Mon Sep 17 00:00:00 2001 From: Cosmin Tanislav Date: Thu, 3 Nov 2022 15:00:29 +0200 Subject: iio: temperature: ltc2983: make bulk write buffer DMA-safe regmap_bulk_write() does not guarantee implicit DMA-safety, even though the current implementation duplicates the given buffer. Do not rely on it. Fixes: f110f3188e56 ("iio: temperature: Add support for LTC2983") Signed-off-by: Cosmin Tanislav Link: https://lore.kernel.org/r/20221103130041.2153295-2-demonsingur@gmail.com Signed-off-by: Jonathan Cameron --- drivers/iio/temperature/ltc2983.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'drivers/iio') diff --git a/drivers/iio/temperature/ltc2983.c b/drivers/iio/temperature/ltc2983.c index a60ccf183687..1117991ca2ab 100644 --- a/drivers/iio/temperature/ltc2983.c +++ b/drivers/iio/temperature/ltc2983.c @@ -209,6 +209,7 @@ struct ltc2983_data { * Holds the converted temperature */ __be32 temp __aligned(IIO_DMA_MINALIGN); + __be32 chan_val; }; struct ltc2983_sensor { @@ -313,19 +314,18 @@ static int __ltc2983_fault_handler(const struct ltc2983_data *st, return 0; } -static int __ltc2983_chan_assign_common(const struct ltc2983_data *st, +static int __ltc2983_chan_assign_common(struct ltc2983_data *st, const struct ltc2983_sensor *sensor, u32 chan_val) { u32 reg = LTC2983_CHAN_START_ADDR(sensor->chan); - __be32 __chan_val; chan_val |= LTC2983_CHAN_TYPE(sensor->type); dev_dbg(&st->spi->dev, "Assign reg:0x%04X, val:0x%08X\n", reg, chan_val); - __chan_val = cpu_to_be32(chan_val); - return regmap_bulk_write(st->regmap, reg, &__chan_val, - sizeof(__chan_val)); + st->chan_val = cpu_to_be32(chan_val); + return regmap_bulk_write(st->regmap, reg, &st->chan_val, + sizeof(st->chan_val)); } static int __ltc2983_chan_custom_sensor_assign(struct ltc2983_data *st, -- cgit v1.2.3 From 6f7cadcf664b04df3b2e9b9c6d65bf626aa1b411 Mon Sep 17 00:00:00 2001 From: Cosmin Tanislav Date: Thu, 3 Nov 2022 15:00:41 +0200 Subject: iio: temperature: ltc2983: support more parts Add support for the following parts: * LTC2984 * LTC2986 * LTM2985 The LTC2984 is a variant of the LTC2983 with EEPROM. The LTC2986 is a variant of the LTC2983 with only 10 channels, EEPROM and support for active analog temperature sensors. The LTM2985 is software-compatible with the LTC2986. Signed-off-by: Cosmin Tanislav Link: https://lore.kernel.org/r/20221103130041.2153295-14-demonsingur@gmail.com Signed-off-by: Jonathan Cameron --- drivers/iio/temperature/ltc2983.c | 183 ++++++++++++++++++++++++++++++++++++-- 1 file changed, 176 insertions(+), 7 deletions(-) (limited to 'drivers/iio') diff --git a/drivers/iio/temperature/ltc2983.c b/drivers/iio/temperature/ltc2983.c index 1117991ca2ab..fcb96c44d954 100644 --- a/drivers/iio/temperature/ltc2983.c +++ b/drivers/iio/temperature/ltc2983.c @@ -25,9 +25,12 @@ #define LTC2983_STATUS_REG 0x0000 #define LTC2983_TEMP_RES_START_REG 0x0010 #define LTC2983_TEMP_RES_END_REG 0x005F +#define LTC2983_EEPROM_KEY_REG 0x00B0 +#define LTC2983_EEPROM_READ_STATUS_REG 0x00D0 #define LTC2983_GLOBAL_CONFIG_REG 0x00F0 #define LTC2983_MULT_CHANNEL_START_REG 0x00F4 #define LTC2983_MULT_CHANNEL_END_REG 0x00F7 +#define LTC2986_EEPROM_STATUS_REG 0x00F9 #define LTC2983_MUX_CONFIG_REG 0x00FF #define LTC2983_CHAN_ASSIGN_START_REG 0x0200 #define LTC2983_CHAN_ASSIGN_END_REG 0x024F @@ -35,13 +38,21 @@ #define LTC2983_CUST_SENS_TBL_END_REG 0x03CF #define LTC2983_DIFFERENTIAL_CHAN_MIN 2 -#define LTC2983_MAX_CHANNELS_NR 20 #define LTC2983_MIN_CHANNELS_NR 1 #define LTC2983_SLEEP 0x97 #define LTC2983_CUSTOM_STEINHART_SIZE 24 #define LTC2983_CUSTOM_SENSOR_ENTRY_SZ 6 #define LTC2983_CUSTOM_STEINHART_ENTRY_SZ 4 +#define LTC2983_EEPROM_KEY 0xA53C0F5A +#define LTC2983_EEPROM_WRITE_CMD 0x15 +#define LTC2983_EEPROM_READ_CMD 0x16 +#define LTC2983_EEPROM_STATUS_FAILURE_MASK GENMASK(3, 1) +#define LTC2983_EEPROM_READ_FAILURE_MASK GENMASK(7, 0) + +#define LTC2983_EEPROM_WRITE_TIME_MS 2600 +#define LTC2983_EEPROM_READ_TIME_MS 20 + #define LTC2983_CHAN_START_ADDR(chan) \ (((chan - 1) * 4) + LTC2983_CHAN_ASSIGN_START_REG) #define LTC2983_CHAN_RES_ADDR(chan) \ @@ -171,6 +182,7 @@ enum { LTC2983_SENSOR_DIODE = 28, LTC2983_SENSOR_SENSE_RESISTOR = 29, LTC2983_SENSOR_DIRECT_ADC = 30, + LTC2983_SENSOR_ACTIVE_TEMP = 31, }; #define to_thermocouple(_sensor) \ @@ -191,7 +203,17 @@ enum { #define to_adc(_sensor) \ container_of(_sensor, struct ltc2983_adc, sensor) +#define to_temp(_sensor) \ + container_of(_sensor, struct ltc2983_temp, sensor) + +struct ltc2983_chip_info { + unsigned int max_channels_nr; + bool has_temp; + bool has_eeprom; +}; + struct ltc2983_data { + const struct ltc2983_chip_info *info; struct regmap *regmap; struct spi_device *spi; struct mutex lock; @@ -210,6 +232,7 @@ struct ltc2983_data { */ __be32 temp __aligned(IIO_DMA_MINALIGN); __be32 chan_val; + __be32 eeprom_key; }; struct ltc2983_sensor { @@ -272,6 +295,12 @@ struct ltc2983_adc { bool single_ended; }; +struct ltc2983_temp { + struct ltc2983_sensor sensor; + struct ltc2983_custom_sensor *custom; + bool single_ended; +}; + /* * Convert to Q format numbers. These number's are integers where * the number of integer and fractional bits are specified. The resolution @@ -606,6 +635,22 @@ static int ltc2983_adc_assign_chan(struct ltc2983_data *st, return __ltc2983_chan_assign_common(st, sensor, chan_val); } +static int ltc2983_temp_assign_chan(struct ltc2983_data *st, + const struct ltc2983_sensor *sensor) +{ + struct ltc2983_temp *temp = to_temp(sensor); + u32 chan_val; + int ret; + + chan_val = LTC2983_ADC_SINGLE_ENDED(temp->single_ended); + + ret = __ltc2983_chan_custom_sensor_assign(st, temp->custom, &chan_val); + if (ret) + return ret; + + return __ltc2983_chan_assign_common(st, sensor, chan_val); +} + static struct ltc2983_sensor * ltc2983_thermocouple_new(const struct fwnode_handle *child, struct ltc2983_data *st, const struct ltc2983_sensor *sensor) @@ -771,10 +816,10 @@ ltc2983_rtd_new(const struct fwnode_handle *child, struct ltc2983_data *st, if (rtd->sensor_config & LTC2983_RTD_4_WIRE_MASK) { /* 4-wire */ u8 min = LTC2983_DIFFERENTIAL_CHAN_MIN, - max = LTC2983_MAX_CHANNELS_NR; + max = st->info->max_channels_nr; if (rtd->sensor_config & LTC2983_RTD_ROTATION_MASK) - max = LTC2983_MAX_CHANNELS_NR - 1; + max = st->info->max_channels_nr - 1; if (((rtd->sensor_config & LTC2983_RTD_KELVIN_R_SENSE_MASK) == LTC2983_RTD_KELVIN_R_SENSE_MASK) && @@ -1143,6 +1188,38 @@ static struct ltc2983_sensor *ltc2983_adc_new(struct fwnode_handle *child, return &adc->sensor; } +static struct ltc2983_sensor *ltc2983_temp_new(struct fwnode_handle *child, + struct ltc2983_data *st, + const struct ltc2983_sensor *sensor) +{ + struct ltc2983_temp *temp; + + temp = devm_kzalloc(&st->spi->dev, sizeof(*temp), GFP_KERNEL); + if (!temp) + return ERR_PTR(-ENOMEM); + + if (fwnode_property_read_bool(child, "adi,single-ended")) + temp->single_ended = true; + + if (!temp->single_ended && + sensor->chan < LTC2983_DIFFERENTIAL_CHAN_MIN) { + dev_err(&st->spi->dev, "Invalid chan:%d for differential temp\n", + sensor->chan); + return ERR_PTR(-EINVAL); + } + + temp->custom = __ltc2983_custom_sensor_new(st, child, "adi,custom-temp", + false, 4096, true); + if (IS_ERR(temp->custom)) + return ERR_CAST(temp->custom); + + /* set common parameters */ + temp->sensor.assign_chan = ltc2983_temp_assign_chan; + temp->sensor.fault_handler = ltc2983_common_fault_handler; + + return &temp->sensor; +} + static int ltc2983_chan_read(struct ltc2983_data *st, const struct ltc2983_sensor *sensor, int *val) { @@ -1302,10 +1379,10 @@ static int ltc2983_parse_dt(struct ltc2983_data *st) /* check if we have a valid channel */ if (sensor.chan < LTC2983_MIN_CHANNELS_NR || - sensor.chan > LTC2983_MAX_CHANNELS_NR) { + sensor.chan > st->info->max_channels_nr) { ret = -EINVAL; dev_err(dev, "chan:%d must be from %u to %u\n", sensor.chan, - LTC2983_MIN_CHANNELS_NR, LTC2983_MAX_CHANNELS_NR); + LTC2983_MIN_CHANNELS_NR, st->info->max_channels_nr); goto put_child; } else if (channel_avail_mask & BIT(sensor.chan)) { ret = -EINVAL; @@ -1345,6 +1422,9 @@ static int ltc2983_parse_dt(struct ltc2983_data *st) st->iio_channels--; } else if (sensor.type == LTC2983_SENSOR_DIRECT_ADC) { st->sensors[chan] = ltc2983_adc_new(child, st, &sensor); + } else if (st->info->has_temp && + sensor.type == LTC2983_SENSOR_ACTIVE_TEMP) { + st->sensors[chan] = ltc2983_temp_new(child, st, &sensor); } else { dev_err(dev, "Unknown sensor type %d\n", sensor.type); ret = -EINVAL; @@ -1371,6 +1451,45 @@ put_child: return ret; } +static int ltc2983_eeprom_cmd(struct ltc2983_data *st, unsigned int cmd, + unsigned int wait_time, unsigned int status_reg, + unsigned long status_fail_mask) +{ + unsigned long time; + unsigned int val; + int ret; + + ret = regmap_bulk_write(st->regmap, LTC2983_EEPROM_KEY_REG, + &st->eeprom_key, sizeof(st->eeprom_key)); + if (ret) + return ret; + + reinit_completion(&st->completion); + + ret = regmap_write(st->regmap, LTC2983_STATUS_REG, + LTC2983_STATUS_START(true) | cmd); + if (ret) + return ret; + + time = wait_for_completion_timeout(&st->completion, + msecs_to_jiffies(wait_time)); + if (!time) { + dev_err(&st->spi->dev, "EEPROM command timed out\n"); + return -ETIMEDOUT; + } + + ret = regmap_read(st->regmap, status_reg, &val); + if (ret) + return ret; + + if (val & status_fail_mask) { + dev_err(&st->spi->dev, "EEPROM command failed: 0x%02X\n", val); + return -EINVAL; + } + + return 0; +} + static int ltc2983_setup(struct ltc2983_data *st, bool assign_iio) { u32 iio_chan_t = 0, iio_chan_v = 0, chan, iio_idx = 0, status; @@ -1396,6 +1515,15 @@ static int ltc2983_setup(struct ltc2983_data *st, bool assign_iio) if (ret) return ret; + if (st->info->has_eeprom && !assign_iio) { + ret = ltc2983_eeprom_cmd(st, LTC2983_EEPROM_READ_CMD, + LTC2983_EEPROM_READ_TIME_MS, + LTC2983_EEPROM_READ_STATUS_REG, + LTC2983_EEPROM_READ_FAILURE_MASK); + if (!ret) + return 0; + } + for (chan = 0; chan < st->num_channels; chan++) { u32 chan_type = 0, *iio_chan; @@ -1435,9 +1563,13 @@ static int ltc2983_setup(struct ltc2983_data *st, bool assign_iio) static const struct regmap_range ltc2983_reg_ranges[] = { regmap_reg_range(LTC2983_STATUS_REG, LTC2983_STATUS_REG), regmap_reg_range(LTC2983_TEMP_RES_START_REG, LTC2983_TEMP_RES_END_REG), + regmap_reg_range(LTC2983_EEPROM_KEY_REG, LTC2983_EEPROM_KEY_REG), + regmap_reg_range(LTC2983_EEPROM_READ_STATUS_REG, + LTC2983_EEPROM_READ_STATUS_REG), regmap_reg_range(LTC2983_GLOBAL_CONFIG_REG, LTC2983_GLOBAL_CONFIG_REG), regmap_reg_range(LTC2983_MULT_CHANNEL_START_REG, LTC2983_MULT_CHANNEL_END_REG), + regmap_reg_range(LTC2986_EEPROM_STATUS_REG, LTC2986_EEPROM_STATUS_REG), regmap_reg_range(LTC2983_MUX_CONFIG_REG, LTC2983_MUX_CONFIG_REG), regmap_reg_range(LTC2983_CHAN_ASSIGN_START_REG, LTC2983_CHAN_ASSIGN_END_REG), @@ -1482,6 +1614,12 @@ static int ltc2983_probe(struct spi_device *spi) st = iio_priv(indio_dev); + st->info = device_get_match_data(&spi->dev); + if (!st->info) + st->info = (void *)spi_get_device_id(spi)->driver_data; + if (!st->info) + return -ENODEV; + st->regmap = devm_regmap_init_spi(spi, <c2983_regmap_config); if (IS_ERR(st->regmap)) { dev_err(&spi->dev, "Failed to initialize regmap\n"); @@ -1491,6 +1629,7 @@ static int ltc2983_probe(struct spi_device *spi) mutex_init(&st->lock); init_completion(&st->completion); st->spi = spi; + st->eeprom_key = cpu_to_be32(LTC2983_EEPROM_KEY); spi_set_drvdata(spi, st); ret = ltc2983_parse_dt(st); @@ -1524,6 +1663,15 @@ static int ltc2983_probe(struct spi_device *spi) return ret; } + if (st->info->has_eeprom) { + ret = ltc2983_eeprom_cmd(st, LTC2983_EEPROM_WRITE_CMD, + LTC2983_EEPROM_WRITE_TIME_MS, + LTC2986_EEPROM_STATUS_REG, + LTC2983_EEPROM_STATUS_FAILURE_MASK); + if (ret) + return ret; + } + indio_dev->name = name; indio_dev->num_channels = st->iio_channels; indio_dev->channels = st->iio_chan; @@ -1554,14 +1702,35 @@ static int ltc2983_suspend(struct device *dev) static DEFINE_SIMPLE_DEV_PM_OPS(ltc2983_pm_ops, ltc2983_suspend, ltc2983_resume); +static const struct ltc2983_chip_info ltc2983_chip_info_data = { + .max_channels_nr = 20, +}; + +static const struct ltc2983_chip_info ltc2984_chip_info_data = { + .max_channels_nr = 20, + .has_eeprom = true, +}; + +static const struct ltc2983_chip_info ltc2986_chip_info_data = { + .max_channels_nr = 10, + .has_temp = true, + .has_eeprom = true, +}; + static const struct spi_device_id ltc2983_id_table[] = { - { "ltc2983" }, + { "ltc2983", (kernel_ulong_t)<c2983_chip_info_data }, + { "ltc2984", (kernel_ulong_t)<c2984_chip_info_data }, + { "ltc2986", (kernel_ulong_t)<c2986_chip_info_data }, + { "ltm2985", (kernel_ulong_t)<c2986_chip_info_data }, {}, }; MODULE_DEVICE_TABLE(spi, ltc2983_id_table); static const struct of_device_id ltc2983_of_match[] = { - { .compatible = "adi,ltc2983" }, + { .compatible = "adi,ltc2983", .data = <c2983_chip_info_data }, + { .compatible = "adi,ltc2984", .data = <c2984_chip_info_data }, + { .compatible = "adi,ltc2986", .data = <c2986_chip_info_data }, + { .compatible = "adi,ltm2985", .data = <c2986_chip_info_data }, {}, }; MODULE_DEVICE_TABLE(of, ltc2983_of_match); -- cgit v1.2.3 From bcf22afd2ce0b8bd4fad50bfda92e8cbbc483c72 Mon Sep 17 00:00:00 2001 From: Jonathan Cameron Date: Sat, 5 Nov 2022 12:51:07 +0000 Subject: iio: temperature: mlx90632: Add error handling for devm_pm_runtime_enable() This call can fail so handling is necessary even if it is very unlikely. Reported-by: coverity-bot Addresses-Coverity-ID: 1527134 ("Error handling issues") Fixes: 2aebc223fc7c ("iio: temperature: mlx90632 Add runtime powermanagement modes") Signed-off-by: Jonathan Cameron Acked-off-by: Crt Mori Link: https://lore.kernel.org/r/20221105125108.383193-2-jic23@kernel.org --- drivers/iio/temperature/mlx90632.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'drivers/iio') diff --git a/drivers/iio/temperature/mlx90632.c b/drivers/iio/temperature/mlx90632.c index a17fe5f4967a..7572ae3f8432 100644 --- a/drivers/iio/temperature/mlx90632.c +++ b/drivers/iio/temperature/mlx90632.c @@ -1267,7 +1267,10 @@ static int mlx90632_probe(struct i2c_client *client, pm_runtime_get_noresume(&client->dev); pm_runtime_set_active(&client->dev); - devm_pm_runtime_enable(&client->dev); + ret = devm_pm_runtime_enable(&client->dev); + if (ret) + return ret; + pm_runtime_set_autosuspend_delay(&client->dev, MLX90632_SLEEP_DELAY_MS); pm_runtime_use_autosuspend(&client->dev); pm_runtime_put_autosuspend(&client->dev); -- cgit v1.2.3 From 99043ba702243f69d1853bd8aeca01e22836ede3 Mon Sep 17 00:00:00 2001 From: Jonathan Cameron Date: Sat, 5 Nov 2022 12:51:08 +0000 Subject: iio: temperature: mlx90632: Add missing static marking on devm_pm_ops Only used within this file, so should be marked static. Fixes: 2aebc223fc7c ("iio: temperature: mlx90632 Add runtime powermanagement modes") Signed-off-by: Jonathan Cameron Acked-off-by: Crt Mori Link: https://lore.kernel.org/r/20221105125108.383193-3-jic23@kernel.org --- drivers/iio/temperature/mlx90632.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/iio') diff --git a/drivers/iio/temperature/mlx90632.c b/drivers/iio/temperature/mlx90632.c index 7572ae3f8432..f1f5ebc145b1 100644 --- a/drivers/iio/temperature/mlx90632.c +++ b/drivers/iio/temperature/mlx90632.c @@ -1326,7 +1326,7 @@ static int mlx90632_pm_runtime_suspend(struct device *dev) return mlx90632_pwr_set_sleep_step(data->regmap); } -const struct dev_pm_ops mlx90632_pm_ops = { +static const struct dev_pm_ops mlx90632_pm_ops = { SYSTEM_SLEEP_PM_OPS(mlx90632_pm_suspend, mlx90632_pm_resume) RUNTIME_PM_OPS(mlx90632_pm_runtime_suspend, NULL, NULL) }; -- cgit v1.2.3 From c486b7019398a7a451631d5d99b67480768bfd25 Mon Sep 17 00:00:00 2001 From: Gwendal Grignou Date: Sat, 5 Nov 2022 15:51:57 -0700 Subject: iio: proximity: sx9360: Add a new ACPI hardware ID From https://treexy.com/products/driver-fusion/database/sensors/semtech/sx9360-proximity/ sx9360 SAR sensor can be presented with ACPI ID SAMM0208. Whilst this does not appear to be an official ACPI ID, it is in the wild (perhaps due to a typo on the SAM PnP ID). Reported-by: Jordi Torres Signed-off-by: Gwendal Grignou Link: https://lore.kernel.org/r/20221105225157.10081-1-gwendal@chromium.org Signed-off-by: Jonathan Cameron --- drivers/iio/proximity/sx9360.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers/iio') diff --git a/drivers/iio/proximity/sx9360.c b/drivers/iio/proximity/sx9360.c index 7fa2213d23ba..6e19d22e6a01 100644 --- a/drivers/iio/proximity/sx9360.c +++ b/drivers/iio/proximity/sx9360.c @@ -865,6 +865,7 @@ static DEFINE_SIMPLE_DEV_PM_OPS(sx9360_pm_ops, sx9360_suspend, sx9360_resume); static const struct acpi_device_id sx9360_acpi_match[] = { { "STH9360", SX9360_WHOAMI_VALUE }, + { "SAMM0208", SX9360_WHOAMI_VALUE }, { } }; MODULE_DEVICE_TABLE(acpi, sx9360_acpi_match); -- cgit v1.2.3 From 46975081f75105de5a6bda05af90323a4894d2be Mon Sep 17 00:00:00 2001 From: Lorenzo Bianconi Date: Sun, 6 Nov 2022 15:36:53 +0100 Subject: iio: imu: st_lsm6dsx: add support to LSM6DSV16X Add support to STM LSM6DSV16X (accelerometer and gyroscope) Mems sensor. The LSM6DSV16X sensor can use LSM6DSV as fallback device since it implements all the LSM6DSV16X features currently implemented in st_lsm6dsx. Datasheet: https://www.st.com/resource/en/datasheet/lsm6dsv16x.pdf Signed-off-by: Lorenzo Bianconi Link: https://lore.kernel.org/r/284b251f861dff30c399e5736a843c8e3a497249.1667745215.git.lorenzo@kernel.org Signed-off-by: Jonathan Cameron --- drivers/iio/imu/st_lsm6dsx/Kconfig | 3 ++- drivers/iio/imu/st_lsm6dsx/st_lsm6dsx.h | 2 ++ drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c | 6 +++++- drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_i2c.c | 5 +++++ drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_spi.c | 5 +++++ 5 files changed, 19 insertions(+), 2 deletions(-) (limited to 'drivers/iio') diff --git a/drivers/iio/imu/st_lsm6dsx/Kconfig b/drivers/iio/imu/st_lsm6dsx/Kconfig index 1c68bac94bce..37d02e0fc227 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, - lsm6dsv, the accelerometer/gyroscope of lsm9ds1 and lsm6dst. + lsm6dsv, lsm6dsv16x, the accelerometer/gyroscope of lsm9ds1 + and lsm6dst. 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 ab61895cf072..683cfadcf62e 100644 --- a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx.h +++ b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx.h @@ -34,6 +34,7 @@ #define ST_ASM330LHHX_DEV_NAME "asm330lhhx" #define ST_LSM6DSTX_DEV_NAME "lsm6dstx" #define ST_LSM6DSV_DEV_NAME "lsm6dsv" +#define ST_LSM6DSV16X_DEV_NAME "lsm6dsv16x" enum st_lsm6dsx_hw_id { ST_LSM6DS3_ID, @@ -55,6 +56,7 @@ enum st_lsm6dsx_hw_id { ST_ASM330LHHX_ID, ST_LSM6DSTX_ID, ST_LSM6DSV_ID, + ST_LSM6DSV16X_ID, ST_LSM6DSX_MAX_ID, }; diff --git a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c index 5e716a5071fd..acb6101aec5d 100644 --- a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c +++ b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c @@ -27,7 +27,7 @@ * - FIFO size: 4KB * * - LSM6DSO/LSM6DSOX/ASM330LHH/ASM330LHHX/LSM6DSR/ISM330DHCX/LSM6DST/LSM6DSOP/ - * LSM6DSTX: + * LSM6DSTX/LSM6DSV/LSM6DSV16X: * - Accelerometer/Gyroscope supported ODR [Hz]: 12.5, 26, 52, 104, 208, 416, * 833 * - Accelerometer supported full-scale [g]: +-2/+-4/+-8/+-16 @@ -1180,6 +1180,10 @@ static const struct st_lsm6dsx_settings st_lsm6dsx_sensor_settings[] = { .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 = { diff --git a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_i2c.c b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_i2c.c index 239c8920a31f..0faf1b4c11af 100644 --- a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_i2c.c +++ b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_i2c.c @@ -113,6 +113,10 @@ static const struct of_device_id st_lsm6dsx_i2c_of_match[] = { .compatible = "st,lsm6dsv", .data = (void *)ST_LSM6DSV_ID, }, + { + .compatible = "st,lsm6dsv16x", + .data = (void *)ST_LSM6DSV16X_ID, + }, {}, }; MODULE_DEVICE_TABLE(of, st_lsm6dsx_i2c_of_match); @@ -137,6 +141,7 @@ static const struct i2c_device_id st_lsm6dsx_i2c_id_table[] = { { 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 }, {}, }; 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 66705ef16ed0..57597aaa2a92 100644 --- a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_spi.c +++ b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_spi.c @@ -113,6 +113,10 @@ static const struct of_device_id st_lsm6dsx_spi_of_match[] = { .compatible = "st,lsm6dsv", .data = (void *)ST_LSM6DSV_ID, }, + { + .compatible = "st,lsm6dsv16x", + .data = (void *)ST_LSM6DSV16X_ID, + }, {}, }; MODULE_DEVICE_TABLE(of, st_lsm6dsx_spi_of_match); @@ -137,6 +141,7 @@ static const struct spi_device_id st_lsm6dsx_spi_id_table[] = { { 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 }, {}, }; MODULE_DEVICE_TABLE(spi, st_lsm6dsx_spi_id_table); -- cgit v1.2.3 From c896b9f0920fdcb9a815014ca1917522ba2c9b9a Mon Sep 17 00:00:00 2001 From: Jay Greco Date: Thu, 10 Nov 2022 19:29:32 +0000 Subject: iio: imu: inv_icm42600: Add support for icm42631 Add the required WHOAMI and device_id definitions to support the icm42631. Signed-off-by: Jay Greco Acked-by: Jean-Baptiste Maneyrol Link: https://lore.kernel.org/r/20221110192933.13616-2-grecojay@amazon.com Signed-off-by: Jonathan Cameron --- drivers/iio/imu/inv_icm42600/inv_icm42600.h | 2 ++ drivers/iio/imu/inv_icm42600/inv_icm42600_core.c | 5 +++++ drivers/iio/imu/inv_icm42600/inv_icm42600_i2c.c | 3 +++ drivers/iio/imu/inv_icm42600/inv_icm42600_spi.c | 3 +++ 4 files changed, 13 insertions(+) (limited to 'drivers/iio') 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 b63c5dab1a56..7b3a2a0dc2cb 100644 --- a/drivers/iio/imu/inv_icm42600/inv_icm42600_core.c +++ b/drivers/iio/imu/inv_icm42600/inv_icm42600_core.c @@ -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 * diff --git a/drivers/iio/imu/inv_icm42600/inv_icm42600_i2c.c b/drivers/iio/imu/inv_icm42600/inv_icm42600_i2c.c index 4f96989ddf4a..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, }, {} }; diff --git a/drivers/iio/imu/inv_icm42600/inv_icm42600_spi.c b/drivers/iio/imu/inv_icm42600/inv_icm42600_spi.c index 486b46e53113..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, }, {} }; -- cgit v1.2.3 From 5ae34494cf37ae6383f4bd674f343ef20833024d Mon Sep 17 00:00:00 2001 From: Subhajit Ghosh Date: Thu, 10 Nov 2022 18:12:41 +0800 Subject: iio: light: apds9960: Fix iio_event_spec structures There is only one interrupt enable option for both ALS low and high thresholds, and one for both Proximity low and high thresholds. Signed-off-by: Subhajit Ghosh Reviewed-by: Matt Ranostay Link: https://lore.kernel.org/r/20221110101241.10576-1-subhajit.ghosh@vixtechnology.com Signed-off-by: Jonathan Cameron --- drivers/iio/light/apds9960.c | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) (limited to 'drivers/iio') diff --git a/drivers/iio/light/apds9960.c b/drivers/iio/light/apds9960.c index b62c139baf41..997aa01ecc11 100644 --- a/drivers/iio/light/apds9960.c +++ b/drivers/iio/light/apds9960.c @@ -223,14 +223,16 @@ static const struct iio_event_spec apds9960_pxs_event_spec[] = { { .type = IIO_EV_TYPE_THRESH, .dir = IIO_EV_DIR_RISING, - .mask_separate = BIT(IIO_EV_INFO_VALUE) | - BIT(IIO_EV_INFO_ENABLE), + .mask_separate = BIT(IIO_EV_INFO_VALUE), }, { .type = IIO_EV_TYPE_THRESH, .dir = IIO_EV_DIR_FALLING, - .mask_separate = BIT(IIO_EV_INFO_VALUE) | - BIT(IIO_EV_INFO_ENABLE), + .mask_separate = BIT(IIO_EV_INFO_VALUE), + }, + { + .type = IIO_EV_TYPE_THRESH, + .mask_separate = BIT(IIO_EV_INFO_ENABLE), }, }; @@ -238,14 +240,16 @@ static const struct iio_event_spec apds9960_als_event_spec[] = { { .type = IIO_EV_TYPE_THRESH, .dir = IIO_EV_DIR_RISING, - .mask_separate = BIT(IIO_EV_INFO_VALUE) | - BIT(IIO_EV_INFO_ENABLE), + .mask_separate = BIT(IIO_EV_INFO_VALUE), }, { .type = IIO_EV_TYPE_THRESH, .dir = IIO_EV_DIR_FALLING, - .mask_separate = BIT(IIO_EV_INFO_VALUE) | - BIT(IIO_EV_INFO_ENABLE), + .mask_separate = BIT(IIO_EV_INFO_VALUE), + }, + { + .type = IIO_EV_TYPE_THRESH, + .mask_separate = BIT(IIO_EV_INFO_ENABLE), }, }; -- cgit v1.2.3 From 10c4539d1d5581646997d7f9b430319bcb9245b1 Mon Sep 17 00:00:00 2001 From: Cosmin Tanislav Date: Mon, 14 Nov 2022 15:36:49 +0200 Subject: iio: adc: ad4130: depend on GPIOLIB Fixes undefined references to 'gpiochip_get_data' and 'devm_gpiochip_add_data_with_key'. Signed-off-by: Cosmin Tanislav Reported-by: kernel test robot Fixes: 62094060cf3a ("iio: adc: ad4130: add AD4130 driver") Link: https://lore.kernel.org/r/20221114133649.1737027-1-cosmin.tanislav@analog.com Signed-off-by: Jonathan Cameron --- drivers/iio/adc/Kconfig | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers/iio') diff --git a/drivers/iio/adc/Kconfig b/drivers/iio/adc/Kconfig index 8d719fbb6acc..63f80d747cbd 100644 --- a/drivers/iio/adc/Kconfig +++ b/drivers/iio/adc/Kconfig @@ -24,6 +24,7 @@ config AD_SIGMA_DELTA config AD4130 tristate "Analog Device AD4130 ADC Driver" depends on SPI + depends on GPIOLIB select IIO_BUFFER select IIO_KFIFO_BUF select REGMAP_SPI -- cgit v1.2.3 From d94fbd9231a2b4062cf5972629999402ea7dd6fa Mon Sep 17 00:00:00 2001 From: Lorenzo Bianconi Date: Mon, 14 Nov 2022 10:25:34 +0100 Subject: iio: imu: st_lsm6dsx: fix LSM6DSV sensor description Fix sensor ODR description for LSM6DSV/LSM6DSVX Fixes: a1c6d631ff12 ("iio: imu: st_lsm6dsx: add support to LSM6DSV") Signed-off-by: Lorenzo Bianconi Link: https://lore.kernel.org/r/653e14bf79bb88d8581d2bc42da2f784caaf3776.1668417770.git.lorenzo@kernel.org Signed-off-by: Jonathan Cameron --- drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) (limited to 'drivers/iio') diff --git a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c index acb6101aec5d..b680682f9833 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/LSM6DSV/LSM6DSV16X: + * LSM6DSTX: * - 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 -- cgit v1.2.3 From 2c5c45e236c4706a261042f67766b0486c72d603 Mon Sep 17 00:00:00 2001 From: Uwe Kleine-König Date: Fri, 18 Nov 2022 23:36:23 +0100 Subject: iio: accel: adxl372_i2c: Convert to i2c's .probe_new() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit .probe_new() doesn't get the i2c_device_id * parameter, so determine that explicitly in the probe function. Signed-off-by: Uwe Kleine-König Reviewed-by: Andy Shevchenko Link: https://lore.kernel.org/r/20221118224540.619276-50-uwe@kleine-koenig.org Signed-off-by: Jonathan Cameron --- drivers/iio/accel/adxl372_i2c.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers/iio') diff --git a/drivers/iio/accel/adxl372_i2c.c b/drivers/iio/accel/adxl372_i2c.c index 4efb70a5fe40..e5f310ea65ff 100644 --- a/drivers/iio/accel/adxl372_i2c.c +++ b/drivers/iio/accel/adxl372_i2c.c @@ -18,9 +18,9 @@ static const struct regmap_config adxl372_regmap_config = { .readable_noinc_reg = adxl372_readable_noinc_reg, }; -static int adxl372_i2c_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int adxl372_i2c_probe(struct i2c_client *client) { + const struct i2c_device_id *id = i2c_client_get_device_id(client); struct regmap *regmap; unsigned int regval; int ret; @@ -58,7 +58,7 @@ static struct i2c_driver adxl372_i2c_driver = { .name = "adxl372_i2c", .of_match_table = adxl372_of_match, }, - .probe = adxl372_i2c_probe, + .probe_new = adxl372_i2c_probe, .id_table = adxl372_i2c_id, }; -- cgit v1.2.3 From c476246bd5abb1f6d40054d83fea3f1a407ccb11 Mon Sep 17 00:00:00 2001 From: Uwe Kleine-König Date: Fri, 18 Nov 2022 23:36:24 +0100 Subject: iio: accel: bma180: Convert to i2c's .probe_new() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit .probe_new() doesn't get the i2c_device_id * parameter, so determine that explicitly in the probe function. Signed-off-by: Uwe Kleine-König Reviewed-by: Andy Shevchenko Link: https://lore.kernel.org/r/20221118224540.619276-51-uwe@kleine-koenig.org Signed-off-by: Jonathan Cameron --- drivers/iio/accel/bma180.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers/iio') diff --git a/drivers/iio/accel/bma180.c b/drivers/iio/accel/bma180.c index d03fc3400f94..eb697eeb4301 100644 --- a/drivers/iio/accel/bma180.c +++ b/drivers/iio/accel/bma180.c @@ -921,9 +921,9 @@ static const struct iio_trigger_ops bma180_trigger_ops = { .reenable = bma180_trig_reen, }; -static int bma180_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int bma180_probe(struct i2c_client *client) { + const struct i2c_device_id *id = i2c_client_get_device_id(client); struct device *dev = &client->dev; struct bma180_data *data; struct iio_dev *indio_dev; @@ -1134,7 +1134,7 @@ static struct i2c_driver bma180_driver = { .pm = pm_sleep_ptr(&bma180_pm_ops), .of_match_table = bma180_of_match, }, - .probe = bma180_probe, + .probe_new = bma180_probe, .remove = bma180_remove, .id_table = bma180_ids, }; -- cgit v1.2.3 From e599500f96fb51417320b8b51ae4c36868672b13 Mon Sep 17 00:00:00 2001 From: Uwe Kleine-König Date: Fri, 18 Nov 2022 23:36:25 +0100 Subject: iio: accel: bma400: Convert to i2c's .probe_new() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit .probe_new() doesn't get the i2c_device_id * parameter, so determine that explicitly in the probe function. Signed-off-by: Uwe Kleine-König Reviewed-by: Andy Shevchenko Link: https://lore.kernel.org/r/20221118224540.619276-52-uwe@kleine-koenig.org Signed-off-by: Jonathan Cameron --- drivers/iio/accel/bma400_i2c.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers/iio') diff --git a/drivers/iio/accel/bma400_i2c.c b/drivers/iio/accel/bma400_i2c.c index 1ba2a982ea73..688b06dae669 100644 --- a/drivers/iio/accel/bma400_i2c.c +++ b/drivers/iio/accel/bma400_i2c.c @@ -13,9 +13,9 @@ #include "bma400.h" -static int bma400_i2c_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int bma400_i2c_probe(struct i2c_client *client) { + const struct i2c_device_id *id = i2c_client_get_device_id(client); struct regmap *regmap; regmap = devm_regmap_init_i2c(client, &bma400_regmap_config); @@ -44,7 +44,7 @@ static struct i2c_driver bma400_i2c_driver = { .name = "bma400", .of_match_table = bma400_of_i2c_match, }, - .probe = bma400_i2c_probe, + .probe_new = bma400_i2c_probe, .id_table = bma400_i2c_ids, }; -- cgit v1.2.3 From a141d225f6d62809d2b6a6c916929a8bbaaaaad5 Mon Sep 17 00:00:00 2001 From: Uwe Kleine-König Date: Fri, 18 Nov 2022 23:36:26 +0100 Subject: iio: accel: bmc150: Convert to i2c's .probe_new() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit .probe_new() doesn't get the i2c_device_id * parameter, so determine that explicitly in the probe function. Signed-off-by: Uwe Kleine-König Reviewed-by: Andy Shevchenko Link: https://lore.kernel.org/r/20221118224540.619276-53-uwe@kleine-koenig.org Signed-off-by: Jonathan Cameron --- drivers/iio/accel/bmc150-accel-i2c.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers/iio') diff --git a/drivers/iio/accel/bmc150-accel-i2c.c b/drivers/iio/accel/bmc150-accel-i2c.c index be8cc598b88e..509cab2bd694 100644 --- a/drivers/iio/accel/bmc150-accel-i2c.c +++ b/drivers/iio/accel/bmc150-accel-i2c.c @@ -171,9 +171,9 @@ static void bmc150_acpi_dual_accel_probe(struct i2c_client *client) {} static void bmc150_acpi_dual_accel_remove(struct i2c_client *client) {} #endif -static int bmc150_accel_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int bmc150_accel_probe(struct i2c_client *client) { + const struct i2c_device_id *id = i2c_client_get_device_id(client); struct regmap *regmap; const char *name = NULL; enum bmc150_type type = BOSCH_UNKNOWN; @@ -269,7 +269,7 @@ static struct i2c_driver bmc150_accel_driver = { .acpi_match_table = ACPI_PTR(bmc150_accel_acpi_match), .pm = &bmc150_accel_pm_ops, }, - .probe = bmc150_accel_probe, + .probe_new = bmc150_accel_probe, .remove = bmc150_accel_remove, .id_table = bmc150_accel_id, }; -- cgit v1.2.3 From a8fab44897dd959c01a88a806fd4252a29c62055 Mon Sep 17 00:00:00 2001 From: Uwe Kleine-König Date: Fri, 18 Nov 2022 23:36:27 +0100 Subject: iio: accel: da280: Convert to i2c's .probe_new() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit .probe_new() doesn't get the i2c_device_id * parameter, so determine that explicitly in the probe function. Signed-off-by: Uwe Kleine-König Reviewed-by: Andy Shevchenko Link: https://lore.kernel.org/r/20221118224540.619276-54-uwe@kleine-koenig.org Signed-off-by: Jonathan Cameron --- drivers/iio/accel/da280.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers/iio') diff --git a/drivers/iio/accel/da280.c b/drivers/iio/accel/da280.c index 04e9c5678964..38a7d811610e 100644 --- a/drivers/iio/accel/da280.c +++ b/drivers/iio/accel/da280.c @@ -105,9 +105,9 @@ static void da280_disable(void *client) da280_enable(client, false); } -static int da280_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int da280_probe(struct i2c_client *client) { + const struct i2c_device_id *id = i2c_client_get_device_id(client); int ret; struct iio_dev *indio_dev; struct da280_data *data; @@ -184,7 +184,7 @@ static struct i2c_driver da280_driver = { .acpi_match_table = ACPI_PTR(da280_acpi_match), .pm = pm_sleep_ptr(&da280_pm_ops), }, - .probe = da280_probe, + .probe_new = da280_probe, .id_table = da280_i2c_id, }; -- cgit v1.2.3 From 09cec0835243b17316995bce30532f5ad51db355 Mon Sep 17 00:00:00 2001 From: Uwe Kleine-König Date: Fri, 18 Nov 2022 23:36:28 +0100 Subject: iio: accel: kxcjk-1013: Convert to i2c's .probe_new() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit .probe_new() doesn't get the i2c_device_id * parameter, so determine that explicitly in the probe function. Signed-off-by: Uwe Kleine-König Reviewed-by: Andy Shevchenko Link: https://lore.kernel.org/r/20221118224540.619276-55-uwe@kleine-koenig.org Signed-off-by: Jonathan Cameron --- drivers/iio/accel/kxcjk-1013.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers/iio') diff --git a/drivers/iio/accel/kxcjk-1013.c b/drivers/iio/accel/kxcjk-1013.c index e626b6fa8a36..98da4bda22df 100644 --- a/drivers/iio/accel/kxcjk-1013.c +++ b/drivers/iio/accel/kxcjk-1013.c @@ -1424,9 +1424,9 @@ static const char *kxcjk1013_match_acpi_device(struct device *dev, return dev_name(dev); } -static int kxcjk1013_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int kxcjk1013_probe(struct i2c_client *client) { + const struct i2c_device_id *id = i2c_client_get_device_id(client); static const char * const regulator_names[] = { "vdd", "vddio" }; struct kxcjk1013_data *data; struct iio_dev *indio_dev; @@ -1732,7 +1732,7 @@ static struct i2c_driver kxcjk1013_driver = { .of_match_table = kxcjk1013_of_match, .pm = &kxcjk1013_pm_ops, }, - .probe = kxcjk1013_probe, + .probe_new = kxcjk1013_probe, .remove = kxcjk1013_remove, .id_table = kxcjk1013_id, }; -- cgit v1.2.3 From 17b9a72f4a11c64a12d7cd4a7951ba44c5f2f374 Mon Sep 17 00:00:00 2001 From: Uwe Kleine-König Date: Fri, 18 Nov 2022 23:36:29 +0100 Subject: iio: accel: mma7455_i2c: Convert to i2c's .probe_new() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit .probe_new() doesn't get the i2c_device_id * parameter, so determine that explicitly in the probe function. Signed-off-by: Uwe Kleine-König Reviewed-by: Andy Shevchenko Link: https://lore.kernel.org/r/20221118224540.619276-56-uwe@kleine-koenig.org Signed-off-by: Jonathan Cameron --- drivers/iio/accel/mma7455_i2c.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers/iio') diff --git a/drivers/iio/accel/mma7455_i2c.c b/drivers/iio/accel/mma7455_i2c.c index c63b321b01cd..a3864dbe2761 100644 --- a/drivers/iio/accel/mma7455_i2c.c +++ b/drivers/iio/accel/mma7455_i2c.c @@ -10,9 +10,9 @@ #include "mma7455.h" -static int mma7455_i2c_probe(struct i2c_client *i2c, - const struct i2c_device_id *id) +static int mma7455_i2c_probe(struct i2c_client *i2c) { + const struct i2c_device_id *id = i2c_client_get_device_id(i2c); struct regmap *regmap; const char *name = NULL; @@ -46,7 +46,7 @@ static const struct of_device_id mma7455_of_match[] = { MODULE_DEVICE_TABLE(of, mma7455_of_match); static struct i2c_driver mma7455_i2c_driver = { - .probe = mma7455_i2c_probe, + .probe_new = mma7455_i2c_probe, .remove = mma7455_i2c_remove, .id_table = mma7455_i2c_ids, .driver = { -- cgit v1.2.3 From 12491d35551df69709777bd7769e1e33641943cc Mon Sep 17 00:00:00 2001 From: Angel Iglesias Date: Sun, 13 Nov 2022 18:54:46 +0100 Subject: iio: pressure: bmp280: convert to i2c's .probe_new() Use i2c_client_get_device_id() to get the i2c_device_id* parameter in the .new_probe() callback. Signed-off-by: Angel Iglesias Reviewed-by: Andy Shevchenko Link: https://lore.kernel.org/r/5dcaa389ea2ffe7050091b07a3bc4b0c1c9d586b.1668361368.git.ang.iglesiasg@gmail.com Signed-off-by: Jonathan Cameron --- drivers/iio/pressure/bmp280-i2c.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers/iio') diff --git a/drivers/iio/pressure/bmp280-i2c.c b/drivers/iio/pressure/bmp280-i2c.c index 0c27211f3ea0..14eab086d24a 100644 --- a/drivers/iio/pressure/bmp280-i2c.c +++ b/drivers/iio/pressure/bmp280-i2c.c @@ -5,11 +5,11 @@ #include "bmp280.h" -static int bmp280_i2c_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int bmp280_i2c_probe(struct i2c_client *client) { struct regmap *regmap; const struct regmap_config *regmap_config; + const struct i2c_device_id *id = i2c_client_get_device_id(client); switch (id->driver_data) { case BMP180_CHIP_ID: @@ -65,7 +65,7 @@ static struct i2c_driver bmp280_i2c_driver = { .of_match_table = bmp280_of_i2c_match, .pm = pm_ptr(&bmp280_dev_pm_ops), }, - .probe = bmp280_i2c_probe, + .probe_new = bmp280_i2c_probe, .id_table = bmp280_i2c_id, }; module_i2c_driver(bmp280_i2c_driver); -- cgit v1.2.3 From 226d6dbac88336f37b1fae76aabe6fa610e9b872 Mon Sep 17 00:00:00 2001 From: Uwe Kleine-König Date: Fri, 18 Nov 2022 23:36:30 +0100 Subject: iio: accel: mma8452: Convert to i2c's .probe_new() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit .probe_new() doesn't get the i2c_device_id * parameter, so determine that explicitly in the probe function. Signed-off-by: Uwe Kleine-König Reviewed-by: Hans de Goede Reviewed-by: Andy Shevchenko Link: https://lore.kernel.org/r/20221118224540.619276-57-uwe@kleine-koenig.org Signed-off-by: Jonathan Cameron --- drivers/iio/accel/mma8452.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers/iio') diff --git a/drivers/iio/accel/mma8452.c b/drivers/iio/accel/mma8452.c index 3ba28c2ff68a..f97fb68e3a71 100644 --- a/drivers/iio/accel/mma8452.c +++ b/drivers/iio/accel/mma8452.c @@ -1545,9 +1545,9 @@ static const struct of_device_id mma8452_dt_ids[] = { }; MODULE_DEVICE_TABLE(of, mma8452_dt_ids); -static int mma8452_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int mma8452_probe(struct i2c_client *client) { + const struct i2c_device_id *id = i2c_client_get_device_id(client); struct mma8452_data *data; struct iio_dev *indio_dev; int ret; @@ -1846,7 +1846,7 @@ static struct i2c_driver mma8452_driver = { .of_match_table = mma8452_dt_ids, .pm = &mma8452_pm_ops, }, - .probe = mma8452_probe, + .probe_new = mma8452_probe, .remove = mma8452_remove, .id_table = mma8452_id, }; -- cgit v1.2.3 From 6dae5d11e29d2935e7995d05468d72660dde5f7b Mon Sep 17 00:00:00 2001 From: Uwe Kleine-König Date: Fri, 18 Nov 2022 23:36:31 +0100 Subject: iio: accel: mma9551: Convert to i2c's .probe_new() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit .probe_new() doesn't get the i2c_device_id * parameter, so determine that explicitly in the probe function. Signed-off-by: Uwe Kleine-König Reviewed-by: Andy Shevchenko Link: https://lore.kernel.org/r/20221118224540.619276-58-uwe@kleine-koenig.org Signed-off-by: Jonathan Cameron --- drivers/iio/accel/mma9551.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers/iio') diff --git a/drivers/iio/accel/mma9551.c b/drivers/iio/accel/mma9551.c index f7a793f4a8e3..aa4f5842859e 100644 --- a/drivers/iio/accel/mma9551.c +++ b/drivers/iio/accel/mma9551.c @@ -446,9 +446,9 @@ static const char *mma9551_match_acpi_device(struct device *dev) return dev_name(dev); } -static int mma9551_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int mma9551_probe(struct i2c_client *client) { + const struct i2c_device_id *id = i2c_client_get_device_id(client); struct mma9551_data *data; struct iio_dev *indio_dev; const char *name = NULL; @@ -607,7 +607,7 @@ static struct i2c_driver mma9551_driver = { .acpi_match_table = ACPI_PTR(mma9551_acpi_match), .pm = pm_ptr(&mma9551_pm_ops), }, - .probe = mma9551_probe, + .probe_new = mma9551_probe, .remove = mma9551_remove, .id_table = mma9551_id, }; -- cgit v1.2.3 From 50434e4605d66a55e7422cb24804c88b57cfb2bc Mon Sep 17 00:00:00 2001 From: Uwe Kleine-König Date: Fri, 18 Nov 2022 23:36:32 +0100 Subject: iio: accel: mma9553: Convert to i2c's .probe_new() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit .probe_new() doesn't get the i2c_device_id * parameter, so determine that explicitly in the probe function. Signed-off-by: Uwe Kleine-König Reviewed-by: Andy Shevchenko Link: https://lore.kernel.org/r/20221118224540.619276-59-uwe@kleine-koenig.org Signed-off-by: Jonathan Cameron --- drivers/iio/accel/mma9553.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers/iio') diff --git a/drivers/iio/accel/mma9553.c b/drivers/iio/accel/mma9553.c index 2da0e005b13e..0af578ef9d3d 100644 --- a/drivers/iio/accel/mma9553.c +++ b/drivers/iio/accel/mma9553.c @@ -1073,9 +1073,9 @@ static const char *mma9553_match_acpi_device(struct device *dev) return dev_name(dev); } -static int mma9553_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int mma9553_probe(struct i2c_client *client) { + const struct i2c_device_id *id = i2c_client_get_device_id(client); struct mma9553_data *data; struct iio_dev *indio_dev; const char *name = NULL; @@ -1246,7 +1246,7 @@ static struct i2c_driver mma9553_driver = { .acpi_match_table = ACPI_PTR(mma9553_acpi_match), .pm = pm_ptr(&mma9553_pm_ops), }, - .probe = mma9553_probe, + .probe_new = mma9553_probe, .remove = mma9553_remove, .id_table = mma9553_id, }; -- cgit v1.2.3 From fe44f0738dd142a173e1b62e13b59d134abca003 Mon Sep 17 00:00:00 2001 From: Uwe Kleine-König Date: Fri, 18 Nov 2022 23:36:33 +0100 Subject: iio: adc: ad7091r5: Convert to i2c's .probe_new() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit .probe_new() doesn't get the i2c_device_id * parameter, so determine that explicitly in the probe function. Signed-off-by: Uwe Kleine-König Reviewed-by: Andy Shevchenko Link: https://lore.kernel.org/r/20221118224540.619276-60-uwe@kleine-koenig.org Signed-off-by: Jonathan Cameron --- drivers/iio/adc/ad7091r5.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers/iio') diff --git a/drivers/iio/adc/ad7091r5.c b/drivers/iio/adc/ad7091r5.c index 47f5763023a4..7d6709da1005 100644 --- a/drivers/iio/adc/ad7091r5.c +++ b/drivers/iio/adc/ad7091r5.c @@ -69,9 +69,9 @@ static const struct ad7091r_chip_info ad7091r5_chip_info_noirq = { .vref_mV = 2500, }; -static int ad7091r5_i2c_probe(struct i2c_client *i2c, - const struct i2c_device_id *id) +static int ad7091r5_i2c_probe(struct i2c_client *i2c) { + const struct i2c_device_id *id = i2c_client_get_device_id(i2c); const struct ad7091r_chip_info *chip_info; struct regmap *map = devm_regmap_init_i2c(i2c, &ad7091r_regmap_config); @@ -103,7 +103,7 @@ static struct i2c_driver ad7091r5_driver = { .name = "ad7091r5", .of_match_table = ad7091r5_dt_ids, }, - .probe = ad7091r5_i2c_probe, + .probe_new = ad7091r5_i2c_probe, .id_table = ad7091r5_i2c_ids, }; module_i2c_driver(ad7091r5_driver); -- cgit v1.2.3 From 3ff5dd78f6b7e5aa73ddbc8f609f5ba53d1d49bc Mon Sep 17 00:00:00 2001 From: Uwe Kleine-König Date: Fri, 18 Nov 2022 23:36:34 +0100 Subject: iio: adc: ad7291: Convert to i2c's .probe_new() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit .probe_new() doesn't get the i2c_device_id * parameter, so determine that explicitly in the probe function. Signed-off-by: Uwe Kleine-König Reviewed-by: Andy Shevchenko Link: https://lore.kernel.org/r/20221118224540.619276-61-uwe@kleine-koenig.org Signed-off-by: Jonathan Cameron --- drivers/iio/adc/ad7291.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers/iio') diff --git a/drivers/iio/adc/ad7291.c b/drivers/iio/adc/ad7291.c index e9129dac762f..3dd0105f63d7 100644 --- a/drivers/iio/adc/ad7291.c +++ b/drivers/iio/adc/ad7291.c @@ -465,9 +465,9 @@ static void ad7291_reg_disable(void *reg) regulator_disable(reg); } -static int ad7291_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int ad7291_probe(struct i2c_client *client) { + const struct i2c_device_id *id = i2c_client_get_device_id(client); struct ad7291_chip_info *chip; struct iio_dev *indio_dev; int ret; @@ -553,7 +553,7 @@ static struct i2c_driver ad7291_driver = { .name = KBUILD_MODNAME, .of_match_table = ad7291_of_match, }, - .probe = ad7291_probe, + .probe_new = ad7291_probe, .id_table = ad7291_id, }; module_i2c_driver(ad7291_driver); -- cgit v1.2.3 From 28ae41885ab2bec935a61a9c811713df6e70043e Mon Sep 17 00:00:00 2001 From: Uwe Kleine-König Date: Fri, 18 Nov 2022 23:36:35 +0100 Subject: iio: adc: ad799x: Convert to i2c's .probe_new() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit .probe_new() doesn't get the i2c_device_id * parameter, so determine that explicitly in the probe function. Signed-off-by: Uwe Kleine-König Reviewed-by: Andy Shevchenko Link: https://lore.kernel.org/r/20221118224540.619276-62-uwe@kleine-koenig.org Signed-off-by: Jonathan Cameron --- drivers/iio/adc/ad799x.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers/iio') diff --git a/drivers/iio/adc/ad799x.c b/drivers/iio/adc/ad799x.c index 4730d8d0f4c3..8f0a3a35e727 100644 --- a/drivers/iio/adc/ad799x.c +++ b/drivers/iio/adc/ad799x.c @@ -775,9 +775,9 @@ static const struct ad799x_chip_info ad799x_chip_info_tbl[] = { }, }; -static int ad799x_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int ad799x_probe(struct i2c_client *client) { + const struct i2c_device_id *id = i2c_client_get_device_id(client); int ret; int extra_config = 0; struct ad799x_state *st; @@ -968,7 +968,7 @@ static struct i2c_driver ad799x_driver = { .name = "ad799x", .pm = pm_sleep_ptr(&ad799x_pm_ops), }, - .probe = ad799x_probe, + .probe_new = ad799x_probe, .remove = ad799x_remove, .id_table = ad799x_id, }; -- cgit v1.2.3 From 203a5e83dd3f7ea4d0d827563a317bd656d2f579 Mon Sep 17 00:00:00 2001 From: Uwe Kleine-König Date: Fri, 18 Nov 2022 23:36:36 +0100 Subject: iio: adc: ina2xx-adc: Convert to i2c's .probe_new() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit .probe_new() doesn't get the i2c_device_id * parameter, so determine that explicitly in the probe function. Signed-off-by: Uwe Kleine-König Reviewed-by: Andy Shevchenko Link: https://lore.kernel.org/r/20221118224540.619276-63-uwe@kleine-koenig.org Signed-off-by: Jonathan Cameron --- drivers/iio/adc/ina2xx-adc.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers/iio') diff --git a/drivers/iio/adc/ina2xx-adc.c b/drivers/iio/adc/ina2xx-adc.c index 910e7e965fc4..38d9d7b2313e 100644 --- a/drivers/iio/adc/ina2xx-adc.c +++ b/drivers/iio/adc/ina2xx-adc.c @@ -946,9 +946,9 @@ static int ina2xx_init(struct ina2xx_chip_info *chip, unsigned int config) return ina2xx_set_calibration(chip); } -static int ina2xx_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int ina2xx_probe(struct i2c_client *client) { + const struct i2c_device_id *id = i2c_client_get_device_id(client); struct ina2xx_chip_info *chip; struct iio_dev *indio_dev; unsigned int val; @@ -1090,7 +1090,7 @@ static struct i2c_driver ina2xx_driver = { .name = KBUILD_MODNAME, .of_match_table = ina2xx_of_match, }, - .probe = ina2xx_probe, + .probe_new = ina2xx_probe, .remove = ina2xx_remove, .id_table = ina2xx_id, }; -- cgit v1.2.3 From 7b8c4fa43583ea1a7e60658ad23302608fe19ce9 Mon Sep 17 00:00:00 2001 From: Uwe Kleine-König Date: Fri, 18 Nov 2022 23:36:37 +0100 Subject: iio: adc: ltc2471: Convert to i2c's .probe_new() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit .probe_new() doesn't get the i2c_device_id * parameter, so determine that explicitly in the probe function. Signed-off-by: Uwe Kleine-König Reviewed-by: Andy Shevchenko Link: https://lore.kernel.org/r/20221118224540.619276-64-uwe@kleine-koenig.org Signed-off-by: Jonathan Cameron --- drivers/iio/adc/ltc2471.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers/iio') diff --git a/drivers/iio/adc/ltc2471.c b/drivers/iio/adc/ltc2471.c index 0e0fe881a8e6..eeb2945829eb 100644 --- a/drivers/iio/adc/ltc2471.c +++ b/drivers/iio/adc/ltc2471.c @@ -99,9 +99,9 @@ static const struct iio_info ltc2471_info = { .read_raw = ltc2471_read_raw, }; -static int ltc2471_i2c_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int ltc2471_i2c_probe(struct i2c_client *client) { + const struct i2c_device_id *id = i2c_client_get_device_id(client); struct iio_dev *indio_dev; struct ltc2471_data *data; int ret; @@ -146,7 +146,7 @@ static struct i2c_driver ltc2471_i2c_driver = { .driver = { .name = "ltc2471", }, - .probe = ltc2471_i2c_probe, + .probe_new = ltc2471_i2c_probe, .id_table = ltc2471_i2c_id, }; -- cgit v1.2.3 From 11e67cc9675f1289556e1524fa7717cc95282487 Mon Sep 17 00:00:00 2001 From: Uwe Kleine-König Date: Fri, 18 Nov 2022 23:36:38 +0100 Subject: iio: adc: ltc2485: Convert to i2c's .probe_new() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit .probe_new() doesn't get the i2c_device_id * parameter, so determine that explicitly in the probe function. Signed-off-by: Uwe Kleine-König Reviewed-by: Andy Shevchenko Link: https://lore.kernel.org/r/20221118224540.619276-65-uwe@kleine-koenig.org Signed-off-by: Jonathan Cameron --- drivers/iio/adc/ltc2485.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers/iio') diff --git a/drivers/iio/adc/ltc2485.c b/drivers/iio/adc/ltc2485.c index 37c762f8218c..6a23427344ec 100644 --- a/drivers/iio/adc/ltc2485.c +++ b/drivers/iio/adc/ltc2485.c @@ -89,9 +89,9 @@ static const struct iio_info ltc2485_info = { .read_raw = ltc2485_read_raw, }; -static int ltc2485_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int ltc2485_probe(struct i2c_client *client) { + const struct i2c_device_id *id = i2c_client_get_device_id(client); struct iio_dev *indio_dev; struct ltc2485_data *data; int ret; @@ -133,7 +133,7 @@ static struct i2c_driver ltc2485_driver = { .driver = { .name = "ltc2485", }, - .probe = ltc2485_probe, + .probe_new = ltc2485_probe, .id_table = ltc2485_id, }; module_i2c_driver(ltc2485_driver); -- cgit v1.2.3 From 3a79844428c39fa54a30ec11eaad5a8e577ef706 Mon Sep 17 00:00:00 2001 From: Uwe Kleine-König Date: Fri, 18 Nov 2022 23:36:39 +0100 Subject: iio: adc: ltc2497: Convert to i2c's .probe_new() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit .probe_new() doesn't get the i2c_device_id * parameter, so determine that explicitly in the probe function. Signed-off-by: Uwe Kleine-König Reviewed-by: Andy Shevchenko Link: https://lore.kernel.org/r/20221118224540.619276-66-uwe@kleine-koenig.org Signed-off-by: Jonathan Cameron --- drivers/iio/adc/ltc2497.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers/iio') diff --git a/drivers/iio/adc/ltc2497.c b/drivers/iio/adc/ltc2497.c index 556f10dfb502..17370c5eb6fe 100644 --- a/drivers/iio/adc/ltc2497.c +++ b/drivers/iio/adc/ltc2497.c @@ -94,9 +94,9 @@ static int ltc2497_result_and_measure(struct ltc2497core_driverdata *ddata, return ret; } -static int ltc2497_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int ltc2497_probe(struct i2c_client *client) { + const struct i2c_device_id *id = i2c_client_get_device_id(client); const struct ltc2497_chip_info *chip_info; struct iio_dev *indio_dev; struct ltc2497_driverdata *st; @@ -165,7 +165,7 @@ static struct i2c_driver ltc2497_driver = { .name = "ltc2497", .of_match_table = ltc2497_of_match, }, - .probe = ltc2497_probe, + .probe_new = ltc2497_probe, .remove = ltc2497_remove, .id_table = ltc2497_id, }; -- cgit v1.2.3 From a69e45a411ea3ae0bbec474e4303c4281f3f8376 Mon Sep 17 00:00:00 2001 From: Uwe Kleine-König Date: Fri, 18 Nov 2022 23:36:40 +0100 Subject: iio: adc: max1363: Convert to i2c's .probe_new() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit .probe_new() doesn't get the i2c_device_id * parameter, so determine that explicitly in the probe function. Signed-off-by: Uwe Kleine-König Reviewed-by: Andy Shevchenko Link: https://lore.kernel.org/r/20221118224540.619276-67-uwe@kleine-koenig.org Signed-off-by: Jonathan Cameron --- drivers/iio/adc/max1363.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers/iio') diff --git a/drivers/iio/adc/max1363.c b/drivers/iio/adc/max1363.c index 42d3479cefb7..73b783b430d7 100644 --- a/drivers/iio/adc/max1363.c +++ b/drivers/iio/adc/max1363.c @@ -1579,9 +1579,9 @@ static void max1363_reg_disable(void *reg) regulator_disable(reg); } -static int max1363_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int max1363_probe(struct i2c_client *client) { + const struct i2c_device_id *id = i2c_client_get_device_id(client); int ret; struct max1363_state *st; struct iio_dev *indio_dev; @@ -1718,7 +1718,7 @@ static struct i2c_driver max1363_driver = { .name = "max1363", .of_match_table = max1363_of_match, }, - .probe = max1363_probe, + .probe_new = max1363_probe, .id_table = max1363_id, }; module_i2c_driver(max1363_driver); -- cgit v1.2.3 From d59ecbc48a1c74cfe6bc2d4ff503fb3e7455d19f Mon Sep 17 00:00:00 2001 From: Uwe Kleine-König Date: Fri, 18 Nov 2022 23:36:41 +0100 Subject: iio: adc: max9611: Convert to i2c's .probe_new() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The probe function doesn't make use of the i2c_device_id * parameter so it can be trivially converted. Signed-off-by: Uwe Kleine-König Acked-by: Jacopo Mondi Reviewed-by: Andy Shevchenko Link: https://lore.kernel.org/r/20221118224540.619276-68-uwe@kleine-koenig.org Signed-off-by: Jonathan Cameron --- drivers/iio/adc/max9611.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'drivers/iio') diff --git a/drivers/iio/adc/max9611.c b/drivers/iio/adc/max9611.c index f982f00303dc..cb7f4785423a 100644 --- a/drivers/iio/adc/max9611.c +++ b/drivers/iio/adc/max9611.c @@ -510,8 +510,7 @@ static const struct of_device_id max9611_of_table[] = { }; MODULE_DEVICE_TABLE(of, max9611_of_table); -static int max9611_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int max9611_probe(struct i2c_client *client) { const char * const shunt_res_prop = "shunt-resistor-micro-ohms"; struct max9611_dev *max9611; @@ -557,7 +556,7 @@ static struct i2c_driver max9611_driver = { .name = DRIVER_NAME, .of_match_table = max9611_of_table, }, - .probe = max9611_probe, + .probe_new = max9611_probe, }; module_i2c_driver(max9611_driver); -- cgit v1.2.3 From 6168215dbfea1c1d42a7aff145efbbcbdb5d6051 Mon Sep 17 00:00:00 2001 From: Uwe Kleine-König Date: Fri, 18 Nov 2022 23:36:42 +0100 Subject: iio: adc: mcp3422: Convert to i2c's .probe_new() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit .probe_new() doesn't get the i2c_device_id * parameter, so determine that explicitly in the probe function. Signed-off-by: Uwe Kleine-König Reviewed-by: Andy Shevchenko Link: https://lore.kernel.org/r/20221118224540.619276-69-uwe@kleine-koenig.org Signed-off-by: Jonathan Cameron --- drivers/iio/adc/mcp3422.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers/iio') diff --git a/drivers/iio/adc/mcp3422.c b/drivers/iio/adc/mcp3422.c index da353dcb1e9d..ada844c3f7ec 100644 --- a/drivers/iio/adc/mcp3422.c +++ b/drivers/iio/adc/mcp3422.c @@ -330,9 +330,9 @@ static const struct iio_info mcp3422_info = { .attrs = &mcp3422_attribute_group, }; -static int mcp3422_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int mcp3422_probe(struct i2c_client *client) { + const struct i2c_device_id *id = i2c_client_get_device_id(client); struct iio_dev *indio_dev; struct mcp3422 *adc; int err; @@ -417,7 +417,7 @@ static struct i2c_driver mcp3422_driver = { .name = "mcp3422", .of_match_table = mcp3422_of_match, }, - .probe = mcp3422_probe, + .probe_new = mcp3422_probe, .id_table = mcp3422_id, }; module_i2c_driver(mcp3422_driver); -- cgit v1.2.3 From 4b50867f6a328c13d40223937c34b4146eafd883 Mon Sep 17 00:00:00 2001 From: Uwe Kleine-König Date: Fri, 18 Nov 2022 23:36:43 +0100 Subject: iio: adc: ti-adc081c: Convert to i2c's .probe_new() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit .probe_new() doesn't get the i2c_device_id * parameter, so determine that explicitly in the probe function. Signed-off-by: Uwe Kleine-König Reviewed-by: Andy Shevchenko Link: https://lore.kernel.org/r/20221118224540.619276-70-uwe@kleine-koenig.org Signed-off-by: Jonathan Cameron --- drivers/iio/adc/ti-adc081c.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers/iio') diff --git a/drivers/iio/adc/ti-adc081c.c b/drivers/iio/adc/ti-adc081c.c index bd48b073e720..c663dc59d459 100644 --- a/drivers/iio/adc/ti-adc081c.c +++ b/drivers/iio/adc/ti-adc081c.c @@ -152,9 +152,9 @@ static void adc081c_reg_disable(void *reg) regulator_disable(reg); } -static int adc081c_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int adc081c_probe(struct i2c_client *client) { + const struct i2c_device_id *id = i2c_client_get_device_id(client); struct iio_dev *iio; struct adc081c *adc; const struct adcxx1c_model *model; @@ -235,7 +235,7 @@ static struct i2c_driver adc081c_driver = { .of_match_table = adc081c_of_match, .acpi_match_table = adc081c_acpi_match, }, - .probe = adc081c_probe, + .probe_new = adc081c_probe, .id_table = adc081c_id, }; module_i2c_driver(adc081c_driver); -- cgit v1.2.3 From 0143ce1039f70e2656865d75c163ed4dbf40db30 Mon Sep 17 00:00:00 2001 From: Uwe Kleine-König Date: Fri, 18 Nov 2022 23:36:44 +0100 Subject: iio: adc: ti-ads1015: Convert to i2c's .probe_new() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit .probe_new() doesn't get the i2c_device_id * parameter, so determine that explicitly in the probe function. Signed-off-by: Uwe Kleine-König Reviewed-by: Andy Shevchenko Link: https://lore.kernel.org/r/20221118224540.619276-71-uwe@kleine-koenig.org Signed-off-by: Jonathan Cameron --- drivers/iio/adc/ti-ads1015.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers/iio') diff --git a/drivers/iio/adc/ti-ads1015.c b/drivers/iio/adc/ti-ads1015.c index 8bceba694026..56af5e148802 100644 --- a/drivers/iio/adc/ti-ads1015.c +++ b/drivers/iio/adc/ti-ads1015.c @@ -974,9 +974,9 @@ static int ads1015_set_conv_mode(struct ads1015_data *data, int mode) mode << ADS1015_CFG_MOD_SHIFT); } -static int ads1015_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int ads1015_probe(struct i2c_client *client) { + const struct i2c_device_id *id = i2c_client_get_device_id(client); const struct ads1015_chip_data *chip; struct iio_dev *indio_dev; struct ads1015_data *data; @@ -1195,7 +1195,7 @@ static struct i2c_driver ads1015_driver = { .of_match_table = ads1015_of_match, .pm = &ads1015_pm_ops, }, - .probe = ads1015_probe, + .probe_new = ads1015_probe, .remove = ads1015_remove, .id_table = ads1015_id, }; -- cgit v1.2.3 From 7558eaa9727dbf2efd41d29101d1639975cf778e Mon Sep 17 00:00:00 2001 From: Uwe Kleine-König Date: Fri, 18 Nov 2022 23:36:45 +0100 Subject: iio: cdc: ad7150: Convert to i2c's .probe_new() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit .probe_new() doesn't get the i2c_device_id * parameter, so determine that explicitly in the probe function. Signed-off-by: Uwe Kleine-König Reviewed-by: Andy Shevchenko Link: https://lore.kernel.org/r/20221118224540.619276-72-uwe@kleine-koenig.org Signed-off-by: Jonathan Cameron --- drivers/iio/cdc/ad7150.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers/iio') diff --git a/drivers/iio/cdc/ad7150.c b/drivers/iio/cdc/ad7150.c index 1113745890ca..79aeb0aaea67 100644 --- a/drivers/iio/cdc/ad7150.c +++ b/drivers/iio/cdc/ad7150.c @@ -536,9 +536,9 @@ static const struct iio_info ad7150_info_no_irq = { .read_raw = &ad7150_read_raw, }; -static int ad7150_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int ad7150_probe(struct i2c_client *client) { + const struct i2c_device_id *id = i2c_client_get_device_id(client); struct ad7150_chip_info *chip; struct iio_dev *indio_dev; int ret; @@ -647,7 +647,7 @@ static struct i2c_driver ad7150_driver = { .name = "ad7150", .of_match_table = ad7150_of_match, }, - .probe = ad7150_probe, + .probe_new = ad7150_probe, .id_table = ad7150_id, }; module_i2c_driver(ad7150_driver); -- cgit v1.2.3 From 9b1cd21eafc34beb50194a060e1cd3902b763a82 Mon Sep 17 00:00:00 2001 From: Uwe Kleine-König Date: Fri, 18 Nov 2022 23:36:46 +0100 Subject: iio: cdc: ad7746: Convert to i2c's .probe_new() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit .probe_new() doesn't get the i2c_device_id * parameter, so determine that explicitly in the probe function. Signed-off-by: Uwe Kleine-König Reviewed-by: Andy Shevchenko Link: https://lore.kernel.org/r/20221118224540.619276-73-uwe@kleine-koenig.org Signed-off-by: Jonathan Cameron --- drivers/iio/cdc/ad7746.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers/iio') diff --git a/drivers/iio/cdc/ad7746.c b/drivers/iio/cdc/ad7746.c index b266f5328140..6f68651ce1d5 100644 --- a/drivers/iio/cdc/ad7746.c +++ b/drivers/iio/cdc/ad7746.c @@ -717,9 +717,9 @@ static const struct iio_info ad7746_info = { .write_raw = ad7746_write_raw, }; -static int ad7746_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int ad7746_probe(struct i2c_client *client) { + const struct i2c_device_id *id = i2c_client_get_device_id(client); struct device *dev = &client->dev; struct ad7746_chip_info *chip; struct iio_dev *indio_dev; @@ -810,7 +810,7 @@ static struct i2c_driver ad7746_driver = { .name = KBUILD_MODNAME, .of_match_table = ad7746_of_match, }, - .probe = ad7746_probe, + .probe_new = ad7746_probe, .id_table = ad7746_id, }; module_i2c_driver(ad7746_driver); -- cgit v1.2.3 From 89d63224e20c8409afb553d334d38bb2675757ec Mon Sep 17 00:00:00 2001 From: Uwe Kleine-König Date: Fri, 18 Nov 2022 23:36:47 +0100 Subject: iio: chemical: ams-iaq-core: Convert to i2c's .probe_new() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The probe function doesn't make use of the i2c_device_id * parameter so it can be trivially converted. Signed-off-by: Uwe Kleine-König Reviewed-by: Andy Shevchenko Link: https://lore.kernel.org/r/20221118224540.619276-74-uwe@kleine-koenig.org Signed-off-by: Jonathan Cameron --- drivers/iio/chemical/ams-iaq-core.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'drivers/iio') diff --git a/drivers/iio/chemical/ams-iaq-core.c b/drivers/iio/chemical/ams-iaq-core.c index 97be3669c554..0a0fbcdd4469 100644 --- a/drivers/iio/chemical/ams-iaq-core.c +++ b/drivers/iio/chemical/ams-iaq-core.c @@ -135,8 +135,7 @@ static const struct iio_info ams_iaqcore_info = { .read_raw = ams_iaqcore_read_raw, }; -static int ams_iaqcore_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int ams_iaqcore_probe(struct i2c_client *client) { struct iio_dev *indio_dev; struct ams_iaqcore_data *data; @@ -180,7 +179,7 @@ static struct i2c_driver ams_iaqcore_driver = { .name = "ams-iaq-core", .of_match_table = ams_iaqcore_dt_ids, }, - .probe = ams_iaqcore_probe, + .probe_new = ams_iaqcore_probe, .id_table = ams_iaqcore_id, }; module_i2c_driver(ams_iaqcore_driver); -- cgit v1.2.3 From e9c812ca569f1314f0a9c0420cb17c9db0a55457 Mon Sep 17 00:00:00 2001 From: Uwe Kleine-König Date: Fri, 18 Nov 2022 23:36:48 +0100 Subject: iio: chemical: atlas-ezo-sensor: Convert to i2c's .probe_new() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit .probe_new() doesn't get the i2c_device_id * parameter, so determine that explicitly in the probe function. Signed-off-by: Uwe Kleine-König Reviewed-by: Andy Shevchenko Link: https://lore.kernel.org/r/20221118224540.619276-75-uwe@kleine-koenig.org Signed-off-by: Jonathan Cameron --- drivers/iio/chemical/atlas-ezo-sensor.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers/iio') diff --git a/drivers/iio/chemical/atlas-ezo-sensor.c b/drivers/iio/chemical/atlas-ezo-sensor.c index bbcf5a59c1f4..307c3488f4bd 100644 --- a/drivers/iio/chemical/atlas-ezo-sensor.c +++ b/drivers/iio/chemical/atlas-ezo-sensor.c @@ -201,9 +201,9 @@ static const struct of_device_id atlas_ezo_dt_ids[] = { }; MODULE_DEVICE_TABLE(of, atlas_ezo_dt_ids); -static int atlas_ezo_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int atlas_ezo_probe(struct i2c_client *client) { + const struct i2c_device_id *id = i2c_client_get_device_id(client); const struct atlas_ezo_device *chip; struct atlas_ezo_data *data; struct iio_dev *indio_dev; @@ -238,7 +238,7 @@ static struct i2c_driver atlas_ezo_driver = { .name = ATLAS_EZO_DRV_NAME, .of_match_table = atlas_ezo_dt_ids, }, - .probe = atlas_ezo_probe, + .probe_new = atlas_ezo_probe, .id_table = atlas_ezo_id, }; module_i2c_driver(atlas_ezo_driver); -- cgit v1.2.3 From 50c359245069f7e64880fe01b06d40954df71d9f Mon Sep 17 00:00:00 2001 From: Uwe Kleine-König Date: Fri, 18 Nov 2022 23:36:49 +0100 Subject: iio: chemical: atlas-sensor: Convert to i2c's .probe_new() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit .probe_new() doesn't get the i2c_device_id * parameter, so determine that explicitly in the probe function. Signed-off-by: Uwe Kleine-König Reviewed-by: Andy Shevchenko Link: https://lore.kernel.org/r/20221118224540.619276-76-uwe@kleine-koenig.org Signed-off-by: Jonathan Cameron --- drivers/iio/chemical/atlas-sensor.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers/iio') diff --git a/drivers/iio/chemical/atlas-sensor.c b/drivers/iio/chemical/atlas-sensor.c index 7cac77a931c7..024657bc59e1 100644 --- a/drivers/iio/chemical/atlas-sensor.c +++ b/drivers/iio/chemical/atlas-sensor.c @@ -608,9 +608,9 @@ static const struct of_device_id atlas_dt_ids[] = { }; MODULE_DEVICE_TABLE(of, atlas_dt_ids); -static int atlas_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int atlas_probe(struct i2c_client *client) { + const struct i2c_device_id *id = i2c_client_get_device_id(client); struct atlas_data *data; struct atlas_device *chip; struct iio_trigger *trig; @@ -767,7 +767,7 @@ static struct i2c_driver atlas_driver = { .of_match_table = atlas_dt_ids, .pm = pm_ptr(&atlas_pm_ops), }, - .probe = atlas_probe, + .probe_new = atlas_probe, .remove = atlas_remove, .id_table = atlas_id, }; -- cgit v1.2.3 From 5aa377658458cb7c4ea20dab7405b795a5cc8a11 Mon Sep 17 00:00:00 2001 From: Uwe Kleine-König Date: Fri, 18 Nov 2022 23:36:50 +0100 Subject: iio: chemical: bme680_i2c: Convert to i2c's .probe_new() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit .probe_new() doesn't get the i2c_device_id * parameter, so determine that explicitly in the probe function. Signed-off-by: Uwe Kleine-König Reviewed-by: Andy Shevchenko Link: https://lore.kernel.org/r/20221118224540.619276-77-uwe@kleine-koenig.org Signed-off-by: Jonathan Cameron --- drivers/iio/chemical/bme680_i2c.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers/iio') diff --git a/drivers/iio/chemical/bme680_i2c.c b/drivers/iio/chemical/bme680_i2c.c index 20f2c20b6b02..61b12079858d 100644 --- a/drivers/iio/chemical/bme680_i2c.c +++ b/drivers/iio/chemical/bme680_i2c.c @@ -17,9 +17,9 @@ #include "bme680.h" -static int bme680_i2c_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int bme680_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; @@ -52,7 +52,7 @@ static struct i2c_driver bme680_i2c_driver = { .name = "bme680_i2c", .of_match_table = bme680_of_i2c_match, }, - .probe = bme680_i2c_probe, + .probe_new = bme680_i2c_probe, .id_table = bme680_i2c_id, }; module_i2c_driver(bme680_i2c_driver); -- cgit v1.2.3 From 684e57366e68e4ba2abc5ab56041b4d6534f28ad Mon Sep 17 00:00:00 2001 From: Uwe Kleine-König Date: Fri, 18 Nov 2022 23:36:51 +0100 Subject: iio: chemical: ccs811: Convert to i2c's .probe_new() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit .probe_new() doesn't get the i2c_device_id * parameter, so determine that explicitly in the probe function. Signed-off-by: Uwe Kleine-König Reviewed-by: Andy Shevchenko Link: https://lore.kernel.org/r/20221118224540.619276-78-uwe@kleine-koenig.org Signed-off-by: Jonathan Cameron --- drivers/iio/chemical/ccs811.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers/iio') diff --git a/drivers/iio/chemical/ccs811.c b/drivers/iio/chemical/ccs811.c index ba4045e20303..6ead80c08924 100644 --- a/drivers/iio/chemical/ccs811.c +++ b/drivers/iio/chemical/ccs811.c @@ -401,9 +401,9 @@ static int ccs811_reset(struct i2c_client *client) return 0; } -static int ccs811_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int ccs811_probe(struct i2c_client *client) { + const struct i2c_device_id *id = i2c_client_get_device_id(client); struct iio_dev *indio_dev; struct ccs811_data *data; int ret; @@ -567,7 +567,7 @@ static struct i2c_driver ccs811_driver = { .name = "ccs811", .of_match_table = ccs811_dt_ids, }, - .probe = ccs811_probe, + .probe_new = ccs811_probe, .remove = ccs811_remove, .id_table = ccs811_id, }; -- cgit v1.2.3 From 2f2adc666335cad150b720a6b19cec33464e2680 Mon Sep 17 00:00:00 2001 From: Uwe Kleine-König Date: Fri, 18 Nov 2022 23:36:52 +0100 Subject: iio: chemical: scd4x: Convert to i2c's .probe_new() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The probe function doesn't make use of the i2c_device_id * parameter so it can be trivially converted. Signed-off-by: Uwe Kleine-König Reviewed-by: Andy Shevchenko Link: https://lore.kernel.org/r/20221118224540.619276-79-uwe@kleine-koenig.org Signed-off-by: Jonathan Cameron --- drivers/iio/chemical/scd4x.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/iio') diff --git a/drivers/iio/chemical/scd4x.c b/drivers/iio/chemical/scd4x.c index 54066532ea45..f7ed9455b3c8 100644 --- a/drivers/iio/chemical/scd4x.c +++ b/drivers/iio/chemical/scd4x.c @@ -615,7 +615,7 @@ out: return IRQ_HANDLED; } -static int scd4x_probe(struct i2c_client *client, const struct i2c_device_id *id) +static int scd4x_probe(struct i2c_client *client) { static const unsigned long scd4x_scan_masks[] = { 0x07, 0x00 }; struct device *dev = &client->dev; @@ -690,7 +690,7 @@ static struct i2c_driver scd4x_i2c_driver = { .of_match_table = scd4x_dt_ids, .pm = pm_sleep_ptr(&scd4x_pm_ops), }, - .probe = scd4x_probe, + .probe_new = scd4x_probe, }; module_i2c_driver(scd4x_i2c_driver); -- cgit v1.2.3 From 67eba68bfccbdf6598200d70f80971e454d1ee2f Mon Sep 17 00:00:00 2001 From: Uwe Kleine-König Date: Fri, 18 Nov 2022 23:36:53 +0100 Subject: iio: chemical: sgp30: Convert to i2c's .probe_new() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit .probe_new() doesn't get the i2c_device_id * parameter, so determine that explicitly in the probe function. Signed-off-by: Uwe Kleine-König Reviewed-by: Andy Shevchenko Link: https://lore.kernel.org/r/20221118224540.619276-80-uwe@kleine-koenig.org Signed-off-by: Jonathan Cameron --- drivers/iio/chemical/sgp30.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers/iio') diff --git a/drivers/iio/chemical/sgp30.c b/drivers/iio/chemical/sgp30.c index e2c13c78c7e0..9d0c68485b63 100644 --- a/drivers/iio/chemical/sgp30.c +++ b/drivers/iio/chemical/sgp30.c @@ -496,9 +496,9 @@ static const struct of_device_id sgp_dt_ids[] = { { } }; -static int sgp_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int sgp_probe(struct i2c_client *client) { + const struct i2c_device_id *id = i2c_client_get_device_id(client); struct device *dev = &client->dev; struct iio_dev *indio_dev; struct sgp_data *data; @@ -575,7 +575,7 @@ static struct i2c_driver sgp_driver = { .name = "sgp30", .of_match_table = sgp_dt_ids, }, - .probe = sgp_probe, + .probe_new = sgp_probe, .remove = sgp_remove, .id_table = sgp_id, }; -- cgit v1.2.3 From 07eda54d92f7ae7439a77903b9a43bfe563ebf21 Mon Sep 17 00:00:00 2001 From: Uwe Kleine-König Date: Fri, 18 Nov 2022 23:36:54 +0100 Subject: iio: chemical: sgp40: Convert to i2c's .probe_new() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit .probe_new() doesn't get the i2c_device_id * parameter, so determine that explicitly in the probe function. Signed-off-by: Uwe Kleine-König Reviewed-by: Andy Shevchenko Link: https://lore.kernel.org/r/20221118224540.619276-81-uwe@kleine-koenig.org Signed-off-by: Jonathan Cameron --- drivers/iio/chemical/sgp40.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers/iio') diff --git a/drivers/iio/chemical/sgp40.c b/drivers/iio/chemical/sgp40.c index 8a56394cea4e..c0ea01300908 100644 --- a/drivers/iio/chemical/sgp40.c +++ b/drivers/iio/chemical/sgp40.c @@ -311,9 +311,9 @@ static const struct iio_info sgp40_info = { .write_raw = sgp40_write_raw, }; -static int sgp40_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int sgp40_probe(struct i2c_client *client) { + const struct i2c_device_id *id = i2c_client_get_device_id(client); struct device *dev = &client->dev; struct iio_dev *indio_dev; struct sgp40_data *data; @@ -368,7 +368,7 @@ static struct i2c_driver sgp40_driver = { .name = "sgp40", .of_match_table = sgp40_dt_ids, }, - .probe = sgp40_probe, + .probe_new = sgp40_probe, .id_table = sgp40_id, }; module_i2c_driver(sgp40_driver); -- cgit v1.2.3 From 0d8535ee52f0392f6293e564e3ff4522d6c37cfd Mon Sep 17 00:00:00 2001 From: Uwe Kleine-König Date: Fri, 18 Nov 2022 23:36:55 +0100 Subject: iio: chemical: vz89x: Convert to i2c's .probe_new() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit .probe_new() doesn't get the i2c_device_id * parameter, so determine that explicitly in the probe function. Signed-off-by: Uwe Kleine-König Reviewed-by: Andy Shevchenko Link: https://lore.kernel.org/r/20221118224540.619276-82-uwe@kleine-koenig.org Signed-off-by: Jonathan Cameron --- drivers/iio/chemical/vz89x.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers/iio') diff --git a/drivers/iio/chemical/vz89x.c b/drivers/iio/chemical/vz89x.c index e7e1c74a351e..d4604f7ccd1e 100644 --- a/drivers/iio/chemical/vz89x.c +++ b/drivers/iio/chemical/vz89x.c @@ -348,9 +348,9 @@ static const struct of_device_id vz89x_dt_ids[] = { }; MODULE_DEVICE_TABLE(of, vz89x_dt_ids); -static int vz89x_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int vz89x_probe(struct i2c_client *client) { + const struct i2c_device_id *id = i2c_client_get_device_id(client); struct device *dev = &client->dev; struct iio_dev *indio_dev; struct vz89x_data *data; @@ -402,7 +402,7 @@ static struct i2c_driver vz89x_driver = { .name = "vz89x", .of_match_table = vz89x_dt_ids, }, - .probe = vz89x_probe, + .probe_new = vz89x_probe, .id_table = vz89x_id, }; module_i2c_driver(vz89x_driver); -- cgit v1.2.3 From 16fb97c4aacf5db311f4fb54745f852d1183e662 Mon Sep 17 00:00:00 2001 From: Uwe Kleine-König Date: Fri, 18 Nov 2022 23:36:56 +0100 Subject: iio: dac: ad5064: Convert to i2c's .probe_new() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit .probe_new() doesn't get the i2c_device_id * parameter, so determine that explicitly in the probe function. Signed-off-by: Uwe Kleine-König Reviewed-by: Andy Shevchenko Link: https://lore.kernel.org/r/20221118224540.619276-83-uwe@kleine-koenig.org Signed-off-by: Jonathan Cameron --- drivers/iio/dac/ad5064.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers/iio') diff --git a/drivers/iio/dac/ad5064.c b/drivers/iio/dac/ad5064.c index 4447b8811827..f01249c1ba93 100644 --- a/drivers/iio/dac/ad5064.c +++ b/drivers/iio/dac/ad5064.c @@ -993,9 +993,9 @@ static int ad5064_i2c_write(struct ad5064_state *st, unsigned int cmd, return 0; } -static int ad5064_i2c_probe(struct i2c_client *i2c, - const struct i2c_device_id *id) +static int ad5064_i2c_probe(struct i2c_client *i2c) { + const struct i2c_device_id *id = i2c_client_get_device_id(i2c); return ad5064_probe(&i2c->dev, id->driver_data, id->name, ad5064_i2c_write); } @@ -1056,7 +1056,7 @@ static struct i2c_driver ad5064_i2c_driver = { .driver = { .name = "ad5064", }, - .probe = ad5064_i2c_probe, + .probe_new = ad5064_i2c_probe, .id_table = ad5064_i2c_ids, }; -- cgit v1.2.3 From 4b2b4370a8459982d78d5716361a7a51089fecbb Mon Sep 17 00:00:00 2001 From: Uwe Kleine-König Date: Fri, 18 Nov 2022 23:36:57 +0100 Subject: iio: dac: ad5380: Convert to i2c's .probe_new() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit .probe_new() doesn't get the i2c_device_id * parameter, so determine that explicitly in the probe function. Signed-off-by: Uwe Kleine-König Reviewed-by: Andy Shevchenko Link: https://lore.kernel.org/r/20221118224540.619276-84-uwe@kleine-koenig.org Signed-off-by: Jonathan Cameron --- drivers/iio/dac/ad5380.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers/iio') diff --git a/drivers/iio/dac/ad5380.c b/drivers/iio/dac/ad5380.c index a81bfa47a221..64b4519f8f5e 100644 --- a/drivers/iio/dac/ad5380.c +++ b/drivers/iio/dac/ad5380.c @@ -546,9 +546,9 @@ static inline void ad5380_spi_unregister_driver(void) #if IS_ENABLED(CONFIG_I2C) -static int ad5380_i2c_probe(struct i2c_client *i2c, - const struct i2c_device_id *id) +static int ad5380_i2c_probe(struct i2c_client *i2c) { + const struct i2c_device_id *id = i2c_client_get_device_id(i2c); struct regmap *regmap; regmap = devm_regmap_init_i2c(i2c, &ad5380_regmap_config); @@ -589,7 +589,7 @@ static struct i2c_driver ad5380_i2c_driver = { .driver = { .name = "ad5380", }, - .probe = ad5380_i2c_probe, + .probe_new = ad5380_i2c_probe, .remove = ad5380_i2c_remove, .id_table = ad5380_i2c_ids, }; -- cgit v1.2.3 From 94e5ddbaac1ea9b5bda64af53d8a57b19be890ae Mon Sep 17 00:00:00 2001 From: Uwe Kleine-König Date: Fri, 18 Nov 2022 23:36:58 +0100 Subject: iio: dac: ad5446: Convert to i2c's .probe_new() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit .probe_new() doesn't get the i2c_device_id * parameter, so determine that explicitly in the probe function. Signed-off-by: Uwe Kleine-König Reviewed-by: Andy Shevchenko Link: https://lore.kernel.org/r/20221118224540.619276-85-uwe@kleine-koenig.org Signed-off-by: Jonathan Cameron --- drivers/iio/dac/ad5446.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers/iio') diff --git a/drivers/iio/dac/ad5446.c b/drivers/iio/dac/ad5446.c index 7324065d3782..aa3130b33456 100644 --- a/drivers/iio/dac/ad5446.c +++ b/drivers/iio/dac/ad5446.c @@ -568,9 +568,9 @@ static const struct ad5446_chip_info ad5446_i2c_chip_info[] = { }, }; -static int ad5446_i2c_probe(struct i2c_client *i2c, - const struct i2c_device_id *id) +static int ad5446_i2c_probe(struct i2c_client *i2c) { + const struct i2c_device_id *id = i2c_client_get_device_id(i2c); return ad5446_probe(&i2c->dev, id->name, &ad5446_i2c_chip_info[id->driver_data]); } @@ -595,7 +595,7 @@ static struct i2c_driver ad5446_i2c_driver = { .driver = { .name = "ad5446", }, - .probe = ad5446_i2c_probe, + .probe_new = ad5446_i2c_probe, .remove = ad5446_i2c_remove, .id_table = ad5446_i2c_ids, }; -- cgit v1.2.3 From a17c748115cb1f95675b322e955763cd9bb628ad Mon Sep 17 00:00:00 2001 From: Uwe Kleine-König Date: Fri, 18 Nov 2022 23:36:59 +0100 Subject: iio: dac: ad5593r: Convert to i2c's .probe_new() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit .probe_new() doesn't get the i2c_device_id * parameter, so determine that explicitly in the probe function. Signed-off-by: Uwe Kleine-König Reviewed-by: Andy Shevchenko Link: https://lore.kernel.org/r/20221118224540.619276-86-uwe@kleine-koenig.org Signed-off-by: Jonathan Cameron --- drivers/iio/dac/ad5593r.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers/iio') diff --git a/drivers/iio/dac/ad5593r.c b/drivers/iio/dac/ad5593r.c index 8e5e014e0c28..d311567ab324 100644 --- a/drivers/iio/dac/ad5593r.c +++ b/drivers/iio/dac/ad5593r.c @@ -99,9 +99,9 @@ static const struct ad5592r_rw_ops ad5593r_rw_ops = { .gpio_read = ad5593r_gpio_read, }; -static int ad5593r_i2c_probe(struct i2c_client *i2c, - const struct i2c_device_id *id) +static int ad5593r_i2c_probe(struct i2c_client *i2c) { + const struct i2c_device_id *id = i2c_client_get_device_id(i2c); if (!i2c_check_functionality(i2c->adapter, I2C_FUNC_SMBUS_BYTE | I2C_FUNC_I2C)) return -EOPNOTSUPP; @@ -138,7 +138,7 @@ static struct i2c_driver ad5593r_driver = { .of_match_table = ad5593r_of_match, .acpi_match_table = ad5593r_acpi_match, }, - .probe = ad5593r_i2c_probe, + .probe_new = ad5593r_i2c_probe, .remove = ad5593r_i2c_remove, .id_table = ad5593r_i2c_ids, }; -- cgit v1.2.3 From 92cd05a0968d60b3d76dc8d3a5880b25b1af96b9 Mon Sep 17 00:00:00 2001 From: Uwe Kleine-König Date: Fri, 18 Nov 2022 23:37:00 +0100 Subject: iio: dac: ad5696-i2c: Convert to i2c's .probe_new() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit .probe_new() doesn't get the i2c_device_id * parameter, so determine that explicitly in the probe function. Signed-off-by: Uwe Kleine-König Reviewed-by: Andy Shevchenko Link: https://lore.kernel.org/r/20221118224540.619276-87-uwe@kleine-koenig.org Signed-off-by: Jonathan Cameron --- drivers/iio/dac/ad5696-i2c.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers/iio') diff --git a/drivers/iio/dac/ad5696-i2c.c b/drivers/iio/dac/ad5696-i2c.c index aa36cbf0137c..160e80cf9135 100644 --- a/drivers/iio/dac/ad5696-i2c.c +++ b/drivers/iio/dac/ad5696-i2c.c @@ -58,9 +58,9 @@ static int ad5686_i2c_write(struct ad5686_state *st, return (ret != 3) ? -EIO : 0; } -static int ad5686_i2c_probe(struct i2c_client *i2c, - const struct i2c_device_id *id) +static int ad5686_i2c_probe(struct i2c_client *i2c) { + const struct i2c_device_id *id = i2c_client_get_device_id(i2c); return ad5686_probe(&i2c->dev, id->driver_data, id->name, ad5686_i2c_write, ad5686_i2c_read); } @@ -113,7 +113,7 @@ static struct i2c_driver ad5686_i2c_driver = { .name = "ad5696", .of_match_table = ad5686_of_match, }, - .probe = ad5686_i2c_probe, + .probe_new = ad5686_i2c_probe, .remove = ad5686_i2c_remove, .id_table = ad5686_i2c_id, }; -- cgit v1.2.3 From 53f46605c3656c181e49df0d5fdba014cffa498e Mon Sep 17 00:00:00 2001 From: Uwe Kleine-König Date: Fri, 18 Nov 2022 23:37:01 +0100 Subject: iio: dac: ds4424: Convert to i2c's .probe_new() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit .probe_new() doesn't get the i2c_device_id * parameter, so determine that explicitly in the probe function. Signed-off-by: Uwe Kleine-König Reviewed-by: Andy Shevchenko Link: https://lore.kernel.org/r/20221118224540.619276-88-uwe@kleine-koenig.org Signed-off-by: Jonathan Cameron --- drivers/iio/dac/ds4424.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers/iio') diff --git a/drivers/iio/dac/ds4424.c b/drivers/iio/dac/ds4424.c index 3e17a681174e..a16a6a934d9d 100644 --- a/drivers/iio/dac/ds4424.c +++ b/drivers/iio/dac/ds4424.c @@ -213,9 +213,9 @@ static const struct iio_info ds4424_info = { .write_raw = ds4424_write_raw, }; -static int ds4424_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int ds4424_probe(struct i2c_client *client) { + const struct i2c_device_id *id = i2c_client_get_device_id(client); struct ds4424_data *data; struct iio_dev *indio_dev; int ret; @@ -312,7 +312,7 @@ static struct i2c_driver ds4424_driver = { .of_match_table = ds4424_of_match, .pm = pm_sleep_ptr(&ds4424_pm_ops), }, - .probe = ds4424_probe, + .probe_new = ds4424_probe, .remove = ds4424_remove, .id_table = ds4424_id, }; -- cgit v1.2.3 From 44d7a03c98f466c1567a8cad84908ce6a9d1f2c3 Mon Sep 17 00:00:00 2001 From: Uwe Kleine-König Date: Fri, 18 Nov 2022 23:37:02 +0100 Subject: iio: dac: m62332: Convert to i2c's .probe_new() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The probe function doesn't make use of the i2c_device_id * parameter so it can be trivially converted. Signed-off-by: Uwe Kleine-König Reviewed-by: Andy Shevchenko Link: https://lore.kernel.org/r/20221118224540.619276-89-uwe@kleine-koenig.org Signed-off-by: Jonathan Cameron --- drivers/iio/dac/m62332.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'drivers/iio') diff --git a/drivers/iio/dac/m62332.c b/drivers/iio/dac/m62332.c index 5a812f87970c..b692459b0f23 100644 --- a/drivers/iio/dac/m62332.c +++ b/drivers/iio/dac/m62332.c @@ -176,8 +176,7 @@ static const struct iio_chan_spec m62332_channels[M62332_CHANNELS] = { M62332_CHANNEL(1) }; -static int m62332_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int m62332_probe(struct i2c_client *client) { struct m62332_data *data; struct iio_dev *indio_dev; @@ -239,7 +238,7 @@ static struct i2c_driver m62332_driver = { .name = "m62332", .pm = pm_sleep_ptr(&m62332_pm_ops), }, - .probe = m62332_probe, + .probe_new = m62332_probe, .remove = m62332_remove, .id_table = m62332_id, }; -- cgit v1.2.3 From 090515edf46dc1f2ff7dbc78a60ba7692ff8420f Mon Sep 17 00:00:00 2001 From: Uwe Kleine-König Date: Fri, 18 Nov 2022 23:37:03 +0100 Subject: iio: dac: max517: Convert to i2c's .probe_new() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit .probe_new() doesn't get the i2c_device_id * parameter, so determine that explicitly in the probe function. Signed-off-by: Uwe Kleine-König Reviewed-by: Andy Shevchenko Link: https://lore.kernel.org/r/20221118224540.619276-90-uwe@kleine-koenig.org Signed-off-by: Jonathan Cameron --- drivers/iio/dac/max517.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers/iio') diff --git a/drivers/iio/dac/max517.c b/drivers/iio/dac/max517.c index 373ce6ff83b7..25967c39365d 100644 --- a/drivers/iio/dac/max517.c +++ b/drivers/iio/dac/max517.c @@ -141,9 +141,9 @@ static const struct iio_chan_spec max517_channels[] = { MAX517_CHANNEL(7), }; -static int max517_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int max517_probe(struct i2c_client *client) { + const struct i2c_device_id *id = i2c_client_get_device_id(client); struct max517_data *data; struct iio_dev *indio_dev; struct max517_platform_data *platform_data = client->dev.platform_data; @@ -203,7 +203,7 @@ static struct i2c_driver max517_driver = { .name = MAX517_DRV_NAME, .pm = pm_sleep_ptr(&max517_pm_ops), }, - .probe = max517_probe, + .probe_new = max517_probe, .id_table = max517_id, }; module_i2c_driver(max517_driver); -- cgit v1.2.3 From 62b001dad803e40274db2c712dd4dc0d3a4a37d3 Mon Sep 17 00:00:00 2001 From: Uwe Kleine-König Date: Fri, 18 Nov 2022 23:37:04 +0100 Subject: iio: dac: max5821: Convert to i2c's .probe_new() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit .probe_new() doesn't get the i2c_device_id * parameter, so determine that explicitly in the probe function. Signed-off-by: Uwe Kleine-König Reviewed-by: Andy Shevchenko Link: https://lore.kernel.org/r/20221118224540.619276-91-uwe@kleine-koenig.org Signed-off-by: Jonathan Cameron --- drivers/iio/dac/max5821.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers/iio') diff --git a/drivers/iio/dac/max5821.c b/drivers/iio/dac/max5821.c index e001b594d5b1..23da345b9250 100644 --- a/drivers/iio/dac/max5821.c +++ b/drivers/iio/dac/max5821.c @@ -300,9 +300,9 @@ static void max5821_regulator_disable(void *reg) regulator_disable(reg); } -static int max5821_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int max5821_probe(struct i2c_client *client) { + const struct i2c_device_id *id = i2c_client_get_device_id(client); struct max5821_data *data; struct iio_dev *indio_dev; u32 tmp; @@ -377,7 +377,7 @@ static struct i2c_driver max5821_driver = { .of_match_table = max5821_of_match, .pm = pm_sleep_ptr(&max5821_pm_ops), }, - .probe = max5821_probe, + .probe_new = max5821_probe, .id_table = max5821_id, }; module_i2c_driver(max5821_driver); -- cgit v1.2.3 From 818fe4546521f5e836ab02eeb6533bfd6aee6829 Mon Sep 17 00:00:00 2001 From: Uwe Kleine-König Date: Fri, 18 Nov 2022 23:37:05 +0100 Subject: iio: dac: mcp4725: Convert to i2c's .probe_new() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit .probe_new() doesn't get the i2c_device_id * parameter, so determine that explicitly in the probe function. Signed-off-by: Uwe Kleine-König Reviewed-by: Andy Shevchenko Link: https://lore.kernel.org/r/20221118224540.619276-92-uwe@kleine-koenig.org Signed-off-by: Jonathan Cameron --- drivers/iio/dac/mcp4725.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers/iio') diff --git a/drivers/iio/dac/mcp4725.c b/drivers/iio/dac/mcp4725.c index 446d1a8fe4be..46bf758760f8 100644 --- a/drivers/iio/dac/mcp4725.c +++ b/drivers/iio/dac/mcp4725.c @@ -369,9 +369,9 @@ static int mcp4725_probe_dt(struct device *dev, return 0; } -static int mcp4725_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int mcp4725_probe(struct i2c_client *client) { + const struct i2c_device_id *id = i2c_client_get_device_id(client); struct mcp4725_data *data; struct iio_dev *indio_dev; struct mcp4725_platform_data *pdata, pdata_dt; @@ -524,7 +524,7 @@ static struct i2c_driver mcp4725_driver = { .of_match_table = mcp4725_of_match, .pm = pm_sleep_ptr(&mcp4725_pm_ops), }, - .probe = mcp4725_probe, + .probe_new = mcp4725_probe, .remove = mcp4725_remove, .id_table = mcp4725_id, }; -- cgit v1.2.3 From 3de8dd69fad2c2ee7ca623d78fb2806d7b8b5a80 Mon Sep 17 00:00:00 2001 From: Uwe Kleine-König Date: Fri, 18 Nov 2022 23:37:06 +0100 Subject: iio: dac: ti-dac5571: Convert to i2c's .probe_new() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit .probe_new() doesn't get the i2c_device_id * parameter, so determine that explicitly in the probe function. Signed-off-by: Uwe Kleine-König Reviewed-by: Andy Shevchenko Reviewed-by: Laurent Pinchart Link: https://lore.kernel.org/r/20221118224540.619276-93-uwe@kleine-koenig.org Signed-off-by: Jonathan Cameron --- drivers/iio/dac/ti-dac5571.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers/iio') diff --git a/drivers/iio/dac/ti-dac5571.c b/drivers/iio/dac/ti-dac5571.c index 3210e3098f9a..40191947fea3 100644 --- a/drivers/iio/dac/ti-dac5571.c +++ b/drivers/iio/dac/ti-dac5571.c @@ -306,9 +306,9 @@ static const struct iio_info dac5571_info = { .write_raw_get_fmt = dac5571_write_raw_get_fmt, }; -static int dac5571_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int dac5571_probe(struct i2c_client *client) { + const struct i2c_device_id *id = i2c_client_get_device_id(client); struct device *dev = &client->dev; const struct dac5571_spec *spec; struct dac5571_data *data; @@ -426,7 +426,7 @@ static struct i2c_driver dac5571_driver = { .name = "ti-dac5571", .of_match_table = dac5571_of_id, }, - .probe = dac5571_probe, + .probe_new = dac5571_probe, .remove = dac5571_remove, .id_table = dac5571_id, }; -- cgit v1.2.3 From 840ef016c202fc196c91f020750fab08c9a0779f Mon Sep 17 00:00:00 2001 From: Uwe Kleine-König Date: Fri, 18 Nov 2022 23:37:07 +0100 Subject: iio: gyro: bmg160_i2c: Convert to i2c's .probe_new() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit .probe_new() doesn't get the i2c_device_id * parameter, so determine that explicitly in the probe function. Signed-off-by: Uwe Kleine-König Reviewed-by: Andy Shevchenko Link: https://lore.kernel.org/r/20221118224540.619276-94-uwe@kleine-koenig.org Signed-off-by: Jonathan Cameron --- drivers/iio/gyro/bmg160_i2c.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers/iio') diff --git a/drivers/iio/gyro/bmg160_i2c.c b/drivers/iio/gyro/bmg160_i2c.c index 908ccc385254..2b019ee5b2eb 100644 --- a/drivers/iio/gyro/bmg160_i2c.c +++ b/drivers/iio/gyro/bmg160_i2c.c @@ -13,9 +13,9 @@ static const struct regmap_config bmg160_regmap_i2c_conf = { .max_register = 0x3f }; -static int bmg160_i2c_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int bmg160_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; @@ -70,7 +70,7 @@ static struct i2c_driver bmg160_i2c_driver = { .of_match_table = bmg160_of_match, .pm = &bmg160_pm_ops, }, - .probe = bmg160_i2c_probe, + .probe_new = bmg160_i2c_probe, .remove = bmg160_i2c_remove, .id_table = bmg160_i2c_id, }; -- cgit v1.2.3 From 8312841060b8bc4b463dcf6a2cb8cc2452c6ac8f Mon Sep 17 00:00:00 2001 From: Uwe Kleine-König Date: Fri, 18 Nov 2022 23:37:08 +0100 Subject: iio: gyro: itg3200_core: Convert to i2c's .probe_new() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The probe function doesn't make use of the i2c_device_id * parameter so it can be trivially converted. Signed-off-by: Uwe Kleine-König Reviewed-by: Andy Shevchenko Link: https://lore.kernel.org/r/20221118224540.619276-95-uwe@kleine-koenig.org Signed-off-by: Jonathan Cameron --- drivers/iio/gyro/itg3200_core.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'drivers/iio') diff --git a/drivers/iio/gyro/itg3200_core.c b/drivers/iio/gyro/itg3200_core.c index 74ca22468496..ceacd863d3ea 100644 --- a/drivers/iio/gyro/itg3200_core.c +++ b/drivers/iio/gyro/itg3200_core.c @@ -295,8 +295,7 @@ static const struct iio_info itg3200_info = { static const unsigned long itg3200_available_scan_masks[] = { 0xffffffff, 0x0 }; -static int itg3200_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int itg3200_probe(struct i2c_client *client) { int ret; struct itg3200 *st; @@ -406,7 +405,7 @@ static struct i2c_driver itg3200_driver = { .pm = pm_sleep_ptr(&itg3200_pm_ops), }, .id_table = itg3200_id, - .probe = itg3200_probe, + .probe_new = itg3200_probe, .remove = itg3200_remove, }; -- cgit v1.2.3 From b97db5284e9ae169de79f78c3f09514d661407a7 Mon Sep 17 00:00:00 2001 From: Uwe Kleine-König Date: Fri, 18 Nov 2022 23:37:09 +0100 Subject: iio: gyro: mpu3050-i2c: Convert to i2c's .probe_new() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit .probe_new() doesn't get the i2c_device_id * parameter, so determine that explicitly in the probe function. Signed-off-by: Uwe Kleine-König Reviewed-by: Andy Shevchenko Link: https://lore.kernel.org/r/20221118224540.619276-96-uwe@kleine-koenig.org Signed-off-by: Jonathan Cameron --- drivers/iio/gyro/mpu3050-i2c.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers/iio') diff --git a/drivers/iio/gyro/mpu3050-i2c.c b/drivers/iio/gyro/mpu3050-i2c.c index 12e3afa9dd11..2116798226bf 100644 --- a/drivers/iio/gyro/mpu3050-i2c.c +++ b/drivers/iio/gyro/mpu3050-i2c.c @@ -32,9 +32,9 @@ static int mpu3050_i2c_bypass_deselect(struct i2c_mux_core *mux, u32 chan_id) return 0; } -static int mpu3050_i2c_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int mpu3050_i2c_probe(struct i2c_client *client) { + const struct i2c_device_id *id = i2c_client_get_device_id(client); struct regmap *regmap; const char *name; struct mpu3050 *mpu3050; @@ -108,7 +108,7 @@ static const struct of_device_id mpu3050_i2c_of_match[] = { MODULE_DEVICE_TABLE(of, mpu3050_i2c_of_match); static struct i2c_driver mpu3050_i2c_driver = { - .probe = mpu3050_i2c_probe, + .probe_new = mpu3050_i2c_probe, .remove = mpu3050_i2c_remove, .id_table = mpu3050_i2c_id, .driver = { -- cgit v1.2.3 From 1522b453c153cd93fe295a6dbd589f0f62fb168b Mon Sep 17 00:00:00 2001 From: Uwe Kleine-König Date: Fri, 18 Nov 2022 23:37:10 +0100 Subject: iio: gyro: st_gyro_i2c: Convert to i2c's .probe_new() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The probe function doesn't make use of the i2c_device_id * parameter so it can be trivially converted. Signed-off-by: Uwe Kleine-König Reviewed-by: Andy Shevchenko Link: https://lore.kernel.org/r/20221118224540.619276-97-uwe@kleine-koenig.org Signed-off-by: Jonathan Cameron --- drivers/iio/gyro/st_gyro_i2c.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'drivers/iio') diff --git a/drivers/iio/gyro/st_gyro_i2c.c b/drivers/iio/gyro/st_gyro_i2c.c index 8c7af42b6558..797a1c6a0402 100644 --- a/drivers/iio/gyro/st_gyro_i2c.c +++ b/drivers/iio/gyro/st_gyro_i2c.c @@ -58,8 +58,7 @@ static const struct of_device_id st_gyro_of_match[] = { }; MODULE_DEVICE_TABLE(of, st_gyro_of_match); -static int st_gyro_i2c_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int st_gyro_i2c_probe(struct i2c_client *client) { const struct st_sensor_settings *settings; struct st_sensor_data *gdata; @@ -112,7 +111,7 @@ static struct i2c_driver st_gyro_driver = { .name = "st-gyro-i2c", .of_match_table = st_gyro_of_match, }, - .probe = st_gyro_i2c_probe, + .probe_new = st_gyro_i2c_probe, .id_table = st_gyro_id_table, }; module_i2c_driver(st_gyro_driver); -- cgit v1.2.3 From d4764a4045b14a938594a082662b780c2c8eec78 Mon Sep 17 00:00:00 2001 From: Uwe Kleine-König Date: Fri, 18 Nov 2022 23:37:11 +0100 Subject: iio: health: afe4404: Convert to i2c's .probe_new() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The probe function doesn't make use of the i2c_device_id * parameter so it can be trivially converted. Signed-off-by: Uwe Kleine-König Reviewed-by: Andy Shevchenko Link: https://lore.kernel.org/r/20221118224540.619276-98-uwe@kleine-koenig.org Signed-off-by: Jonathan Cameron --- drivers/iio/health/afe4404.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'drivers/iio') diff --git a/drivers/iio/health/afe4404.c b/drivers/iio/health/afe4404.c index 8fca787b2524..658dfc1a346c 100644 --- a/drivers/iio/health/afe4404.c +++ b/drivers/iio/health/afe4404.c @@ -459,8 +459,7 @@ static int afe4404_resume(struct device *dev) static DEFINE_SIMPLE_DEV_PM_OPS(afe4404_pm_ops, afe4404_suspend, afe4404_resume); -static int afe4404_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int afe4404_probe(struct i2c_client *client) { struct iio_dev *indio_dev; struct afe4404_data *afe; @@ -608,7 +607,7 @@ static struct i2c_driver afe4404_i2c_driver = { .of_match_table = afe4404_of_match, .pm = pm_sleep_ptr(&afe4404_pm_ops), }, - .probe = afe4404_probe, + .probe_new = afe4404_probe, .remove = afe4404_remove, .id_table = afe4404_ids, }; -- cgit v1.2.3 From 3ef7e6e019c66beb6e4c8749a70d09d26326be8d Mon Sep 17 00:00:00 2001 From: Uwe Kleine-König Date: Fri, 18 Nov 2022 23:37:12 +0100 Subject: iio: health: max30100: Convert to i2c's .probe_new() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The probe function doesn't make use of the i2c_device_id * parameter so it can be trivially converted. Signed-off-by: Uwe Kleine-König Reviewed-by: Andy Shevchenko Link: https://lore.kernel.org/r/20221118224540.619276-99-uwe@kleine-koenig.org Signed-off-by: Jonathan Cameron --- drivers/iio/health/max30100.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'drivers/iio') diff --git a/drivers/iio/health/max30100.c b/drivers/iio/health/max30100.c index 3aa5d037a1c3..a80fa9852c22 100644 --- a/drivers/iio/health/max30100.c +++ b/drivers/iio/health/max30100.c @@ -417,8 +417,7 @@ static const struct iio_info max30100_info = { .read_raw = max30100_read_raw, }; -static int max30100_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int max30100_probe(struct i2c_client *client) { struct max30100_data *data; struct iio_dev *indio_dev; @@ -500,7 +499,7 @@ static struct i2c_driver max30100_driver = { .name = MAX30100_DRV_NAME, .of_match_table = max30100_dt_ids, }, - .probe = max30100_probe, + .probe_new = max30100_probe, .remove = max30100_remove, .id_table = max30100_id, }; -- cgit v1.2.3 From 15818f0890133372fb7eb875841dbcdb8c8ed592 Mon Sep 17 00:00:00 2001 From: Uwe Kleine-König Date: Fri, 18 Nov 2022 23:37:13 +0100 Subject: iio: health: max30102: Convert to i2c's .probe_new() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit .probe_new() doesn't get the i2c_device_id * parameter, so determine that explicitly in the probe function. Signed-off-by: Uwe Kleine-König Reviewed-by: Andy Shevchenko Link: https://lore.kernel.org/r/20221118224540.619276-100-uwe@kleine-koenig.org Signed-off-by: Jonathan Cameron --- drivers/iio/health/max30102.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers/iio') diff --git a/drivers/iio/health/max30102.c b/drivers/iio/health/max30102.c index 66df4aaa31a7..7edcf9e05687 100644 --- a/drivers/iio/health/max30102.c +++ b/drivers/iio/health/max30102.c @@ -513,9 +513,9 @@ static const struct iio_info max30102_info = { .read_raw = max30102_read_raw, }; -static int max30102_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int max30102_probe(struct i2c_client *client) { + const struct i2c_device_id *id = i2c_client_get_device_id(client); struct max30102_data *data; struct iio_dev *indio_dev; int ret; @@ -631,7 +631,7 @@ static struct i2c_driver max30102_driver = { .name = MAX30102_DRV_NAME, .of_match_table = max30102_dt_ids, }, - .probe = max30102_probe, + .probe_new = max30102_probe, .remove = max30102_remove, .id_table = max30102_id, }; -- cgit v1.2.3 From 1b1a60e70b0cd7ec46df424f6e7d342585c446b3 Mon Sep 17 00:00:00 2001 From: Uwe Kleine-König Date: Fri, 18 Nov 2022 23:37:14 +0100 Subject: iio: humidity: am2315: Convert to i2c's .probe_new() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The probe function doesn't make use of the i2c_device_id * parameter so it can be trivially converted. Signed-off-by: Uwe Kleine-König Reviewed-by: Andy Shevchenko Link: https://lore.kernel.org/r/20221118224540.619276-101-uwe@kleine-koenig.org Signed-off-by: Jonathan Cameron --- drivers/iio/humidity/am2315.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'drivers/iio') diff --git a/drivers/iio/humidity/am2315.c b/drivers/iio/humidity/am2315.c index 4a39f1019347..f246516bd45e 100644 --- a/drivers/iio/humidity/am2315.c +++ b/drivers/iio/humidity/am2315.c @@ -218,8 +218,7 @@ static const struct iio_info am2315_info = { .read_raw = am2315_read_raw, }; -static int am2315_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int am2315_probe(struct i2c_client *client) { int ret; struct iio_dev *indio_dev; @@ -263,7 +262,7 @@ static struct i2c_driver am2315_driver = { .driver = { .name = "am2315", }, - .probe = am2315_probe, + .probe_new = am2315_probe, .id_table = am2315_i2c_id, }; -- cgit v1.2.3 From c5f1c4fdbfa2ac6ca247bf5f32fb4c35ba0b1ec5 Mon Sep 17 00:00:00 2001 From: Uwe Kleine-König Date: Fri, 18 Nov 2022 23:37:15 +0100 Subject: iio: humidity: hdc100x: Convert to i2c's .probe_new() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The probe function doesn't make use of the i2c_device_id * parameter so it can be trivially converted. Signed-off-by: Uwe Kleine-König Reviewed-by: Andy Shevchenko Link: https://lore.kernel.org/r/20221118224540.619276-102-uwe@kleine-koenig.org Signed-off-by: Jonathan Cameron --- drivers/iio/humidity/hdc100x.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'drivers/iio') diff --git a/drivers/iio/humidity/hdc100x.c b/drivers/iio/humidity/hdc100x.c index 47f8e8ef56d6..49a950d739e4 100644 --- a/drivers/iio/humidity/hdc100x.c +++ b/drivers/iio/humidity/hdc100x.c @@ -351,8 +351,7 @@ static const struct iio_info hdc100x_info = { .attrs = &hdc100x_attribute_group, }; -static int hdc100x_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int hdc100x_probe(struct i2c_client *client) { struct iio_dev *indio_dev; struct hdc100x_data *data; @@ -429,7 +428,7 @@ static struct i2c_driver hdc100x_driver = { .of_match_table = hdc100x_dt_ids, .acpi_match_table = hdc100x_acpi_match, }, - .probe = hdc100x_probe, + .probe_new = hdc100x_probe, .id_table = hdc100x_id, }; module_i2c_driver(hdc100x_driver); -- cgit v1.2.3 From 0a78deeb639a464c9160f6bba912c97567f18b17 Mon Sep 17 00:00:00 2001 From: Uwe Kleine-König Date: Fri, 18 Nov 2022 23:37:16 +0100 Subject: iio: humidity: hdc2010: Convert to i2c's .probe_new() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The probe function doesn't make use of the i2c_device_id * parameter so it can be trivially converted. Signed-off-by: Uwe Kleine-König Reviewed-by: Andy Shevchenko Link: https://lore.kernel.org/r/20221118224540.619276-103-uwe@kleine-koenig.org Signed-off-by: Jonathan Cameron --- drivers/iio/humidity/hdc2010.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'drivers/iio') diff --git a/drivers/iio/humidity/hdc2010.c b/drivers/iio/humidity/hdc2010.c index d6858ccb056e..c8fddd612e06 100644 --- a/drivers/iio/humidity/hdc2010.c +++ b/drivers/iio/humidity/hdc2010.c @@ -251,8 +251,7 @@ static const struct iio_info hdc2010_info = { .attrs = &hdc2010_attribute_group, }; -static int hdc2010_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int hdc2010_probe(struct i2c_client *client) { struct iio_dev *indio_dev; struct hdc2010_data *data; @@ -339,7 +338,7 @@ static struct i2c_driver hdc2010_driver = { .name = "hdc2010", .of_match_table = hdc2010_dt_ids, }, - .probe = hdc2010_probe, + .probe_new = hdc2010_probe, .remove = hdc2010_remove, .id_table = hdc2010_id, }; -- cgit v1.2.3 From 7b64a83ce6f94bbb91d91a66555f17bf3e9bc085 Mon Sep 17 00:00:00 2001 From: Uwe Kleine-König Date: Fri, 18 Nov 2022 23:37:17 +0100 Subject: iio: humidity: hts221_i2c: Convert to i2c's .probe_new() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The probe function doesn't make use of the i2c_device_id * parameter so it can be trivially converted. Signed-off-by: Uwe Kleine-König Reviewed-by: Andy Shevchenko Link: https://lore.kernel.org/r/20221118224540.619276-104-uwe@kleine-koenig.org Signed-off-by: Jonathan Cameron --- drivers/iio/humidity/hts221_i2c.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'drivers/iio') diff --git a/drivers/iio/humidity/hts221_i2c.c b/drivers/iio/humidity/hts221_i2c.c index afbc611f7712..d81869423cf0 100644 --- a/drivers/iio/humidity/hts221_i2c.c +++ b/drivers/iio/humidity/hts221_i2c.c @@ -25,8 +25,7 @@ static const struct regmap_config hts221_i2c_regmap_config = { .read_flag_mask = HTS221_I2C_AUTO_INCREMENT, }; -static int hts221_i2c_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int hts221_i2c_probe(struct i2c_client *client) { struct regmap *regmap; @@ -66,7 +65,7 @@ static struct i2c_driver hts221_driver = { .of_match_table = hts221_i2c_of_match, .acpi_match_table = ACPI_PTR(hts221_acpi_match), }, - .probe = hts221_i2c_probe, + .probe_new = hts221_i2c_probe, .id_table = hts221_i2c_id_table, }; module_i2c_driver(hts221_driver); -- cgit v1.2.3 From 1a144b6320f32feec3e54dbbda8b4c58b69f86c7 Mon Sep 17 00:00:00 2001 From: Uwe Kleine-König Date: Fri, 18 Nov 2022 23:37:18 +0100 Subject: iio: humidity: htu21: Convert to i2c's .probe_new() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit .probe_new() doesn't get the i2c_device_id * parameter, so determine that explicitly in the probe function. Signed-off-by: Uwe Kleine-König Reviewed-by: Andy Shevchenko Link: https://lore.kernel.org/r/20221118224540.619276-105-uwe@kleine-koenig.org Signed-off-by: Jonathan Cameron --- drivers/iio/humidity/htu21.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers/iio') diff --git a/drivers/iio/humidity/htu21.c b/drivers/iio/humidity/htu21.c index fd9e2565f8a2..8411a9f3e828 100644 --- a/drivers/iio/humidity/htu21.c +++ b/drivers/iio/humidity/htu21.c @@ -177,9 +177,9 @@ static const struct iio_info htu21_info = { .attrs = &htu21_attribute_group, }; -static int htu21_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int htu21_probe(struct i2c_client *client) { + const struct i2c_device_id *id = i2c_client_get_device_id(client); struct ms_ht_dev *dev_data; struct iio_dev *indio_dev; int ret; @@ -244,7 +244,7 @@ static const struct of_device_id htu21_of_match[] = { MODULE_DEVICE_TABLE(of, htu21_of_match); static struct i2c_driver htu21_driver = { - .probe = htu21_probe, + .probe_new = htu21_probe, .id_table = htu21_id, .driver = { .name = "htu21", -- cgit v1.2.3 From e18594f6d87f8f7f2623263eb230139382e1a080 Mon Sep 17 00:00:00 2001 From: Uwe Kleine-König Date: Fri, 18 Nov 2022 23:37:19 +0100 Subject: iio: humidity: si7005: Convert to i2c's .probe_new() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The probe function doesn't make use of the i2c_device_id * parameter so it can be trivially converted. Signed-off-by: Uwe Kleine-König Reviewed-by: Andy Shevchenko Link: https://lore.kernel.org/r/20221118224540.619276-106-uwe@kleine-koenig.org Signed-off-by: Jonathan Cameron --- drivers/iio/humidity/si7005.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'drivers/iio') diff --git a/drivers/iio/humidity/si7005.c b/drivers/iio/humidity/si7005.c index 160b3d92df61..fa1faf168c8d 100644 --- a/drivers/iio/humidity/si7005.c +++ b/drivers/iio/humidity/si7005.c @@ -123,8 +123,7 @@ static const struct iio_info si7005_info = { .read_raw = si7005_read_raw, }; -static int si7005_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int si7005_probe(struct i2c_client *client) { struct iio_dev *indio_dev; struct si7005_data *data; @@ -174,7 +173,7 @@ static struct i2c_driver si7005_driver = { .driver = { .name = "si7005", }, - .probe = si7005_probe, + .probe_new = si7005_probe, .id_table = si7005_id, }; module_i2c_driver(si7005_driver); -- cgit v1.2.3 From e6b610550e2c17b9eb83b10109462fc88f9a6367 Mon Sep 17 00:00:00 2001 From: Uwe Kleine-König Date: Fri, 18 Nov 2022 23:37:20 +0100 Subject: iio: humidity: si7020: Convert to i2c's .probe_new() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The probe function doesn't make use of the i2c_device_id * parameter so it can be trivially converted. Signed-off-by: Uwe Kleine-König Reviewed-by: Andy Shevchenko Link: https://lore.kernel.org/r/20221118224540.619276-107-uwe@kleine-koenig.org Signed-off-by: Jonathan Cameron --- drivers/iio/humidity/si7020.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'drivers/iio') diff --git a/drivers/iio/humidity/si7020.c b/drivers/iio/humidity/si7020.c index ab6537f136ba..3e50592e8e68 100644 --- a/drivers/iio/humidity/si7020.c +++ b/drivers/iio/humidity/si7020.c @@ -103,8 +103,7 @@ static const struct iio_info si7020_info = { .read_raw = si7020_read_raw, }; -static int si7020_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int si7020_probe(struct i2c_client *client) { struct iio_dev *indio_dev; struct i2c_client **data; @@ -156,7 +155,7 @@ static struct i2c_driver si7020_driver = { .name = "si7020", .of_match_table = si7020_dt_ids, }, - .probe = si7020_probe, + .probe_new = si7020_probe, .id_table = si7020_id, }; -- cgit v1.2.3 From 97202c55041806ba3fcddd6ca1b467154b5812cd Mon Sep 17 00:00:00 2001 From: Uwe Kleine-König Date: Fri, 18 Nov 2022 23:37:21 +0100 Subject: iio: imu: bmi160/bmi160_i2c: Convert to i2c's .probe_new() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit .probe_new() doesn't get the i2c_device_id * parameter, so determine that explicitly in the probe function. Signed-off-by: Uwe Kleine-König Reviewed-by: Andy Shevchenko Link: https://lore.kernel.org/r/20221118224540.619276-108-uwe@kleine-koenig.org Signed-off-by: Jonathan Cameron --- drivers/iio/imu/bmi160/bmi160_i2c.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers/iio') 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); -- cgit v1.2.3 From 4fee985aaf3afaa4ce908342a854439fd8480196 Mon Sep 17 00:00:00 2001 From: Uwe Kleine-König Date: Fri, 18 Nov 2022 23:37:22 +0100 Subject: iio: imu: fxos8700_i2c: Convert to i2c's .probe_new() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit .probe_new() doesn't get the i2c_device_id * parameter, so determine that explicitly in the probe function. Signed-off-by: Uwe Kleine-König Reviewed-by: Andy Shevchenko Link: https://lore.kernel.org/r/20221118224540.619276-109-uwe@kleine-koenig.org Signed-off-by: Jonathan Cameron --- drivers/iio/imu/fxos8700_i2c.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers/iio') 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); -- cgit v1.2.3 From 4f218ae01c5c365f78f97e5d5b2c8cb15b503fe3 Mon Sep 17 00:00:00 2001 From: Uwe Kleine-König Date: Fri, 18 Nov 2022 23:37:23 +0100 Subject: iio: imu: inv_mpu6050: Convert to i2c's .probe_new() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit .probe_new() doesn't get the i2c_device_id * parameter, so determine that explicitly in the probe function. Signed-off-by: Uwe Kleine-König Acked-by: Jean-Baptiste Maneyrol Reviewed-by: Andy Shevchenko Link: https://lore.kernel.org/r/20221118224540.619276-110-uwe@kleine-koenig.org Signed-off-by: Jonathan Cameron --- drivers/iio/imu/inv_mpu6050/inv_mpu_i2c.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) (limited to 'drivers/iio') diff --git a/drivers/iio/imu/inv_mpu6050/inv_mpu_i2c.c b/drivers/iio/imu/inv_mpu6050/inv_mpu_i2c.c index 7a8d60a5afa9..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,7 +259,7 @@ 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 = { -- cgit v1.2.3 From 4bf718bc3b7f07f82895d4e56a2af93b9a89f43a Mon Sep 17 00:00:00 2001 From: Uwe Kleine-König Date: Fri, 18 Nov 2022 23:37:24 +0100 Subject: iio: imu: kmx61: Convert to i2c's .probe_new() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit .probe_new() doesn't get the i2c_device_id * parameter, so determine that explicitly in the probe function. Signed-off-by: Uwe Kleine-König Reviewed-by: Andy Shevchenko Link: https://lore.kernel.org/r/20221118224540.619276-111-uwe@kleine-koenig.org Signed-off-by: Jonathan Cameron --- drivers/iio/imu/kmx61.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers/iio') 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, }; -- cgit v1.2.3 From b7dbc0aecb2f4ca38475f0ef9d1b6ab6137be599 Mon Sep 17 00:00:00 2001 From: Uwe Kleine-König Date: Fri, 18 Nov 2022 23:37:25 +0100 Subject: iio: imu: st_lsm6dsx: Convert to i2c's .probe_new() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit .probe_new() doesn't get the i2c_device_id * parameter, so determine that explicitly in the probe function. Signed-off-by: Uwe Kleine-König Reviewed-by: Andy Shevchenko Link: https://lore.kernel.org/r/20221118224540.619276-112-uwe@kleine-koenig.org Signed-off-by: Jonathan Cameron --- drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_i2c.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers/iio') diff --git a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_i2c.c b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_i2c.c index 0faf1b4c11af..3570fac1b612 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; @@ -152,7 +152,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); -- cgit v1.2.3 From 39c7d963d54a4dee2c6d95a4c5461600b26ca295 Mon Sep 17 00:00:00 2001 From: Uwe Kleine-König Date: Fri, 18 Nov 2022 23:37:26 +0100 Subject: iio: light: adjd_s311: Convert to i2c's .probe_new() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The probe function doesn't make use of the i2c_device_id * parameter so it can be trivially converted. Signed-off-by: Uwe Kleine-König Reviewed-by: Andy Shevchenko Link: https://lore.kernel.org/r/20221118224540.619276-113-uwe@kleine-koenig.org Signed-off-by: Jonathan Cameron --- drivers/iio/light/adjd_s311.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'drivers/iio') diff --git a/drivers/iio/light/adjd_s311.c b/drivers/iio/light/adjd_s311.c index 6b33975c8d73..210a90f44c53 100644 --- a/drivers/iio/light/adjd_s311.c +++ b/drivers/iio/light/adjd_s311.c @@ -233,8 +233,7 @@ static const struct iio_info adjd_s311_info = { .write_raw = adjd_s311_write_raw, }; -static int adjd_s311_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int adjd_s311_probe(struct i2c_client *client) { struct adjd_s311_data *data; struct iio_dev *indio_dev; @@ -271,7 +270,7 @@ static struct i2c_driver adjd_s311_driver = { .driver = { .name = ADJD_S311_DRV_NAME, }, - .probe = adjd_s311_probe, + .probe_new = adjd_s311_probe, .id_table = adjd_s311_id, }; module_i2c_driver(adjd_s311_driver); -- cgit v1.2.3 From fd63b0a46acf4b00ff69e6c60ecdd3c78a68fc71 Mon Sep 17 00:00:00 2001 From: Uwe Kleine-König Date: Fri, 18 Nov 2022 23:37:27 +0100 Subject: iio: light: adux1020: Convert to i2c's .probe_new() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The probe function doesn't make use of the i2c_device_id * parameter so it can be trivially converted. Signed-off-by: Uwe Kleine-König Reviewed-by: Andy Shevchenko Link: https://lore.kernel.org/r/20221118224540.619276-114-uwe@kleine-koenig.org Signed-off-by: Jonathan Cameron --- drivers/iio/light/adux1020.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'drivers/iio') diff --git a/drivers/iio/light/adux1020.c b/drivers/iio/light/adux1020.c index 9aa28695e6f1..606075350d01 100644 --- a/drivers/iio/light/adux1020.c +++ b/drivers/iio/light/adux1020.c @@ -774,8 +774,7 @@ static int adux1020_chip_init(struct adux1020_data *data) ADUX1020_MODE_INT_MASK, ADUX1020_MODE_INT_DISABLE); } -static int adux1020_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int adux1020_probe(struct i2c_client *client) { struct adux1020_data *data; struct iio_dev *indio_dev; @@ -838,7 +837,7 @@ static struct i2c_driver adux1020_driver = { .name = ADUX1020_DRV_NAME, .of_match_table = adux1020_of_match, }, - .probe = adux1020_probe, + .probe_new = adux1020_probe, .id_table = adux1020_id, }; module_i2c_driver(adux1020_driver); -- cgit v1.2.3 From ad428de325d27964f1c471ae496232df89b22885 Mon Sep 17 00:00:00 2001 From: Uwe Kleine-König Date: Fri, 18 Nov 2022 23:37:28 +0100 Subject: iio: light: al3010: Convert to i2c's .probe_new() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The probe function doesn't make use of the i2c_device_id * parameter so it can be trivially converted. Signed-off-by: Uwe Kleine-König Reviewed-by: David Heidelberg Reviewed-by: Andy Shevchenko Link: https://lore.kernel.org/r/20221118224540.619276-115-uwe@kleine-koenig.org Signed-off-by: Jonathan Cameron --- drivers/iio/light/al3010.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'drivers/iio') diff --git a/drivers/iio/light/al3010.c b/drivers/iio/light/al3010.c index ce5363845b22..69cc723e2ac4 100644 --- a/drivers/iio/light/al3010.c +++ b/drivers/iio/light/al3010.c @@ -164,8 +164,7 @@ static const struct iio_info al3010_info = { .attrs = &al3010_attribute_group, }; -static int al3010_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int al3010_probe(struct i2c_client *client) { struct al3010_data *data; struct iio_dev *indio_dev; @@ -230,7 +229,7 @@ static struct i2c_driver al3010_driver = { .of_match_table = al3010_of_match, .pm = pm_sleep_ptr(&al3010_pm_ops), }, - .probe = al3010_probe, + .probe_new = al3010_probe, .id_table = al3010_id, }; module_i2c_driver(al3010_driver); -- cgit v1.2.3 From a76c90301f86107240eebb404d9881f16344f779 Mon Sep 17 00:00:00 2001 From: Uwe Kleine-König Date: Fri, 18 Nov 2022 23:37:29 +0100 Subject: iio: light: al3320a: Convert to i2c's .probe_new() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The probe function doesn't make use of the i2c_device_id * parameter so it can be trivially converted. Signed-off-by: Uwe Kleine-König Reviewed-by: Andy Shevchenko Link: https://lore.kernel.org/r/20221118224540.619276-116-uwe@kleine-koenig.org Signed-off-by: Jonathan Cameron --- drivers/iio/light/al3320a.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'drivers/iio') diff --git a/drivers/iio/light/al3320a.c b/drivers/iio/light/al3320a.c index bc99179728ed..9ff28bbf34bb 100644 --- a/drivers/iio/light/al3320a.c +++ b/drivers/iio/light/al3320a.c @@ -187,8 +187,7 @@ static const struct iio_info al3320a_info = { .attrs = &al3320a_attribute_group, }; -static int al3320a_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int al3320a_probe(struct i2c_client *client) { struct al3320a_data *data; struct iio_dev *indio_dev; @@ -254,7 +253,7 @@ static struct i2c_driver al3320a_driver = { .of_match_table = al3320a_of_match, .pm = pm_sleep_ptr(&al3320a_pm_ops), }, - .probe = al3320a_probe, + .probe_new = al3320a_probe, .id_table = al3320a_id, }; -- cgit v1.2.3 From debe8c7568242ae7e49803c6bffc56362e43bfd0 Mon Sep 17 00:00:00 2001 From: Uwe Kleine-König Date: Fri, 18 Nov 2022 23:37:30 +0100 Subject: iio: light: apds9300: Convert to i2c's .probe_new() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The probe function doesn't make use of the i2c_device_id * parameter so it can be trivially converted. Signed-off-by: Uwe Kleine-König Reviewed-by: Andy Shevchenko Link: https://lore.kernel.org/r/20221118224540.619276-117-uwe@kleine-koenig.org Signed-off-by: Jonathan Cameron --- drivers/iio/light/apds9300.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'drivers/iio') diff --git a/drivers/iio/light/apds9300.c b/drivers/iio/light/apds9300.c index b70f2681bcb3..15dfb753734f 100644 --- a/drivers/iio/light/apds9300.c +++ b/drivers/iio/light/apds9300.c @@ -398,8 +398,7 @@ static irqreturn_t apds9300_interrupt_handler(int irq, void *private) return IRQ_HANDLED; } -static int apds9300_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int apds9300_probe(struct i2c_client *client) { struct apds9300_data *data; struct iio_dev *indio_dev; @@ -505,7 +504,7 @@ static struct i2c_driver apds9300_driver = { .name = APDS9300_DRV_NAME, .pm = pm_sleep_ptr(&apds9300_pm_ops), }, - .probe = apds9300_probe, + .probe_new = apds9300_probe, .remove = apds9300_remove, .id_table = apds9300_id, }; -- cgit v1.2.3 From 783964ae9752541356e40f47b677069151543c80 Mon Sep 17 00:00:00 2001 From: Uwe Kleine-König Date: Fri, 18 Nov 2022 23:37:31 +0100 Subject: iio: light: apds9960: Convert to i2c's .probe_new() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The probe function doesn't make use of the i2c_device_id * parameter so it can be trivially converted. Signed-off-by: Uwe Kleine-König Acked-by: Matt Ranostay Reviewed-by: Andy Shevchenko Link: https://lore.kernel.org/r/20221118224540.619276-118-uwe@kleine-koenig.org Signed-off-by: Jonathan Cameron --- drivers/iio/light/apds9960.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'drivers/iio') diff --git a/drivers/iio/light/apds9960.c b/drivers/iio/light/apds9960.c index 997aa01ecc11..ee6acc6a36ee 100644 --- a/drivers/iio/light/apds9960.c +++ b/drivers/iio/light/apds9960.c @@ -988,8 +988,7 @@ static int apds9960_chip_init(struct apds9960_data *data) return apds9960_set_powermode(data, 1); } -static int apds9960_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int apds9960_probe(struct i2c_client *client) { struct apds9960_data *data; struct iio_dev *indio_dev; @@ -1132,7 +1131,7 @@ static struct i2c_driver apds9960_driver = { .pm = &apds9960_pm_ops, .acpi_match_table = apds9960_acpi_match, }, - .probe = apds9960_probe, + .probe_new = apds9960_probe, .remove = apds9960_remove, .id_table = apds9960_id, }; -- cgit v1.2.3 From 058d6333ea4fe069cce36adb12d6a6341ddcb540 Mon Sep 17 00:00:00 2001 From: Uwe Kleine-König Date: Fri, 18 Nov 2022 23:37:32 +0100 Subject: iio: light: bh1750: Convert to i2c's .probe_new() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit .probe_new() doesn't get the i2c_device_id * parameter, so determine that explicitly in the probe function. Signed-off-by: Uwe Kleine-König Reviewed-by: Andy Shevchenko Link: https://lore.kernel.org/r/20221118224540.619276-119-uwe@kleine-koenig.org Signed-off-by: Jonathan Cameron --- drivers/iio/light/bh1750.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers/iio') diff --git a/drivers/iio/light/bh1750.c b/drivers/iio/light/bh1750.c index 3e92820bc820..390c5b3ad4f6 100644 --- a/drivers/iio/light/bh1750.c +++ b/drivers/iio/light/bh1750.c @@ -228,9 +228,9 @@ static const struct iio_chan_spec bh1750_channels[] = { } }; -static int bh1750_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int bh1750_probe(struct i2c_client *client) { + const struct i2c_device_id *id = i2c_client_get_device_id(client); int ret, usec; struct bh1750_data *data; struct iio_dev *indio_dev; @@ -320,7 +320,7 @@ static struct i2c_driver bh1750_driver = { .of_match_table = bh1750_of_match, .pm = pm_sleep_ptr(&bh1750_pm_ops), }, - .probe = bh1750_probe, + .probe_new = bh1750_probe, .remove = bh1750_remove, .id_table = bh1750_id, -- cgit v1.2.3 From ed5c6b1ce4e1d412f9a97973348c7b8f3e12025a Mon Sep 17 00:00:00 2001 From: Uwe Kleine-König Date: Fri, 18 Nov 2022 23:37:33 +0100 Subject: iio: light: bh1780: Convert to i2c's .probe_new() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The probe function doesn't make use of the i2c_device_id * parameter so it can be trivially converted. Signed-off-by: Uwe Kleine-König Reviewed-by: Andy Shevchenko Link: https://lore.kernel.org/r/20221118224540.619276-120-uwe@kleine-koenig.org Signed-off-by: Jonathan Cameron --- drivers/iio/light/bh1780.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'drivers/iio') diff --git a/drivers/iio/light/bh1780.c b/drivers/iio/light/bh1780.c index 90bca392b262..da9039e5a839 100644 --- a/drivers/iio/light/bh1780.c +++ b/drivers/iio/light/bh1780.c @@ -141,8 +141,7 @@ static const struct iio_chan_spec bh1780_channels[] = { } }; -static int bh1780_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int bh1780_probe(struct i2c_client *client) { int ret; struct bh1780_data *bh1780; @@ -270,7 +269,7 @@ static const struct of_device_id of_bh1780_match[] = { MODULE_DEVICE_TABLE(of, of_bh1780_match); static struct i2c_driver bh1780_driver = { - .probe = bh1780_probe, + .probe_new = bh1780_probe, .remove = bh1780_remove, .id_table = bh1780_id, .driver = { -- cgit v1.2.3 From f8232aad7609a946d4bbb76b747cb9d73b8180f3 Mon Sep 17 00:00:00 2001 From: Uwe Kleine-König Date: Fri, 18 Nov 2022 23:37:34 +0100 Subject: iio: light: cm3232: Convert to i2c's .probe_new() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit .probe_new() doesn't get the i2c_device_id * parameter, so determine that explicitly in the probe function. Signed-off-by: Uwe Kleine-König Reviewed-by: Andy Shevchenko Link: https://lore.kernel.org/r/20221118224540.619276-121-uwe@kleine-koenig.org Signed-off-by: Jonathan Cameron --- drivers/iio/light/cm3232.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers/iio') diff --git a/drivers/iio/light/cm3232.c b/drivers/iio/light/cm3232.c index 5214cd014cf8..43e492f5051d 100644 --- a/drivers/iio/light/cm3232.c +++ b/drivers/iio/light/cm3232.c @@ -325,9 +325,9 @@ static const struct iio_info cm3232_info = { .attrs = &cm3232_attribute_group, }; -static int cm3232_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int cm3232_probe(struct i2c_client *client) { + const struct i2c_device_id *id = i2c_client_get_device_id(client); struct cm3232_chip *chip; struct iio_dev *indio_dev; int ret; @@ -417,7 +417,7 @@ static struct i2c_driver cm3232_driver = { .pm = pm_sleep_ptr(&cm3232_pm_ops), }, .id_table = cm3232_id, - .probe = cm3232_probe, + .probe_new = cm3232_probe, .remove = cm3232_remove, }; -- cgit v1.2.3 From ebbcdb1a9ddec05b37347d3fbf537e1741876901 Mon Sep 17 00:00:00 2001 From: Uwe Kleine-König Date: Fri, 18 Nov 2022 23:37:35 +0100 Subject: iio: light: cm3323: Convert to i2c's .probe_new() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The probe function doesn't make use of the i2c_device_id * parameter so it can be trivially converted. Signed-off-by: Uwe Kleine-König Reviewed-by: Andy Shevchenko Link: https://lore.kernel.org/r/20221118224540.619276-122-uwe@kleine-koenig.org Signed-off-by: Jonathan Cameron --- drivers/iio/light/cm3323.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'drivers/iio') diff --git a/drivers/iio/light/cm3323.c b/drivers/iio/light/cm3323.c index fd9a8c27de2e..e5ce7d0fd272 100644 --- a/drivers/iio/light/cm3323.c +++ b/drivers/iio/light/cm3323.c @@ -214,8 +214,7 @@ static const struct iio_info cm3323_info = { .attrs = &cm3323_attribute_group, }; -static int cm3323_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int cm3323_probe(struct i2c_client *client) { struct cm3323_data *data; struct iio_dev *indio_dev; @@ -267,7 +266,7 @@ static struct i2c_driver cm3323_driver = { .name = CM3323_DRV_NAME, .of_match_table = cm3323_of_match, }, - .probe = cm3323_probe, + .probe_new = cm3323_probe, .id_table = cm3323_id, }; -- cgit v1.2.3 From 31ceb2f5b4fbd7dd46d7d679b990e9195f1b3db6 Mon Sep 17 00:00:00 2001 From: Uwe Kleine-König Date: Fri, 18 Nov 2022 23:37:36 +0100 Subject: iio: light: cm36651: Convert to i2c's .probe_new() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit .probe_new() doesn't get the i2c_device_id * parameter, so determine that explicitly in the probe function. Signed-off-by: Uwe Kleine-König Reviewed-by: Andy Shevchenko Link: https://lore.kernel.org/r/20221118224540.619276-123-uwe@kleine-koenig.org Signed-off-by: Jonathan Cameron --- drivers/iio/light/cm36651.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers/iio') diff --git a/drivers/iio/light/cm36651.c b/drivers/iio/light/cm36651.c index 6615c98b601c..1707dbf2ce26 100644 --- a/drivers/iio/light/cm36651.c +++ b/drivers/iio/light/cm36651.c @@ -618,9 +618,9 @@ static const struct iio_info cm36651_info = { .attrs = &cm36651_attribute_group, }; -static int cm36651_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int cm36651_probe(struct i2c_client *client) { + const struct i2c_device_id *id = i2c_client_get_device_id(client); struct cm36651_data *cm36651; struct iio_dev *indio_dev; int ret; @@ -730,7 +730,7 @@ static struct i2c_driver cm36651_driver = { .name = "cm36651", .of_match_table = cm36651_of_match, }, - .probe = cm36651_probe, + .probe_new = cm36651_probe, .remove = cm36651_remove, .id_table = cm36651_id, }; -- cgit v1.2.3 From b3f8e22e737e7991a3754675c7418215cdb461b9 Mon Sep 17 00:00:00 2001 From: Uwe Kleine-König Date: Fri, 18 Nov 2022 23:37:37 +0100 Subject: iio: light: gp2ap002: Convert to i2c's .probe_new() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The probe function doesn't make use of the i2c_device_id * parameter so it can be trivially converted. Signed-off-by: Uwe Kleine-König Reviewed-by: Andy Shevchenko Link: https://lore.kernel.org/r/20221118224540.619276-124-uwe@kleine-koenig.org Signed-off-by: Jonathan Cameron --- drivers/iio/light/gp2ap002.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'drivers/iio') diff --git a/drivers/iio/light/gp2ap002.c b/drivers/iio/light/gp2ap002.c index 8000fa347344..c0430db0038a 100644 --- a/drivers/iio/light/gp2ap002.c +++ b/drivers/iio/light/gp2ap002.c @@ -425,8 +425,7 @@ static struct regmap_bus gp2ap002_regmap_bus = { .reg_write = gp2ap002_regmap_i2c_write, }; -static int gp2ap002_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int gp2ap002_probe(struct i2c_client *client) { struct gp2ap002 *gp2ap002; struct iio_dev *indio_dev; @@ -711,7 +710,7 @@ static struct i2c_driver gp2ap002_driver = { .of_match_table = gp2ap002_of_match, .pm = pm_ptr(&gp2ap002_dev_pm_ops), }, - .probe = gp2ap002_probe, + .probe_new = gp2ap002_probe, .remove = gp2ap002_remove, .id_table = gp2ap002_id_table, }; -- cgit v1.2.3 From a969195001bcf0d8baa5363fc8a1b4d3fc5aff0f Mon Sep 17 00:00:00 2001 From: Uwe Kleine-König Date: Fri, 18 Nov 2022 23:37:38 +0100 Subject: iio: light: gp2ap020a00f: Convert to i2c's .probe_new() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit .probe_new() doesn't get the i2c_device_id * parameter, so determine that explicitly in the probe function. Signed-off-by: Uwe Kleine-König Reviewed-by: Andy Shevchenko Link: https://lore.kernel.org/r/20221118224540.619276-125-uwe@kleine-koenig.org Signed-off-by: Jonathan Cameron --- drivers/iio/light/gp2ap020a00f.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers/iio') diff --git a/drivers/iio/light/gp2ap020a00f.c b/drivers/iio/light/gp2ap020a00f.c index 826439299e8b..a5bf9da0d2f3 100644 --- a/drivers/iio/light/gp2ap020a00f.c +++ b/drivers/iio/light/gp2ap020a00f.c @@ -1467,9 +1467,9 @@ static const struct iio_buffer_setup_ops gp2ap020a00f_buffer_setup_ops = { .predisable = &gp2ap020a00f_buffer_predisable, }; -static int gp2ap020a00f_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int gp2ap020a00f_probe(struct i2c_client *client) { + const struct i2c_device_id *id = i2c_client_get_device_id(client); struct gp2ap020a00f_data *data; struct iio_dev *indio_dev; struct regmap *regmap; @@ -1609,7 +1609,7 @@ static struct i2c_driver gp2ap020a00f_driver = { .name = GP2A_I2C_NAME, .of_match_table = gp2ap020a00f_of_match, }, - .probe = gp2ap020a00f_probe, + .probe_new = gp2ap020a00f_probe, .remove = gp2ap020a00f_remove, .id_table = gp2ap020a00f_id, }; -- cgit v1.2.3 From ee6e0241f854b23f2177b05a6cdd538bcfe8d9cb Mon Sep 17 00:00:00 2001 From: Uwe Kleine-König Date: Fri, 18 Nov 2022 23:37:39 +0100 Subject: iio: light: isl29018: Convert to i2c's .probe_new() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit .probe_new() doesn't get the i2c_device_id * parameter, so determine that explicitly in the probe function. Signed-off-by: Uwe Kleine-König Reviewed-by: Andy Shevchenko Link: https://lore.kernel.org/r/20221118224540.619276-126-uwe@kleine-koenig.org Signed-off-by: Jonathan Cameron --- drivers/iio/light/isl29018.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers/iio') diff --git a/drivers/iio/light/isl29018.c b/drivers/iio/light/isl29018.c index b36f8b7ca68e..141845fb47f9 100644 --- a/drivers/iio/light/isl29018.c +++ b/drivers/iio/light/isl29018.c @@ -711,9 +711,9 @@ static void isl29018_disable_regulator_action(void *_data) pr_err("failed to disable isl29018's VCC regulator!\n"); } -static int isl29018_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int isl29018_probe(struct i2c_client *client) { + const struct i2c_device_id *id = i2c_client_get_device_id(client); struct isl29018_chip *chip; struct iio_dev *indio_dev; int err; @@ -865,7 +865,7 @@ static struct i2c_driver isl29018_driver = { .pm = pm_sleep_ptr(&isl29018_pm_ops), .of_match_table = isl29018_of_match, }, - .probe = isl29018_probe, + .probe_new = isl29018_probe, .id_table = isl29018_id, }; module_i2c_driver(isl29018_driver); -- cgit v1.2.3 From 2086bafffdf7200238ba887a4ac9bdba0c4503e4 Mon Sep 17 00:00:00 2001 From: Uwe Kleine-König Date: Fri, 18 Nov 2022 23:37:40 +0100 Subject: iio: light: isl29028: Convert to i2c's .probe_new() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit .probe_new() doesn't get the i2c_device_id * parameter, so determine that explicitly in the probe function. Signed-off-by: Uwe Kleine-König Reviewed-by: Andy Shevchenko Link: https://lore.kernel.org/r/20221118224540.619276-127-uwe@kleine-koenig.org Signed-off-by: Jonathan Cameron --- drivers/iio/light/isl29028.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers/iio') diff --git a/drivers/iio/light/isl29028.c b/drivers/iio/light/isl29028.c index 32d58e18f26d..bcf3a556e41a 100644 --- a/drivers/iio/light/isl29028.c +++ b/drivers/iio/light/isl29028.c @@ -565,9 +565,9 @@ static const struct regmap_config isl29028_regmap_config = { .cache_type = REGCACHE_RBTREE, }; -static int isl29028_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int isl29028_probe(struct i2c_client *client) { + const struct i2c_device_id *id = i2c_client_get_device_id(client); struct isl29028_chip *chip; struct iio_dev *indio_dev; int ret; @@ -698,7 +698,7 @@ static struct i2c_driver isl29028_driver = { .pm = pm_ptr(&isl29028_pm_ops), .of_match_table = isl29028_of_match, }, - .probe = isl29028_probe, + .probe_new = isl29028_probe, .remove = isl29028_remove, .id_table = isl29028_id, }; -- cgit v1.2.3 From 3059126a449c8c62c6b766da7744f853cce6ad36 Mon Sep 17 00:00:00 2001 From: Uwe Kleine-König Date: Fri, 18 Nov 2022 23:37:41 +0100 Subject: iio: light: isl29125: Convert to i2c's .probe_new() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The probe function doesn't make use of the i2c_device_id * parameter so it can be trivially converted. Signed-off-by: Uwe Kleine-König Reviewed-by: Andy Shevchenko Link: https://lore.kernel.org/r/20221118224540.619276-128-uwe@kleine-koenig.org Signed-off-by: Jonathan Cameron --- drivers/iio/light/isl29125.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'drivers/iio') diff --git a/drivers/iio/light/isl29125.c b/drivers/iio/light/isl29125.c index c199e63cce82..b4bd656ca169 100644 --- a/drivers/iio/light/isl29125.c +++ b/drivers/iio/light/isl29125.c @@ -241,8 +241,7 @@ static const struct iio_buffer_setup_ops isl29125_buffer_setup_ops = { .predisable = isl29125_buffer_predisable, }; -static int isl29125_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int isl29125_probe(struct i2c_client *client) { struct isl29125_data *data; struct iio_dev *indio_dev; @@ -338,7 +337,7 @@ static struct i2c_driver isl29125_driver = { .name = ISL29125_DRV_NAME, .pm = pm_sleep_ptr(&isl29125_pm_ops), }, - .probe = isl29125_probe, + .probe_new = isl29125_probe, .remove = isl29125_remove, .id_table = isl29125_id, }; -- cgit v1.2.3 From dd97aab4f02c72d053335424752ee648a572ff81 Mon Sep 17 00:00:00 2001 From: Uwe Kleine-König Date: Fri, 18 Nov 2022 23:37:42 +0100 Subject: iio: light: jsa1212: Convert to i2c's .probe_new() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The probe function doesn't make use of the i2c_device_id * parameter so it can be trivially converted. Signed-off-by: Uwe Kleine-König Reviewed-by: Andy Shevchenko Link: https://lore.kernel.org/r/20221118224540.619276-129-uwe@kleine-koenig.org Signed-off-by: Jonathan Cameron --- drivers/iio/light/jsa1212.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'drivers/iio') diff --git a/drivers/iio/light/jsa1212.c b/drivers/iio/light/jsa1212.c index 57ce6d75966c..d3834d0a0635 100644 --- a/drivers/iio/light/jsa1212.c +++ b/drivers/iio/light/jsa1212.c @@ -308,8 +308,7 @@ static const struct regmap_config jsa1212_regmap_config = { .volatile_reg = jsa1212_is_volatile_reg, }; -static int jsa1212_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int jsa1212_probe(struct i2c_client *client) { struct jsa1212_data *data; struct iio_dev *indio_dev; @@ -441,7 +440,7 @@ static struct i2c_driver jsa1212_driver = { .pm = pm_sleep_ptr(&jsa1212_pm_ops), .acpi_match_table = ACPI_PTR(jsa1212_acpi_match), }, - .probe = jsa1212_probe, + .probe_new = jsa1212_probe, .remove = jsa1212_remove, .id_table = jsa1212_id, }; -- cgit v1.2.3 From 958f5a0de0f67289e6bc0fa7850056b2af0c14f2 Mon Sep 17 00:00:00 2001 From: Uwe Kleine-König Date: Fri, 18 Nov 2022 23:37:43 +0100 Subject: iio: light: ltr501: Convert to i2c's .probe_new() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit .probe_new() doesn't get the i2c_device_id * parameter, so determine that explicitly in the probe function. Signed-off-by: Uwe Kleine-König Reviewed-by: Andy Shevchenko Link: https://lore.kernel.org/r/20221118224540.619276-130-uwe@kleine-koenig.org Signed-off-by: Jonathan Cameron --- drivers/iio/light/ltr501.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers/iio') diff --git a/drivers/iio/light/ltr501.c b/drivers/iio/light/ltr501.c index 453b845ef265..bdbd918213e4 100644 --- a/drivers/iio/light/ltr501.c +++ b/drivers/iio/light/ltr501.c @@ -1432,9 +1432,9 @@ static const char *ltr501_match_acpi_device(struct device *dev, int *chip_idx) return dev_name(dev); } -static int ltr501_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int ltr501_probe(struct i2c_client *client) { + const struct i2c_device_id *id = i2c_client_get_device_id(client); static const char * const regulator_names[] = { "vdd", "vddio" }; struct ltr501_data *data; struct iio_dev *indio_dev; @@ -1641,7 +1641,7 @@ static struct i2c_driver ltr501_driver = { .pm = pm_sleep_ptr(<r501_pm_ops), .acpi_match_table = ACPI_PTR(ltr_acpi_match), }, - .probe = ltr501_probe, + .probe_new = ltr501_probe, .remove = ltr501_remove, .id_table = ltr501_id, }; -- cgit v1.2.3 From f0a6f7674ef29e01e8db2986f534476f60aac3cf Mon Sep 17 00:00:00 2001 From: Uwe Kleine-König Date: Fri, 18 Nov 2022 23:37:44 +0100 Subject: iio: light: lv0104cs: Convert to i2c's .probe_new() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The probe function doesn't make use of the i2c_device_id * parameter so it can be trivially converted. Signed-off-by: Uwe Kleine-König Reviewed-by: Andy Shevchenko Link: https://lore.kernel.org/r/20221118224540.619276-131-uwe@kleine-koenig.org Signed-off-by: Jonathan Cameron --- drivers/iio/light/lv0104cs.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'drivers/iio') diff --git a/drivers/iio/light/lv0104cs.c b/drivers/iio/light/lv0104cs.c index c2aef88f4e63..c041fa0faa5d 100644 --- a/drivers/iio/light/lv0104cs.c +++ b/drivers/iio/light/lv0104cs.c @@ -474,8 +474,7 @@ static const struct iio_chan_spec lv0104cs_channels[] = { }, }; -static int lv0104cs_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int lv0104cs_probe(struct i2c_client *client) { struct iio_dev *indio_dev; struct lv0104cs_private *lv0104cs; @@ -521,7 +520,7 @@ static struct i2c_driver lv0104cs_i2c_driver = { .name = "lv0104cs", }, .id_table = lv0104cs_id, - .probe = lv0104cs_probe, + .probe_new = lv0104cs_probe, }; module_i2c_driver(lv0104cs_i2c_driver); -- cgit v1.2.3 From 0978ef36b24cb10937417e94d49d5a3f1092e3d4 Mon Sep 17 00:00:00 2001 From: Uwe Kleine-König Date: Fri, 18 Nov 2022 23:37:45 +0100 Subject: iio: light: max44000: Convert to i2c's .probe_new() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The probe function doesn't make use of the i2c_device_id * parameter so it can be trivially converted. Signed-off-by: Uwe Kleine-König Reviewed-by: Andy Shevchenko Link: https://lore.kernel.org/r/20221118224540.619276-132-uwe@kleine-koenig.org Signed-off-by: Jonathan Cameron --- drivers/iio/light/max44000.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'drivers/iio') diff --git a/drivers/iio/light/max44000.c b/drivers/iio/light/max44000.c index 85689dffbcbf..5dcabc43a30e 100644 --- a/drivers/iio/light/max44000.c +++ b/drivers/iio/light/max44000.c @@ -523,8 +523,7 @@ out_unlock: return IRQ_HANDLED; } -static int max44000_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int max44000_probe(struct i2c_client *client) { struct max44000_data *data; struct iio_dev *indio_dev; @@ -617,7 +616,7 @@ static struct i2c_driver max44000_driver = { .name = MAX44000_DRV_NAME, .acpi_match_table = ACPI_PTR(max44000_acpi_match), }, - .probe = max44000_probe, + .probe_new = max44000_probe, .id_table = max44000_id, }; -- cgit v1.2.3 From c49135d99f5285a3e781a50ee7111f68150d5cd2 Mon Sep 17 00:00:00 2001 From: Uwe Kleine-König Date: Fri, 18 Nov 2022 23:37:47 +0100 Subject: iio: light: noa1305: Convert to i2c's .probe_new() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The probe function doesn't make use of the i2c_device_id * parameter so it can be trivially converted. Signed-off-by: Uwe Kleine-König Reviewed-by: Andy Shevchenko Link: https://lore.kernel.org/r/20221118224540.619276-134-uwe@kleine-koenig.org Signed-off-by: Jonathan Cameron --- drivers/iio/light/noa1305.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'drivers/iio') diff --git a/drivers/iio/light/noa1305.c b/drivers/iio/light/noa1305.c index be3536b390fc..eaf548d4649e 100644 --- a/drivers/iio/light/noa1305.c +++ b/drivers/iio/light/noa1305.c @@ -186,8 +186,7 @@ static const struct regmap_config noa1305_regmap_config = { .writeable_reg = noa1305_writable_reg, }; -static int noa1305_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int noa1305_probe(struct i2c_client *client) { struct noa1305_priv *priv; struct iio_dev *indio_dev; @@ -279,7 +278,7 @@ static struct i2c_driver noa1305_driver = { .name = NOA1305_DRIVER_NAME, .of_match_table = noa1305_of_match, }, - .probe = noa1305_probe, + .probe_new = noa1305_probe, .id_table = noa1305_ids, }; -- cgit v1.2.3 From 06d10073283e5b301bd850a9ded6f592fb74a803 Mon Sep 17 00:00:00 2001 From: Uwe Kleine-König Date: Fri, 18 Nov 2022 23:37:48 +0100 Subject: iio: light: opt3001: Convert to i2c's .probe_new() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The probe function doesn't make use of the i2c_device_id * parameter so it can be trivially converted. Signed-off-by: Uwe Kleine-König Reviewed-by: Andy Shevchenko Link: https://lore.kernel.org/r/20221118224540.619276-135-uwe@kleine-koenig.org Signed-off-by: Jonathan Cameron --- drivers/iio/light/opt3001.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'drivers/iio') diff --git a/drivers/iio/light/opt3001.c b/drivers/iio/light/opt3001.c index a26d1c3f9543..ec4f5c2369c4 100644 --- a/drivers/iio/light/opt3001.c +++ b/drivers/iio/light/opt3001.c @@ -735,8 +735,7 @@ out: return IRQ_HANDLED; } -static int opt3001_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int opt3001_probe(struct i2c_client *client) { struct device *dev = &client->dev; @@ -835,7 +834,7 @@ static const struct of_device_id opt3001_of_match[] = { MODULE_DEVICE_TABLE(of, opt3001_of_match); static struct i2c_driver opt3001_driver = { - .probe = opt3001_probe, + .probe_new = opt3001_probe, .remove = opt3001_remove, .id_table = opt3001_id, -- cgit v1.2.3 From e16302076d8a42b760878fe603593e2c59106948 Mon Sep 17 00:00:00 2001 From: Uwe Kleine-König Date: Fri, 18 Nov 2022 23:37:49 +0100 Subject: iio: light: pa12203001: Convert to i2c's .probe_new() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The probe function doesn't make use of the i2c_device_id * parameter so it can be trivially converted. Signed-off-by: Uwe Kleine-König Reviewed-by: Andy Shevchenko Link: https://lore.kernel.org/r/20221118224540.619276-136-uwe@kleine-koenig.org Signed-off-by: Jonathan Cameron --- drivers/iio/light/pa12203001.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'drivers/iio') diff --git a/drivers/iio/light/pa12203001.c b/drivers/iio/light/pa12203001.c index 3cb2de51f4aa..15a666f15c27 100644 --- a/drivers/iio/light/pa12203001.c +++ b/drivers/iio/light/pa12203001.c @@ -338,8 +338,7 @@ out: return ret; } -static int pa12203001_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int pa12203001_probe(struct i2c_client *client) { struct pa12203001_data *data; struct iio_dev *indio_dev; @@ -475,7 +474,7 @@ static struct i2c_driver pa12203001_driver = { .pm = &pa12203001_pm_ops, .acpi_match_table = ACPI_PTR(pa12203001_acpi_match), }, - .probe = pa12203001_probe, + .probe_new = pa12203001_probe, .remove = pa12203001_remove, .id_table = pa12203001_id, -- cgit v1.2.3 From 314ba3b4208b8fdc66ca6a94dac778ab673444e2 Mon Sep 17 00:00:00 2001 From: Uwe Kleine-König Date: Fri, 18 Nov 2022 23:37:50 +0100 Subject: iio: light: rpr0521: Convert to i2c's .probe_new() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The probe function doesn't make use of the i2c_device_id * parameter so it can be trivially converted. Signed-off-by: Uwe Kleine-König Reviewed-by: Andy Shevchenko Link: https://lore.kernel.org/r/20221118224540.619276-137-uwe@kleine-koenig.org Signed-off-by: Jonathan Cameron --- drivers/iio/light/rpr0521.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'drivers/iio') diff --git a/drivers/iio/light/rpr0521.c b/drivers/iio/light/rpr0521.c index d1c16dd76058..668e444f6049 100644 --- a/drivers/iio/light/rpr0521.c +++ b/drivers/iio/light/rpr0521.c @@ -927,8 +927,7 @@ static const struct regmap_config rpr0521_regmap_config = { .volatile_reg = rpr0521_is_volatile_reg, }; -static int rpr0521_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int rpr0521_probe(struct i2c_client *client) { struct rpr0521_data *data; struct iio_dev *indio_dev; @@ -1122,7 +1121,7 @@ static struct i2c_driver rpr0521_driver = { .pm = pm_ptr(&rpr0521_pm_ops), .acpi_match_table = ACPI_PTR(rpr0521_acpi_match), }, - .probe = rpr0521_probe, + .probe_new = rpr0521_probe, .remove = rpr0521_remove, .id_table = rpr0521_id, }; -- cgit v1.2.3 From 122b0c0ba505a2faebb883bbfc178449d47c4fba Mon Sep 17 00:00:00 2001 From: Uwe Kleine-König Date: Fri, 18 Nov 2022 23:37:51 +0100 Subject: iio: light: si1133: Convert to i2c's .probe_new() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit .probe_new() doesn't get the i2c_device_id * parameter, so determine that explicitly in the probe function. Signed-off-by: Uwe Kleine-König Reviewed-by: Andy Shevchenko Link: https://lore.kernel.org/r/20221118224540.619276-138-uwe@kleine-koenig.org Signed-off-by: Jonathan Cameron --- drivers/iio/light/si1133.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers/iio') diff --git a/drivers/iio/light/si1133.c b/drivers/iio/light/si1133.c index f8c9b2cc322e..a08fbc8f5adb 100644 --- a/drivers/iio/light/si1133.c +++ b/drivers/iio/light/si1133.c @@ -990,9 +990,9 @@ static int si1133_validate_ids(struct iio_dev *iio_dev) return 0; } -static int si1133_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int si1133_probe(struct i2c_client *client) { + const struct i2c_device_id *id = i2c_client_get_device_id(client); struct si1133_data *data; struct iio_dev *iio_dev; int err; @@ -1064,7 +1064,7 @@ static struct i2c_driver si1133_driver = { .driver = { .name = "si1133", }, - .probe = si1133_probe, + .probe_new = si1133_probe, .id_table = si1133_ids, }; -- cgit v1.2.3 From fb006652dc597b2807bab56d25fe3b3404f87e53 Mon Sep 17 00:00:00 2001 From: Uwe Kleine-König Date: Fri, 18 Nov 2022 23:37:52 +0100 Subject: iio: light: si1145: Convert to i2c's .probe_new() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit .probe_new() doesn't get the i2c_device_id * parameter, so determine that explicitly in the probe function. Signed-off-by: Uwe Kleine-König Reviewed-by: Andy Shevchenko Link: https://lore.kernel.org/r/20221118224540.619276-139-uwe@kleine-koenig.org Signed-off-by: Jonathan Cameron --- drivers/iio/light/si1145.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers/iio') diff --git a/drivers/iio/light/si1145.c b/drivers/iio/light/si1145.c index e8f6cdf26f22..f7126235f94c 100644 --- a/drivers/iio/light/si1145.c +++ b/drivers/iio/light/si1145.c @@ -1269,9 +1269,9 @@ static int si1145_probe_trigger(struct iio_dev *indio_dev) return 0; } -static int si1145_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int si1145_probe(struct i2c_client *client) { + const struct i2c_device_id *id = i2c_client_get_device_id(client); struct si1145_data *data; struct iio_dev *indio_dev; u8 part_id, rev_id, seq_id; @@ -1352,7 +1352,7 @@ static struct i2c_driver si1145_driver = { .driver = { .name = "si1145", }, - .probe = si1145_probe, + .probe_new = si1145_probe, .id_table = si1145_ids, }; -- cgit v1.2.3 From c3ff326a9d3c809b493775bd65c07dccb73258cf Mon Sep 17 00:00:00 2001 From: Uwe Kleine-König Date: Fri, 18 Nov 2022 23:37:53 +0100 Subject: iio: light: st_uvis25_i2c: Convert to i2c's .probe_new() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The probe function doesn't make use of the i2c_device_id * parameter so it can be trivially converted. Signed-off-by: Uwe Kleine-König Reviewed-by: Andy Shevchenko Link: https://lore.kernel.org/r/20221118224540.619276-140-uwe@kleine-koenig.org Signed-off-by: Jonathan Cameron --- drivers/iio/light/st_uvis25_i2c.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'drivers/iio') diff --git a/drivers/iio/light/st_uvis25_i2c.c b/drivers/iio/light/st_uvis25_i2c.c index c982b0b255cf..2160e87bb498 100644 --- a/drivers/iio/light/st_uvis25_i2c.c +++ b/drivers/iio/light/st_uvis25_i2c.c @@ -25,8 +25,7 @@ static const struct regmap_config st_uvis25_i2c_regmap_config = { .read_flag_mask = UVIS25_I2C_AUTO_INCREMENT, }; -static int st_uvis25_i2c_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int st_uvis25_i2c_probe(struct i2c_client *client) { struct regmap *regmap; @@ -58,7 +57,7 @@ static struct i2c_driver st_uvis25_driver = { .pm = pm_sleep_ptr(&st_uvis25_pm_ops), .of_match_table = st_uvis25_i2c_of_match, }, - .probe = st_uvis25_i2c_probe, + .probe_new = st_uvis25_i2c_probe, .id_table = st_uvis25_i2c_id_table, }; module_i2c_driver(st_uvis25_driver); -- cgit v1.2.3 From 9046d80dce04c65c92ea5550f220a2de236e3ff0 Mon Sep 17 00:00:00 2001 From: Uwe Kleine-König Date: Fri, 18 Nov 2022 23:37:54 +0100 Subject: iio: light: stk3310: Convert to i2c's .probe_new() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The probe function doesn't make use of the i2c_device_id * parameter so it can be trivially converted. Signed-off-by: Uwe Kleine-König Reviewed-by: Andy Shevchenko Link: https://lore.kernel.org/r/20221118224540.619276-141-uwe@kleine-koenig.org Signed-off-by: Jonathan Cameron --- drivers/iio/light/stk3310.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'drivers/iio') diff --git a/drivers/iio/light/stk3310.c b/drivers/iio/light/stk3310.c index 7b8e0da6aabc..48ae6ff0015e 100644 --- a/drivers/iio/light/stk3310.c +++ b/drivers/iio/light/stk3310.c @@ -586,8 +586,7 @@ out: return IRQ_HANDLED; } -static int stk3310_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int stk3310_probe(struct i2c_client *client) { int ret; struct iio_dev *indio_dev; @@ -715,7 +714,7 @@ static struct i2c_driver stk3310_driver = { .pm = pm_sleep_ptr(&stk3310_pm_ops), .acpi_match_table = ACPI_PTR(stk3310_acpi_id), }, - .probe = stk3310_probe, + .probe_new = stk3310_probe, .remove = stk3310_remove, .id_table = stk3310_i2c_id, }; -- cgit v1.2.3 From b30cfdeb9f7fe03103472c4c79e65e382935082a Mon Sep 17 00:00:00 2001 From: Uwe Kleine-König Date: Fri, 18 Nov 2022 23:37:55 +0100 Subject: iio: light: tcs3414: Convert to i2c's .probe_new() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The probe function doesn't make use of the i2c_device_id * parameter so it can be trivially converted. Signed-off-by: Uwe Kleine-König Reviewed-by: Andy Shevchenko Link: https://lore.kernel.org/r/20221118224540.619276-142-uwe@kleine-koenig.org Signed-off-by: Jonathan Cameron --- drivers/iio/light/tcs3414.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'drivers/iio') diff --git a/drivers/iio/light/tcs3414.c b/drivers/iio/light/tcs3414.c index 3951536022b3..5100732fbaf0 100644 --- a/drivers/iio/light/tcs3414.c +++ b/drivers/iio/light/tcs3414.c @@ -279,8 +279,7 @@ static void tcs3414_powerdown_cleanup(void *data) tcs3414_powerdown(data); } -static int tcs3414_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int tcs3414_probe(struct i2c_client *client) { struct tcs3414_data *data; struct iio_dev *indio_dev; @@ -374,7 +373,7 @@ static struct i2c_driver tcs3414_driver = { .name = TCS3414_DRV_NAME, .pm = pm_sleep_ptr(&tcs3414_pm_ops), }, - .probe = tcs3414_probe, + .probe_new = tcs3414_probe, .id_table = tcs3414_id, }; module_i2c_driver(tcs3414_driver); -- cgit v1.2.3 From e498cc544eae9b6264c9a535f8784aafe5788965 Mon Sep 17 00:00:00 2001 From: Uwe Kleine-König Date: Fri, 18 Nov 2022 23:37:56 +0100 Subject: iio: light: tcs3472: Convert to i2c's .probe_new() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The probe function doesn't make use of the i2c_device_id * parameter so it can be trivially converted. Signed-off-by: Uwe Kleine-König Reviewed-by: Andy Shevchenko Link: https://lore.kernel.org/r/20221118224540.619276-143-uwe@kleine-koenig.org Signed-off-by: Jonathan Cameron --- drivers/iio/light/tcs3472.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'drivers/iio') diff --git a/drivers/iio/light/tcs3472.c b/drivers/iio/light/tcs3472.c index db17fec634be..6187c5487916 100644 --- a/drivers/iio/light/tcs3472.c +++ b/drivers/iio/light/tcs3472.c @@ -442,8 +442,7 @@ static const struct iio_info tcs3472_info = { .attrs = &tcs3472_attribute_group, }; -static int tcs3472_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int tcs3472_probe(struct i2c_client *client) { struct tcs3472_data *data; struct iio_dev *indio_dev; @@ -610,7 +609,7 @@ static struct i2c_driver tcs3472_driver = { .name = TCS3472_DRV_NAME, .pm = pm_sleep_ptr(&tcs3472_pm_ops), }, - .probe = tcs3472_probe, + .probe_new = tcs3472_probe, .remove = tcs3472_remove, .id_table = tcs3472_id, }; -- cgit v1.2.3 From 74cd01b3f9041ef3e44cc043b8bb10f79ec52c43 Mon Sep 17 00:00:00 2001 From: Uwe Kleine-König Date: Fri, 18 Nov 2022 23:37:57 +0100 Subject: iio: light: tsl2563: Convert to i2c's .probe_new() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The probe function doesn't make use of the i2c_device_id * parameter so it can be trivially converted. Signed-off-by: Uwe Kleine-König Reviewed-by: Andy Shevchenko Link: https://lore.kernel.org/r/20221118224540.619276-144-uwe@kleine-koenig.org Signed-off-by: Jonathan Cameron --- drivers/iio/light/tsl2563.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'drivers/iio') diff --git a/drivers/iio/light/tsl2563.c b/drivers/iio/light/tsl2563.c index 951f35ef3f41..d0e42b73203a 100644 --- a/drivers/iio/light/tsl2563.c +++ b/drivers/iio/light/tsl2563.c @@ -699,8 +699,7 @@ static const struct iio_info tsl2563_info = { .write_event_config = &tsl2563_write_interrupt_config, }; -static int tsl2563_probe(struct i2c_client *client, - const struct i2c_device_id *device_id) +static int tsl2563_probe(struct i2c_client *client) { struct iio_dev *indio_dev; struct tsl2563_chip *chip; @@ -880,7 +879,7 @@ static struct i2c_driver tsl2563_i2c_driver = { .of_match_table = tsl2563_of_match, .pm = pm_sleep_ptr(&tsl2563_pm_ops), }, - .probe = tsl2563_probe, + .probe_new = tsl2563_probe, .remove = tsl2563_remove, .id_table = tsl2563_id, }; -- cgit v1.2.3 From dcc484a21108441f7970c4813b1223154dd23ea6 Mon Sep 17 00:00:00 2001 From: Uwe Kleine-König Date: Fri, 18 Nov 2022 23:37:58 +0100 Subject: iio: light: tsl2583: Convert to i2c's .probe_new() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The probe function doesn't make use of the i2c_device_id * parameter so it can be trivially converted. Signed-off-by: Uwe Kleine-König Reviewed-by: Andy Shevchenko Link: https://lore.kernel.org/r/20221118224540.619276-145-uwe@kleine-koenig.org Signed-off-by: Jonathan Cameron --- drivers/iio/light/tsl2583.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'drivers/iio') diff --git a/drivers/iio/light/tsl2583.c b/drivers/iio/light/tsl2583.c index 7bcb5c718922..a05f1c0453d1 100644 --- a/drivers/iio/light/tsl2583.c +++ b/drivers/iio/light/tsl2583.c @@ -809,8 +809,7 @@ static const struct iio_info tsl2583_info = { .write_raw = tsl2583_write_raw, }; -static int tsl2583_probe(struct i2c_client *clientp, - const struct i2c_device_id *idp) +static int tsl2583_probe(struct i2c_client *clientp) { int ret; struct tsl2583_chip *chip; @@ -943,7 +942,7 @@ static struct i2c_driver tsl2583_driver = { .of_match_table = tsl2583_of_match, }, .id_table = tsl2583_idtable, - .probe = tsl2583_probe, + .probe_new = tsl2583_probe, .remove = tsl2583_remove, }; module_i2c_driver(tsl2583_driver); -- cgit v1.2.3 From e723b95135b1510873c832eaf8361e6b8d76bfb8 Mon Sep 17 00:00:00 2001 From: Uwe Kleine-König Date: Fri, 18 Nov 2022 23:37:59 +0100 Subject: iio: light: tsl2772: Convert to i2c's .probe_new() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit .probe_new() doesn't get the i2c_device_id * parameter, so determine that explicitly in the probe function. Signed-off-by: Uwe Kleine-König Reviewed-by: Andy Shevchenko Link: https://lore.kernel.org/r/20221118224540.619276-146-uwe@kleine-koenig.org Signed-off-by: Jonathan Cameron --- drivers/iio/light/tsl2772.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers/iio') diff --git a/drivers/iio/light/tsl2772.c b/drivers/iio/light/tsl2772.c index dd9051f1cc1a..ad50baa0202c 100644 --- a/drivers/iio/light/tsl2772.c +++ b/drivers/iio/light/tsl2772.c @@ -1750,9 +1750,9 @@ static const struct tsl2772_chip_info tsl2772_chip_info_tbl[] = { }, }; -static int tsl2772_probe(struct i2c_client *clientp, - const struct i2c_device_id *id) +static int tsl2772_probe(struct i2c_client *clientp) { + const struct i2c_device_id *id = i2c_client_get_device_id(clientp); struct iio_dev *indio_dev; struct tsl2772_chip *chip; int ret; @@ -1931,7 +1931,7 @@ static struct i2c_driver tsl2772_driver = { .pm = &tsl2772_pm_ops, }, .id_table = tsl2772_idtable, - .probe = tsl2772_probe, + .probe_new = tsl2772_probe, }; module_i2c_driver(tsl2772_driver); -- cgit v1.2.3 From 081f6b9dc055f9ccb19a86346b80df691972120b Mon Sep 17 00:00:00 2001 From: Uwe Kleine-König Date: Fri, 18 Nov 2022 23:38:00 +0100 Subject: iio: light: tsl4531: Convert to i2c's .probe_new() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The probe function doesn't make use of the i2c_device_id * parameter so it can be trivially converted. Signed-off-by: Uwe Kleine-König Reviewed-by: Andy Shevchenko Link: https://lore.kernel.org/r/20221118224540.619276-147-uwe@kleine-koenig.org Signed-off-by: Jonathan Cameron --- drivers/iio/light/tsl4531.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'drivers/iio') diff --git a/drivers/iio/light/tsl4531.c b/drivers/iio/light/tsl4531.c index 090038fed889..d95397eb1526 100644 --- a/drivers/iio/light/tsl4531.c +++ b/drivers/iio/light/tsl4531.c @@ -160,8 +160,7 @@ static int tsl4531_check_id(struct i2c_client *client) } } -static int tsl4531_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int tsl4531_probe(struct i2c_client *client) { struct tsl4531_data *data; struct iio_dev *indio_dev; @@ -238,7 +237,7 @@ static struct i2c_driver tsl4531_driver = { .name = TSL4531_DRV_NAME, .pm = pm_sleep_ptr(&tsl4531_pm_ops), }, - .probe = tsl4531_probe, + .probe_new = tsl4531_probe, .remove = tsl4531_remove, .id_table = tsl4531_id, }; -- cgit v1.2.3 From 3ed2b14de4d36a9335e93798bf966c521df42a95 Mon Sep 17 00:00:00 2001 From: Uwe Kleine-König Date: Fri, 18 Nov 2022 23:38:01 +0100 Subject: iio: light: us5182d: Convert to i2c's .probe_new() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The probe function doesn't make use of the i2c_device_id * parameter so it can be trivially converted. Signed-off-by: Uwe Kleine-König Reviewed-by: Andy Shevchenko Link: https://lore.kernel.org/r/20221118224540.619276-148-uwe@kleine-koenig.org Signed-off-by: Jonathan Cameron --- drivers/iio/light/us5182d.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'drivers/iio') diff --git a/drivers/iio/light/us5182d.c b/drivers/iio/light/us5182d.c index 3e652d7f3b0e..8b2a0c99c8e6 100644 --- a/drivers/iio/light/us5182d.c +++ b/drivers/iio/light/us5182d.c @@ -832,8 +832,7 @@ static irqreturn_t us5182d_irq_thread_handler(int irq, void *private) return IRQ_HANDLED; } -static int us5182d_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int us5182d_probe(struct i2c_client *client) { struct us5182d_data *data; struct iio_dev *indio_dev; @@ -975,7 +974,7 @@ static struct i2c_driver us5182d_driver = { .of_match_table = us5182d_of_match, .acpi_match_table = ACPI_PTR(us5182d_acpi_match), }, - .probe = us5182d_probe, + .probe_new = us5182d_probe, .remove = us5182d_remove, .id_table = us5182d_id, -- cgit v1.2.3 From e61295e0d7cf6de3d7cc25e7f387ffe021f0b0a1 Mon Sep 17 00:00:00 2001 From: Uwe Kleine-König Date: Fri, 18 Nov 2022 23:38:02 +0100 Subject: iio: light: vcnl4000: Convert to i2c's .probe_new() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit .probe_new() doesn't get the i2c_device_id * parameter, so determine that explicitly in the probe function. Signed-off-by: Uwe Kleine-König Reviewed-by: Andy Shevchenko Link: https://lore.kernel.org/r/20221118224540.619276-149-uwe@kleine-koenig.org Signed-off-by: Jonathan Cameron --- drivers/iio/light/vcnl4000.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers/iio') diff --git a/drivers/iio/light/vcnl4000.c b/drivers/iio/light/vcnl4000.c index fdb3922ae4ac..cc1a2062e76d 100644 --- a/drivers/iio/light/vcnl4000.c +++ b/drivers/iio/light/vcnl4000.c @@ -1180,9 +1180,9 @@ static int vcnl4010_probe_trigger(struct iio_dev *indio_dev) return devm_iio_trigger_register(&client->dev, trigger); } -static int vcnl4000_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int vcnl4000_probe(struct i2c_client *client) { + const struct i2c_device_id *id = i2c_client_get_device_id(client); struct vcnl4000_data *data; struct iio_dev *indio_dev; int ret; @@ -1326,7 +1326,7 @@ static struct i2c_driver vcnl4000_driver = { .pm = pm_ptr(&vcnl4000_pm_ops), .of_match_table = vcnl_4000_of_match, }, - .probe = vcnl4000_probe, + .probe_new = vcnl4000_probe, .id_table = vcnl4000_id, .remove = vcnl4000_remove, }; -- cgit v1.2.3 From 9da43dcc54a19fe40e3aa7dc03fbca3f8c0395ff Mon Sep 17 00:00:00 2001 From: Uwe Kleine-König Date: Fri, 18 Nov 2022 23:38:03 +0100 Subject: iio: light: vcnl4035: Convert to i2c's .probe_new() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The probe function doesn't make use of the i2c_device_id * parameter so it can be trivially converted. Signed-off-by: Uwe Kleine-König Reviewed-by: Andy Shevchenko Link: https://lore.kernel.org/r/20221118224540.619276-150-uwe@kleine-koenig.org Signed-off-by: Jonathan Cameron --- drivers/iio/light/vcnl4035.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'drivers/iio') diff --git a/drivers/iio/light/vcnl4035.c b/drivers/iio/light/vcnl4035.c index 3ed37f6057fb..84148b944000 100644 --- a/drivers/iio/light/vcnl4035.c +++ b/drivers/iio/light/vcnl4035.c @@ -539,8 +539,7 @@ static int vcnl4035_probe_trigger(struct iio_dev *indio_dev) return ret; } -static int vcnl4035_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int vcnl4035_probe(struct i2c_client *client) { struct vcnl4035_data *data; struct iio_dev *indio_dev; @@ -668,7 +667,7 @@ static struct i2c_driver vcnl4035_driver = { .pm = pm_ptr(&vcnl4035_pm_ops), .of_match_table = vcnl4035_of_match, }, - .probe = vcnl4035_probe, + .probe_new = vcnl4035_probe, .remove = vcnl4035_remove, .id_table = vcnl4035_id, }; -- cgit v1.2.3 From e465524d64d11fbd25a9eb65ce4e77b965979291 Mon Sep 17 00:00:00 2001 From: Uwe Kleine-König Date: Fri, 18 Nov 2022 23:38:04 +0100 Subject: iio: light: veml6030: Convert to i2c's .probe_new() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The probe function doesn't make use of the i2c_device_id * parameter so it can be trivially converted. Signed-off-by: Uwe Kleine-König Reviewed-by: Andy Shevchenko Link: https://lore.kernel.org/r/20221118224540.619276-151-uwe@kleine-koenig.org Signed-off-by: Jonathan Cameron --- drivers/iio/light/veml6030.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'drivers/iio') diff --git a/drivers/iio/light/veml6030.c b/drivers/iio/light/veml6030.c index 9a7800cdfee2..e7d2d5d177d4 100644 --- a/drivers/iio/light/veml6030.c +++ b/drivers/iio/light/veml6030.c @@ -786,8 +786,7 @@ static int veml6030_hw_init(struct iio_dev *indio_dev) return ret; } -static int veml6030_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int veml6030_probe(struct i2c_client *client) { int ret; struct veml6030_data *data; @@ -893,7 +892,7 @@ static struct i2c_driver veml6030_driver = { .of_match_table = veml6030_of_match, .pm = pm_ptr(&veml6030_pm_ops), }, - .probe = veml6030_probe, + .probe_new = veml6030_probe, .id_table = veml6030_id, }; module_i2c_driver(veml6030_driver); -- cgit v1.2.3 From f90b8694f355566c2ff70564942d4932d76e28e0 Mon Sep 17 00:00:00 2001 From: Uwe Kleine-König Date: Fri, 18 Nov 2022 23:38:05 +0100 Subject: iio: light: veml6070: Convert to i2c's .probe_new() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The probe function doesn't make use of the i2c_device_id * parameter so it can be trivially converted. Signed-off-by: Uwe Kleine-König Reviewed-by: Andy Shevchenko Link: https://lore.kernel.org/r/20221118224540.619276-152-uwe@kleine-koenig.org Signed-off-by: Jonathan Cameron --- drivers/iio/light/veml6070.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'drivers/iio') diff --git a/drivers/iio/light/veml6070.c b/drivers/iio/light/veml6070.c index cfa4e9e7c803..ee76a68deb24 100644 --- a/drivers/iio/light/veml6070.c +++ b/drivers/iio/light/veml6070.c @@ -135,8 +135,7 @@ static const struct iio_info veml6070_info = { .read_raw = veml6070_read_raw, }; -static int veml6070_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int veml6070_probe(struct i2c_client *client) { struct veml6070_data *data; struct iio_dev *indio_dev; @@ -199,7 +198,7 @@ static struct i2c_driver veml6070_driver = { .driver = { .name = VEML6070_DRV_NAME, }, - .probe = veml6070_probe, + .probe_new = veml6070_probe, .remove = veml6070_remove, .id_table = veml6070_id, }; -- cgit v1.2.3 From 6811c7a52f025ab50f53b3107e6071132a8fe1f5 Mon Sep 17 00:00:00 2001 From: Uwe Kleine-König Date: Fri, 18 Nov 2022 23:38:06 +0100 Subject: iio: light: zopt2201: Convert to i2c's .probe_new() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The probe function doesn't make use of the i2c_device_id * parameter so it can be trivially converted. Signed-off-by: Uwe Kleine-König Reviewed-by: Andy Shevchenko Link: https://lore.kernel.org/r/20221118224540.619276-153-uwe@kleine-koenig.org Signed-off-by: Jonathan Cameron --- drivers/iio/light/zopt2201.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'drivers/iio') diff --git a/drivers/iio/light/zopt2201.c b/drivers/iio/light/zopt2201.c index e0bc9df9c88b..e3bac8b56380 100644 --- a/drivers/iio/light/zopt2201.c +++ b/drivers/iio/light/zopt2201.c @@ -501,8 +501,7 @@ static const struct iio_info zopt2201_info = { .attrs = &zopt2201_attribute_group, }; -static int zopt2201_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int zopt2201_probe(struct i2c_client *client) { struct zopt2201_data *data; struct iio_dev *indio_dev; @@ -555,7 +554,7 @@ static struct i2c_driver zopt2201_driver = { .driver = { .name = ZOPT2201_DRV_NAME, }, - .probe = zopt2201_probe, + .probe_new = zopt2201_probe, .id_table = zopt2201_id, }; -- cgit v1.2.3 From 149a5043b6f9b100471a1fdbdc22a395602fadd1 Mon Sep 17 00:00:00 2001 From: Uwe Kleine-König Date: Fri, 18 Nov 2022 23:38:07 +0100 Subject: iio: magnetometer: ak8974: Convert to i2c's .probe_new() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The probe function doesn't make use of the i2c_device_id * parameter so it can be trivially converted. Signed-off-by: Uwe Kleine-König Reviewed-by: Andy Shevchenko Link: https://lore.kernel.org/r/20221118224540.619276-154-uwe@kleine-koenig.org Signed-off-by: Jonathan Cameron --- drivers/iio/magnetometer/ak8974.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'drivers/iio') diff --git a/drivers/iio/magnetometer/ak8974.c b/drivers/iio/magnetometer/ak8974.c index 7ec9ab3beb45..45abdcce6bc0 100644 --- a/drivers/iio/magnetometer/ak8974.c +++ b/drivers/iio/magnetometer/ak8974.c @@ -814,8 +814,7 @@ static const struct regmap_config ak8974_regmap_config = { .precious_reg = ak8974_precious_reg, }; -static int ak8974_probe(struct i2c_client *i2c, - const struct i2c_device_id *id) +static int ak8974_probe(struct i2c_client *i2c) { struct iio_dev *indio_dev; struct ak8974 *ak8974; @@ -1047,7 +1046,7 @@ static struct i2c_driver ak8974_driver = { .pm = pm_ptr(&ak8974_dev_pm_ops), .of_match_table = ak8974_of_match, }, - .probe = ak8974_probe, + .probe_new = ak8974_probe, .remove = ak8974_remove, .id_table = ak8974_id, }; -- cgit v1.2.3 From f64eecea19ba974f03e3614ebcc3749d9a24da77 Mon Sep 17 00:00:00 2001 From: Uwe Kleine-König Date: Fri, 18 Nov 2022 23:38:08 +0100 Subject: iio: magnetometer: ak8975: Convert to i2c's .probe_new() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit .probe_new() doesn't get the i2c_device_id * parameter, so determine that explicitly in the probe function. Signed-off-by: Uwe Kleine-König Reviewed-by: Andy Shevchenko Link: https://lore.kernel.org/r/20221118224540.619276-155-uwe@kleine-koenig.org Signed-off-by: Jonathan Cameron --- drivers/iio/magnetometer/ak8975.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers/iio') diff --git a/drivers/iio/magnetometer/ak8975.c b/drivers/iio/magnetometer/ak8975.c index caf03a2a98a5..924b481a3034 100644 --- a/drivers/iio/magnetometer/ak8975.c +++ b/drivers/iio/magnetometer/ak8975.c @@ -876,9 +876,9 @@ static irqreturn_t ak8975_handle_trigger(int irq, void *p) return IRQ_HANDLED; } -static int ak8975_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int ak8975_probe(struct i2c_client *client) { + const struct i2c_device_id *id = i2c_client_get_device_id(client); struct ak8975_data *data; struct iio_dev *indio_dev; struct gpio_desc *eoc_gpiod; @@ -1110,7 +1110,7 @@ static struct i2c_driver ak8975_driver = { .of_match_table = ak8975_of_match, .acpi_match_table = ak_acpi_match, }, - .probe = ak8975_probe, + .probe_new = ak8975_probe, .remove = ak8975_remove, .id_table = ak8975_id, }; -- cgit v1.2.3 From f23215c1e5a1255ed2097afe3e564dec96f73911 Mon Sep 17 00:00:00 2001 From: Uwe Kleine-König Date: Fri, 18 Nov 2022 23:38:09 +0100 Subject: iio: magnetometer: bmc150_magn_i2c: Convert to i2c's .probe_new() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit .probe_new() doesn't get the i2c_device_id * parameter, so determine that explicitly in the probe function. Signed-off-by: Uwe Kleine-König Reviewed-by: Andy Shevchenko Link: https://lore.kernel.org/r/20221118224540.619276-156-uwe@kleine-koenig.org Signed-off-by: Jonathan Cameron --- drivers/iio/magnetometer/bmc150_magn_i2c.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers/iio') diff --git a/drivers/iio/magnetometer/bmc150_magn_i2c.c b/drivers/iio/magnetometer/bmc150_magn_i2c.c index 570deaa87836..44b8960eea17 100644 --- a/drivers/iio/magnetometer/bmc150_magn_i2c.c +++ b/drivers/iio/magnetometer/bmc150_magn_i2c.c @@ -16,9 +16,9 @@ #include "bmc150_magn.h" -static int bmc150_magn_i2c_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int bmc150_magn_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; @@ -71,7 +71,7 @@ static struct i2c_driver bmc150_magn_driver = { .acpi_match_table = ACPI_PTR(bmc150_magn_acpi_match), .pm = &bmc150_magn_pm_ops, }, - .probe = bmc150_magn_i2c_probe, + .probe_new = bmc150_magn_i2c_probe, .remove = bmc150_magn_i2c_remove, .id_table = bmc150_magn_i2c_id, }; -- cgit v1.2.3 From bcf73c37f7c7e7c1d0cac6ebea36cfd7bf626727 Mon Sep 17 00:00:00 2001 From: Uwe Kleine-König Date: Fri, 18 Nov 2022 23:38:10 +0100 Subject: iio: magnetometer: hmc5843: Convert to i2c's .probe_new() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit .probe_new() doesn't get the i2c_device_id * parameter, so determine that explicitly in the probe function. Signed-off-by: Uwe Kleine-König Reviewed-by: Andy Shevchenko Link: https://lore.kernel.org/r/20221118224540.619276-157-uwe@kleine-koenig.org Signed-off-by: Jonathan Cameron --- drivers/iio/magnetometer/hmc5843_i2c.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers/iio') diff --git a/drivers/iio/magnetometer/hmc5843_i2c.c b/drivers/iio/magnetometer/hmc5843_i2c.c index 18a13dd51296..7ef2b1d56289 100644 --- a/drivers/iio/magnetometer/hmc5843_i2c.c +++ b/drivers/iio/magnetometer/hmc5843_i2c.c @@ -52,9 +52,9 @@ static const struct regmap_config hmc5843_i2c_regmap_config = { .cache_type = REGCACHE_RBTREE, }; -static int hmc5843_i2c_probe(struct i2c_client *cli, - const struct i2c_device_id *id) +static int hmc5843_i2c_probe(struct i2c_client *cli) { + const struct i2c_device_id *id = i2c_client_get_device_id(cli); struct regmap *regmap = devm_regmap_init_i2c(cli, &hmc5843_i2c_regmap_config); if (IS_ERR(regmap)) @@ -95,7 +95,7 @@ static struct i2c_driver hmc5843_driver = { .of_match_table = hmc5843_of_match, }, .id_table = hmc5843_id, - .probe = hmc5843_i2c_probe, + .probe_new = hmc5843_i2c_probe, .remove = hmc5843_i2c_remove, }; module_i2c_driver(hmc5843_driver); -- cgit v1.2.3 From cee51403c696aac364fd991bc3a95a90722678b1 Mon Sep 17 00:00:00 2001 From: Uwe Kleine-König Date: Fri, 18 Nov 2022 23:38:11 +0100 Subject: iio: magnetometer: mag3110: Convert to i2c's .probe_new() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit .probe_new() doesn't get the i2c_device_id * parameter, so determine that explicitly in the probe function. Signed-off-by: Uwe Kleine-König Reviewed-by: Andy Shevchenko Link: https://lore.kernel.org/r/20221118224540.619276-158-uwe@kleine-koenig.org Signed-off-by: Jonathan Cameron --- drivers/iio/magnetometer/mag3110.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers/iio') diff --git a/drivers/iio/magnetometer/mag3110.c b/drivers/iio/magnetometer/mag3110.c index b870ad803862..661176a885ad 100644 --- a/drivers/iio/magnetometer/mag3110.c +++ b/drivers/iio/magnetometer/mag3110.c @@ -469,9 +469,9 @@ static const struct iio_info mag3110_info = { static const unsigned long mag3110_scan_masks[] = {0x7, 0xf, 0}; -static int mag3110_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int mag3110_probe(struct i2c_client *client) { + const struct i2c_device_id *id = i2c_client_get_device_id(client); struct mag3110_data *data; struct iio_dev *indio_dev; int ret; @@ -641,7 +641,7 @@ static struct i2c_driver mag3110_driver = { .of_match_table = mag3110_of_match, .pm = pm_sleep_ptr(&mag3110_pm_ops), }, - .probe = mag3110_probe, + .probe_new = mag3110_probe, .remove = mag3110_remove, .id_table = mag3110_id, }; -- cgit v1.2.3 From e7a45a76351b6b5163af4a581ab46fdad137d62a Mon Sep 17 00:00:00 2001 From: Uwe Kleine-König Date: Fri, 18 Nov 2022 23:38:12 +0100 Subject: iio: magnetometer: mmc35240: Convert to i2c's .probe_new() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The probe function doesn't make use of the i2c_device_id * parameter so it can be trivially converted. Signed-off-by: Uwe Kleine-König Reviewed-by: Andy Shevchenko Link: https://lore.kernel.org/r/20221118224540.619276-159-uwe@kleine-koenig.org Signed-off-by: Jonathan Cameron --- drivers/iio/magnetometer/mmc35240.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'drivers/iio') diff --git a/drivers/iio/magnetometer/mmc35240.c b/drivers/iio/magnetometer/mmc35240.c index 186edfcda0b7..756dadbad106 100644 --- a/drivers/iio/magnetometer/mmc35240.c +++ b/drivers/iio/magnetometer/mmc35240.c @@ -481,8 +481,7 @@ static const struct regmap_config mmc35240_regmap_config = { .num_reg_defaults = ARRAY_SIZE(mmc35240_reg_defaults), }; -static int mmc35240_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int mmc35240_probe(struct i2c_client *client) { struct mmc35240_data *data; struct iio_dev *indio_dev; @@ -576,7 +575,7 @@ static struct i2c_driver mmc35240_driver = { .pm = pm_sleep_ptr(&mmc35240_pm_ops), .acpi_match_table = ACPI_PTR(mmc35240_acpi_match), }, - .probe = mmc35240_probe, + .probe_new = mmc35240_probe, .id_table = mmc35240_id, }; -- cgit v1.2.3 From fcd969675290cd3cbe911b350502332be58f100b Mon Sep 17 00:00:00 2001 From: Uwe Kleine-König Date: Fri, 18 Nov 2022 23:38:13 +0100 Subject: iio: magnetometer: yamaha-yas530: Convert to i2c's .probe_new() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit .probe_new() doesn't get the i2c_device_id * parameter, so determine that explicitly in the probe function. Signed-off-by: Uwe Kleine-König Reviewed-by: Andy Shevchenko Link: https://lore.kernel.org/r/20221118224540.619276-160-uwe@kleine-koenig.org Signed-off-by: Jonathan Cameron --- drivers/iio/magnetometer/yamaha-yas530.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers/iio') diff --git a/drivers/iio/magnetometer/yamaha-yas530.c b/drivers/iio/magnetometer/yamaha-yas530.c index 801c760feb4d..753717158b07 100644 --- a/drivers/iio/magnetometer/yamaha-yas530.c +++ b/drivers/iio/magnetometer/yamaha-yas530.c @@ -1384,9 +1384,9 @@ static const struct yas5xx_chip_info yas5xx_chip_info_tbl[] = { }, }; -static int yas5xx_probe(struct i2c_client *i2c, - const struct i2c_device_id *id) +static int yas5xx_probe(struct i2c_client *i2c) { + const struct i2c_device_id *id = i2c_client_get_device_id(i2c); struct iio_dev *indio_dev; struct device *dev = &i2c->dev; struct yas5xx *yas5xx; @@ -1605,7 +1605,7 @@ static struct i2c_driver yas5xx_driver = { .of_match_table = yas5xx_of_match, .pm = pm_ptr(&yas5xx_dev_pm_ops), }, - .probe = yas5xx_probe, + .probe_new = yas5xx_probe, .remove = yas5xx_remove, .id_table = yas5xx_id, }; -- cgit v1.2.3 From b11df8374c0d0581474e0b8f74a7ba8f4a10be7d Mon Sep 17 00:00:00 2001 From: Uwe Kleine-König Date: Fri, 18 Nov 2022 23:38:14 +0100 Subject: iio: potentiometer: ad5272: Convert to i2c's .probe_new() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit .probe_new() doesn't get the i2c_device_id * parameter, so determine that explicitly in the probe function. Signed-off-by: Uwe Kleine-König Reviewed-by: Andy Shevchenko Link: https://lore.kernel.org/r/20221118224540.619276-161-uwe@kleine-koenig.org Signed-off-by: Jonathan Cameron --- drivers/iio/potentiometer/ad5272.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers/iio') diff --git a/drivers/iio/potentiometer/ad5272.c b/drivers/iio/potentiometer/ad5272.c index ed5fc0b50fe9..aa140d632101 100644 --- a/drivers/iio/potentiometer/ad5272.c +++ b/drivers/iio/potentiometer/ad5272.c @@ -158,9 +158,9 @@ static int ad5272_reset(struct ad5272_data *data) return 0; } -static int ad5272_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int ad5272_probe(struct i2c_client *client) { + const struct i2c_device_id *id = i2c_client_get_device_id(client); struct device *dev = &client->dev; struct iio_dev *indio_dev; struct ad5272_data *data; @@ -218,7 +218,7 @@ static struct i2c_driver ad5272_driver = { .name = "ad5272", .of_match_table = ad5272_dt_ids, }, - .probe = ad5272_probe, + .probe_new = ad5272_probe, .id_table = ad5272_id, }; -- cgit v1.2.3 From 705f1ce22b967b8fd7fc3cb0de31830ec9eda3c0 Mon Sep 17 00:00:00 2001 From: Uwe Kleine-König Date: Fri, 18 Nov 2022 23:38:15 +0100 Subject: iio: potentiometer: ds1803: Convert to i2c's .probe_new() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit .probe_new() doesn't get the i2c_device_id * parameter, so determine that explicitly in the probe function. Signed-off-by: Uwe Kleine-König Reviewed-by: Andy Shevchenko Link: https://lore.kernel.org/r/20221118224540.619276-162-uwe@kleine-koenig.org Signed-off-by: Jonathan Cameron --- drivers/iio/potentiometer/ds1803.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'drivers/iio') diff --git a/drivers/iio/potentiometer/ds1803.c b/drivers/iio/potentiometer/ds1803.c index 5c212ed7a931..0b5e475807cb 100644 --- a/drivers/iio/potentiometer/ds1803.c +++ b/drivers/iio/potentiometer/ds1803.c @@ -202,8 +202,9 @@ static const struct iio_info ds1803_info = { .read_avail = ds1803_read_avail, }; -static int ds1803_probe(struct i2c_client *client, const struct i2c_device_id *id) +static int ds1803_probe(struct i2c_client *client) { + const struct i2c_device_id *id = i2c_client_get_device_id(client); struct device *dev = &client->dev; struct ds1803_data *data; struct iio_dev *indio_dev; @@ -251,7 +252,7 @@ static struct i2c_driver ds1803_driver = { .name = "ds1803", .of_match_table = ds1803_dt_ids, }, - .probe = ds1803_probe, + .probe_new = ds1803_probe, .id_table = ds1803_id, }; -- cgit v1.2.3 From e005024112dd3800e78d056facf958fc6451ba10 Mon Sep 17 00:00:00 2001 From: Uwe Kleine-König Date: Fri, 18 Nov 2022 23:38:16 +0100 Subject: iio: potentiometer: max5432: Convert to i2c's .probe_new() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The probe function doesn't make use of the i2c_device_id * parameter so it can be trivially converted. Signed-off-by: Uwe Kleine-König Reviewed-by: Andy Shevchenko Link: https://lore.kernel.org/r/20221118224540.619276-163-uwe@kleine-koenig.org Signed-off-by: Jonathan Cameron --- drivers/iio/potentiometer/max5432.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'drivers/iio') diff --git a/drivers/iio/potentiometer/max5432.c b/drivers/iio/potentiometer/max5432.c index aed3b6ab82a2..94ef27ef3fb5 100644 --- a/drivers/iio/potentiometer/max5432.c +++ b/drivers/iio/potentiometer/max5432.c @@ -85,8 +85,7 @@ static const struct iio_info max5432_info = { .write_raw = max5432_write_raw, }; -static int max5432_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int max5432_probe(struct i2c_client *client) { struct device *dev = &client->dev; struct iio_dev *indio_dev; @@ -124,7 +123,7 @@ static struct i2c_driver max5432_driver = { .name = "max5432", .of_match_table = max5432_dt_ids, }, - .probe = max5432_probe, + .probe_new = max5432_probe, }; module_i2c_driver(max5432_driver); -- cgit v1.2.3 From 4c1142cc436842eefffcd800ca41f8327bf61f88 Mon Sep 17 00:00:00 2001 From: Uwe Kleine-König Date: Fri, 18 Nov 2022 23:38:17 +0100 Subject: iio: potentiometer: tpl0102: Convert to i2c's .probe_new() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit .probe_new() doesn't get the i2c_device_id * parameter, so determine that explicitly in the probe function. Signed-off-by: Uwe Kleine-König Reviewed-by: Andy Shevchenko Link: https://lore.kernel.org/r/20221118224540.619276-164-uwe@kleine-koenig.org Signed-off-by: Jonathan Cameron --- drivers/iio/potentiometer/tpl0102.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers/iio') diff --git a/drivers/iio/potentiometer/tpl0102.c b/drivers/iio/potentiometer/tpl0102.c index d996dc367fb7..a3465b413b0c 100644 --- a/drivers/iio/potentiometer/tpl0102.c +++ b/drivers/iio/potentiometer/tpl0102.c @@ -120,9 +120,9 @@ static const struct iio_info tpl0102_info = { .write_raw = tpl0102_write_raw, }; -static int tpl0102_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int tpl0102_probe(struct i2c_client *client) { + const struct i2c_device_id *id = i2c_client_get_device_id(client); struct device *dev = &client->dev; struct tpl0102_data *data; struct iio_dev *indio_dev; @@ -161,7 +161,7 @@ static struct i2c_driver tpl0102_driver = { .driver = { .name = "tpl0102", }, - .probe = tpl0102_probe, + .probe_new = tpl0102_probe, .id_table = tpl0102_id, }; -- cgit v1.2.3 From 7d8b3e100abeeff40f54853ce82bc1d900cb2bf4 Mon Sep 17 00:00:00 2001 From: Uwe Kleine-König Date: Fri, 18 Nov 2022 23:38:18 +0100 Subject: iio: potentiostat: lmp91000: Convert to i2c's .probe_new() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The probe function doesn't make use of the i2c_device_id * parameter so it can be trivially converted. Signed-off-by: Uwe Kleine-König Reviewed-by: Andy Shevchenko Link: https://lore.kernel.org/r/20221118224540.619276-165-uwe@kleine-koenig.org Signed-off-by: Jonathan Cameron --- drivers/iio/potentiostat/lmp91000.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'drivers/iio') diff --git a/drivers/iio/potentiostat/lmp91000.c b/drivers/iio/potentiostat/lmp91000.c index 5ec7060d31d9..b82f093f1e6a 100644 --- a/drivers/iio/potentiostat/lmp91000.c +++ b/drivers/iio/potentiostat/lmp91000.c @@ -292,8 +292,7 @@ static const struct iio_buffer_setup_ops lmp91000_buffer_setup_ops = { .predisable = lmp91000_buffer_predisable, }; -static int lmp91000_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int lmp91000_probe(struct i2c_client *client) { struct device *dev = &client->dev; struct lmp91000_data *data; @@ -417,7 +416,7 @@ static struct i2c_driver lmp91000_driver = { .name = LMP91000_DRV_NAME, .of_match_table = lmp91000_of_match, }, - .probe = lmp91000_probe, + .probe_new = lmp91000_probe, .remove = lmp91000_remove, .id_table = lmp91000_id, }; -- cgit v1.2.3 From 576306ab4ceb16a032b5f67aeb635f385390193c Mon Sep 17 00:00:00 2001 From: Uwe Kleine-König Date: Fri, 18 Nov 2022 23:38:19 +0100 Subject: iio: pressure: abp060mg: Convert to i2c's .probe_new() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit .probe_new() doesn't get the i2c_device_id * parameter, so determine that explicitly in the probe function. Signed-off-by: Uwe Kleine-König Reviewed-by: Andy Shevchenko Link: https://lore.kernel.org/r/20221118224540.619276-166-uwe@kleine-koenig.org Signed-off-by: Jonathan Cameron --- drivers/iio/pressure/abp060mg.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers/iio') diff --git a/drivers/iio/pressure/abp060mg.c b/drivers/iio/pressure/abp060mg.c index e1c3bdb371ee..c0140779366a 100644 --- a/drivers/iio/pressure/abp060mg.c +++ b/drivers/iio/pressure/abp060mg.c @@ -174,9 +174,9 @@ static void abp060mg_init_device(struct iio_dev *indio_dev, unsigned long id) state->offset -= ABP060MG_NUM_COUNTS >> 1; } -static int abp060mg_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int abp060mg_probe(struct i2c_client *client) { + const struct i2c_device_id *id = i2c_client_get_device_id(client); struct iio_dev *indio_dev; struct abp_state *state; unsigned long cfg_id = id->driver_data; @@ -255,7 +255,7 @@ static struct i2c_driver abp060mg_driver = { .driver = { .name = "abp060mg", }, - .probe = abp060mg_probe, + .probe_new = abp060mg_probe, .id_table = abp060mg_id_table, }; module_i2c_driver(abp060mg_driver); -- cgit v1.2.3 From 046ae105f266aae218f76dc6321eebebeead6b94 Mon Sep 17 00:00:00 2001 From: Uwe Kleine-König Date: Fri, 18 Nov 2022 23:38:21 +0100 Subject: iio: pressure: dlhl60d: Convert to i2c's .probe_new() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit .probe_new() doesn't get the i2c_device_id * parameter, so determine that explicitly in the probe function. Signed-off-by: Uwe Kleine-König Reviewed-by: Andy Shevchenko Link: https://lore.kernel.org/r/20221118224540.619276-168-uwe@kleine-koenig.org Signed-off-by: Jonathan Cameron --- drivers/iio/pressure/dlhl60d.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers/iio') diff --git a/drivers/iio/pressure/dlhl60d.c b/drivers/iio/pressure/dlhl60d.c index f0b0d198c6d4..43650b048d62 100644 --- a/drivers/iio/pressure/dlhl60d.c +++ b/drivers/iio/pressure/dlhl60d.c @@ -282,9 +282,9 @@ static irqreturn_t dlh_interrupt(int irq, void *private) return IRQ_HANDLED; }; -static int dlh_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int dlh_probe(struct i2c_client *client) { + const struct i2c_device_id *id = i2c_client_get_device_id(client); struct dlh_state *st; struct iio_dev *indio_dev; int ret; @@ -362,7 +362,7 @@ static struct i2c_driver dlh_driver = { .name = "dlhl60d", .of_match_table = dlh_of_match, }, - .probe = dlh_probe, + .probe_new = dlh_probe, .id_table = dlh_id, }; module_i2c_driver(dlh_driver); -- cgit v1.2.3 From 92a54a29cf39f8f18632f9af43aa5baf4ff805bb Mon Sep 17 00:00:00 2001 From: Uwe Kleine-König Date: Fri, 18 Nov 2022 23:38:22 +0100 Subject: iio: pressure: dps310: Convert to i2c's .probe_new() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit .probe_new() doesn't get the i2c_device_id * parameter, so determine that explicitly in the probe function. Signed-off-by: Uwe Kleine-König Reviewed-by: Andy Shevchenko Link: https://lore.kernel.org/r/20221118224540.619276-169-uwe@kleine-koenig.org Signed-off-by: Jonathan Cameron --- drivers/iio/pressure/dps310.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers/iio') diff --git a/drivers/iio/pressure/dps310.c b/drivers/iio/pressure/dps310.c index 984a3f511a1a..2af275a24ff9 100644 --- a/drivers/iio/pressure/dps310.c +++ b/drivers/iio/pressure/dps310.c @@ -827,9 +827,9 @@ static const struct iio_info dps310_info = { .write_raw = dps310_write_raw, }; -static int dps310_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int dps310_probe(struct i2c_client *client) { + const struct i2c_device_id *id = i2c_client_get_device_id(client); struct dps310_data *data; struct iio_dev *iio; int rc; @@ -887,7 +887,7 @@ static struct i2c_driver dps310_driver = { .name = DPS310_DEV_NAME, .acpi_match_table = dps310_acpi_match, }, - .probe = dps310_probe, + .probe_new = dps310_probe, .id_table = dps310_id, }; module_i2c_driver(dps310_driver); -- cgit v1.2.3 From 3d5f5d599f61a2ab99768471cf56c61b1751f98f Mon Sep 17 00:00:00 2001 From: Uwe Kleine-König Date: Fri, 18 Nov 2022 23:38:23 +0100 Subject: iio: pressure: hp03: Convert to i2c's .probe_new() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit .probe_new() doesn't get the i2c_device_id * parameter, so determine that explicitly in the probe function. Signed-off-by: Uwe Kleine-König Reviewed-by: Andy Shevchenko Link: https://lore.kernel.org/r/20221118224540.619276-170-uwe@kleine-koenig.org Signed-off-by: Jonathan Cameron --- drivers/iio/pressure/hp03.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers/iio') diff --git a/drivers/iio/pressure/hp03.c b/drivers/iio/pressure/hp03.c index 9538118c9648..bd1f71a99cfa 100644 --- a/drivers/iio/pressure/hp03.c +++ b/drivers/iio/pressure/hp03.c @@ -208,9 +208,9 @@ static const struct iio_info hp03_info = { .read_raw = &hp03_read_raw, }; -static int hp03_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int hp03_probe(struct i2c_client *client) { + const struct i2c_device_id *id = i2c_client_get_device_id(client); struct device *dev = &client->dev; struct iio_dev *indio_dev; struct hp03_priv *priv; @@ -282,7 +282,7 @@ static struct i2c_driver hp03_driver = { .name = "hp03", .of_match_table = hp03_of_match, }, - .probe = hp03_probe, + .probe_new = hp03_probe, .id_table = hp03_id, }; module_i2c_driver(hp03_driver); -- cgit v1.2.3 From 240c69e09d3f77673653f56867aba2c69a66264d Mon Sep 17 00:00:00 2001 From: Uwe Kleine-König Date: Fri, 18 Nov 2022 23:38:24 +0100 Subject: iio: pressure: hp206c: Convert to i2c's .probe_new() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit .probe_new() doesn't get the i2c_device_id * parameter, so determine that explicitly in the probe function. Signed-off-by: Uwe Kleine-König Reviewed-by: Andy Shevchenko Link: https://lore.kernel.org/r/20221118224540.619276-171-uwe@kleine-koenig.org Signed-off-by: Jonathan Cameron --- drivers/iio/pressure/hp206c.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers/iio') diff --git a/drivers/iio/pressure/hp206c.c b/drivers/iio/pressure/hp206c.c index 986b7a59712e..b6d2ff464341 100644 --- a/drivers/iio/pressure/hp206c.c +++ b/drivers/iio/pressure/hp206c.c @@ -352,9 +352,9 @@ static const struct iio_info hp206c_info = { .write_raw = hp206c_write_raw, }; -static int hp206c_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int hp206c_probe(struct i2c_client *client) { + const struct i2c_device_id *id = i2c_client_get_device_id(client); struct iio_dev *indio_dev; struct hp206c_data *data; int ret; @@ -409,7 +409,7 @@ MODULE_DEVICE_TABLE(acpi, hp206c_acpi_match); #endif static struct i2c_driver hp206c_driver = { - .probe = hp206c_probe, + .probe_new = hp206c_probe, .id_table = hp206c_id, .driver = { .name = "hp206c", -- cgit v1.2.3 From 7a5da8b28618426a81f53f496de3a83d47df2634 Mon Sep 17 00:00:00 2001 From: Uwe Kleine-König Date: Fri, 18 Nov 2022 23:38:25 +0100 Subject: iio: pressure: icp10100: Convert to i2c's .probe_new() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The probe function doesn't make use of the i2c_device_id * parameter so it can be trivially converted. Signed-off-by: Uwe Kleine-König Reviewed-by: Andy Shevchenko Acked-by: Jean-Baptiste Maneyrol Link: https://lore.kernel.org/r/20221118224540.619276-172-uwe@kleine-koenig.org Signed-off-by: Jonathan Cameron --- drivers/iio/pressure/icp10100.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'drivers/iio') diff --git a/drivers/iio/pressure/icp10100.c b/drivers/iio/pressure/icp10100.c index b62f28585db5..407cf25ea0e3 100644 --- a/drivers/iio/pressure/icp10100.c +++ b/drivers/iio/pressure/icp10100.c @@ -530,8 +530,7 @@ static void icp10100_pm_disable(void *data) pm_runtime_disable(dev); } -static int icp10100_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int icp10100_probe(struct i2c_client *client) { struct iio_dev *indio_dev; struct icp10100_state *st; @@ -649,7 +648,7 @@ static struct i2c_driver icp10100_driver = { .pm = pm_ptr(&icp10100_pm), .of_match_table = icp10100_of_match, }, - .probe = icp10100_probe, + .probe_new = icp10100_probe, .id_table = icp10100_id, }; module_i2c_driver(icp10100_driver); -- cgit v1.2.3 From 8afce858762fc767dbd52d313adf058098332aaf Mon Sep 17 00:00:00 2001 From: Uwe Kleine-König Date: Fri, 18 Nov 2022 23:38:26 +0100 Subject: iio: pressure: mpl115_i2c: Convert to i2c's .probe_new() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit .probe_new() doesn't get the i2c_device_id * parameter, so determine that explicitly in the probe function. Signed-off-by: Uwe Kleine-König Reviewed-by: Andy Shevchenko Link: https://lore.kernel.org/r/20221118224540.619276-173-uwe@kleine-koenig.org Signed-off-by: Jonathan Cameron --- drivers/iio/pressure/mpl115_i2c.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers/iio') diff --git a/drivers/iio/pressure/mpl115_i2c.c b/drivers/iio/pressure/mpl115_i2c.c index 555bda1146fb..ade4dd854ddf 100644 --- a/drivers/iio/pressure/mpl115_i2c.c +++ b/drivers/iio/pressure/mpl115_i2c.c @@ -35,9 +35,9 @@ static const struct mpl115_ops mpl115_i2c_ops = { .write = mpl115_i2c_write, }; -static int mpl115_i2c_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int mpl115_i2c_probe(struct i2c_client *client) { + const struct i2c_device_id *id = i2c_client_get_device_id(client); if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_WORD_DATA)) return -EOPNOTSUPP; @@ -55,7 +55,7 @@ static struct i2c_driver mpl115_i2c_driver = { .name = "mpl115", .pm = pm_ptr(&mpl115_dev_pm_ops), }, - .probe = mpl115_i2c_probe, + .probe_new = mpl115_i2c_probe, .id_table = mpl115_i2c_id, }; module_i2c_driver(mpl115_i2c_driver); -- cgit v1.2.3 From 0586ce78a70c2792c4dfd415d1a427ea447bebd4 Mon Sep 17 00:00:00 2001 From: Uwe Kleine-König Date: Fri, 18 Nov 2022 23:38:27 +0100 Subject: iio: pressure: mpl3115: Convert to i2c's .probe_new() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit .probe_new() doesn't get the i2c_device_id * parameter, so determine that explicitly in the probe function. Signed-off-by: Uwe Kleine-König Reviewed-by: Andy Shevchenko Link: https://lore.kernel.org/r/20221118224540.619276-174-uwe@kleine-koenig.org Signed-off-by: Jonathan Cameron --- drivers/iio/pressure/mpl3115.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers/iio') diff --git a/drivers/iio/pressure/mpl3115.c b/drivers/iio/pressure/mpl3115.c index 2f22aba61e4d..72e811a5c96e 100644 --- a/drivers/iio/pressure/mpl3115.c +++ b/drivers/iio/pressure/mpl3115.c @@ -230,9 +230,9 @@ static const struct iio_info mpl3115_info = { .read_raw = &mpl3115_read_raw, }; -static int mpl3115_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int mpl3115_probe(struct i2c_client *client) { + const struct i2c_device_id *id = i2c_client_get_device_id(client); struct mpl3115_data *data; struct iio_dev *indio_dev; int ret; @@ -335,7 +335,7 @@ static struct i2c_driver mpl3115_driver = { .of_match_table = mpl3115_of_match, .pm = pm_sleep_ptr(&mpl3115_pm_ops), }, - .probe = mpl3115_probe, + .probe_new = mpl3115_probe, .remove = mpl3115_remove, .id_table = mpl3115_id, }; -- cgit v1.2.3 From eba7dcb65337dc2b081508317e10d0f1187121a9 Mon Sep 17 00:00:00 2001 From: Uwe Kleine-König Date: Fri, 18 Nov 2022 23:38:28 +0100 Subject: iio: pressure: ms5611_i2c: Convert to i2c's .probe_new() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit .probe_new() doesn't get the i2c_device_id * parameter, so determine that explicitly in the probe function. Signed-off-by: Uwe Kleine-König Reviewed-by: Andy Shevchenko Link: https://lore.kernel.org/r/20221118224540.619276-175-uwe@kleine-koenig.org Signed-off-by: Jonathan Cameron --- drivers/iio/pressure/ms5611_i2c.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers/iio') diff --git a/drivers/iio/pressure/ms5611_i2c.c b/drivers/iio/pressure/ms5611_i2c.c index b681a4183909..caf882497656 100644 --- a/drivers/iio/pressure/ms5611_i2c.c +++ b/drivers/iio/pressure/ms5611_i2c.c @@ -79,9 +79,9 @@ static int ms5611_i2c_read_adc_temp_and_pressure(struct ms5611_state *st, return ms5611_i2c_read_adc(st, pressure); } -static int ms5611_i2c_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int ms5611_i2c_probe(struct i2c_client *client) { + const struct i2c_device_id *id = i2c_client_get_device_id(client); struct ms5611_state *st; struct iio_dev *indio_dev; @@ -130,7 +130,7 @@ static struct i2c_driver ms5611_driver = { .of_match_table = ms5611_i2c_matches, }, .id_table = ms5611_id, - .probe = ms5611_i2c_probe, + .probe_new = ms5611_i2c_probe, .remove = ms5611_i2c_remove, }; module_i2c_driver(ms5611_driver); -- cgit v1.2.3 From f80ccc71c3f38d55662a6cfdec5a9e0907f6dfb6 Mon Sep 17 00:00:00 2001 From: Uwe Kleine-König Date: Fri, 18 Nov 2022 23:38:29 +0100 Subject: iio: pressure: ms5637: Convert to i2c's .probe_new() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit .probe_new() doesn't get the i2c_device_id * parameter, so determine that explicitly in the probe function. Signed-off-by: Uwe Kleine-König Reviewed-by: Andy Shevchenko Link: https://lore.kernel.org/r/20221118224540.619276-176-uwe@kleine-koenig.org Signed-off-by: Jonathan Cameron --- drivers/iio/pressure/ms5637.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers/iio') diff --git a/drivers/iio/pressure/ms5637.c b/drivers/iio/pressure/ms5637.c index 70c70019142a..c4981b29dccb 100644 --- a/drivers/iio/pressure/ms5637.c +++ b/drivers/iio/pressure/ms5637.c @@ -142,9 +142,9 @@ static const struct iio_info ms5637_info = { .attrs = &ms5637_attribute_group, }; -static int ms5637_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int ms5637_probe(struct i2c_client *client) { + const struct i2c_device_id *id = i2c_client_get_device_id(client); const struct ms_tp_data *data; struct ms_tp_dev *dev_data; struct iio_dev *indio_dev; @@ -238,7 +238,7 @@ static const struct of_device_id ms5637_of_match[] = { MODULE_DEVICE_TABLE(of, ms5637_of_match); static struct i2c_driver ms5637_driver = { - .probe = ms5637_probe, + .probe_new = ms5637_probe, .id_table = ms5637_id, .driver = { .name = "ms5637", -- cgit v1.2.3 From a52833a526b5e38be1aaf3e8f2e74a21bc679cb3 Mon Sep 17 00:00:00 2001 From: Uwe Kleine-König Date: Fri, 18 Nov 2022 23:38:30 +0100 Subject: iio: pressure: st_pressure_i2c: Convert to i2c's .probe_new() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The probe function doesn't make use of the i2c_device_id * parameter so it can be trivially converted. Signed-off-by: Uwe Kleine-König Reviewed-by: Andy Shevchenko Link: https://lore.kernel.org/r/20221118224540.619276-177-uwe@kleine-koenig.org Signed-off-by: Jonathan Cameron --- drivers/iio/pressure/st_pressure_i2c.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'drivers/iio') diff --git a/drivers/iio/pressure/st_pressure_i2c.c b/drivers/iio/pressure/st_pressure_i2c.c index 58fede861891..f2c3bb568d16 100644 --- a/drivers/iio/pressure/st_pressure_i2c.c +++ b/drivers/iio/pressure/st_pressure_i2c.c @@ -76,8 +76,7 @@ static const struct i2c_device_id st_press_id_table[] = { }; MODULE_DEVICE_TABLE(i2c, st_press_id_table); -static int st_press_i2c_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int st_press_i2c_probe(struct i2c_client *client) { const struct st_sensor_settings *settings; struct st_sensor_data *press_data; @@ -117,7 +116,7 @@ static struct i2c_driver st_press_driver = { .of_match_table = st_press_of_match, .acpi_match_table = ACPI_PTR(st_press_acpi_match), }, - .probe = st_press_i2c_probe, + .probe_new = st_press_i2c_probe, .id_table = st_press_id_table, }; module_i2c_driver(st_press_driver); -- cgit v1.2.3 From aa9b3321735d42d3a2a2e58ce25be5586396c8a8 Mon Sep 17 00:00:00 2001 From: Uwe Kleine-König Date: Fri, 18 Nov 2022 23:38:31 +0100 Subject: iio: pressure: t5403: Convert to i2c's .probe_new() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit .probe_new() doesn't get the i2c_device_id * parameter, so determine that explicitly in the probe function. Signed-off-by: Uwe Kleine-König Reviewed-by: Andy Shevchenko Link: https://lore.kernel.org/r/20221118224540.619276-178-uwe@kleine-koenig.org Signed-off-by: Jonathan Cameron --- drivers/iio/pressure/t5403.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers/iio') diff --git a/drivers/iio/pressure/t5403.c b/drivers/iio/pressure/t5403.c index 685fcf65334f..2fbf14aff033 100644 --- a/drivers/iio/pressure/t5403.c +++ b/drivers/iio/pressure/t5403.c @@ -208,9 +208,9 @@ static const struct iio_info t5403_info = { .attrs = &t5403_attribute_group, }; -static int t5403_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int t5403_probe(struct i2c_client *client) { + const struct i2c_device_id *id = i2c_client_get_device_id(client); struct t5403_data *data; struct iio_dev *indio_dev; int ret; @@ -260,7 +260,7 @@ static struct i2c_driver t5403_driver = { .driver = { .name = "t5403", }, - .probe = t5403_probe, + .probe_new = t5403_probe, .id_table = t5403_id, }; module_i2c_driver(t5403_driver); -- cgit v1.2.3 From 1bee48f48a69013cdd5ed5fdbff1e0410a18a381 Mon Sep 17 00:00:00 2001 From: Uwe Kleine-König Date: Fri, 18 Nov 2022 23:38:32 +0100 Subject: iio: pressure: zpa2326_i2c: Convert to i2c's .probe_new() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit .probe_new() doesn't get the i2c_device_id * parameter, so determine that explicitly in the probe function. Signed-off-by: Uwe Kleine-König Reviewed-by: Andy Shevchenko Link: https://lore.kernel.org/r/20221118224540.619276-179-uwe@kleine-koenig.org Signed-off-by: Jonathan Cameron --- drivers/iio/pressure/zpa2326_i2c.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers/iio') diff --git a/drivers/iio/pressure/zpa2326_i2c.c b/drivers/iio/pressure/zpa2326_i2c.c index f26dd8cbb387..ade465014be1 100644 --- a/drivers/iio/pressure/zpa2326_i2c.c +++ b/drivers/iio/pressure/zpa2326_i2c.c @@ -38,9 +38,9 @@ static unsigned int zpa2326_i2c_hwid(const struct i2c_client *client) (ZPA2326_SA0(client->addr) << ZPA2326_DEVICE_ID_SA0_SHIFT)); } -static int zpa2326_probe_i2c(struct i2c_client *client, - const struct i2c_device_id *i2c_id) +static int zpa2326_probe_i2c(struct i2c_client *client) { + const struct i2c_device_id *i2c_id = i2c_client_get_device_id(client); struct regmap *regmap; regmap = devm_regmap_init_i2c(client, &zpa2326_regmap_i2c_config); @@ -76,7 +76,7 @@ static struct i2c_driver zpa2326_i2c_driver = { .of_match_table = zpa2326_i2c_matches, .pm = ZPA2326_PM_OPS, }, - .probe = zpa2326_probe_i2c, + .probe_new = zpa2326_probe_i2c, .remove = zpa2326_remove_i2c, .id_table = zpa2326_i2c_ids, }; -- cgit v1.2.3 From 9d6f774dd4ff150ce7a5bb2bf64918b3b72cda11 Mon Sep 17 00:00:00 2001 From: Uwe Kleine-König Date: Fri, 18 Nov 2022 23:38:33 +0100 Subject: iio: proximity: isl29501: Convert to i2c's .probe_new() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The probe function doesn't make use of the i2c_device_id * parameter so it can be trivially converted. Signed-off-by: Uwe Kleine-König Reviewed-by: Andy Shevchenko Link: https://lore.kernel.org/r/20221118224540.619276-180-uwe@kleine-koenig.org Signed-off-by: Jonathan Cameron --- drivers/iio/proximity/isl29501.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'drivers/iio') diff --git a/drivers/iio/proximity/isl29501.c b/drivers/iio/proximity/isl29501.c index 5b6ea783795d..7b8f40b7ccf3 100644 --- a/drivers/iio/proximity/isl29501.c +++ b/drivers/iio/proximity/isl29501.c @@ -949,8 +949,7 @@ static irqreturn_t isl29501_trigger_handler(int irq, void *p) return IRQ_HANDLED; } -static int isl29501_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int isl29501_probe(struct i2c_client *client) { struct iio_dev *indio_dev; struct isl29501_private *isl29501; @@ -1009,7 +1008,7 @@ static struct i2c_driver isl29501_driver = { .name = "isl29501", }, .id_table = isl29501_id, - .probe = isl29501_probe, + .probe_new = isl29501_probe, }; module_i2c_driver(isl29501_driver); -- cgit v1.2.3 From 5c5c482e02bcd09bf113853b7520ad121dba081b Mon Sep 17 00:00:00 2001 From: Uwe Kleine-König Date: Fri, 18 Nov 2022 23:38:34 +0100 Subject: iio: proximity: mb1232: Convert to i2c's .probe_new() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit .probe_new() doesn't get the i2c_device_id * parameter, so determine that explicitly in the probe function. Signed-off-by: Uwe Kleine-König Reviewed-by: Andy Shevchenko Link: https://lore.kernel.org/r/20221118224540.619276-181-uwe@kleine-koenig.org Signed-off-by: Jonathan Cameron --- drivers/iio/proximity/mb1232.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers/iio') diff --git a/drivers/iio/proximity/mb1232.c b/drivers/iio/proximity/mb1232.c index 0bca5f74de68..e70cac8240af 100644 --- a/drivers/iio/proximity/mb1232.c +++ b/drivers/iio/proximity/mb1232.c @@ -180,9 +180,9 @@ static const struct iio_info mb1232_info = { .read_raw = mb1232_read_raw, }; -static int mb1232_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int mb1232_probe(struct i2c_client *client) { + const struct i2c_device_id *id = i2c_client_get_device_id(client); struct iio_dev *indio_dev; struct mb1232_data *data; int ret; @@ -264,7 +264,7 @@ static struct i2c_driver mb1232_driver = { .name = "maxbotix-mb1232", .of_match_table = of_mb1232_match, }, - .probe = mb1232_probe, + .probe_new = mb1232_probe, .id_table = mb1232_id, }; module_i2c_driver(mb1232_driver); -- cgit v1.2.3 From 94c80ea7677c9d1886673a4f6764e19c5309b11c Mon Sep 17 00:00:00 2001 From: Uwe Kleine-König Date: Fri, 18 Nov 2022 23:38:35 +0100 Subject: iio: proximity: pulsedlight-lidar-lite-v2: Convert to i2c's .probe_new() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The probe function doesn't make use of the i2c_device_id * parameter so it can be trivially converted. Signed-off-by: Uwe Kleine-König Reviewed-by: Andy Shevchenko Link: https://lore.kernel.org/r/20221118224540.619276-182-uwe@kleine-koenig.org Signed-off-by: Jonathan Cameron --- drivers/iio/proximity/pulsedlight-lidar-lite-v2.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'drivers/iio') diff --git a/drivers/iio/proximity/pulsedlight-lidar-lite-v2.c b/drivers/iio/proximity/pulsedlight-lidar-lite-v2.c index 791a33d5286c..c9eead01a031 100644 --- a/drivers/iio/proximity/pulsedlight-lidar-lite-v2.c +++ b/drivers/iio/proximity/pulsedlight-lidar-lite-v2.c @@ -253,8 +253,7 @@ static const struct iio_info lidar_info = { .read_raw = lidar_read_raw, }; -static int lidar_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int lidar_probe(struct i2c_client *client) { struct lidar_data *data; struct iio_dev *indio_dev; @@ -366,7 +365,7 @@ static struct i2c_driver lidar_driver = { .of_match_table = lidar_dt_ids, .pm = pm_ptr(&lidar_pm_ops), }, - .probe = lidar_probe, + .probe_new = lidar_probe, .remove = lidar_remove, .id_table = lidar_id, }; -- cgit v1.2.3 From 576eb2b091084425eea6edd36d4407d139387d6d Mon Sep 17 00:00:00 2001 From: Uwe Kleine-König Date: Fri, 18 Nov 2022 23:38:36 +0100 Subject: iio: proximity: rfd77402: Convert to i2c's .probe_new() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The probe function doesn't make use of the i2c_device_id * parameter so it can be trivially converted. Signed-off-by: Uwe Kleine-König Reviewed-by: Andy Shevchenko Link: https://lore.kernel.org/r/20221118224540.619276-183-uwe@kleine-koenig.org Signed-off-by: Jonathan Cameron --- drivers/iio/proximity/rfd77402.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'drivers/iio') diff --git a/drivers/iio/proximity/rfd77402.c b/drivers/iio/proximity/rfd77402.c index cb80b3c9d073..44f72b78bd50 100644 --- a/drivers/iio/proximity/rfd77402.c +++ b/drivers/iio/proximity/rfd77402.c @@ -257,8 +257,7 @@ static void rfd77402_disable(void *client) rfd77402_powerdown(client); } -static int rfd77402_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int rfd77402_probe(struct i2c_client *client) { struct rfd77402_data *data; struct iio_dev *indio_dev; @@ -319,7 +318,7 @@ static struct i2c_driver rfd77402_driver = { .name = RFD77402_DRV_NAME, .pm = pm_sleep_ptr(&rfd77402_pm_ops), }, - .probe = rfd77402_probe, + .probe_new = rfd77402_probe, .id_table = rfd77402_id, }; -- cgit v1.2.3 From 038b0fac0abe2f5d9beee2511434f231a58f41fd Mon Sep 17 00:00:00 2001 From: Uwe Kleine-König Date: Fri, 18 Nov 2022 23:38:37 +0100 Subject: iio: proximity: srf08: Convert to i2c's .probe_new() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit .probe_new() doesn't get the i2c_device_id * parameter, so determine that explicitly in the probe function. Signed-off-by: Uwe Kleine-König Reviewed-by: Andy Shevchenko Link: https://lore.kernel.org/r/20221118224540.619276-184-uwe@kleine-koenig.org Signed-off-by: Jonathan Cameron --- drivers/iio/proximity/srf08.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers/iio') diff --git a/drivers/iio/proximity/srf08.c b/drivers/iio/proximity/srf08.c index 7ed11339c31e..61866d0440f7 100644 --- a/drivers/iio/proximity/srf08.c +++ b/drivers/iio/proximity/srf08.c @@ -443,9 +443,9 @@ static const struct iio_info srf02_info = { .read_raw = srf08_read_raw, }; -static int srf08_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int srf08_probe(struct i2c_client *client) { + const struct i2c_device_id *id = i2c_client_get_device_id(client); struct iio_dev *indio_dev; struct srf08_data *data; int ret; @@ -549,7 +549,7 @@ static struct i2c_driver srf08_driver = { .name = "srf08", .of_match_table = of_srf08_match, }, - .probe = srf08_probe, + .probe_new = srf08_probe, .id_table = srf08_id, }; module_i2c_driver(srf08_driver); -- cgit v1.2.3 From 7660d32e6f9608b5bea7d066c74d63fc7666c510 Mon Sep 17 00:00:00 2001 From: Uwe Kleine-König Date: Fri, 18 Nov 2022 23:38:38 +0100 Subject: iio: proximity: sx9500: Convert to i2c's .probe_new() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The probe function doesn't make use of the i2c_device_id * parameter so it can be trivially converted. Signed-off-by: Uwe Kleine-König Reviewed-by: Andy Shevchenko Link: https://lore.kernel.org/r/20221118224540.619276-185-uwe@kleine-koenig.org Signed-off-by: Jonathan Cameron --- drivers/iio/proximity/sx9500.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'drivers/iio') diff --git a/drivers/iio/proximity/sx9500.c b/drivers/iio/proximity/sx9500.c index d4670864ddc7..8794e75e5bf9 100644 --- a/drivers/iio/proximity/sx9500.c +++ b/drivers/iio/proximity/sx9500.c @@ -901,8 +901,7 @@ static void sx9500_gpio_probe(struct i2c_client *client, } } -static int sx9500_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int sx9500_probe(struct i2c_client *client) { int ret; struct iio_dev *indio_dev; @@ -1056,7 +1055,7 @@ static struct i2c_driver sx9500_driver = { .of_match_table = of_match_ptr(sx9500_of_match), .pm = pm_sleep_ptr(&sx9500_pm_ops), }, - .probe = sx9500_probe, + .probe_new = sx9500_probe, .remove = sx9500_remove, .id_table = sx9500_id, }; -- cgit v1.2.3 From 160c7140bb25a1921c4f3845bb15423721bcc0fb Mon Sep 17 00:00:00 2001 From: Uwe Kleine-König Date: Fri, 18 Nov 2022 23:38:39 +0100 Subject: iio: temperature: mlx90614: Convert to i2c's .probe_new() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit .probe_new() doesn't get the i2c_device_id * parameter, so determine that explicitly in the probe function. Signed-off-by: Uwe Kleine-König Acked-by: Crt Mori Reviewed-by: Andy Shevchenko Link: https://lore.kernel.org/r/20221118224540.619276-186-uwe@kleine-koenig.org Signed-off-by: Jonathan Cameron --- drivers/iio/temperature/mlx90614.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers/iio') diff --git a/drivers/iio/temperature/mlx90614.c b/drivers/iio/temperature/mlx90614.c index 8eb0f962ed25..909fadb62349 100644 --- a/drivers/iio/temperature/mlx90614.c +++ b/drivers/iio/temperature/mlx90614.c @@ -537,9 +537,9 @@ static int mlx90614_probe_num_ir_sensors(struct i2c_client *client) return (ret & MLX90614_CONFIG_DUAL_MASK) ? 1 : 0; } -static int mlx90614_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int mlx90614_probe(struct i2c_client *client) { + const struct i2c_device_id *id = i2c_client_get_device_id(client); struct iio_dev *indio_dev; struct mlx90614_data *data; int ret; @@ -675,7 +675,7 @@ static struct i2c_driver mlx90614_driver = { .of_match_table = mlx90614_of_match, .pm = pm_ptr(&mlx90614_pm_ops), }, - .probe = mlx90614_probe, + .probe_new = mlx90614_probe, .remove = mlx90614_remove, .id_table = mlx90614_id, }; -- cgit v1.2.3 From 40fbb59b9c132e401b7487ab2792e6dcd3f14809 Mon Sep 17 00:00:00 2001 From: Uwe Kleine-König Date: Fri, 18 Nov 2022 23:38:40 +0100 Subject: iio: temperature: mlx90632: Convert to i2c's .probe_new() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit .probe_new() doesn't get the i2c_device_id * parameter, so determine that explicitly in the probe function. Signed-off-by: Uwe Kleine-König Acked-by: Crt Mori Reviewed-by: Andy Shevchenko Link: https://lore.kernel.org/r/20221118224540.619276-187-uwe@kleine-koenig.org Signed-off-by: Jonathan Cameron --- drivers/iio/temperature/mlx90632.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers/iio') diff --git a/drivers/iio/temperature/mlx90632.c b/drivers/iio/temperature/mlx90632.c index f1f5ebc145b1..753b7a4ccfdd 100644 --- a/drivers/iio/temperature/mlx90632.c +++ b/drivers/iio/temperature/mlx90632.c @@ -1168,9 +1168,9 @@ static int mlx90632_enable_regulator(struct mlx90632_data *data) return ret; } -static int mlx90632_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int mlx90632_probe(struct i2c_client *client) { + const struct i2c_device_id *id = i2c_client_get_device_id(client); struct mlx90632_data *mlx90632; struct iio_dev *indio_dev; struct regmap *regmap; @@ -1337,7 +1337,7 @@ static struct i2c_driver mlx90632_driver = { .of_match_table = mlx90632_of_match, .pm = pm_ptr(&mlx90632_pm_ops), }, - .probe = mlx90632_probe, + .probe_new = mlx90632_probe, .id_table = mlx90632_id, }; module_i2c_driver(mlx90632_driver); -- cgit v1.2.3 From 89824f4cb65e7a7174cb24e4c0835e4c37f74a21 Mon Sep 17 00:00:00 2001 From: Uwe Kleine-König Date: Fri, 18 Nov 2022 23:38:41 +0100 Subject: iio: temperature: tmp006: Convert to i2c's .probe_new() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The probe function doesn't make use of the i2c_device_id * parameter so it can be trivially converted. Signed-off-by: Uwe Kleine-König Reviewed-by: Andy Shevchenko Link: https://lore.kernel.org/r/20221118224540.619276-188-uwe@kleine-koenig.org Signed-off-by: Jonathan Cameron --- drivers/iio/temperature/tmp006.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'drivers/iio') diff --git a/drivers/iio/temperature/tmp006.c b/drivers/iio/temperature/tmp006.c index 706a760f30b4..cdf08477e63f 100644 --- a/drivers/iio/temperature/tmp006.c +++ b/drivers/iio/temperature/tmp006.c @@ -212,8 +212,7 @@ static void tmp006_powerdown_cleanup(void *dev) tmp006_power(dev, false); } -static int tmp006_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int tmp006_probe(struct i2c_client *client) { struct iio_dev *indio_dev; struct tmp006_data *data; @@ -284,7 +283,7 @@ static struct i2c_driver tmp006_driver = { .name = "tmp006", .pm = pm_sleep_ptr(&tmp006_pm_ops), }, - .probe = tmp006_probe, + .probe_new = tmp006_probe, .id_table = tmp006_id, }; module_i2c_driver(tmp006_driver); -- cgit v1.2.3 From f1e7d53ddfc309149521a2812c3ffcd54eb67b04 Mon Sep 17 00:00:00 2001 From: Uwe Kleine-König Date: Fri, 18 Nov 2022 23:38:42 +0100 Subject: iio: temperature: tmp007: Convert to i2c's .probe_new() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit .probe_new() doesn't get the i2c_device_id * parameter, so determine that explicitly in the probe function. Signed-off-by: Uwe Kleine-König Reviewed-by: Andy Shevchenko Link: https://lore.kernel.org/r/20221118224540.619276-189-uwe@kleine-koenig.org Signed-off-by: Jonathan Cameron --- drivers/iio/temperature/tmp007.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers/iio') diff --git a/drivers/iio/temperature/tmp007.c b/drivers/iio/temperature/tmp007.c index f3420d8a0e35..8d27aa3bdd6d 100644 --- a/drivers/iio/temperature/tmp007.c +++ b/drivers/iio/temperature/tmp007.c @@ -446,9 +446,9 @@ static void tmp007_powerdown_action_cb(void *priv) tmp007_powerdown(data); } -static int tmp007_probe(struct i2c_client *client, - const struct i2c_device_id *tmp007_id) +static int tmp007_probe(struct i2c_client *client) { + const struct i2c_device_id *tmp007_id = i2c_client_get_device_id(client); struct tmp007_data *data; struct iio_dev *indio_dev; int ret; @@ -574,7 +574,7 @@ static struct i2c_driver tmp007_driver = { .of_match_table = tmp007_of_match, .pm = pm_sleep_ptr(&tmp007_pm_ops), }, - .probe = tmp007_probe, + .probe_new = tmp007_probe, .id_table = tmp007_id, }; module_i2c_driver(tmp007_driver); -- cgit v1.2.3 From d7c9422850aad0e57316f74c2f9cdfc18be39459 Mon Sep 17 00:00:00 2001 From: Uwe Kleine-König Date: Fri, 18 Nov 2022 23:38:43 +0100 Subject: iio: temperature: tsys01: Convert to i2c's .probe_new() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The probe function doesn't make use of the i2c_device_id * parameter so it can be trivially converted. Signed-off-by: Uwe Kleine-König Reviewed-by: Andy Shevchenko Link: https://lore.kernel.org/r/20221118224540.619276-190-uwe@kleine-koenig.org Signed-off-by: Jonathan Cameron --- drivers/iio/temperature/tsys01.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'drivers/iio') diff --git a/drivers/iio/temperature/tsys01.c b/drivers/iio/temperature/tsys01.c index 60d58ec5b063..30b268ba82cc 100644 --- a/drivers/iio/temperature/tsys01.c +++ b/drivers/iio/temperature/tsys01.c @@ -176,8 +176,7 @@ static int tsys01_probe(struct iio_dev *indio_dev, struct device *dev) return devm_iio_device_register(dev, indio_dev); } -static int tsys01_i2c_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int tsys01_i2c_probe(struct i2c_client *client) { struct tsys01_dev *dev_data; struct iio_dev *indio_dev; @@ -219,7 +218,7 @@ static const struct of_device_id tsys01_of_match[] = { MODULE_DEVICE_TABLE(of, tsys01_of_match); static struct i2c_driver tsys01_driver = { - .probe = tsys01_i2c_probe, + .probe_new = tsys01_i2c_probe, .id_table = tsys01_id, .driver = { .name = "tsys01", -- cgit v1.2.3 From 6a9113195fff8e48d8898cdab82c96bb77780228 Mon Sep 17 00:00:00 2001 From: Uwe Kleine-König Date: Fri, 18 Nov 2022 23:38:44 +0100 Subject: iio: temperature: tsys02d: Convert to i2c's .probe_new() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit .probe_new() doesn't get the i2c_device_id * parameter, so determine that explicitly in the probe function. Signed-off-by: Uwe Kleine-König Reviewed-by: Andy Shevchenko Link: https://lore.kernel.org/r/20221118224540.619276-191-uwe@kleine-koenig.org Signed-off-by: Jonathan Cameron --- drivers/iio/temperature/tsys02d.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers/iio') diff --git a/drivers/iio/temperature/tsys02d.c b/drivers/iio/temperature/tsys02d.c index 49c275e4f510..cdefe046ab17 100644 --- a/drivers/iio/temperature/tsys02d.c +++ b/drivers/iio/temperature/tsys02d.c @@ -121,9 +121,9 @@ static const struct iio_info tsys02d_info = { .attrs = &tsys02d_attribute_group, }; -static int tsys02d_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int tsys02d_probe(struct i2c_client *client) { + const struct i2c_device_id *id = i2c_client_get_device_id(client); struct ms_ht_dev *dev_data; struct iio_dev *indio_dev; int ret; @@ -174,7 +174,7 @@ static const struct i2c_device_id tsys02d_id[] = { MODULE_DEVICE_TABLE(i2c, tsys02d_id); static struct i2c_driver tsys02d_driver = { - .probe = tsys02d_probe, + .probe_new = tsys02d_probe, .id_table = tsys02d_id, .driver = { .name = "tsys02d", -- cgit v1.2.3 From 9ee95ae4cffd04e0773f16118b343104bab80634 Mon Sep 17 00:00:00 2001 From: Rajat Khandelwal Date: Tue, 22 Nov 2022 23:23:00 +0530 Subject: iio: temperature: Add driver support for Maxim MAX30208 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Maxim MAX30208 is a digital temperature sensor with 0.1°C accuracy. Add support for max30208 driver in iio subsystem. Datasheet: https://datasheets.maximintegrated.com/en/ds/MAX30208.pdf Signed-off-by: Rajat Khandelwal Link: https://lore.kernel.org/r/20221122175300.800956-1-rajat.khandelwal@linux.intel.com Signed-off-by: Jonathan Cameron --- MAINTAINERS | 6 + drivers/iio/temperature/Kconfig | 10 ++ drivers/iio/temperature/Makefile | 1 + drivers/iio/temperature/max30208.c | 252 +++++++++++++++++++++++++++++++++++++ 4 files changed, 269 insertions(+) create mode 100644 drivers/iio/temperature/max30208.c (limited to 'drivers/iio') diff --git a/MAINTAINERS b/MAINTAINERS index be373dfae4dd..f1e1ac23a1c6 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -12518,6 +12518,12 @@ S: Maintained F: Documentation/devicetree/bindings/regulator/maxim,max20086.yaml F: drivers/regulator/max20086-regulator.c +MAXIM MAX30208 TEMPERATURE SENSOR DRIVER +M: Rajat Khandelwal +L: linux-iio@vger.kernel.org +S: Maintained +F: drivers/iio/temperature/max30208.c + MAXIM MAX77650 PMIC MFD DRIVER M: Bartosz Golaszewski L: linux-kernel@vger.kernel.org diff --git a/drivers/iio/temperature/Kconfig b/drivers/iio/temperature/Kconfig index e8ed849e3b76..ed384f33e0c7 100644 --- a/drivers/iio/temperature/Kconfig +++ b/drivers/iio/temperature/Kconfig @@ -128,6 +128,16 @@ config TSYS02D This driver can also be built as a module. If so, the module will be called tsys02d. +config MAX30208 + tristate "Maxim MAX30208 digital temperature sensor" + depends on I2C + help + If you say yes here you get support for Maxim MAX30208 + digital temperature sensor connected via I2C. + + This driver can also be built as a module. If so, the module + will be called max30208. + config MAX31856 tristate "MAX31856 thermocouple sensor" depends on SPI diff --git a/drivers/iio/temperature/Makefile b/drivers/iio/temperature/Makefile index dd08e562ffe0..dfec8c6d3019 100644 --- a/drivers/iio/temperature/Makefile +++ b/drivers/iio/temperature/Makefile @@ -7,6 +7,7 @@ obj-$(CONFIG_IQS620AT_TEMP) += iqs620at-temp.o obj-$(CONFIG_LTC2983) += ltc2983.o obj-$(CONFIG_HID_SENSOR_TEMP) += hid-sensor-temperature.o obj-$(CONFIG_MAXIM_THERMOCOUPLE) += maxim_thermocouple.o +obj-$(CONFIG_MAX30208) += max30208.o obj-$(CONFIG_MAX31856) += max31856.o obj-$(CONFIG_MAX31865) += max31865.o obj-$(CONFIG_MLX90614) += mlx90614.o diff --git a/drivers/iio/temperature/max30208.c b/drivers/iio/temperature/max30208.c new file mode 100644 index 000000000000..c85c21474711 --- /dev/null +++ b/drivers/iio/temperature/max30208.c @@ -0,0 +1,252 @@ +// SPDX-License-Identifier: GPL-2.0-only + +/* + * Copyright (c) Rajat Khandelwal + * + * Maxim MAX30208 digital temperature sensor with 0.1°C accuracy + * (7-bit I2C slave address (0x50 - 0x53)) + */ + +#include +#include +#include +#include +#include +#include + +#define MAX30208_STATUS 0x00 +#define MAX30208_STATUS_TEMP_RDY BIT(0) +#define MAX30208_INT_ENABLE 0x01 +#define MAX30208_INT_ENABLE_TEMP_RDY BIT(0) + +#define MAX30208_FIFO_OVF_CNTR 0x06 +#define MAX30208_FIFO_DATA_CNTR 0x07 +#define MAX30208_FIFO_DATA 0x08 + +#define MAX30208_FIFO_CONFIG 0x0a +#define MAX30208_FIFO_CONFIG_RO BIT(1) + +#define MAX30208_SYSTEM_CTRL 0x0c +#define MAX30208_SYSTEM_CTRL_RESET 0x01 + +#define MAX30208_TEMP_SENSOR_SETUP 0x14 +#define MAX30208_TEMP_SENSOR_SETUP_CONV BIT(0) + +struct max30208_data { + struct i2c_client *client; + struct iio_dev *indio_dev; + struct mutex lock; /* Lock to prevent concurrent reads of temperature readings */ +}; + +static const struct iio_chan_spec max30208_channels[] = { + { + .type = IIO_TEMP, + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | BIT(IIO_CHAN_INFO_SCALE), + }, +}; + +/** + * max30208_request() - Request a reading + * @data: Struct comprising member elements of the device + * + * Requests a reading from the device and waits until the conversion is ready. + */ +static int max30208_request(struct max30208_data *data) +{ + /* + * Sensor can take up to 500 ms to respond so execute a total of + * 10 retries to give the device sufficient time. + */ + int retries = 10; + u8 regval; + int ret; + + ret = i2c_smbus_read_byte_data(data->client, MAX30208_TEMP_SENSOR_SETUP); + if (ret < 0) + return ret; + + regval = ret | MAX30208_TEMP_SENSOR_SETUP_CONV; + + ret = i2c_smbus_write_byte_data(data->client, MAX30208_TEMP_SENSOR_SETUP, regval); + if (ret) + return ret; + + while (retries--) { + ret = i2c_smbus_read_byte_data(data->client, MAX30208_STATUS); + if (ret < 0) + return ret; + + if (ret & MAX30208_STATUS_TEMP_RDY) + return 0; + + msleep(50); + } + dev_err(&data->client->dev, "Temperature conversion failed\n"); + + return -ETIMEDOUT; +} + +static int max30208_update_temp(struct max30208_data *data) +{ + u8 data_count; + int ret; + + mutex_lock(&data->lock); + + ret = max30208_request(data); + if (ret) + goto unlock; + + ret = i2c_smbus_read_byte_data(data->client, MAX30208_FIFO_OVF_CNTR); + if (ret < 0) + goto unlock; + else if (!ret) { + ret = i2c_smbus_read_byte_data(data->client, MAX30208_FIFO_DATA_CNTR); + if (ret < 0) + goto unlock; + + data_count = ret; + } else + data_count = 1; + + while (data_count) { + ret = i2c_smbus_read_word_swapped(data->client, MAX30208_FIFO_DATA); + if (ret < 0) + goto unlock; + + data_count--; + } + +unlock: + mutex_unlock(&data->lock); + return ret; +} + +/** + * max30208_config_setup() - Set up FIFO configuration register + * @data: Struct comprising member elements of the device + * + * Sets the rollover bit to '1' to enable overwriting FIFO during overflow. + */ +static int max30208_config_setup(struct max30208_data *data) +{ + u8 regval; + int ret; + + ret = i2c_smbus_read_byte_data(data->client, MAX30208_FIFO_CONFIG); + if (ret < 0) + return ret; + + regval = ret | MAX30208_FIFO_CONFIG_RO; + + ret = i2c_smbus_write_byte_data(data->client, MAX30208_FIFO_CONFIG, regval); + if (ret) + return ret; + + return 0; +} + +static int max30208_read(struct iio_dev *indio_dev, + struct iio_chan_spec const *chan, + int *val, int *val2, long mask) +{ + struct max30208_data *data = iio_priv(indio_dev); + int ret; + + switch (mask) { + case IIO_CHAN_INFO_RAW: + ret = max30208_update_temp(data); + if (ret < 0) + return ret; + + *val = sign_extend32(ret, 15); + return IIO_VAL_INT; + + case IIO_CHAN_INFO_SCALE: + *val = 5; + return IIO_VAL_INT; + + default: + return -EINVAL; + } +} + +static const struct iio_info max30208_info = { + .read_raw = max30208_read, +}; + +static int max30208_probe(struct i2c_client *i2c) +{ + struct device *dev = &i2c->dev; + struct max30208_data *data; + struct iio_dev *indio_dev; + int ret; + + indio_dev = devm_iio_device_alloc(dev, sizeof(*data)); + if (!indio_dev) + return -ENOMEM; + + data = iio_priv(indio_dev); + data->client = i2c; + mutex_init(&data->lock); + + indio_dev->name = "max30208"; + indio_dev->channels = max30208_channels; + indio_dev->num_channels = ARRAY_SIZE(max30208_channels); + indio_dev->info = &max30208_info; + indio_dev->modes = INDIO_DIRECT_MODE; + + ret = i2c_smbus_write_byte_data(data->client, MAX30208_SYSTEM_CTRL, + MAX30208_SYSTEM_CTRL_RESET); + if (ret) { + dev_err(dev, "Failure in performing reset\n"); + return ret; + } + + msleep(50); + + ret = max30208_config_setup(data); + if (ret) + return ret; + + ret = devm_iio_device_register(dev, indio_dev); + if (ret) { + dev_err(dev, "Failed to register IIO device\n"); + return ret; + } + + return 0; +} + +static const struct i2c_device_id max30208_id_table[] = { + { "max30208" }, + { } +}; +MODULE_DEVICE_TABLE(i2c, max30208_id_table); + +static const struct acpi_device_id max30208_acpi_match[] = { + { "MAX30208" }, + { } +}; +MODULE_DEVICE_TABLE(acpi, max30208_acpi_match); + +static const struct of_device_id max30208_of_match[] = { + { .compatible = "maxim,max30208" }, + { } +}; +MODULE_DEVICE_TABLE(of, max30208_of_match); + +static struct i2c_driver max30208_driver = { + .driver = { + .name = "max30208", + .of_match_table = max30208_of_match, + .acpi_match_table = max30208_acpi_match, + }, + .probe_new = max30208_probe, + .id_table = max30208_id_table, +}; +module_i2c_driver(max30208_driver); + +MODULE_AUTHOR("Rajat Khandelwal "); +MODULE_DESCRIPTION("Maxim MAX30208 digital temperature sensor"); +MODULE_LICENSE("GPL"); -- cgit v1.2.3 From 99b43a15915543484d7538cb32f49901e802628a Mon Sep 17 00:00:00 2001 From: Ibrahim Tilki Date: Tue, 22 Nov 2022 14:47:18 +0300 Subject: iio: adc: max11410: fix incomplete vref buffer mask VREFP bit was missing from channel configuration mask and VREFN bit was included twice instead which fails to enable positive reference buffer when requested by a channel. Channels that don't enable vrefp buffer were not affected. Fixes: a44ef7c46097 ("iio: adc: add max11410 adc driver") Reported-by: kernel test robot Reported-by: Julia Lawall Signed-off-by: Ibrahim Tilki Link: https://lore.kernel.org/r/20221122114718.17557-1-Ibrahim.Tilki@analog.com Signed-off-by: Jonathan Cameron --- drivers/iio/adc/max11410.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/iio') diff --git a/drivers/iio/adc/max11410.c b/drivers/iio/adc/max11410.c index 8cd566367187..fdc9f03135b5 100644 --- a/drivers/iio/adc/max11410.c +++ b/drivers/iio/adc/max11410.c @@ -370,7 +370,7 @@ static int max11410_configure_channel(struct max11410_state *st, FIELD_PREP(MAX11410_CTRL_UNIPOLAR_BIT, cfg.bipolar ? 0 : 1); ret = regmap_update_bits(st->regmap, MAX11410_REG_CTRL, MAX11410_CTRL_REFSEL_MASK | - MAX11410_CTRL_VREFN_BUF_BIT | + MAX11410_CTRL_VREFP_BUF_BIT | MAX11410_CTRL_VREFN_BUF_BIT | MAX11410_CTRL_UNIPOLAR_BIT, regval); if (ret) -- cgit v1.2.3 From 99c05e4283a19a02a256f14100ca4ec3b2da3f62 Mon Sep 17 00:00:00 2001 From: Ramona Bolboaca Date: Tue, 22 Nov 2022 10:27:49 +0200 Subject: iio: adis: add '__adis_enable_irq()' implementation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add '__adis_enable_irq()' implementation which is the unlocked version of 'adis_enable_irq()'. Call '__adis_enable_irq()' instead of 'adis_enable_irq()' from '__adis_intial_startup()' to keep the expected unlocked functionality. This fix is needed to remove a deadlock for all devices which are using 'adis_initial_startup()'. The deadlock occurs because the same mutex is acquired twice, without releasing it. The mutex is acquired once inside 'adis_initial_startup()', before calling '__adis_initial_startup()', and once inside 'adis_enable_irq()', which is called by '__adis_initial_startup()'. The deadlock is removed by calling '__adis_enable_irq()', instead of 'adis_enable_irq()' from within '__adis_initial_startup()'. Fixes: b600bd7eb3335 ("iio: adis: do not disabe IRQs in 'adis_init()'") Signed-off-by: Ramona Bolboaca Reviewed-by: Nuno Sá Link: https://lore.kernel.org/r/20221122082757.449452-2-ramona.bolboaca@analog.com Signed-off-by: Jonathan Cameron --- drivers/iio/imu/adis.c | 28 ++++++++++------------------ include/linux/iio/imu/adis.h | 13 ++++++++++++- 2 files changed, 22 insertions(+), 19 deletions(-) (limited to 'drivers/iio') 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/include/linux/iio/imu/adis.h b/include/linux/iio/imu/adis.h index 515ca09764fe..bcbefb757475 100644 --- a/include/linux/iio/imu/adis.h +++ b/include/linux/iio/imu/adis.h @@ -402,9 +402,20 @@ static inline int adis_update_bits_base(struct adis *adis, unsigned int reg, __adis_update_bits_base(adis, reg, mask, val, sizeof(val)); \ }) -int adis_enable_irq(struct adis *adis, bool enable); int __adis_check_status(struct adis *adis); int __adis_initial_startup(struct adis *adis); +int __adis_enable_irq(struct adis *adis, bool enable); + +static inline int adis_enable_irq(struct adis *adis, bool enable) +{ + int ret; + + mutex_lock(&adis->state_lock); + ret = __adis_enable_irq(adis, enable); + mutex_unlock(&adis->state_lock); + + return ret; +} static inline int adis_check_status(struct adis *adis) { -- cgit v1.2.3 From 594ff4c49e9dd7aba84d82052643c1e4b09b8788 Mon Sep 17 00:00:00 2001 From: Ramona Bolboaca Date: Tue, 22 Nov 2022 10:27:50 +0200 Subject: iio: accel: adis16201: Call '__adis_initial_startup()' in probe MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Call '__adis_initial_startup()' instead of its locked variant in 'adis16201_probe()'. The locks are not needed at this point. Signed-off-by: Ramona Bolboaca Reviewed-by: Nuno Sá Link: https://lore.kernel.org/r/20221122082757.449452-3-ramona.bolboaca@analog.com Signed-off-by: Jonathan Cameron --- drivers/iio/accel/adis16201.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/iio') diff --git a/drivers/iio/accel/adis16201.c b/drivers/iio/accel/adis16201.c index dfb8e2e5bdf5..d054721859b3 100644 --- a/drivers/iio/accel/adis16201.c +++ b/drivers/iio/accel/adis16201.c @@ -281,7 +281,7 @@ static int adis16201_probe(struct spi_device *spi) if (ret) return ret; - ret = adis_initial_startup(st); + ret = __adis_initial_startup(st); if (ret) return ret; -- cgit v1.2.3 From 09f8360f3a8843733d9e54960405c902982062f4 Mon Sep 17 00:00:00 2001 From: Ramona Bolboaca Date: Tue, 22 Nov 2022 10:27:51 +0200 Subject: iio: accel: adis16209: Call '__adis_initial_startup()' in probe MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Call '__adis_initial_startup()' instead of its locked variant in 'adis16209_probe()'. The locks are not needed at this point. Signed-off-by: Ramona Bolboaca Reviewed-by: Nuno Sá Link: https://lore.kernel.org/r/20221122082757.449452-4-ramona.bolboaca@analog.com Signed-off-by: Jonathan Cameron --- drivers/iio/accel/adis16209.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/iio') diff --git a/drivers/iio/accel/adis16209.c b/drivers/iio/accel/adis16209.c index 5a9c6e2296f1..0035e4f4db63 100644 --- a/drivers/iio/accel/adis16209.c +++ b/drivers/iio/accel/adis16209.c @@ -291,7 +291,7 @@ static int adis16209_probe(struct spi_device *spi) if (ret) return ret; - ret = adis_initial_startup(st); + ret = __adis_initial_startup(st); if (ret) return ret; -- cgit v1.2.3 From c5de7d4c026f4c4310e6cb1e06e1ae0bd57cd838 Mon Sep 17 00:00:00 2001 From: Ramona Bolboaca Date: Tue, 22 Nov 2022 10:27:52 +0200 Subject: iio: gyro: adis16136: Call '__adis_initial_startup()' in probe MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Call '__adis_initial_startup()' instead of its locked variant in 'adis16136_probe()'. The locks are not needed at this point. Signed-off-by: Ramona Bolboaca Reviewed-by: Nuno Sá Link: https://lore.kernel.org/r/20221122082757.449452-5-ramona.bolboaca@analog.com Signed-off-by: Jonathan Cameron --- drivers/iio/gyro/adis16136.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/iio') diff --git a/drivers/iio/gyro/adis16136.c b/drivers/iio/gyro/adis16136.c index 71295709f2b9..c95cf41be34b 100644 --- a/drivers/iio/gyro/adis16136.c +++ b/drivers/iio/gyro/adis16136.c @@ -429,7 +429,7 @@ static int adis16136_initial_setup(struct iio_dev *indio_dev) uint16_t prod_id; int ret; - ret = adis_initial_startup(&adis16136->adis); + ret = __adis_initial_startup(&adis16136->adis); if (ret) return ret; -- cgit v1.2.3 From 2647f0e4d397fa5f80c78370d514b05a2110f987 Mon Sep 17 00:00:00 2001 From: Ramona Bolboaca Date: Tue, 22 Nov 2022 10:27:53 +0200 Subject: iio: gyro: adis16260: Call '__adis_initial_startup()' in probe MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Call '__adis_initial_startup()' instead of its locked variant in 'adis16260_probe()'. The locks are not needed at this point. Signed-off-by: Ramona Bolboaca Reviewed-by: Nuno Sá Link: https://lore.kernel.org/r/20221122082757.449452-6-ramona.bolboaca@analog.com Signed-off-by: Jonathan Cameron --- drivers/iio/gyro/adis16260.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/iio') diff --git a/drivers/iio/gyro/adis16260.c b/drivers/iio/gyro/adis16260.c index eaf57bd339ed..112d635b7dfd 100644 --- a/drivers/iio/gyro/adis16260.c +++ b/drivers/iio/gyro/adis16260.c @@ -395,7 +395,7 @@ static int adis16260_probe(struct spi_device *spi) return ret; /* Get the device into a sane initial state */ - ret = adis_initial_startup(&adis16260->adis); + ret = __adis_initial_startup(&adis16260->adis); if (ret) return ret; -- cgit v1.2.3 From 40fd61b0698c1ecf73f8da61b461937b7d91ee26 Mon Sep 17 00:00:00 2001 From: Ramona Bolboaca Date: Tue, 22 Nov 2022 10:27:54 +0200 Subject: iio: imu: adis16400: Call '__adis_initial_startup()' in probe MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Call '__adis_initial_startup()' instead of its locked variant in 'adis16400_probe()'. The locks are not needed at this point. Signed-off-by: Ramona Bolboaca Reviewed-by: Nuno Sá Link: https://lore.kernel.org/r/20221122082757.449452-7-ramona.bolboaca@analog.com Signed-off-by: Jonathan Cameron --- drivers/iio/imu/adis16400.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/iio') 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; -- cgit v1.2.3 From 8aa2e715ca65757e0eb625862491f95e8baf0328 Mon Sep 17 00:00:00 2001 From: Minghao Chi Date: Tue, 22 Nov 2022 09:35:33 +0800 Subject: iio: use devm_platform_get_and_ioremap_resource() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Convert platform_get_resource(), devm_ioremap_resource() to a single call to devm_platform_get_and_ioremap_resource(), as this is exactly what this function does. Signed-off-by: Minghao Chi Signed-off-by: ye xingchen Reviewed-by: Nuno Sá Link: https://lore.kernel.org/r/202211220935338446115@zte.com.cn Signed-off-by: Jonathan Cameron --- drivers/iio/adc/ad7606_par.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'drivers/iio') diff --git a/drivers/iio/adc/ad7606_par.c b/drivers/iio/adc/ad7606_par.c index b912b4df9b56..d8408052262e 100644 --- a/drivers/iio/adc/ad7606_par.c +++ b/drivers/iio/adc/ad7606_par.c @@ -57,8 +57,7 @@ static int ad7606_par_probe(struct platform_device *pdev) if (irq < 0) return irq; - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - addr = devm_ioremap_resource(&pdev->dev, res); + addr = devm_platform_get_and_ioremap_resource(pdev, 0, &res); if (IS_ERR(addr)) return PTR_ERR(addr); -- cgit v1.2.3 From 980389d06d08442fad0139874bff455c76125e47 Mon Sep 17 00:00:00 2001 From: Rasmus Villemoes Date: Fri, 18 Nov 2022 13:32:08 +0100 Subject: iio: addac: ad74413r: fix integer promotion bug in ad74413_get_input_current_offset() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The constant AD74413R_ADC_RESULT_MAX is defined via GENMASK, so its type is "unsigned long". Hence in the expression voltage_offset * AD74413R_ADC_RESULT_MAX, voltage_offset is first promoted to unsigned long, and since it may be negative, that results in a garbage value. For example, when range is AD74413R_ADC_RANGE_5V_BI_DIR, voltage_offset is -2500 and voltage_range is 5000, so the RHS of this assignment is, depending on sizeof(long), either 826225UL or 3689348814709142UL, which after truncation to int then results in either 826225 or 1972216214 being the output from in_currentX_offset. Casting to int avoids that promotion and results in the correct -32767 output. Signed-off-by: Rasmus Villemoes Fixes: fea251b6a5db (iio: addac: add AD74413R driver) Reviewed-by: Nuno Sá Link: https://lore.kernel.org/r/20221118123209.1658420-1-linux@rasmusvillemoes.dk Cc: Signed-off-by: Jonathan Cameron --- drivers/iio/addac/ad74413r.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/iio') diff --git a/drivers/iio/addac/ad74413r.c b/drivers/iio/addac/ad74413r.c index 899bcd83f40b..e0e130ba9d3e 100644 --- a/drivers/iio/addac/ad74413r.c +++ b/drivers/iio/addac/ad74413r.c @@ -691,7 +691,7 @@ static int ad74413_get_input_current_offset(struct ad74413r_state *st, if (ret) return ret; - *val = voltage_offset * AD74413R_ADC_RESULT_MAX / voltage_range; + *val = voltage_offset * (int)AD74413R_ADC_RESULT_MAX / voltage_range; return IIO_VAL_INT; } -- cgit v1.2.3 From 48ea75598db2b38e4a4b5738d65f226be717bd59 Mon Sep 17 00:00:00 2001 From: Cosmin Tanislav Date: Thu, 17 Nov 2022 10:09:16 +0200 Subject: iio: addac: add AD74115 driver The AD74115H is a single-channel, software-configurable, input and output device for industrial control applications. The AD74115H provides a wide range of use cases, integrated on a single chip. These use cases include analog output, analog input, digital output, digital input, resistance temperature detector (RTD), and thermocouple measurement capability. The AD74115H also has an integrated HART modem. A serial peripheral interface (SPI) is used to handle all communications to the device, including communications with the HART modem. The digital input and digital outputs can be accessed via the SPI or the general-purpose input and output (GPIO) pins to support higher speed data rates. The device features a 16-bit, sigma-delta analog-to-digital converter (ADC) and a 14-bit digital-to-analog converter (DAC). The AD74115H contains a high accuracy 2.5 V on-chip reference that can be used as the DAC and ADC reference. Signed-off-by: Cosmin Tanislav Reviewed-by: Linus Walleij Link: https://lore.kernel.org/r/20221117080916.411766-3-cosmin.tanislav@analog.com Signed-off-by: Jonathan Cameron --- MAINTAINERS | 1 + drivers/iio/addac/Kconfig | 14 + drivers/iio/addac/Makefile | 1 + drivers/iio/addac/ad74115.c | 1947 +++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 1963 insertions(+) create mode 100644 drivers/iio/addac/ad74115.c (limited to 'drivers/iio') diff --git a/MAINTAINERS b/MAINTAINERS index d1ba33eb0cec..860075c493dd 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -1181,6 +1181,7 @@ L: linux-iio@vger.kernel.org S: Supported W: http://ez.analog.com/community/linux-device-drivers F: Documentation/devicetree/bindings/iio/addac/adi,ad74115.yaml +F: drivers/iio/addac/ad74115.c ANALOG DEVICES INC AD74413R DRIVER M: Cosmin Tanislav diff --git a/drivers/iio/addac/Kconfig b/drivers/iio/addac/Kconfig index fcf6d2269bfc..2843fcb70e24 100644 --- a/drivers/iio/addac/Kconfig +++ b/drivers/iio/addac/Kconfig @@ -5,6 +5,20 @@ menu "Analog to digital and digital to analog converters" +config AD74115 + tristate "Analog Devices AD74115H driver" + depends on GPIOLIB && SPI + select CRC8 + select IIO_BUFFER + select IIO_TRIGGERED_BUFFER + select REGMAP_SPI + help + Say yes here to build support for Analog Devices AD74115H + single-channel software configurable input/output solution. + + To compile this driver as a module, choose M here: the + module will be called ad74115. + config AD74413R tristate "Analog Devices AD74412R/AD74413R driver" depends on GPIOLIB && SPI diff --git a/drivers/iio/addac/Makefile b/drivers/iio/addac/Makefile index 17de20ef0d8e..577777276e43 100644 --- a/drivers/iio/addac/Makefile +++ b/drivers/iio/addac/Makefile @@ -4,5 +4,6 @@ # # When adding new entries keep the list in alphabetical order +obj-$(CONFIG_AD74115) += ad74115.o obj-$(CONFIG_AD74413R) += ad74413r.o obj-$(CONFIG_STX104) += stx104.o diff --git a/drivers/iio/addac/ad74115.c b/drivers/iio/addac/ad74115.c new file mode 100644 index 000000000000..383b92e7b682 --- /dev/null +++ b/drivers/iio/addac/ad74115.c @@ -0,0 +1,1947 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (C) 2022 Analog Devices, Inc. + * Author: Cosmin Tanislav + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include +#include +#include +#include + +#define AD74115_NAME "ad74115" + +#define AD74115_CH_FUNC_SETUP_REG 0x01 + +#define AD74115_ADC_CONFIG_REG 0x02 +#define AD74115_ADC_CONFIG_CONV2_RATE_MASK GENMASK(15, 13) +#define AD74115_ADC_CONFIG_CONV1_RATE_MASK GENMASK(12, 10) +#define AD74115_ADC_CONFIG_CONV2_RANGE_MASK GENMASK(9, 7) +#define AD74115_ADC_CONFIG_CONV1_RANGE_MASK GENMASK(6, 4) + +#define AD74115_PWR_OPTIM_CONFIG_REG 0x03 + +#define AD74115_DIN_CONFIG1_REG 0x04 +#define AD74115_DIN_COMPARATOR_EN_MASK BIT(13) +#define AD74115_DIN_SINK_MASK GENMASK(11, 7) +#define AD74115_DIN_DEBOUNCE_MASK GENMASK(4, 0) + +#define AD74115_DIN_CONFIG2_REG 0x05 +#define AD74115_COMP_THRESH_MASK GENMASK(6, 0) + +#define AD74115_OUTPUT_CONFIG_REG 0x06 +#define AD74115_OUTPUT_SLEW_EN_MASK GENMASK(6, 5) +#define AD74115_OUTPUT_SLEW_LIN_STEP_MASK GENMASK(4, 3) +#define AD74115_OUTPUT_SLEW_LIN_RATE_MASK GENMASK(2, 1) + +#define AD74115_RTD3W4W_CONFIG_REG 0x07 + +#define AD74115_BURNOUT_CONFIG_REG 0x0a +#define AD74115_BURNOUT_EXT2_EN_MASK BIT(10) +#define AD74115_BURNOUT_EXT1_EN_MASK BIT(5) +#define AD74115_BURNOUT_VIOUT_EN_MASK BIT(0) + +#define AD74115_DAC_CODE_REG 0x0b + +#define AD74115_DAC_ACTIVE_REG 0x0d + +#define AD74115_GPIO_CONFIG_X_REG(x) (0x35 + (x)) +#define AD74115_GPIO_CONFIG_GPI_DATA BIT(5) +#define AD74115_GPIO_CONFIG_GPO_DATA BIT(4) +#define AD74115_GPIO_CONFIG_SELECT_MASK GENMASK(2, 0) + +#define AD74115_CHARGE_PUMP_REG 0x3a + +#define AD74115_ADC_CONV_CTRL_REG 0x3b +#define AD74115_ADC_CONV_SEQ_MASK GENMASK(13, 12) + +#define AD74115_DIN_COMP_OUT_REG 0x40 + +#define AD74115_LIVE_STATUS_REG 0x42 +#define AD74115_ADC_DATA_RDY_MASK BIT(3) + +#define AD74115_READ_SELECT_REG 0x64 + +#define AD74115_CMD_KEY_REG 0x78 +#define AD74115_CMD_KEY_RESET1 0x15fa +#define AD74115_CMD_KEY_RESET2 0xaf51 + +#define AD74115_CRC_POLYNOMIAL 0x7 +DECLARE_CRC8_TABLE(ad74115_crc8_table); + +#define AD74115_ADC_CODE_MAX ((int)GENMASK(15, 0)) +#define AD74115_ADC_CODE_HALF (AD74115_ADC_CODE_MAX / 2) + +#define AD74115_DAC_VOLTAGE_MAX 12000 +#define AD74115_DAC_CURRENT_MAX 25 +#define AD74115_DAC_CODE_MAX ((int)GENMASK(13, 0)) +#define AD74115_DAC_CODE_HALF (AD74115_DAC_CODE_MAX / 2) + +#define AD74115_COMP_THRESH_MAX 98 + +#define AD74115_SENSE_RESISTOR_OHMS 100 +#define AD74115_REF_RESISTOR_OHMS 2100 + +#define AD74115_DIN_SINK_LOW_STEP 120 +#define AD74115_DIN_SINK_HIGH_STEP 240 +#define AD74115_DIN_SINK_MAX 31 + +#define AD74115_FRAME_SIZE 4 +#define AD74115_GPIO_NUM 4 + +#define AD74115_CONV_TIME_US 1000000 + +enum ad74115_dac_ch { + AD74115_DAC_CH_MAIN, + AD74115_DAC_CH_COMPARATOR, +}; + +enum ad74115_adc_ch { + AD74115_ADC_CH_CONV1, + AD74115_ADC_CH_CONV2, + AD74115_ADC_CH_NUM +}; + +enum ad74115_ch_func { + AD74115_CH_FUNC_HIGH_IMPEDANCE, + AD74115_CH_FUNC_VOLTAGE_OUTPUT, + AD74115_CH_FUNC_CURRENT_OUTPUT, + AD74115_CH_FUNC_VOLTAGE_INPUT, + AD74115_CH_FUNC_CURRENT_INPUT_EXT_POWER, + AD74115_CH_FUNC_CURRENT_INPUT_LOOP_POWER, + AD74115_CH_FUNC_2_WIRE_RESISTANCE_INPUT, + AD74115_CH_FUNC_3_4_WIRE_RESISTANCE_INPUT, + AD74115_CH_FUNC_DIGITAL_INPUT_LOGIC, + AD74115_CH_FUNC_DIGITAL_INPUT_LOOP_POWER, + AD74115_CH_FUNC_CURRENT_OUTPUT_HART, + AD74115_CH_FUNC_CURRENT_INPUT_EXT_POWER_HART, + AD74115_CH_FUNC_CURRENT_INPUT_LOOP_POWER_HART, + AD74115_CH_FUNC_MAX = AD74115_CH_FUNC_CURRENT_INPUT_LOOP_POWER_HART, + AD74115_CH_FUNC_NUM +}; + +enum ad74115_adc_range { + AD74115_ADC_RANGE_12V, + AD74115_ADC_RANGE_12V_BIPOLAR, + AD74115_ADC_RANGE_2_5V_BIPOLAR, + AD74115_ADC_RANGE_2_5V_NEG, + AD74115_ADC_RANGE_2_5V, + AD74115_ADC_RANGE_0_625V, + AD74115_ADC_RANGE_104MV_BIPOLAR, + AD74115_ADC_RANGE_12V_OTHER, + AD74115_ADC_RANGE_MAX = AD74115_ADC_RANGE_12V_OTHER, + AD74115_ADC_RANGE_NUM +}; + +enum ad74115_adc_conv_seq { + AD74115_ADC_CONV_SEQ_STANDBY = 0b00, + AD74115_ADC_CONV_SEQ_SINGLE = 0b01, + AD74115_ADC_CONV_SEQ_CONTINUOUS = 0b10, +}; + +enum ad74115_din_threshold_mode { + AD74115_DIN_THRESHOLD_MODE_AVDD, + AD74115_DIN_THRESHOLD_MODE_FIXED, + AD74115_DIN_THRESHOLD_MODE_MAX = AD74115_DIN_THRESHOLD_MODE_FIXED, +}; + +enum ad74115_slew_mode { + AD74115_SLEW_MODE_DISABLED, + AD74115_SLEW_MODE_LINEAR, + AD74115_SLEW_MODE_HART, +}; + +enum ad74115_slew_step { + AD74115_SLEW_STEP_0_8_PERCENT, + AD74115_SLEW_STEP_1_5_PERCENT, + AD74115_SLEW_STEP_6_1_PERCENT, + AD74115_SLEW_STEP_22_2_PERCENT, +}; + +enum ad74115_slew_rate { + AD74115_SLEW_RATE_4KHZ, + AD74115_SLEW_RATE_64KHZ, + AD74115_SLEW_RATE_150KHZ, + AD74115_SLEW_RATE_240KHZ, +}; + +enum ad74115_gpio_config { + AD74115_GPIO_CONFIG_OUTPUT_BUFFERED = 0b010, + AD74115_GPIO_CONFIG_INPUT = 0b011, +}; + +enum ad74115_gpio_mode { + AD74115_GPIO_MODE_LOGIC = 1, + AD74115_GPIO_MODE_SPECIAL = 2, +}; + +struct ad74115_channels { + struct iio_chan_spec *channels; + unsigned int num_channels; +}; + +struct ad74115_state { + struct spi_device *spi; + struct regmap *regmap; + struct iio_trigger *trig; + struct regulator *avdd; + + /* + * Synchronize consecutive operations when doing a one-shot + * conversion and when updating the ADC samples SPI message. + */ + struct mutex lock; + struct gpio_chip gc; + struct gpio_chip comp_gc; + int irq; + + unsigned int avdd_mv; + unsigned long gpio_valid_mask; + bool dac_bipolar; + bool dac_hart_slew; + bool rtd_mode_4_wire; + enum ad74115_ch_func ch_func; + enum ad74115_din_threshold_mode din_threshold_mode; + + struct completion adc_data_completion; + struct spi_message adc_samples_msg; + struct spi_transfer adc_samples_xfer[AD74115_ADC_CH_NUM + 1]; + + /* + * DMA (thus cache coherency maintenance) requires the + * transfer buffers to live in their own cache lines. + */ + u8 reg_tx_buf[AD74115_FRAME_SIZE] __aligned(IIO_DMA_MINALIGN); + u8 reg_rx_buf[AD74115_FRAME_SIZE]; + u8 adc_samples_tx_buf[AD74115_FRAME_SIZE * AD74115_ADC_CH_NUM]; + u8 adc_samples_rx_buf[AD74115_FRAME_SIZE * AD74115_ADC_CH_NUM]; +}; + +struct ad74115_fw_prop { + const char *name; + bool is_boolean; + bool negate; + unsigned int max; + unsigned int reg; + unsigned int mask; + const unsigned int *lookup_tbl; + unsigned int lookup_tbl_len; +}; + +#define AD74115_FW_PROP(_name, _max, _reg, _mask) \ +{ \ + .name = (_name), \ + .max = (_max), \ + .reg = (_reg), \ + .mask = (_mask), \ +} + +#define AD74115_FW_PROP_TBL(_name, _tbl, _reg, _mask) \ +{ \ + .name = (_name), \ + .reg = (_reg), \ + .mask = (_mask), \ + .lookup_tbl = (_tbl), \ + .lookup_tbl_len = ARRAY_SIZE(_tbl), \ +} + +#define AD74115_FW_PROP_BOOL(_name, _reg, _mask) \ +{ \ + .name = (_name), \ + .is_boolean = true, \ + .reg = (_reg), \ + .mask = (_mask), \ +} + +#define AD74115_FW_PROP_BOOL_NEG(_name, _reg, _mask) \ +{ \ + .name = (_name), \ + .is_boolean = true, \ + .negate = true, \ + .reg = (_reg), \ + .mask = (_mask), \ +} + +static const int ad74115_dac_rate_tbl[] = { + 0, + 4 * 8, + 4 * 15, + 4 * 61, + 4 * 222, + 64 * 8, + 64 * 15, + 64 * 61, + 64 * 222, + 150 * 8, + 150 * 15, + 150 * 61, + 150 * 222, + 240 * 8, + 240 * 15, + 240 * 61, + 240 * 222, +}; + +static const unsigned int ad74115_dac_rate_step_tbl[][3] = { + { AD74115_SLEW_MODE_DISABLED }, + { AD74115_SLEW_MODE_LINEAR, AD74115_SLEW_STEP_0_8_PERCENT, AD74115_SLEW_RATE_4KHZ }, + { AD74115_SLEW_MODE_LINEAR, AD74115_SLEW_STEP_1_5_PERCENT, AD74115_SLEW_RATE_4KHZ }, + { AD74115_SLEW_MODE_LINEAR, AD74115_SLEW_STEP_6_1_PERCENT, AD74115_SLEW_RATE_4KHZ }, + { AD74115_SLEW_MODE_LINEAR, AD74115_SLEW_STEP_22_2_PERCENT, AD74115_SLEW_RATE_4KHZ }, + { AD74115_SLEW_MODE_LINEAR, AD74115_SLEW_STEP_0_8_PERCENT, AD74115_SLEW_RATE_64KHZ }, + { AD74115_SLEW_MODE_LINEAR, AD74115_SLEW_STEP_1_5_PERCENT, AD74115_SLEW_RATE_64KHZ }, + { AD74115_SLEW_MODE_LINEAR, AD74115_SLEW_STEP_6_1_PERCENT, AD74115_SLEW_RATE_64KHZ }, + { AD74115_SLEW_MODE_LINEAR, AD74115_SLEW_STEP_22_2_PERCENT, AD74115_SLEW_RATE_64KHZ }, + { AD74115_SLEW_MODE_LINEAR, AD74115_SLEW_STEP_0_8_PERCENT, AD74115_SLEW_RATE_150KHZ }, + { AD74115_SLEW_MODE_LINEAR, AD74115_SLEW_STEP_1_5_PERCENT, AD74115_SLEW_RATE_150KHZ }, + { AD74115_SLEW_MODE_LINEAR, AD74115_SLEW_STEP_6_1_PERCENT, AD74115_SLEW_RATE_150KHZ }, + { AD74115_SLEW_MODE_LINEAR, AD74115_SLEW_STEP_22_2_PERCENT, AD74115_SLEW_RATE_150KHZ }, + { AD74115_SLEW_MODE_LINEAR, AD74115_SLEW_STEP_0_8_PERCENT, AD74115_SLEW_RATE_240KHZ }, + { AD74115_SLEW_MODE_LINEAR, AD74115_SLEW_STEP_1_5_PERCENT, AD74115_SLEW_RATE_240KHZ }, + { AD74115_SLEW_MODE_LINEAR, AD74115_SLEW_STEP_6_1_PERCENT, AD74115_SLEW_RATE_240KHZ }, + { AD74115_SLEW_MODE_LINEAR, AD74115_SLEW_STEP_22_2_PERCENT, AD74115_SLEW_RATE_240KHZ }, +}; + +static const unsigned int ad74115_dac_slew_rate_hz_tbl[] = { + 4000, 64000, 150000, 240000 +}; + +static const unsigned int ad74115_rtd_excitation_current_ua_tbl[] = { + 250, 500, 750, 1000 +}; + +static const unsigned int ad74115_burnout_current_na_tbl[] = { + 0, 50, 0, 500, 1000, 0, 10000, 0 +}; + +static const unsigned int ad74115_viout_burnout_current_na_tbl[] = { + 0, 0, 0, 0, 1000, 0, 10000, 0 +}; + +static const unsigned int ad74115_gpio_mode_tbl[] = { + 0, 0, 0, 1, 2, 3, 4, 5 +}; + +static const unsigned int ad74115_adc_conv_rate_tbl[] = { + 10, 20, 1200, 4800, 9600 +}; + +static const unsigned int ad74115_debounce_tbl[] = { + 0, 13, 18, 24, 32, 42, 56, 75, + 100, 130, 180, 240, 320, 420, 560, 750, + 1000, 1300, 1800, 2400, 3200, 4200, 5600, 7500, + 10000, 13000, 18000, 24000, 32000, 42000, 56000, 75000, +}; + +static const unsigned int ad74115_adc_ch_data_regs_tbl[] = { + [AD74115_ADC_CH_CONV1] = 0x44, + [AD74115_ADC_CH_CONV2] = 0x46, +}; + +static const unsigned int ad74115_adc_ch_en_bit_tbl[] = { + [AD74115_ADC_CH_CONV1] = BIT(0), + [AD74115_ADC_CH_CONV2] = BIT(1), +}; + +static const bool ad74115_adc_bipolar_tbl[AD74115_ADC_RANGE_NUM] = { + [AD74115_ADC_RANGE_12V_BIPOLAR] = true, + [AD74115_ADC_RANGE_2_5V_BIPOLAR] = true, + [AD74115_ADC_RANGE_104MV_BIPOLAR] = true, +}; + +static const unsigned int ad74115_adc_conv_mul_tbl[AD74115_ADC_RANGE_NUM] = { + [AD74115_ADC_RANGE_12V] = 12000, + [AD74115_ADC_RANGE_12V_BIPOLAR] = 24000, + [AD74115_ADC_RANGE_2_5V_BIPOLAR] = 5000, + [AD74115_ADC_RANGE_2_5V_NEG] = 2500, + [AD74115_ADC_RANGE_2_5V] = 2500, + [AD74115_ADC_RANGE_0_625V] = 625, + [AD74115_ADC_RANGE_104MV_BIPOLAR] = 208, + [AD74115_ADC_RANGE_12V_OTHER] = 12000, +}; + +static const unsigned int ad74115_adc_gain_tbl[AD74115_ADC_RANGE_NUM][2] = { + [AD74115_ADC_RANGE_12V] = { 5, 24 }, + [AD74115_ADC_RANGE_12V_BIPOLAR] = { 5, 24 }, + [AD74115_ADC_RANGE_2_5V_BIPOLAR] = { 1, 1 }, + [AD74115_ADC_RANGE_2_5V_NEG] = { 1, 1 }, + [AD74115_ADC_RANGE_2_5V] = { 1, 1 }, + [AD74115_ADC_RANGE_0_625V] = { 4, 1 }, + [AD74115_ADC_RANGE_104MV_BIPOLAR] = { 24, 1 }, + [AD74115_ADC_RANGE_12V_OTHER] = { 5, 24 }, +}; + +static const int ad74115_adc_range_tbl[AD74115_ADC_RANGE_NUM][2] = { + [AD74115_ADC_RANGE_12V] = { 0, 12000000 }, + [AD74115_ADC_RANGE_12V_BIPOLAR] = { -12000000, 12000000 }, + [AD74115_ADC_RANGE_2_5V_BIPOLAR] = { -2500000, 2500000 }, + [AD74115_ADC_RANGE_2_5V_NEG] = { -2500000, 0 }, + [AD74115_ADC_RANGE_2_5V] = { 0, 2500000 }, + [AD74115_ADC_RANGE_0_625V] = { 0, 625000 }, + [AD74115_ADC_RANGE_104MV_BIPOLAR] = { -104000, 104000 }, + [AD74115_ADC_RANGE_12V_OTHER] = { 0, 12000000 }, +}; + +static int _ad74115_find_tbl_index(const unsigned int *tbl, unsigned int tbl_len, + unsigned int val, unsigned int *index) +{ + unsigned int i; + + for (i = 0; i < tbl_len; i++) + if (val == tbl[i]) { + *index = i; + return 0; + } + + return -EINVAL; +} + +#define ad74115_find_tbl_index(tbl, val, index) \ + _ad74115_find_tbl_index(tbl, ARRAY_SIZE(tbl), val, index) + +static int ad74115_crc(u8 *buf) +{ + return crc8(ad74115_crc8_table, buf, 3, 0); +} + +static void ad74115_format_reg_write(u8 reg, u16 val, u8 *buf) +{ + buf[0] = reg; + put_unaligned_be16(val, &buf[1]); + buf[3] = ad74115_crc(buf); +} + +static int ad74115_reg_write(void *context, unsigned int reg, unsigned int val) +{ + struct ad74115_state *st = context; + + ad74115_format_reg_write(reg, val, st->reg_tx_buf); + + return spi_write(st->spi, st->reg_tx_buf, AD74115_FRAME_SIZE); +} + +static int ad74115_crc_check(struct ad74115_state *st, u8 *buf) +{ + struct device *dev = &st->spi->dev; + u8 expected_crc = ad74115_crc(buf); + + if (buf[3] != expected_crc) { + dev_err(dev, "Bad CRC %02x for %02x%02x%02x, expected %02x\n", + buf[3], buf[0], buf[1], buf[2], expected_crc); + return -EINVAL; + } + + return 0; +} + +static int ad74115_reg_read(void *context, unsigned int reg, unsigned int *val) +{ + struct ad74115_state *st = context; + struct spi_transfer reg_read_xfer[] = { + { + .tx_buf = st->reg_tx_buf, + .len = sizeof(st->reg_tx_buf), + .cs_change = 1, + }, + { + .rx_buf = st->reg_rx_buf, + .len = sizeof(st->reg_rx_buf), + }, + }; + int ret; + + ad74115_format_reg_write(AD74115_READ_SELECT_REG, reg, st->reg_tx_buf); + + ret = spi_sync_transfer(st->spi, reg_read_xfer, ARRAY_SIZE(reg_read_xfer)); + if (ret) + return ret; + + ret = ad74115_crc_check(st, st->reg_rx_buf); + if (ret) + return ret; + + *val = get_unaligned_be16(&st->reg_rx_buf[1]); + + return 0; +} + +static const struct regmap_config ad74115_regmap_config = { + .reg_bits = 8, + .val_bits = 16, + .reg_read = ad74115_reg_read, + .reg_write = ad74115_reg_write, +}; + +static int ad74115_gpio_config_set(struct ad74115_state *st, unsigned int offset, + enum ad74115_gpio_config cfg) +{ + return regmap_update_bits(st->regmap, AD74115_GPIO_CONFIG_X_REG(offset), + AD74115_GPIO_CONFIG_SELECT_MASK, + FIELD_PREP(AD74115_GPIO_CONFIG_SELECT_MASK, cfg)); +} + +static int ad74115_gpio_init_valid_mask(struct gpio_chip *gc, + unsigned long *valid_mask, + unsigned int ngpios) +{ + struct ad74115_state *st = gpiochip_get_data(gc); + + *valid_mask = st->gpio_valid_mask; + + return 0; +} + +static int ad74115_gpio_get_direction(struct gpio_chip *gc, unsigned int offset) +{ + struct ad74115_state *st = gpiochip_get_data(gc); + unsigned int val; + int ret; + + ret = regmap_read(st->regmap, AD74115_GPIO_CONFIG_X_REG(offset), &val); + if (ret) + return ret; + + return FIELD_GET(AD74115_GPIO_CONFIG_SELECT_MASK, val) == AD74115_GPIO_CONFIG_INPUT; +} + +static int ad74115_gpio_direction_input(struct gpio_chip *gc, unsigned int offset) +{ + struct ad74115_state *st = gpiochip_get_data(gc); + + return ad74115_gpio_config_set(st, offset, AD74115_GPIO_CONFIG_INPUT); +} + +static int ad74115_gpio_direction_output(struct gpio_chip *gc, unsigned int offset, + int value) +{ + struct ad74115_state *st = gpiochip_get_data(gc); + + return ad74115_gpio_config_set(st, offset, AD74115_GPIO_CONFIG_OUTPUT_BUFFERED); +} + +static int ad74115_gpio_get(struct gpio_chip *gc, unsigned int offset) +{ + struct ad74115_state *st = gpiochip_get_data(gc); + unsigned int val; + int ret; + + ret = regmap_read(st->regmap, AD74115_GPIO_CONFIG_X_REG(offset), &val); + if (ret) + return ret; + + return FIELD_GET(AD74115_GPIO_CONFIG_GPI_DATA, val); +} + +static void ad74115_gpio_set(struct gpio_chip *gc, unsigned int offset, int value) +{ + struct ad74115_state *st = gpiochip_get_data(gc); + struct device *dev = &st->spi->dev; + int ret; + + ret = regmap_update_bits(st->regmap, AD74115_GPIO_CONFIG_X_REG(offset), + AD74115_GPIO_CONFIG_GPO_DATA, + FIELD_PREP(AD74115_GPIO_CONFIG_GPO_DATA, value)); + if (ret) + dev_err(dev, "Failed to set GPIO %u output value, err: %d\n", + offset, ret); +} + +static int ad74115_set_comp_debounce(struct ad74115_state *st, unsigned int val) +{ + unsigned int len = ARRAY_SIZE(ad74115_debounce_tbl); + unsigned int i; + + for (i = 0; i < len; i++) + if (val <= ad74115_debounce_tbl[i]) + break; + + if (i == len) + i = len - 1; + + return regmap_update_bits(st->regmap, AD74115_DIN_CONFIG1_REG, + AD74115_DIN_DEBOUNCE_MASK, + FIELD_PREP(AD74115_DIN_DEBOUNCE_MASK, val)); +} + +static int ad74115_comp_gpio_get_direction(struct gpio_chip *chip, + unsigned int offset) +{ + return GPIO_LINE_DIRECTION_IN; +} + +static int ad74115_comp_gpio_set_config(struct gpio_chip *chip, + unsigned int offset, + unsigned long config) +{ + struct ad74115_state *st = gpiochip_get_data(chip); + u32 param = pinconf_to_config_param(config); + u32 arg = pinconf_to_config_argument(config); + + switch (param) { + case PIN_CONFIG_INPUT_DEBOUNCE: + return ad74115_set_comp_debounce(st, arg); + default: + return -ENOTSUPP; + } +} + +static int ad74115_comp_gpio_get(struct gpio_chip *chip, unsigned int offset) +{ + struct ad74115_state *st = gpiochip_get_data(chip); + unsigned int val; + int ret; + + ret = regmap_read(st->regmap, AD74115_DIN_COMP_OUT_REG, &val); + if (ret) + return ret; + + return !!val; +} + +static irqreturn_t ad74115_trigger_handler(int irq, void *p) +{ + struct iio_poll_func *pf = p; + struct iio_dev *indio_dev = pf->indio_dev; + struct ad74115_state *st = iio_priv(indio_dev); + int ret; + + ret = spi_sync(st->spi, &st->adc_samples_msg); + if (ret) + goto out; + + iio_push_to_buffers(indio_dev, st->adc_samples_rx_buf); + +out: + iio_trigger_notify_done(indio_dev->trig); + + return IRQ_HANDLED; +} + +static irqreturn_t ad74115_adc_data_interrupt(int irq, void *data) +{ + struct iio_dev *indio_dev = data; + struct ad74115_state *st = iio_priv(indio_dev); + + if (iio_buffer_enabled(indio_dev)) + iio_trigger_poll(st->trig); + else + complete(&st->adc_data_completion); + + return IRQ_HANDLED; +} + +static int ad74115_set_adc_ch_en(struct ad74115_state *st, + enum ad74115_adc_ch channel, bool status) +{ + unsigned int mask = ad74115_adc_ch_en_bit_tbl[channel]; + + return regmap_update_bits(st->regmap, AD74115_ADC_CONV_CTRL_REG, mask, + status ? mask : 0); +} + +static int ad74115_set_adc_conv_seq(struct ad74115_state *st, + enum ad74115_adc_conv_seq conv_seq) +{ + return regmap_update_bits(st->regmap, AD74115_ADC_CONV_CTRL_REG, + AD74115_ADC_CONV_SEQ_MASK, + FIELD_PREP(AD74115_ADC_CONV_SEQ_MASK, conv_seq)); +} + +static int ad74115_update_scan_mode(struct iio_dev *indio_dev, + const unsigned long *active_scan_mask) +{ + struct ad74115_state *st = iio_priv(indio_dev); + struct spi_transfer *xfer = st->adc_samples_xfer; + u8 *rx_buf = st->adc_samples_rx_buf; + u8 *tx_buf = st->adc_samples_tx_buf; + unsigned int i; + int ret = 0; + + mutex_lock(&st->lock); + + spi_message_init(&st->adc_samples_msg); + + for_each_clear_bit(i, active_scan_mask, AD74115_ADC_CH_NUM) { + ret = ad74115_set_adc_ch_en(st, i, false); + if (ret) + goto out; + } + + /* + * The read select register is used to select which register's value + * will be sent by the slave on the next SPI frame. + * + * Create an SPI message that, on each step, writes to the read select + * register to select the ADC result of the next enabled channel, and + * reads the ADC result of the previous enabled channel. + * + * Example: + * W: [WCH1] [WCH2] [WCH2] [WCH3] [ ] + * R: [ ] [RCH1] [RCH2] [RCH3] [RCH4] + */ + for_each_set_bit(i, active_scan_mask, AD74115_ADC_CH_NUM) { + ret = ad74115_set_adc_ch_en(st, i, true); + if (ret) + goto out; + + if (xfer == st->adc_samples_xfer) + xfer->rx_buf = NULL; + else + xfer->rx_buf = rx_buf; + + xfer->tx_buf = tx_buf; + xfer->len = AD74115_FRAME_SIZE; + xfer->cs_change = 1; + + ad74115_format_reg_write(AD74115_READ_SELECT_REG, + ad74115_adc_ch_data_regs_tbl[i], tx_buf); + + spi_message_add_tail(xfer, &st->adc_samples_msg); + + tx_buf += AD74115_FRAME_SIZE; + if (xfer != st->adc_samples_xfer) + rx_buf += AD74115_FRAME_SIZE; + xfer++; + } + + xfer->rx_buf = rx_buf; + xfer->tx_buf = NULL; + xfer->len = AD74115_FRAME_SIZE; + xfer->cs_change = 0; + + spi_message_add_tail(xfer, &st->adc_samples_msg); + +out: + mutex_unlock(&st->lock); + + return ret; +} + +static int ad74115_buffer_postenable(struct iio_dev *indio_dev) +{ + struct ad74115_state *st = iio_priv(indio_dev); + + return ad74115_set_adc_conv_seq(st, AD74115_ADC_CONV_SEQ_CONTINUOUS); +} + +static int ad74115_buffer_predisable(struct iio_dev *indio_dev) +{ + struct ad74115_state *st = iio_priv(indio_dev); + unsigned int i; + int ret; + + mutex_lock(&st->lock); + + ret = ad74115_set_adc_conv_seq(st, AD74115_ADC_CONV_SEQ_STANDBY); + if (ret) + goto out; + + /* + * update_scan_mode() is not called in the disable path, disable all + * channels here. + */ + for (i = 0; i < AD74115_ADC_CH_NUM; i++) { + ret = ad74115_set_adc_ch_en(st, i, false); + if (ret) + goto out; + } + +out: + mutex_unlock(&st->lock); + + return ret; +} + +static const struct iio_buffer_setup_ops ad74115_buffer_ops = { + .postenable = &ad74115_buffer_postenable, + .predisable = &ad74115_buffer_predisable, +}; + +static const struct iio_trigger_ops ad74115_trigger_ops = { + .validate_device = iio_trigger_validate_own_device, +}; + +static int ad74115_get_adc_rate(struct ad74115_state *st, + enum ad74115_adc_ch channel, int *val) +{ + unsigned int i; + int ret; + + ret = regmap_read(st->regmap, AD74115_ADC_CONFIG_REG, &i); + if (ret) + return ret; + + if (channel == AD74115_ADC_CH_CONV1) + i = FIELD_GET(AD74115_ADC_CONFIG_CONV1_RATE_MASK, i); + else + i = FIELD_GET(AD74115_ADC_CONFIG_CONV2_RATE_MASK, i); + + *val = ad74115_adc_conv_rate_tbl[i]; + + return IIO_VAL_INT; +} + +static int _ad74115_get_adc_code(struct ad74115_state *st, + enum ad74115_adc_ch channel, int *val) +{ + unsigned int uval; + int ret; + + reinit_completion(&st->adc_data_completion); + + ret = ad74115_set_adc_ch_en(st, channel, true); + if (ret) + return ret; + + ret = ad74115_set_adc_conv_seq(st, AD74115_ADC_CONV_SEQ_SINGLE); + if (ret) + return ret; + + if (st->irq) { + ret = wait_for_completion_timeout(&st->adc_data_completion, + msecs_to_jiffies(1000)); + if (!ret) + return -ETIMEDOUT; + } else { + unsigned int regval, wait_time; + int rate; + + ret = ad74115_get_adc_rate(st, channel, &rate); + if (ret < 0) + return ret; + + wait_time = DIV_ROUND_CLOSEST(AD74115_CONV_TIME_US, rate); + + ret = regmap_read_poll_timeout(st->regmap, AD74115_LIVE_STATUS_REG, + regval, regval & AD74115_ADC_DATA_RDY_MASK, + wait_time, 5 * wait_time); + if (ret) + return ret; + + /* + * The ADC_DATA_RDY bit is W1C. + * See datasheet page 98, Table 62. Bit Descriptions for + * LIVE_STATUS. + * Although the datasheet mentions that the bit will auto-clear + * when writing to the ADC_CONV_CTRL register, this does not + * seem to happen. + */ + ret = regmap_write_bits(st->regmap, AD74115_LIVE_STATUS_REG, + AD74115_ADC_DATA_RDY_MASK, + FIELD_PREP(AD74115_ADC_DATA_RDY_MASK, 1)); + if (ret) + return ret; + } + + ret = regmap_read(st->regmap, ad74115_adc_ch_data_regs_tbl[channel], &uval); + if (ret) + return ret; + + ret = ad74115_set_adc_conv_seq(st, AD74115_ADC_CONV_SEQ_STANDBY); + if (ret) + return ret; + + ret = ad74115_set_adc_ch_en(st, channel, false); + if (ret) + return ret; + + *val = uval; + + return IIO_VAL_INT; +} + +static int ad74115_get_adc_code(struct iio_dev *indio_dev, + enum ad74115_adc_ch channel, int *val) +{ + struct ad74115_state *st = iio_priv(indio_dev); + int ret; + + ret = iio_device_claim_direct_mode(indio_dev); + if (ret) + return ret; + + mutex_lock(&st->lock); + ret = _ad74115_get_adc_code(st, channel, val); + mutex_unlock(&st->lock); + + iio_device_release_direct_mode(indio_dev); + + return ret; +} + +static int ad74115_adc_code_to_resistance(int code, int *val, int *val2) +{ + if (code == AD74115_ADC_CODE_MAX) + code--; + + *val = code * AD74115_REF_RESISTOR_OHMS; + *val2 = AD74115_ADC_CODE_MAX - code; + + return IIO_VAL_FRACTIONAL; +} + +static int ad74115_set_dac_code(struct ad74115_state *st, + enum ad74115_dac_ch channel, int val) +{ + if (val < 0) + return -EINVAL; + + if (channel == AD74115_DAC_CH_COMPARATOR) { + if (val > AD74115_COMP_THRESH_MAX) + return -EINVAL; + + return regmap_update_bits(st->regmap, AD74115_DIN_CONFIG2_REG, + AD74115_COMP_THRESH_MASK, + FIELD_PREP(AD74115_COMP_THRESH_MASK, val)); + } + + if (val > AD74115_DAC_CODE_MAX) + return -EINVAL; + + return regmap_write(st->regmap, AD74115_DAC_CODE_REG, val); +} + +static int ad74115_get_dac_code(struct ad74115_state *st, + enum ad74115_dac_ch channel, int *val) +{ + unsigned int uval; + int ret; + + if (channel == AD74115_DAC_CH_COMPARATOR) + return -EINVAL; + + ret = regmap_read(st->regmap, AD74115_DAC_ACTIVE_REG, &uval); + if (ret) + return ret; + + *val = uval; + + return IIO_VAL_INT; +} + +static int ad74115_set_adc_rate(struct ad74115_state *st, + enum ad74115_adc_ch channel, int val) +{ + unsigned int i; + int ret; + + ret = ad74115_find_tbl_index(ad74115_adc_conv_rate_tbl, val, &i); + if (ret) + return ret; + + if (channel == AD74115_ADC_CH_CONV1) + return regmap_update_bits(st->regmap, AD74115_ADC_CONFIG_REG, + AD74115_ADC_CONFIG_CONV1_RATE_MASK, + FIELD_PREP(AD74115_ADC_CONFIG_CONV1_RATE_MASK, i)); + + return regmap_update_bits(st->regmap, AD74115_ADC_CONFIG_REG, + AD74115_ADC_CONFIG_CONV2_RATE_MASK, + FIELD_PREP(AD74115_ADC_CONFIG_CONV2_RATE_MASK, i)); +} + +static int ad74115_get_dac_rate(struct ad74115_state *st, int *val) +{ + unsigned int i, en_val, step_val, rate_val, tmp; + int ret; + + ret = regmap_read(st->regmap, AD74115_OUTPUT_CONFIG_REG, &tmp); + if (ret) + return ret; + + en_val = FIELD_GET(AD74115_OUTPUT_SLEW_EN_MASK, tmp); + step_val = FIELD_GET(AD74115_OUTPUT_SLEW_LIN_STEP_MASK, tmp); + rate_val = FIELD_GET(AD74115_OUTPUT_SLEW_LIN_RATE_MASK, tmp); + + for (i = 0; i < ARRAY_SIZE(ad74115_dac_rate_step_tbl); i++) + if (en_val == ad74115_dac_rate_step_tbl[i][0] && + step_val == ad74115_dac_rate_step_tbl[i][1] && + rate_val == ad74115_dac_rate_step_tbl[i][2]) + break; + + if (i == ARRAY_SIZE(ad74115_dac_rate_step_tbl)) + return -EINVAL; + + *val = ad74115_dac_rate_tbl[i]; + + return IIO_VAL_INT; +} + +static int ad74115_set_dac_rate(struct ad74115_state *st, int val) +{ + unsigned int i, en_val, step_val, rate_val, mask, tmp; + int ret; + + ret = ad74115_find_tbl_index(ad74115_dac_rate_tbl, val, &i); + if (ret) + return ret; + + en_val = ad74115_dac_rate_step_tbl[i][0]; + step_val = ad74115_dac_rate_step_tbl[i][1]; + rate_val = ad74115_dac_rate_step_tbl[i][2]; + + mask = AD74115_OUTPUT_SLEW_EN_MASK; + mask |= AD74115_OUTPUT_SLEW_LIN_STEP_MASK; + mask |= AD74115_OUTPUT_SLEW_LIN_RATE_MASK; + + tmp = FIELD_PREP(AD74115_OUTPUT_SLEW_EN_MASK, en_val); + tmp |= FIELD_PREP(AD74115_OUTPUT_SLEW_LIN_STEP_MASK, step_val); + tmp |= FIELD_PREP(AD74115_OUTPUT_SLEW_LIN_RATE_MASK, rate_val); + + return regmap_update_bits(st->regmap, AD74115_OUTPUT_CONFIG_REG, mask, tmp); +} + +static int ad74115_get_dac_scale(struct ad74115_state *st, + struct iio_chan_spec const *chan, + int *val, int *val2) +{ + if (chan->channel == AD74115_DAC_CH_MAIN) { + if (chan->type == IIO_VOLTAGE) { + *val = AD74115_DAC_VOLTAGE_MAX; + + if (st->dac_bipolar) + *val *= 2; + + } else { + *val = AD74115_DAC_CURRENT_MAX; + } + + *val2 = AD74115_DAC_CODE_MAX; + } else { + if (st->din_threshold_mode == AD74115_DIN_THRESHOLD_MODE_AVDD) { + *val = 196 * st->avdd_mv; + *val2 = 10 * AD74115_COMP_THRESH_MAX; + } else { + *val = 49000; + *val2 = AD74115_COMP_THRESH_MAX; + } + } + + return IIO_VAL_FRACTIONAL; +} + +static int ad74115_get_dac_offset(struct ad74115_state *st, + struct iio_chan_spec const *chan, int *val) +{ + if (chan->channel == AD74115_DAC_CH_MAIN) { + if (chan->type == IIO_VOLTAGE && st->dac_bipolar) + *val = -AD74115_DAC_CODE_HALF; + else + *val = 0; + } else { + if (st->din_threshold_mode == AD74115_DIN_THRESHOLD_MODE_AVDD) + *val = -48; + else + *val = -38; + } + + return IIO_VAL_INT; +} + +static int ad74115_get_adc_range(struct ad74115_state *st, + enum ad74115_adc_ch channel, unsigned int *val) +{ + int ret; + + ret = regmap_read(st->regmap, AD74115_ADC_CONFIG_REG, val); + if (ret) + return ret; + + if (channel == AD74115_ADC_CH_CONV1) + *val = FIELD_GET(AD74115_ADC_CONFIG_CONV1_RANGE_MASK, *val); + else + *val = FIELD_GET(AD74115_ADC_CONFIG_CONV2_RANGE_MASK, *val); + + return 0; +} + +static int ad74115_get_adc_resistance_scale(struct ad74115_state *st, + unsigned int range, + int *val, int *val2) +{ + *val = ad74115_adc_gain_tbl[range][1] * AD74115_REF_RESISTOR_OHMS; + *val2 = ad74115_adc_gain_tbl[range][0]; + + if (ad74115_adc_bipolar_tbl[range]) + *val2 *= AD74115_ADC_CODE_HALF; + else + *val2 *= AD74115_ADC_CODE_MAX; + + return IIO_VAL_FRACTIONAL; +} + +static int ad74115_get_adc_scale(struct ad74115_state *st, + struct iio_chan_spec const *chan, + int *val, int *val2) +{ + unsigned int range; + int ret; + + ret = ad74115_get_adc_range(st, chan->channel, &range); + if (ret) + return ret; + + if (chan->type == IIO_RESISTANCE) + return ad74115_get_adc_resistance_scale(st, range, val, val2); + + *val = ad74115_adc_conv_mul_tbl[range]; + *val2 = AD74115_ADC_CODE_MAX; + + if (chan->type == IIO_CURRENT) + *val2 *= AD74115_SENSE_RESISTOR_OHMS; + + return IIO_VAL_FRACTIONAL; +} + +static int ad74115_get_adc_resistance_offset(struct ad74115_state *st, + unsigned int range, + int *val, int *val2) +{ + unsigned int d = 10 * AD74115_REF_RESISTOR_OHMS + * ad74115_adc_gain_tbl[range][1]; + + *val = 5; + + if (ad74115_adc_bipolar_tbl[range]) + *val -= AD74115_ADC_CODE_HALF; + + *val *= d; + + if (!st->rtd_mode_4_wire) { + /* Add 0.2 Ohm to the final result for 3-wire RTD. */ + unsigned int v = 2 * ad74115_adc_gain_tbl[range][0]; + + if (ad74115_adc_bipolar_tbl[range]) + v *= AD74115_ADC_CODE_HALF; + else + v *= AD74115_ADC_CODE_MAX; + + *val += v; + } + + *val2 = d; + + return IIO_VAL_FRACTIONAL; +} + +static int ad74115_get_adc_offset(struct ad74115_state *st, + struct iio_chan_spec const *chan, + int *val, int *val2) +{ + unsigned int range; + int ret; + + ret = ad74115_get_adc_range(st, chan->channel, &range); + if (ret) + return ret; + + if (chan->type == IIO_RESISTANCE) + return ad74115_get_adc_resistance_offset(st, range, val, val2); + + if (ad74115_adc_bipolar_tbl[range]) + *val = -AD74115_ADC_CODE_HALF; + else if (range == AD74115_ADC_RANGE_2_5V_NEG) + *val = -AD74115_ADC_CODE_MAX; + else + *val = 0; + + return IIO_VAL_INT; +} + +static int ad74115_read_raw(struct iio_dev *indio_dev, + struct iio_chan_spec const *chan, + int *val, int *val2, long info) +{ + struct ad74115_state *st = iio_priv(indio_dev); + int ret; + + switch (info) { + case IIO_CHAN_INFO_RAW: + if (chan->output) + return ad74115_get_dac_code(st, chan->channel, val); + + return ad74115_get_adc_code(indio_dev, chan->channel, val); + case IIO_CHAN_INFO_PROCESSED: + ret = ad74115_get_adc_code(indio_dev, chan->channel, val); + if (ret) + return ret; + + return ad74115_adc_code_to_resistance(*val, val, val2); + case IIO_CHAN_INFO_SCALE: + if (chan->output) + return ad74115_get_dac_scale(st, chan, val, val2); + + return ad74115_get_adc_scale(st, chan, val, val2); + case IIO_CHAN_INFO_OFFSET: + if (chan->output) + return ad74115_get_dac_offset(st, chan, val); + + return ad74115_get_adc_offset(st, chan, val, val2); + case IIO_CHAN_INFO_SAMP_FREQ: + if (chan->output) + return ad74115_get_dac_rate(st, val); + + return ad74115_get_adc_rate(st, chan->channel, val); + default: + return -EINVAL; + } +} + +static int ad74115_write_raw(struct iio_dev *indio_dev, + struct iio_chan_spec const *chan, int val, int val2, + long info) +{ + struct ad74115_state *st = iio_priv(indio_dev); + + switch (info) { + case IIO_CHAN_INFO_RAW: + if (!chan->output) + return -EINVAL; + + return ad74115_set_dac_code(st, chan->channel, val); + case IIO_CHAN_INFO_SAMP_FREQ: + if (chan->output) + return ad74115_set_dac_rate(st, val); + + return ad74115_set_adc_rate(st, chan->channel, val); + default: + return -EINVAL; + } +} + +static int ad74115_read_avail(struct iio_dev *indio_dev, + struct iio_chan_spec const *chan, + const int **vals, int *type, int *length, long info) +{ + switch (info) { + case IIO_CHAN_INFO_SAMP_FREQ: + if (chan->output) { + *vals = ad74115_dac_rate_tbl; + *length = ARRAY_SIZE(ad74115_dac_rate_tbl); + } else { + *vals = ad74115_adc_conv_rate_tbl; + *length = ARRAY_SIZE(ad74115_adc_conv_rate_tbl); + } + + *type = IIO_VAL_INT; + + return IIO_AVAIL_LIST; + default: + return -EINVAL; + } +} + +static int ad74115_reg_access(struct iio_dev *indio_dev, unsigned int reg, + unsigned int writeval, unsigned int *readval) +{ + struct ad74115_state *st = iio_priv(indio_dev); + + if (readval) + return regmap_read(st->regmap, reg, readval); + + return regmap_write(st->regmap, reg, writeval); +} + +static const struct iio_info ad74115_info = { + .read_raw = ad74115_read_raw, + .write_raw = ad74115_write_raw, + .read_avail = ad74115_read_avail, + .update_scan_mode = ad74115_update_scan_mode, + .debugfs_reg_access = ad74115_reg_access, +}; + +#define AD74115_DAC_CHANNEL(_type, index) \ + { \ + .type = (_type), \ + .channel = (index), \ + .indexed = 1, \ + .output = 1, \ + .scan_index = -1, \ + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) \ + | BIT(IIO_CHAN_INFO_SCALE) \ + | BIT(IIO_CHAN_INFO_OFFSET), \ + } + +#define _AD74115_ADC_CHANNEL(_type, index, extra_mask_separate) \ + { \ + .type = (_type), \ + .channel = (index), \ + .indexed = 1, \ + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) \ + | BIT(IIO_CHAN_INFO_SAMP_FREQ) \ + | (extra_mask_separate), \ + .info_mask_separate_available = \ + BIT(IIO_CHAN_INFO_SAMP_FREQ), \ + .scan_index = index, \ + .scan_type = { \ + .sign = 'u', \ + .realbits = 16, \ + .storagebits = 32, \ + .shift = 8, \ + .endianness = IIO_BE, \ + }, \ + } + +#define AD74115_ADC_CHANNEL(_type, index) \ + _AD74115_ADC_CHANNEL(_type, index, BIT(IIO_CHAN_INFO_SCALE) \ + | BIT(IIO_CHAN_INFO_OFFSET)) + +static struct iio_chan_spec ad74115_voltage_input_channels[] = { + AD74115_ADC_CHANNEL(IIO_VOLTAGE, AD74115_ADC_CH_CONV1), + AD74115_ADC_CHANNEL(IIO_VOLTAGE, AD74115_ADC_CH_CONV2), +}; + +static struct iio_chan_spec ad74115_voltage_output_channels[] = { + AD74115_DAC_CHANNEL(IIO_VOLTAGE, AD74115_DAC_CH_MAIN), + AD74115_ADC_CHANNEL(IIO_CURRENT, AD74115_ADC_CH_CONV1), + AD74115_ADC_CHANNEL(IIO_VOLTAGE, AD74115_ADC_CH_CONV2), +}; + +static struct iio_chan_spec ad74115_current_input_channels[] = { + AD74115_ADC_CHANNEL(IIO_CURRENT, AD74115_ADC_CH_CONV1), + AD74115_ADC_CHANNEL(IIO_VOLTAGE, AD74115_ADC_CH_CONV2), +}; + +static struct iio_chan_spec ad74115_current_output_channels[] = { + AD74115_DAC_CHANNEL(IIO_CURRENT, AD74115_DAC_CH_MAIN), + AD74115_ADC_CHANNEL(IIO_VOLTAGE, AD74115_ADC_CH_CONV1), + AD74115_ADC_CHANNEL(IIO_VOLTAGE, AD74115_ADC_CH_CONV2), +}; + +static struct iio_chan_spec ad74115_2_wire_resistance_input_channels[] = { + _AD74115_ADC_CHANNEL(IIO_RESISTANCE, AD74115_ADC_CH_CONV1, + BIT(IIO_CHAN_INFO_PROCESSED)), + AD74115_ADC_CHANNEL(IIO_VOLTAGE, AD74115_ADC_CH_CONV2), +}; + +static struct iio_chan_spec ad74115_3_4_wire_resistance_input_channels[] = { + AD74115_ADC_CHANNEL(IIO_RESISTANCE, AD74115_ADC_CH_CONV1), + AD74115_ADC_CHANNEL(IIO_VOLTAGE, AD74115_ADC_CH_CONV2), +}; + +static struct iio_chan_spec ad74115_digital_input_logic_channels[] = { + AD74115_DAC_CHANNEL(IIO_VOLTAGE, AD74115_DAC_CH_COMPARATOR), + AD74115_ADC_CHANNEL(IIO_VOLTAGE, AD74115_ADC_CH_CONV1), + AD74115_ADC_CHANNEL(IIO_VOLTAGE, AD74115_ADC_CH_CONV2), +}; + +static struct iio_chan_spec ad74115_digital_input_loop_channels[] = { + AD74115_DAC_CHANNEL(IIO_CURRENT, AD74115_DAC_CH_MAIN), + AD74115_DAC_CHANNEL(IIO_VOLTAGE, AD74115_DAC_CH_COMPARATOR), + AD74115_ADC_CHANNEL(IIO_VOLTAGE, AD74115_ADC_CH_CONV1), + AD74115_ADC_CHANNEL(IIO_VOLTAGE, AD74115_ADC_CH_CONV2), +}; + +#define _AD74115_CHANNELS(_channels) \ + { \ + .channels = _channels, \ + .num_channels = ARRAY_SIZE(_channels), \ + } + +#define AD74115_CHANNELS(name) \ + _AD74115_CHANNELS(ad74115_ ## name ## _channels) + +static const struct ad74115_channels ad74115_channels_map[AD74115_CH_FUNC_NUM] = { + [AD74115_CH_FUNC_HIGH_IMPEDANCE] = AD74115_CHANNELS(voltage_input), + [AD74115_CH_FUNC_VOLTAGE_INPUT] = AD74115_CHANNELS(voltage_input), + + [AD74115_CH_FUNC_VOLTAGE_OUTPUT] = AD74115_CHANNELS(voltage_output), + + [AD74115_CH_FUNC_CURRENT_INPUT_EXT_POWER] = AD74115_CHANNELS(current_input), + [AD74115_CH_FUNC_CURRENT_INPUT_LOOP_POWER] = AD74115_CHANNELS(current_input), + [AD74115_CH_FUNC_CURRENT_INPUT_EXT_POWER_HART] = AD74115_CHANNELS(current_input), + [AD74115_CH_FUNC_CURRENT_INPUT_LOOP_POWER_HART] = AD74115_CHANNELS(current_input), + + [AD74115_CH_FUNC_CURRENT_OUTPUT] = AD74115_CHANNELS(current_output), + [AD74115_CH_FUNC_CURRENT_OUTPUT_HART] = AD74115_CHANNELS(current_output), + + [AD74115_CH_FUNC_2_WIRE_RESISTANCE_INPUT] = AD74115_CHANNELS(2_wire_resistance_input), + [AD74115_CH_FUNC_3_4_WIRE_RESISTANCE_INPUT] = AD74115_CHANNELS(3_4_wire_resistance_input), + + [AD74115_CH_FUNC_DIGITAL_INPUT_LOGIC] = AD74115_CHANNELS(digital_input_logic), + + [AD74115_CH_FUNC_DIGITAL_INPUT_LOOP_POWER] = AD74115_CHANNELS(digital_input_loop), +}; + +#define AD74115_GPIO_MODE_FW_PROP(i) \ +{ \ + .name = "adi,gpio" __stringify(i) "-mode", \ + .reg = AD74115_GPIO_CONFIG_X_REG(i), \ + .mask = AD74115_GPIO_CONFIG_SELECT_MASK, \ + .lookup_tbl = ad74115_gpio_mode_tbl, \ + .lookup_tbl_len = ARRAY_SIZE(ad74115_gpio_mode_tbl), \ +} + +static const struct ad74115_fw_prop ad74115_gpio_mode_fw_props[] = { + AD74115_GPIO_MODE_FW_PROP(0), + AD74115_GPIO_MODE_FW_PROP(1), + AD74115_GPIO_MODE_FW_PROP(2), + AD74115_GPIO_MODE_FW_PROP(3), +}; + +static const struct ad74115_fw_prop ad74115_din_threshold_mode_fw_prop = + AD74115_FW_PROP_BOOL("adi,digital-input-threshold-mode-fixed", + AD74115_DIN_CONFIG2_REG, BIT(7)); + +static const struct ad74115_fw_prop ad74115_dac_bipolar_fw_prop = + AD74115_FW_PROP_BOOL("adi,dac-bipolar", AD74115_OUTPUT_CONFIG_REG, BIT(7)); + +static const struct ad74115_fw_prop ad74115_ch_func_fw_prop = + AD74115_FW_PROP("adi,ch-func", AD74115_CH_FUNC_MAX, + AD74115_CH_FUNC_SETUP_REG, GENMASK(3, 0)); + +static const struct ad74115_fw_prop ad74115_rtd_mode_fw_prop = + AD74115_FW_PROP_BOOL("adi,4-wire-rtd", AD74115_RTD3W4W_CONFIG_REG, BIT(3)); + +static const struct ad74115_fw_prop ad74115_din_range_fw_prop = + AD74115_FW_PROP_BOOL("adi,digital-input-sink-range-high", + AD74115_DIN_CONFIG1_REG, BIT(12)); + +static const struct ad74115_fw_prop ad74115_ext2_burnout_current_fw_prop = + AD74115_FW_PROP_TBL("adi,ext2-burnout-current-nanoamp", + ad74115_burnout_current_na_tbl, + AD74115_BURNOUT_CONFIG_REG, GENMASK(14, 12)); + +static const struct ad74115_fw_prop ad74115_ext1_burnout_current_fw_prop = + AD74115_FW_PROP_TBL("adi,ext1-burnout-current-nanoamp", + ad74115_burnout_current_na_tbl, + AD74115_BURNOUT_CONFIG_REG, GENMASK(9, 7)); + +static const struct ad74115_fw_prop ad74115_viout_burnout_current_fw_prop = + AD74115_FW_PROP_TBL("adi,viout-burnout-current-nanoamp", + ad74115_viout_burnout_current_na_tbl, + AD74115_BURNOUT_CONFIG_REG, GENMASK(4, 2)); + +static const struct ad74115_fw_prop ad74115_fw_props[] = { + AD74115_FW_PROP("adi,conv2-mux", 3, + AD74115_ADC_CONFIG_REG, GENMASK(3, 2)), + + AD74115_FW_PROP_BOOL_NEG("adi,sense-agnd-buffer-low-power", + AD74115_PWR_OPTIM_CONFIG_REG, BIT(4)), + AD74115_FW_PROP_BOOL_NEG("adi,lf-buffer-low-power", + AD74115_PWR_OPTIM_CONFIG_REG, BIT(3)), + AD74115_FW_PROP_BOOL_NEG("adi,hf-buffer-low-power", + AD74115_PWR_OPTIM_CONFIG_REG, BIT(2)), + AD74115_FW_PROP_BOOL_NEG("adi,ext2-buffer-low-power", + AD74115_PWR_OPTIM_CONFIG_REG, BIT(1)), + AD74115_FW_PROP_BOOL_NEG("adi,ext1-buffer-low-power", + AD74115_PWR_OPTIM_CONFIG_REG, BIT(0)), + + AD74115_FW_PROP_BOOL("adi,comparator-invert", + AD74115_DIN_CONFIG1_REG, BIT(14)), + AD74115_FW_PROP_BOOL("adi,digital-input-debounce-mode-counter-reset", + AD74115_DIN_CONFIG1_REG, BIT(6)), + + AD74115_FW_PROP_BOOL("adi,digital-input-unbuffered", + AD74115_DIN_CONFIG2_REG, BIT(10)), + AD74115_FW_PROP_BOOL("adi,digital-input-short-circuit-detection", + AD74115_DIN_CONFIG2_REG, BIT(9)), + AD74115_FW_PROP_BOOL("adi,digital-input-open-circuit-detection", + AD74115_DIN_CONFIG2_REG, BIT(8)), + + AD74115_FW_PROP_BOOL("adi,dac-current-limit-low", + AD74115_OUTPUT_CONFIG_REG, BIT(0)), + + AD74115_FW_PROP_BOOL("adi,3-wire-rtd-excitation-swap", + AD74115_RTD3W4W_CONFIG_REG, BIT(2)), + AD74115_FW_PROP_TBL("adi,rtd-excitation-current-microamp", + ad74115_rtd_excitation_current_ua_tbl, + AD74115_RTD3W4W_CONFIG_REG, GENMASK(1, 0)), + + AD74115_FW_PROP_BOOL("adi,ext2-burnout-current-polarity-sourcing", + AD74115_BURNOUT_CONFIG_REG, BIT(11)), + AD74115_FW_PROP_BOOL("adi,ext1-burnout-current-polarity-sourcing", + AD74115_BURNOUT_CONFIG_REG, BIT(6)), + AD74115_FW_PROP_BOOL("adi,viout-burnout-current-polarity-sourcing", + AD74115_BURNOUT_CONFIG_REG, BIT(1)), + + AD74115_FW_PROP_BOOL("adi,charge-pump", + AD74115_CHARGE_PUMP_REG, BIT(0)), +}; + +static int ad74115_apply_fw_prop(struct ad74115_state *st, + const struct ad74115_fw_prop *prop, u32 *retval) +{ + struct device *dev = &st->spi->dev; + u32 val = 0; + int ret; + + if (prop->is_boolean) { + val = device_property_read_bool(dev, prop->name); + } else { + ret = device_property_read_u32(dev, prop->name, &val); + if (ret && prop->lookup_tbl) + val = prop->lookup_tbl[0]; + } + + *retval = val; + + if (prop->negate) + val = !val; + + if (prop->lookup_tbl) + ret = _ad74115_find_tbl_index(prop->lookup_tbl, + prop->lookup_tbl_len, val, &val); + else if (prop->max && val > prop->max) + ret = -EINVAL; + else + ret = 0; + + if (ret) + return dev_err_probe(dev, -EINVAL, + "Invalid value %u for prop %s\n", + val, prop->name); + + WARN(!prop->mask, "Prop %s mask is empty\n", prop->name); + + val = (val << __ffs(prop->mask)) & prop->mask; + + return regmap_update_bits(st->regmap, prop->reg, prop->mask, val); +} + +static int ad74115_setup_adc_conv2_range(struct ad74115_state *st) +{ + unsigned int tbl_len = ARRAY_SIZE(ad74115_adc_range_tbl); + const char *prop_name = "adi,conv2-range-microvolt"; + s32 vals[2] = { + ad74115_adc_range_tbl[0][0], + ad74115_adc_range_tbl[0][1], + }; + struct device *dev = &st->spi->dev; + unsigned int i; + + device_property_read_u32_array(dev, prop_name, vals, 2); + + for (i = 0; i < tbl_len; i++) + if (vals[0] == ad74115_adc_range_tbl[i][0] && + vals[1] == ad74115_adc_range_tbl[i][1]) + break; + + if (i == tbl_len) + return dev_err_probe(dev, -EINVAL, + "Invalid value %d, %d for prop %s\n", + vals[0], vals[1], prop_name); + + return regmap_update_bits(st->regmap, AD74115_ADC_CONFIG_REG, + AD74115_ADC_CONFIG_CONV2_RANGE_MASK, + FIELD_PREP(AD74115_ADC_CONFIG_CONV2_RANGE_MASK, i)); +} + +static int ad74115_setup_iio_channels(struct iio_dev *indio_dev) +{ + struct ad74115_state *st = iio_priv(indio_dev); + struct device *dev = &st->spi->dev; + struct iio_chan_spec *channels; + + channels = devm_kcalloc(dev, sizeof(*channels), + indio_dev->num_channels, GFP_KERNEL); + if (!channels) + return -ENOMEM; + + indio_dev->channels = channels; + + memcpy(channels, ad74115_channels_map[st->ch_func].channels, + sizeof(*channels) * ad74115_channels_map[st->ch_func].num_channels); + + if (channels[0].output && channels[0].channel == AD74115_DAC_CH_MAIN && + channels[0].type == IIO_VOLTAGE && !st->dac_hart_slew) { + channels[0].info_mask_separate |= BIT(IIO_CHAN_INFO_SAMP_FREQ); + channels[0].info_mask_separate_available |= BIT(IIO_CHAN_INFO_SAMP_FREQ); + } + + return 0; +} + +static int ad74115_setup_gpio_chip(struct ad74115_state *st) +{ + struct device *dev = &st->spi->dev; + + if (!st->gpio_valid_mask) + return 0; + + st->gc = (struct gpio_chip) { + .owner = THIS_MODULE, + .label = AD74115_NAME, + .base = -1, + .ngpio = AD74115_GPIO_NUM, + .parent = dev, + .can_sleep = true, + .init_valid_mask = ad74115_gpio_init_valid_mask, + .get_direction = ad74115_gpio_get_direction, + .direction_input = ad74115_gpio_direction_input, + .direction_output = ad74115_gpio_direction_output, + .get = ad74115_gpio_get, + .set = ad74115_gpio_set, + }; + + return devm_gpiochip_add_data(dev, &st->gc, st); +} + +static int ad74115_setup_comp_gpio_chip(struct ad74115_state *st) +{ + struct device *dev = &st->spi->dev; + u32 val; + int ret; + + ret = regmap_read(st->regmap, AD74115_DIN_CONFIG1_REG, &val); + if (ret) + return ret; + + if (!(val & AD74115_DIN_COMPARATOR_EN_MASK)) + return 0; + + st->comp_gc = (struct gpio_chip) { + .owner = THIS_MODULE, + .label = AD74115_NAME, + .base = -1, + .ngpio = 1, + .parent = dev, + .can_sleep = true, + .get_direction = ad74115_comp_gpio_get_direction, + .get = ad74115_comp_gpio_get, + .set_config = ad74115_comp_gpio_set_config, + }; + + return devm_gpiochip_add_data(dev, &st->comp_gc, st); +} + +static int ad74115_setup(struct iio_dev *indio_dev) +{ + struct ad74115_state *st = iio_priv(indio_dev); + struct device *dev = &st->spi->dev; + u32 val, din_range_high; + unsigned int i; + int ret; + + ret = ad74115_apply_fw_prop(st, &ad74115_ch_func_fw_prop, &val); + if (ret) + return ret; + + indio_dev->num_channels += ad74115_channels_map[val].num_channels; + st->ch_func = val; + + ret = ad74115_setup_adc_conv2_range(st); + if (ret) + return ret; + + val = device_property_read_bool(dev, "adi,dac-hart-slew"); + if (val) { + st->dac_hart_slew = val; + + ret = regmap_update_bits(st->regmap, AD74115_OUTPUT_CONFIG_REG, + AD74115_OUTPUT_SLEW_EN_MASK, + FIELD_PREP(AD74115_OUTPUT_SLEW_EN_MASK, + AD74115_SLEW_MODE_HART)); + if (ret) + return ret; + } + + ret = ad74115_apply_fw_prop(st, &ad74115_din_range_fw_prop, + &din_range_high); + if (ret) + return ret; + + ret = device_property_read_u32(dev, "adi,digital-input-sink-microamp", &val); + if (!ret) { + if (din_range_high) + val = DIV_ROUND_CLOSEST(val, AD74115_DIN_SINK_LOW_STEP); + else + val = DIV_ROUND_CLOSEST(val, AD74115_DIN_SINK_HIGH_STEP); + + if (val > AD74115_DIN_SINK_MAX) + val = AD74115_DIN_SINK_MAX; + + ret = regmap_update_bits(st->regmap, AD74115_DIN_CONFIG1_REG, + AD74115_DIN_SINK_MASK, + FIELD_PREP(AD74115_DIN_SINK_MASK, val)); + if (ret) + return ret; + } + + ret = ad74115_apply_fw_prop(st, &ad74115_din_threshold_mode_fw_prop, &val); + if (ret) + return ret; + + if (val == AD74115_DIN_THRESHOLD_MODE_AVDD) { + ret = regulator_get_voltage(st->avdd); + if (ret < 0) + return ret; + + st->avdd_mv = ret / 1000; + } + + st->din_threshold_mode = val; + + ret = ad74115_apply_fw_prop(st, &ad74115_dac_bipolar_fw_prop, &val); + if (ret) + return ret; + + st->dac_bipolar = val; + + ret = ad74115_apply_fw_prop(st, &ad74115_rtd_mode_fw_prop, &val); + if (ret) + return ret; + + st->rtd_mode_4_wire = val; + + ret = ad74115_apply_fw_prop(st, &ad74115_ext2_burnout_current_fw_prop, &val); + if (ret) + return ret; + + if (val) { + ret = regmap_update_bits(st->regmap, AD74115_BURNOUT_CONFIG_REG, + AD74115_BURNOUT_EXT2_EN_MASK, + FIELD_PREP(AD74115_BURNOUT_EXT2_EN_MASK, 1)); + if (ret) + return ret; + } + + ret = ad74115_apply_fw_prop(st, &ad74115_ext1_burnout_current_fw_prop, &val); + if (ret) + return ret; + + if (val) { + ret = regmap_update_bits(st->regmap, AD74115_BURNOUT_CONFIG_REG, + AD74115_BURNOUT_EXT1_EN_MASK, + FIELD_PREP(AD74115_BURNOUT_EXT1_EN_MASK, 1)); + if (ret) + return ret; + } + + ret = ad74115_apply_fw_prop(st, &ad74115_viout_burnout_current_fw_prop, &val); + if (ret) + return ret; + + if (val) { + ret = regmap_update_bits(st->regmap, AD74115_BURNOUT_CONFIG_REG, + AD74115_BURNOUT_VIOUT_EN_MASK, + FIELD_PREP(AD74115_BURNOUT_VIOUT_EN_MASK, 1)); + if (ret) + return ret; + } + + for (i = 0; i < AD74115_GPIO_NUM; i++) { + ret = ad74115_apply_fw_prop(st, &ad74115_gpio_mode_fw_props[i], &val); + if (ret) + return ret; + + if (val == AD74115_GPIO_MODE_LOGIC) + st->gpio_valid_mask |= BIT(i); + } + + for (i = 0; i < ARRAY_SIZE(ad74115_fw_props); i++) { + ret = ad74115_apply_fw_prop(st, &ad74115_fw_props[i], &val); + if (ret) + return ret; + } + + ret = ad74115_setup_gpio_chip(st); + if (ret) + return ret; + + ret = ad74115_setup_comp_gpio_chip(st); + if (ret) + return ret; + + return ad74115_setup_iio_channels(indio_dev); +} + +static int ad74115_reset(struct ad74115_state *st) +{ + struct device *dev = &st->spi->dev; + struct gpio_desc *reset_gpio; + int ret; + + reset_gpio = devm_gpiod_get_optional(dev, "reset", GPIOD_OUT_HIGH); + if (IS_ERR(reset_gpio)) + return dev_err_probe(dev, PTR_ERR(reset_gpio), + "Failed to find reset GPIO\n"); + + if (reset_gpio) { + fsleep(100); + + gpiod_set_value_cansleep(reset_gpio, 0); + } else { + ret = regmap_write(st->regmap, AD74115_CMD_KEY_REG, + AD74115_CMD_KEY_RESET1); + if (ret) + return ret; + + ret = regmap_write(st->regmap, AD74115_CMD_KEY_REG, + AD74115_CMD_KEY_RESET2); + if (ret) + return ret; + } + + fsleep(1000); + + return 0; +} + +static void ad74115_regulator_disable(void *data) +{ + regulator_disable(data); +} + +static int ad74115_setup_trigger(struct iio_dev *indio_dev) +{ + struct ad74115_state *st = iio_priv(indio_dev); + struct device *dev = &st->spi->dev; + int ret; + + st->irq = fwnode_irq_get_byname(dev_fwnode(dev), "adc_rdy"); + + if (st->irq == -EPROBE_DEFER) + return -EPROBE_DEFER; + + if (st->irq < 0) { + st->irq = 0; + return 0; + } + + ret = devm_request_irq(dev, st->irq, ad74115_adc_data_interrupt, + 0, AD74115_NAME, indio_dev); + if (ret) + return ret; + + st->trig = devm_iio_trigger_alloc(dev, "%s-dev%d", AD74115_NAME, + iio_device_id(indio_dev)); + if (!st->trig) + return -ENOMEM; + + st->trig->ops = &ad74115_trigger_ops; + iio_trigger_set_drvdata(st->trig, st); + + ret = devm_iio_trigger_register(dev, st->trig); + if (ret) + return ret; + + indio_dev->trig = iio_trigger_get(st->trig); + + return 0; +} + +static int ad74115_probe(struct spi_device *spi) +{ + static const char * const regulator_names[] = { + "avcc", "dvcc", "dovdd", "refin", + }; + struct device *dev = &spi->dev; + struct ad74115_state *st; + struct iio_dev *indio_dev; + int ret; + + indio_dev = devm_iio_device_alloc(dev, sizeof(*st)); + if (!indio_dev) + return -ENOMEM; + + st = iio_priv(indio_dev); + + st->spi = spi; + mutex_init(&st->lock); + init_completion(&st->adc_data_completion); + + indio_dev->name = AD74115_NAME; + indio_dev->modes = INDIO_DIRECT_MODE; + indio_dev->info = &ad74115_info; + + st->avdd = devm_regulator_get(dev, "avdd"); + if (IS_ERR(st->avdd)) + return PTR_ERR(st->avdd); + + ret = regulator_enable(st->avdd); + if (ret) { + dev_err(dev, "Failed to enable avdd regulator\n"); + return ret; + } + + ret = devm_add_action_or_reset(dev, ad74115_regulator_disable, st->avdd); + if (ret) + return ret; + + ret = devm_regulator_bulk_get_enable(dev, ARRAY_SIZE(regulator_names), + regulator_names); + if (ret) + return ret; + + st->regmap = devm_regmap_init(dev, NULL, st, &ad74115_regmap_config); + if (IS_ERR(st->regmap)) + return PTR_ERR(st->regmap); + + ret = ad74115_reset(st); + if (ret) + return ret; + + ret = ad74115_setup(indio_dev); + if (ret) + return ret; + + ret = ad74115_setup_trigger(indio_dev); + if (ret) + return ret; + + ret = devm_iio_triggered_buffer_setup(dev, indio_dev, NULL, + ad74115_trigger_handler, + &ad74115_buffer_ops); + if (ret) + return ret; + + return devm_iio_device_register(dev, indio_dev); +} + +static int ad74115_unregister_driver(struct spi_driver *spi) +{ + spi_unregister_driver(spi); + + return 0; +} + +static int __init ad74115_register_driver(struct spi_driver *spi) +{ + crc8_populate_msb(ad74115_crc8_table, AD74115_CRC_POLYNOMIAL); + + return spi_register_driver(spi); +} + +static const struct spi_device_id ad74115_spi_id[] = { + { "ad74115h" }, + { } +}; + +MODULE_DEVICE_TABLE(spi, ad74115_spi_id); + +static const struct of_device_id ad74115_dt_id[] = { + { .compatible = "adi,ad74115h" }, + { } +}; +MODULE_DEVICE_TABLE(of, ad74115_dt_id); + +static struct spi_driver ad74115_driver = { + .driver = { + .name = "ad74115", + .of_match_table = ad74115_dt_id, + }, + .probe = ad74115_probe, + .id_table = ad74115_spi_id, +}; + +module_driver(ad74115_driver, + ad74115_register_driver, ad74115_unregister_driver); + +MODULE_AUTHOR("Cosmin Tanislav "); +MODULE_DESCRIPTION("Analog Devices AD74115 ADDAC"); +MODULE_LICENSE("GPL"); -- cgit v1.2.3 From f35e1ee9cb5d617efeb0f3695ff65169eb2b9cdd Mon Sep 17 00:00:00 2001 From: Lorenzo Bianconi Date: Wed, 16 Nov 2022 14:40:03 +0100 Subject: iio: imu: st_lsm6dsx: add support to LSM6DSO16IS Add support to STM LSM6DSO16IS (accelerometer and gyroscope) Mems sensor. Datasheet: https://www.st.com/resource/en/datasheet/lsm6dso16is.pdf Tested-by: Mario Tesi Signed-off-by: Lorenzo Bianconi Link: https://lore.kernel.org/r/df6a9d4653cd69f7204190f8b6a9b618fd48bd23.1668605631.git.lorenzo@kernel.org Signed-off-by: Jonathan Cameron --- drivers/iio/imu/st_lsm6dsx/Kconfig | 4 +- drivers/iio/imu/st_lsm6dsx/st_lsm6dsx.h | 2 + drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c | 128 ++++++++++++++++++++++++++- drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_i2c.c | 5 ++ drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_spi.c | 5 ++ 5 files changed, 141 insertions(+), 3 deletions(-) (limited to 'drivers/iio') diff --git a/drivers/iio/imu/st_lsm6dsx/Kconfig b/drivers/iio/imu/st_lsm6dsx/Kconfig index 37d02e0fc227..0096035728cd 100644 --- a/drivers/iio/imu/st_lsm6dsx/Kconfig +++ b/drivers/iio/imu/st_lsm6dsx/Kconfig @@ -13,8 +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, - lsm6dsv, lsm6dsv16x, the accelerometer/gyroscope of lsm9ds1 - and lsm6dst. + lsm6dsv, lsm6dsv16x, lsm6dso16is, the accelerometer/gyroscope + of lsm9ds1 and lsm6dst. 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 683cfadcf62e..abf14a2ce0e9 100644 --- a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx.h +++ b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx.h @@ -35,6 +35,7 @@ #define ST_LSM6DSTX_DEV_NAME "lsm6dstx" #define ST_LSM6DSV_DEV_NAME "lsm6dsv" #define ST_LSM6DSV16X_DEV_NAME "lsm6dsv16x" +#define ST_LSM6DSO16IS_DEV_NAME "lsm6dso16is" enum st_lsm6dsx_hw_id { ST_LSM6DS3_ID, @@ -57,6 +58,7 @@ enum st_lsm6dsx_hw_id { ST_LSM6DSTX_ID, ST_LSM6DSV_ID, ST_LSM6DSV16X_ID, + ST_LSM6DSO16IS_ID, ST_LSM6DSX_MAX_ID, }; diff --git a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c index b680682f9833..57a79bf35bba 100644 --- a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c +++ b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c @@ -27,7 +27,7 @@ * - FIFO size: 4KB * * - LSM6DSO/LSM6DSOX/ASM330LHH/ASM330LHHX/LSM6DSR/ISM330DHCX/LSM6DST/LSM6DSOP/ - * LSM6DSTX: + * LSM6DSTX/LSM6DSO16IS: * - Accelerometer/Gyroscope supported ODR [Hz]: 12.5, 26, 52, 104, 208, 416, * 833 * - Accelerometer supported full-scale [g]: +-2/+-4/+-8/+-16 @@ -1375,6 +1375,132 @@ 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_LSM6DSO16IS_ID, + .name = ST_LSM6DSO16IS_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) diff --git a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_i2c.c b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_i2c.c index 3570fac1b612..c34ccc85e4c7 100644 --- a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_i2c.c +++ b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_i2c.c @@ -117,6 +117,10 @@ static const struct of_device_id st_lsm6dsx_i2c_of_match[] = { .compatible = "st,lsm6dsv16x", .data = (void *)ST_LSM6DSV16X_ID, }, + { + .compatible = "st,lsm6dso16is", + .data = (void *)ST_LSM6DSO16IS_ID, + }, {}, }; MODULE_DEVICE_TABLE(of, st_lsm6dsx_i2c_of_match); @@ -142,6 +146,7 @@ static const struct i2c_device_id st_lsm6dsx_i2c_id_table[] = { { 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 }, {}, }; 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 57597aaa2a92..24d5e51a8662 100644 --- a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_spi.c +++ b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_spi.c @@ -117,6 +117,10 @@ static const struct of_device_id st_lsm6dsx_spi_of_match[] = { .compatible = "st,lsm6dsv16x", .data = (void *)ST_LSM6DSV16X_ID, }, + { + .compatible = "st,lsm6dso16is", + .data = (void *)ST_LSM6DSO16IS_ID, + }, {}, }; MODULE_DEVICE_TABLE(of, st_lsm6dsx_spi_of_match); @@ -142,6 +146,7 @@ static const struct spi_device_id st_lsm6dsx_spi_id_table[] = { { 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 }, {}, }; MODULE_DEVICE_TABLE(spi, st_lsm6dsx_spi_id_table); -- cgit v1.2.3 From 7b2366008125b0849dcbd18afbcb33cbc30c3477 Mon Sep 17 00:00:00 2001 From: Rasmus Villemoes Date: Tue, 15 Nov 2022 10:55:15 +0100 Subject: iio: addac: ad74413r: add spi_device_id table Silence the run-time warning SPI driver ad74413r has no spi_device_id for adi,ad74412r Signed-off-by: Rasmus Villemoes Link: https://lore.kernel.org/r/20221115095517.1008632-2-linux@rasmusvillemoes.dk Signed-off-by: Jonathan Cameron --- drivers/iio/addac/ad74413r.c | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) (limited to 'drivers/iio') diff --git a/drivers/iio/addac/ad74413r.c b/drivers/iio/addac/ad74413r.c index e0e130ba9d3e..29b3a5775f23 100644 --- a/drivers/iio/addac/ad74413r.c +++ b/drivers/iio/addac/ad74413r.c @@ -1305,6 +1305,15 @@ static int ad74413r_probe(struct spi_device *spi) st->spi = spi; st->dev = &spi->dev; st->chip_info = device_get_match_data(&spi->dev); + if (!st->chip_info) { + const struct spi_device_id *id = spi_get_device_id(spi); + if (id) + st->chip_info = + (struct ad74413r_chip_info *)id->driver_data; + if (!st->chip_info) + return -EINVAL; + } + mutex_init(&st->lock); init_completion(&st->adc_data_completion); @@ -1457,12 +1466,20 @@ static const struct of_device_id ad74413r_dt_id[] = { }; MODULE_DEVICE_TABLE(of, ad74413r_dt_id); +static const struct spi_device_id ad74413r_spi_id[] = { + { .name = "ad74412r", .driver_data = (kernel_ulong_t)&ad74412r_chip_info_data }, + { .name = "ad74413r", .driver_data = (kernel_ulong_t)&ad74413r_chip_info_data }, + {} +}; +MODULE_DEVICE_TABLE(spi, ad74413r_spi_id); + static struct spi_driver ad74413r_driver = { .driver = { .name = "ad74413r", .of_match_table = ad74413r_dt_id, }, .probe = ad74413r_probe, + .id_table = ad74413r_spi_id, }; module_driver(ad74413r_driver, -- cgit v1.2.3 From f237cf1914e24ebba88670ecc36e8209c888c9a2 Mon Sep 17 00:00:00 2001 From: Rasmus Villemoes Date: Tue, 15 Nov 2022 10:55:17 +0100 Subject: iio: addac: ad74413r: add support for reset-gpio We have a board where the reset pin of the ad74412 is connected to a gpio, but also pulled low (i.e., asserted) by default. Hence to get the chip out of reset, the driver needs to know about that gpio and deassert the reset signal before attempting to communicate with the chip. When a reset-gpio is given in device tree, use that instead of the software reset. According to the data sheet, the two methods are functionally equivalent. Signed-off-by: Rasmus Villemoes Link: https://lore.kernel.org/r/20221115095517.1008632-4-linux@rasmusvillemoes.dk Signed-off-by: Jonathan Cameron --- drivers/iio/addac/ad74413r.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) (limited to 'drivers/iio') diff --git a/drivers/iio/addac/ad74413r.c b/drivers/iio/addac/ad74413r.c index 29b3a5775f23..61030053cbea 100644 --- a/drivers/iio/addac/ad74413r.c +++ b/drivers/iio/addac/ad74413r.c @@ -71,6 +71,7 @@ struct ad74413r_state { struct regmap *regmap; struct device *dev; struct iio_trigger *trig; + struct gpio_desc *reset_gpio; size_t adc_active_channels; struct spi_message adc_samples_msg; @@ -393,6 +394,13 @@ static int ad74413r_reset(struct ad74413r_state *st) { int ret; + if (st->reset_gpio) { + gpiod_set_value_cansleep(st->reset_gpio, 1); + fsleep(50); + gpiod_set_value_cansleep(st->reset_gpio, 0); + return 0; + } + ret = regmap_write(st->regmap, AD74413R_REG_CMD_KEY, AD74413R_CMD_KEY_RESET1); if (ret) @@ -1322,6 +1330,10 @@ static int ad74413r_probe(struct spi_device *spi) if (IS_ERR(st->regmap)) return PTR_ERR(st->regmap); + st->reset_gpio = devm_gpiod_get_optional(st->dev, "reset", GPIOD_OUT_LOW); + if (IS_ERR(st->reset_gpio)) + return PTR_ERR(st->reset_gpio); + st->refin_reg = devm_regulator_get(st->dev, "refin"); if (IS_ERR(st->refin_reg)) return dev_err_probe(st->dev, PTR_ERR(st->refin_reg), -- cgit v1.2.3 From 9d901e356c8d3640940cb72ff7969f03e85c2e95 Mon Sep 17 00:00:00 2001 From: Olivier Moysan Date: Tue, 15 Nov 2022 11:31:21 +0100 Subject: iio: adc: stm32-adc: smart calibration support Add smart calibration support for STM32MP1. - STM32MP15x: both linear & offset calibration are supported - STM32MP13x: Only offset calibration is supported Linear calibration: Linear calibration is SoC dependent and does not change over time so it can be done only once. Linear calibration may have already been done in u-boot. Skip calibration execution if calibration data are already available. Save calibration factors in private data and restore them from private data on next ADC start. Offset calibration: This calibration may vary over time, depending on temperature or voltage. Run offset single-ended and differential calibration on each ADC start, as it is not time consuming. This calibration do not need to be saved. So, remove calfact_s and calfact_d value and bitfields that are no longer used. Signed-off-by: Olivier Moysan Reviewed-by: Fabrice Gasnier Link: https://lore.kernel.org/r/20221115103124.70074-2-olivier.moysan@foss.st.com Signed-off-by: Jonathan Cameron --- drivers/iio/adc/stm32-adc-core.h | 1 + drivers/iio/adc/stm32-adc.c | 108 +++++++++++++++++++-------------------- 2 files changed, 53 insertions(+), 56 deletions(-) (limited to 'drivers/iio') diff --git a/drivers/iio/adc/stm32-adc-core.h b/drivers/iio/adc/stm32-adc-core.h index 9d6dfa1c03fa..73b2c2e91c08 100644 --- a/drivers/iio/adc/stm32-adc-core.h +++ b/drivers/iio/adc/stm32-adc-core.h @@ -142,6 +142,7 @@ #define STM32H7_LINCALRDYW3 BIT(24) #define STM32H7_LINCALRDYW2 BIT(23) #define STM32H7_LINCALRDYW1 BIT(22) +#define STM32H7_LINCALRDYW_MASK GENMASK(27, 22) #define STM32H7_ADCALLIN BIT(16) #define STM32H7_BOOST BIT(8) #define STM32H7_ADSTP BIT(4) diff --git a/drivers/iio/adc/stm32-adc.c b/drivers/iio/adc/stm32-adc.c index 8d03d21a33d6..2b2b55eb130e 100644 --- a/drivers/iio/adc/stm32-adc.c +++ b/drivers/iio/adc/stm32-adc.c @@ -119,16 +119,12 @@ struct stm32_adc_trig_info { /** * struct stm32_adc_calib - optional adc calibration data - * @calfact_s: Calibration offset for single ended channels - * @calfact_d: Calibration offset in differential * @lincalfact: Linearity calibration factor - * @calibrated: Indicates calibration status + * @lincal_saved: Indicates that linear calibration factors are saved */ struct stm32_adc_calib { - u32 calfact_s; - u32 calfact_d; u32 lincalfact[STM32H7_LINCALFACT_NUM]; - bool calibrated; + bool lincal_saved; }; /** @@ -165,8 +161,6 @@ struct stm32_adc_vrefint { * @extsel: trigger selection register & bitfield * @res: resolution selection register & bitfield * @difsel: differential mode selection register & bitfield - * @calfact_s: single-ended calibration factors register & bitfield - * @calfact_d: differential calibration factors register & bitfield * @smpr: smpr1 & smpr2 registers offset array * @smp_bits: smpr1 & smpr2 index and bitfields * @or_vddcore: option register & vddcore bitfield @@ -186,8 +180,6 @@ struct stm32_adc_regspec { const struct stm32_adc_regs extsel; const struct stm32_adc_regs res; const struct stm32_adc_regs difsel; - const struct stm32_adc_regs calfact_s; - const struct stm32_adc_regs calfact_d; const u32 smpr[2]; const struct stm32_adc_regs *smp_bits; const struct stm32_adc_regs or_vddcore; @@ -525,10 +517,6 @@ static const struct stm32_adc_regspec stm32h7_adc_regspec = { STM32H7_EXTSEL_SHIFT }, .res = { STM32H7_ADC_CFGR, STM32H7_RES_MASK, STM32H7_RES_SHIFT }, .difsel = { STM32H7_ADC_DIFSEL, STM32H7_DIFSEL_MASK}, - .calfact_s = { STM32H7_ADC_CALFACT, STM32H7_CALFACT_S_MASK, - STM32H7_CALFACT_S_SHIFT }, - .calfact_d = { STM32H7_ADC_CALFACT, STM32H7_CALFACT_D_MASK, - STM32H7_CALFACT_D_SHIFT }, .smpr = { STM32H7_ADC_SMPR1, STM32H7_ADC_SMPR2 }, .smp_bits = stm32h7_smp_bits, }; @@ -550,10 +538,6 @@ static const struct stm32_adc_regspec stm32mp13_adc_regspec = { STM32H7_EXTSEL_SHIFT }, .res = { STM32H7_ADC_CFGR, STM32MP13_RES_MASK, STM32MP13_RES_SHIFT }, .difsel = { STM32MP13_ADC_DIFSEL, STM32MP13_DIFSEL_MASK}, - .calfact_s = { STM32MP13_ADC_CALFACT, STM32MP13_CALFACT_S_MASK, - STM32MP13_CALFACT_S_SHIFT }, - .calfact_d = { STM32MP13_ADC_CALFACT, STM32MP13_CALFACT_D_MASK, - STM32MP13_CALFACT_D_SHIFT }, .smpr = { STM32H7_ADC_SMPR1, STM32H7_ADC_SMPR2 }, .smp_bits = stm32h7_smp_bits, .or_vddcore = { STM32MP13_ADC2_OR, STM32MP13_OP0 }, @@ -575,10 +559,6 @@ static const struct stm32_adc_regspec stm32mp1_adc_regspec = { STM32H7_EXTSEL_SHIFT }, .res = { STM32H7_ADC_CFGR, STM32H7_RES_MASK, STM32H7_RES_SHIFT }, .difsel = { STM32H7_ADC_DIFSEL, STM32H7_DIFSEL_MASK}, - .calfact_s = { STM32H7_ADC_CALFACT, STM32H7_CALFACT_S_MASK, - STM32H7_CALFACT_S_SHIFT }, - .calfact_d = { STM32H7_ADC_CALFACT, STM32H7_CALFACT_D_MASK, - STM32H7_CALFACT_D_SHIFT }, .smpr = { STM32H7_ADC_SMPR1, STM32H7_ADC_SMPR2 }, .smp_bits = stm32h7_smp_bits, .or_vddcore = { STM32MP1_ADC2_OR, STM32MP1_VDDCOREEN }, @@ -1000,9 +980,6 @@ static int stm32h7_adc_read_selfcalib(struct iio_dev *indio_dev) int i, ret; u32 lincalrdyw_mask, val; - if (!adc->cfg->has_linearcal) - goto skip_linearcal; - /* Read linearity calibration */ lincalrdyw_mask = STM32H7_LINCALRDYW6; for (i = STM32H7_LINCALFACT_NUM - 1; i >= 0; i--) { @@ -1024,15 +1001,7 @@ static int stm32h7_adc_read_selfcalib(struct iio_dev *indio_dev) lincalrdyw_mask >>= 1; } - -skip_linearcal: - /* Read offset calibration */ - val = stm32_adc_readl(adc, adc->cfg->regs->calfact_s.reg); - adc->cal.calfact_s = (val & adc->cfg->regs->calfact_s.mask); - adc->cal.calfact_s >>= adc->cfg->regs->calfact_s.shift; - adc->cal.calfact_d = (val & adc->cfg->regs->calfact_d.mask); - adc->cal.calfact_d >>= adc->cfg->regs->calfact_d.shift; - adc->cal.calibrated = true; + adc->cal.lincal_saved = true; return 0; } @@ -1048,13 +1017,6 @@ static int stm32h7_adc_restore_selfcalib(struct iio_dev *indio_dev) int i, ret; u32 lincalrdyw_mask, val; - val = (adc->cal.calfact_s << adc->cfg->regs->calfact_s.shift) | - (adc->cal.calfact_d << adc->cfg->regs->calfact_d.shift); - stm32_adc_writel(adc, adc->cfg->regs->calfact_s.reg, val); - - if (!adc->cfg->has_linearcal) - return 0; - lincalrdyw_mask = STM32H7_LINCALRDYW6; for (i = STM32H7_LINCALFACT_NUM - 1; i >= 0; i--) { /* @@ -1116,19 +1078,20 @@ static int stm32h7_adc_restore_selfcalib(struct iio_dev *indio_dev) /** * stm32h7_adc_selfcalib() - Procedure to calibrate ADC * @indio_dev: IIO device instance + * @do_lincal: linear calibration request flag * Note: Must be called once ADC is out of power down. + * + * Run offset calibration unconditionally. + * Run linear calibration if requested & supported. */ -static int stm32h7_adc_selfcalib(struct iio_dev *indio_dev) +static int stm32h7_adc_selfcalib(struct iio_dev *indio_dev, int do_lincal) { struct stm32_adc *adc = iio_priv(indio_dev); int ret; u32 msk = STM32H7_ADCALDIF; u32 val; - if (adc->cal.calibrated) - return true; - - if (adc->cfg->has_linearcal) + if (adc->cfg->has_linearcal && do_lincal) msk |= STM32H7_ADCALLIN; /* ADC must be disabled for calibration */ stm32h7_adc_disable(indio_dev); @@ -1172,6 +1135,33 @@ out: return ret; } +/** + * stm32h7_adc_check_selfcalib() - Check linear calibration status + * @indio_dev: IIO device instance + * + * Used to check if linear calibration has been done. + * Return true if linear calibration factors are already saved in private data + * or if a linear calibration has been done at boot stage. + */ +static int stm32h7_adc_check_selfcalib(struct iio_dev *indio_dev) +{ + struct stm32_adc *adc = iio_priv(indio_dev); + u32 val; + + if (adc->cal.lincal_saved) + return true; + + /* + * Check if linear calibration factors are available in ADC registers, + * by checking that all LINCALRDYWx bits are set. + */ + val = stm32_adc_readl(adc, STM32H7_ADC_CR) & STM32H7_LINCALRDYW_MASK; + if (val == STM32H7_LINCALRDYW_MASK) + return true; + + return false; +} + /** * stm32h7_adc_prepare() - Leave power down mode to enable ADC. * @indio_dev: IIO device instance @@ -1186,16 +1176,20 @@ out: static int stm32h7_adc_prepare(struct iio_dev *indio_dev) { struct stm32_adc *adc = iio_priv(indio_dev); - int calib, ret; + int lincal_done = false; + int ret; ret = stm32h7_adc_exit_pwr_down(indio_dev); if (ret) return ret; - ret = stm32h7_adc_selfcalib(indio_dev); + if (adc->cfg->has_linearcal) + lincal_done = stm32h7_adc_check_selfcalib(indio_dev); + + /* Always run offset calibration. Run linear calibration only once */ + ret = stm32h7_adc_selfcalib(indio_dev, !lincal_done); if (ret < 0) goto pwr_dwn; - calib = ret; stm32_adc_int_ch_enable(indio_dev); @@ -1205,13 +1199,15 @@ static int stm32h7_adc_prepare(struct iio_dev *indio_dev) if (ret) goto ch_disable; - /* Either restore or read calibration result for future reference */ - if (calib) - ret = stm32h7_adc_restore_selfcalib(indio_dev); - else - ret = stm32h7_adc_read_selfcalib(indio_dev); - if (ret) - goto disable; + if (adc->cfg->has_linearcal) { + if (!adc->cal.lincal_saved) + ret = stm32h7_adc_read_selfcalib(indio_dev); + else + ret = stm32h7_adc_restore_selfcalib(indio_dev); + + if (ret) + goto disable; + } if (adc->cfg->has_presel) stm32_adc_writel(adc, STM32H7_ADC_PCSEL, adc->pcsel); -- cgit v1.2.3 From 2206732b9ad1be8c59f714f2912539bf95cf2961 Mon Sep 17 00:00:00 2001 From: Olivier Moysan Date: Tue, 15 Nov 2022 11:31:22 +0100 Subject: iio: adc: stm32-adc: improve calibration error log Add more information in calibration error log to differentiate single-ended and differential calibration. Signed-off-by: Olivier Moysan Reviewed-by: Fabrice Gasnier Link: https://lore.kernel.org/r/20221115103124.70074-3-olivier.moysan@foss.st.com Signed-off-by: Jonathan Cameron --- drivers/iio/adc/stm32-adc.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'drivers/iio') diff --git a/drivers/iio/adc/stm32-adc.c b/drivers/iio/adc/stm32-adc.c index 2b2b55eb130e..65dd45537505 100644 --- a/drivers/iio/adc/stm32-adc.c +++ b/drivers/iio/adc/stm32-adc.c @@ -1109,7 +1109,7 @@ static int stm32h7_adc_selfcalib(struct iio_dev *indio_dev, int do_lincal) !(val & STM32H7_ADCAL), 100, STM32H7_ADC_CALIB_TIMEOUT_US); if (ret) { - dev_err(&indio_dev->dev, "calibration failed\n"); + dev_err(&indio_dev->dev, "calibration (single-ended) error %d\n", ret); goto out; } @@ -1125,7 +1125,8 @@ static int stm32h7_adc_selfcalib(struct iio_dev *indio_dev, int do_lincal) !(val & STM32H7_ADCAL), 100, STM32H7_ADC_CALIB_TIMEOUT_US); if (ret) { - dev_err(&indio_dev->dev, "calibration failed\n"); + dev_err(&indio_dev->dev, "calibration (diff%s) error %d\n", + (msk & STM32H7_ADCALLIN) ? "+linear" : "", ret); goto out; } -- cgit v1.2.3 From 51bcacc6fce8db7085c8652069b68123c6c1897c Mon Sep 17 00:00:00 2001 From: Olivier Moysan Date: Tue, 15 Nov 2022 11:31:23 +0100 Subject: iio: adc: stm32-adc: add debugfs to read raw calibration result Add debugfs to read linear ADC STM32 self calibration results. Signed-off-by: Fabrice Gasnier Signed-off-by: Olivier Moysan Reviewed-by: Fabrice Gasnier Link: https://lore.kernel.org/r/20221115103124.70074-4-olivier.moysan@foss.st.com Signed-off-by: Jonathan Cameron --- drivers/iio/adc/stm32-adc.c | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) (limited to 'drivers/iio') diff --git a/drivers/iio/adc/stm32-adc.c b/drivers/iio/adc/stm32-adc.c index 65dd45537505..45d4e79f8e55 100644 --- a/drivers/iio/adc/stm32-adc.c +++ b/drivers/iio/adc/stm32-adc.c @@ -7,6 +7,7 @@ */ #include +#include #include #include #include @@ -1879,6 +1880,23 @@ static const struct iio_chan_spec_ext_info stm32_adc_ext_info[] = { {}, }; +static void stm32_adc_debugfs_init(struct iio_dev *indio_dev) +{ + struct stm32_adc *adc = iio_priv(indio_dev); + struct dentry *d = iio_get_debugfs_dentry(indio_dev); + struct stm32_adc_calib *cal = &adc->cal; + char buf[16]; + unsigned int i; + + if (!adc->cfg->has_linearcal) + return; + + for (i = 0; i < STM32H7_LINCALFACT_NUM; i++) { + snprintf(buf, sizeof(buf), "lincalfact%d", i + 1); + debugfs_create_u32(buf, 0444, d, &cal->lincalfact[i]); + } +} + static int stm32_adc_fw_get_resolution(struct iio_dev *indio_dev) { struct device *dev = &indio_dev->dev; @@ -2465,6 +2483,9 @@ static int stm32_adc_probe(struct platform_device *pdev) pm_runtime_mark_last_busy(dev); pm_runtime_put_autosuspend(dev); + if (IS_ENABLED(CONFIG_DEBUG_FS)) + stm32_adc_debugfs_init(indio_dev); + return 0; err_hw_stop: @@ -2493,6 +2514,7 @@ static int stm32_adc_remove(struct platform_device *pdev) struct stm32_adc *adc = iio_priv(indio_dev); pm_runtime_get_sync(&pdev->dev); + /* iio_device_unregister() also removes debugfs entries */ iio_device_unregister(indio_dev); stm32_adc_hw_stop(&pdev->dev); pm_runtime_disable(&pdev->dev); -- cgit v1.2.3 From e2af60f5900c6ade53477b494ffb54690eee11f5 Mon Sep 17 00:00:00 2001 From: Rasmus Villemoes Date: Tue, 15 Nov 2022 14:23:23 +0100 Subject: iio: adc128s052: add proper .data members in adc128_of_match table Prior to commit bd5d54e4d49d ("iio: adc128s052: add ACPI _HID AANT1280"), the driver unconditionally used spi_get_device_id() to get the index into the adc128_config array. However, with that commit, OF-based boards now incorrectly treat all supported sensors as if they are an adc128s052, because all the .data members of the adc128_of_match table are implicitly 0. Our board, which has an adc122s021, thus exposes 8 channels whereas it really only has two. Fixes: bd5d54e4d49d ("iio: adc128s052: add ACPI _HID AANT1280") Signed-off-by: Rasmus Villemoes Reviewed-by: Andy Shevchenko Link: https://lore.kernel.org/r/20221115132324.1078169-1-linux@rasmusvillemoes.dk Cc: Signed-off-by: Jonathan Cameron --- drivers/iio/adc/ti-adc128s052.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'drivers/iio') diff --git a/drivers/iio/adc/ti-adc128s052.c b/drivers/iio/adc/ti-adc128s052.c index 622fd384983c..b3d5b9b7255b 100644 --- a/drivers/iio/adc/ti-adc128s052.c +++ b/drivers/iio/adc/ti-adc128s052.c @@ -181,13 +181,13 @@ static int adc128_probe(struct spi_device *spi) } static const struct of_device_id adc128_of_match[] = { - { .compatible = "ti,adc128s052", }, - { .compatible = "ti,adc122s021", }, - { .compatible = "ti,adc122s051", }, - { .compatible = "ti,adc122s101", }, - { .compatible = "ti,adc124s021", }, - { .compatible = "ti,adc124s051", }, - { .compatible = "ti,adc124s101", }, + { .compatible = "ti,adc128s052", .data = (void*)0L, }, + { .compatible = "ti,adc122s021", .data = (void*)1L, }, + { .compatible = "ti,adc122s051", .data = (void*)1L, }, + { .compatible = "ti,adc122s101", .data = (void*)1L, }, + { .compatible = "ti,adc124s021", .data = (void*)2L, }, + { .compatible = "ti,adc124s051", .data = (void*)2L, }, + { .compatible = "ti,adc124s101", .data = (void*)2L, }, { /* sentinel */ }, }; MODULE_DEVICE_TABLE(of, adc128_of_match); -- cgit v1.2.3 From eda549e2e52496d0d374ce457f514a4f14172aa5 Mon Sep 17 00:00:00 2001 From: Antoniu Miclaus Date: Tue, 15 Nov 2022 13:00:41 +0200 Subject: iio: frequency: adf4377: add support for ADF4377 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The ADF4377 is a high performance, ultralow jitter, dual output integer-N phased locked loop (PLL) with integrated voltage controlled oscillator (VCO) ideally suited for data converter and mixed signal front end (MxFE) clock applications. Datasheet: https://www.analog.com/media/en/technical-documentation/data-sheets/adf4377.pdf Signed-off-by: Antoniu Miclaus Reviewed-by: Nuno Sá Link: https://lore.kernel.org/r/20221115110041.71495-2-antoniu.miclaus@analog.com Signed-off-by: Jonathan Cameron --- drivers/iio/frequency/Kconfig | 10 + drivers/iio/frequency/Makefile | 1 + drivers/iio/frequency/adf4377.c | 994 ++++++++++++++++++++++++++++++++++++++++ 3 files changed, 1005 insertions(+) create mode 100644 drivers/iio/frequency/adf4377.c (limited to 'drivers/iio') diff --git a/drivers/iio/frequency/Kconfig b/drivers/iio/frequency/Kconfig index f3702f36436c..9e85dfa58508 100644 --- a/drivers/iio/frequency/Kconfig +++ b/drivers/iio/frequency/Kconfig @@ -50,6 +50,16 @@ config ADF4371 To compile this driver as a module, choose M here: the module will be called adf4371. +config ADF4377 + tristate "Analog Devices ADF4377 Microwave Wideband Synthesizer" + depends on SPI && COMMON_CLK + help + Say yes here to build support for Analog Devices ADF4377 Microwave + Wideband Synthesizer. + + To compile this driver as a module, choose M here: the + module will be called adf4377. + config ADMV1013 tristate "Analog Devices ADMV1013 Microwave Upconverter" depends on SPI && COMMON_CLK diff --git a/drivers/iio/frequency/Makefile b/drivers/iio/frequency/Makefile index 48add732f1d3..b616c29b4a08 100644 --- a/drivers/iio/frequency/Makefile +++ b/drivers/iio/frequency/Makefile @@ -7,6 +7,7 @@ obj-$(CONFIG_AD9523) += ad9523.o obj-$(CONFIG_ADF4350) += adf4350.o obj-$(CONFIG_ADF4371) += adf4371.o +obj-$(CONFIG_ADF4377) += adf4377.o obj-$(CONFIG_ADMV1013) += admv1013.o obj-$(CONFIG_ADMV1014) += admv1014.o obj-$(CONFIG_ADMV4420) += admv4420.o diff --git a/drivers/iio/frequency/adf4377.c b/drivers/iio/frequency/adf4377.c new file mode 100644 index 000000000000..26abecbd51e0 --- /dev/null +++ b/drivers/iio/frequency/adf4377.c @@ -0,0 +1,994 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * ADF4377 driver + * + * Copyright 2022 Analog Devices Inc. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +/* ADF4377 REG0000 Map */ +#define ADF4377_0000_SOFT_RESET_R_MSK BIT(7) +#define ADF4377_0000_LSB_FIRST_R_MSK BIT(6) +#define ADF4377_0000_ADDRESS_ASC_R_MSK BIT(5) +#define ADF4377_0000_SDO_ACTIVE_R_MSK BIT(4) +#define ADF4377_0000_SDO_ACTIVE_MSK BIT(3) +#define ADF4377_0000_ADDRESS_ASC_MSK BIT(2) +#define ADF4377_0000_LSB_FIRST_MSK BIT(1) +#define ADF4377_0000_SOFT_RESET_MSK BIT(0) + +/* ADF4377 REG0000 Bit Definition */ +#define ADF4377_0000_SDO_ACTIVE_SPI_3W 0x0 +#define ADF4377_0000_SDO_ACTIVE_SPI_4W 0x1 + +#define ADF4377_0000_ADDR_ASC_AUTO_DECR 0x0 +#define ADF4377_0000_ADDR_ASC_AUTO_INCR 0x1 + +#define ADF4377_0000_LSB_FIRST_MSB 0x0 +#define ADF4377_0000_LSB_FIRST_LSB 0x1 + +#define ADF4377_0000_SOFT_RESET_N_OP 0x0 +#define ADF4377_0000_SOFT_RESET_EN 0x1 + +/* ADF4377 REG0001 Map */ +#define ADF4377_0001_SINGLE_INSTR_MSK BIT(7) +#define ADF4377_0001_MASTER_RB_CTRL_MSK BIT(5) + +/* ADF4377 REG0003 Bit Definition */ +#define ADF4377_0003_CHIP_TYPE 0x06 + +/* ADF4377 REG0004 Bit Definition */ +#define ADF4377_0004_PRODUCT_ID_LSB 0x0005 + +/* ADF4377 REG0005 Bit Definition */ +#define ADF4377_0005_PRODUCT_ID_MSB 0x0005 + +/* ADF4377 REG000A Map */ +#define ADF4377_000A_SCRATCHPAD_MSK GENMASK(7, 0) + +/* ADF4377 REG000C Bit Definition */ +#define ADF4377_000C_VENDOR_ID_LSB 0x56 + +/* ADF4377 REG000D Bit Definition */ +#define ADF4377_000D_VENDOR_ID_MSB 0x04 + +/* ADF4377 REG000F Bit Definition */ +#define ADF4377_000F_R00F_RSV1_MSK GENMASK(7, 0) + +/* ADF4377 REG0010 Map*/ +#define ADF4377_0010_N_INT_LSB_MSK GENMASK(7, 0) + +/* ADF4377 REG0011 Map*/ +#define ADF4377_0011_EN_AUTOCAL_MSK BIT(7) +#define ADF4377_0011_EN_RDBLR_MSK BIT(6) +#define ADF4377_0011_DCLK_DIV2_MSK GENMASK(5, 4) +#define ADF4377_0011_N_INT_MSB_MSK GENMASK(3, 0) + +/* ADF4377 REG0011 Bit Definition */ +#define ADF4377_0011_DCLK_DIV2_1 0x0 +#define ADF4377_0011_DCLK_DIV2_2 0x1 +#define ADF4377_0011_DCLK_DIV2_4 0x2 +#define ADF4377_0011_DCLK_DIV2_8 0x3 + +/* ADF4377 REG0012 Map*/ +#define ADF4377_0012_CLKOUT_DIV_MSK GENMASK(7, 6) +#define ADF4377_0012_R_DIV_MSK GENMASK(5, 0) + +/* ADF4377 REG0012 Bit Definition */ +#define ADF4377_0012_CLKOUT_DIV_1 0x0 +#define ADF4377_0012_CLKOUT_DIV_2 0x1 +#define ADF4377_0012_CLKOUT_DIV_4 0x2 +#define ADF4377_0012_CLKOUT_DIV_8 0x3 + +/* ADF4377 REG0013 Map */ +#define ADF4377_0013_M_VCO_CORE_MSK GENMASK(5, 4) +#define ADF4377_0013_VCO_BIAS_MSK GENMASK(3, 0) + +/* ADF4377 REG0013 Bit Definition */ +#define ADF4377_0013_M_VCO_0 0x0 +#define ADF4377_0013_M_VCO_1 0x1 +#define ADF4377_0013_M_VCO_2 0x2 +#define ADF4377_0013_M_VCO_3 0x3 + +/* ADF4377 REG0014 Map */ +#define ADF4377_0014_M_VCO_BAND_MSK GENMASK(7, 0) + +/* ADF4377 REG0015 Map */ +#define ADF4377_0015_BLEED_I_LSB_MSK GENMASK(7, 6) +#define ADF4377_0015_BLEED_POL_MSK BIT(5) +#define ADF4377_0015_EN_BLEED_MSK BIT(4) +#define ADF4377_0015_CP_I_MSK GENMASK(3, 0) + +/* ADF4377 REG0015 Bit Definition */ +#define ADF4377_CURRENT_SINK 0x0 +#define ADF4377_CURRENT_SOURCE 0x1 + +#define ADF4377_0015_CP_0MA7 0x0 +#define ADF4377_0015_CP_0MA9 0x1 +#define ADF4377_0015_CP_1MA1 0x2 +#define ADF4377_0015_CP_1MA3 0x3 +#define ADF4377_0015_CP_1MA4 0x4 +#define ADF4377_0015_CP_1MA8 0x5 +#define ADF4377_0015_CP_2MA2 0x6 +#define ADF4377_0015_CP_2MA5 0x7 +#define ADF4377_0015_CP_2MA9 0x8 +#define ADF4377_0015_CP_3MA6 0x9 +#define ADF4377_0015_CP_4MA3 0xA +#define ADF4377_0015_CP_5MA0 0xB +#define ADF4377_0015_CP_5MA7 0xC +#define ADF4377_0015_CP_7MA2 0xD +#define ADF4377_0015_CP_8MA6 0xE +#define ADF4377_0015_CP_10MA1 0xF + +/* ADF4377 REG0016 Map */ +#define ADF4377_0016_BLEED_I_MSB_MSK GENMASK(7, 0) + +/* ADF4377 REG0017 Map */ +#define ADF4377_0016_INV_CLKOUT_MSK BIT(7) +#define ADF4377_0016_N_DEL_MSK GENMASK(6, 0) + +/* ADF4377 REG0018 Map */ +#define ADF4377_0018_CMOS_OV_MSK BIT(7) +#define ADF4377_0018_R_DEL_MSK GENMASK(6, 0) + +/* ADF4377 REG0018 Bit Definition */ +#define ADF4377_0018_1V8_LOGIC 0x0 +#define ADF4377_0018_3V3_LOGIC 0x1 + +/* ADF4377 REG0019 Map */ +#define ADF4377_0019_CLKOUT2_OP_MSK GENMASK(7, 6) +#define ADF4377_0019_CLKOUT1_OP_MSK GENMASK(5, 4) +#define ADF4377_0019_PD_CLK_MSK BIT(3) +#define ADF4377_0019_PD_RDET_MSK BIT(2) +#define ADF4377_0019_PD_ADC_MSK BIT(1) +#define ADF4377_0019_PD_CALADC_MSK BIT(0) + +/* ADF4377 REG0019 Bit Definition */ +#define ADF4377_0019_CLKOUT_320MV 0x0 +#define ADF4377_0019_CLKOUT_420MV 0x1 +#define ADF4377_0019_CLKOUT_530MV 0x2 +#define ADF4377_0019_CLKOUT_640MV 0x3 + +/* ADF4377 REG001A Map */ +#define ADF4377_001A_PD_ALL_MSK BIT(7) +#define ADF4377_001A_PD_RDIV_MSK BIT(6) +#define ADF4377_001A_PD_NDIV_MSK BIT(5) +#define ADF4377_001A_PD_VCO_MSK BIT(4) +#define ADF4377_001A_PD_LD_MSK BIT(3) +#define ADF4377_001A_PD_PFDCP_MSK BIT(2) +#define ADF4377_001A_PD_CLKOUT1_MSK BIT(1) +#define ADF4377_001A_PD_CLKOUT2_MSK BIT(0) + +/* ADF4377 REG001B Map */ +#define ADF4377_001B_EN_LOL_MSK BIT(7) +#define ADF4377_001B_LDWIN_PW_MSK BIT(6) +#define ADF4377_001B_EN_LDWIN_MSK BIT(5) +#define ADF4377_001B_LD_COUNT_MSK GENMASK(4, 0) + +/* ADF4377 REG001B Bit Definition */ +#define ADF4377_001B_LDWIN_PW_NARROW 0x0 +#define ADF4377_001B_LDWIN_PW_WIDE 0x1 + +/* ADF4377 REG001C Map */ +#define ADF4377_001C_EN_DNCLK_MSK BIT(7) +#define ADF4377_001C_EN_DRCLK_MSK BIT(6) +#define ADF4377_001C_RST_LD_MSK BIT(2) +#define ADF4377_001C_R01C_RSV1_MSK BIT(0) + +/* ADF4377 REG001C Bit Definition */ +#define ADF4377_001C_RST_LD_INACTIVE 0x0 +#define ADF4377_001C_RST_LD_ACTIVE 0x1 + +#define ADF4377_001C_R01C_RSV1 0x1 + +/* ADF4377 REG001D Map */ +#define ADF4377_001D_MUXOUT_MSK GENMASK(7, 4) +#define ADF4377_001D_EN_CPTEST_MSK BIT(2) +#define ADF4377_001D_CP_DOWN_MSK BIT(1) +#define ADF4377_001D_CP_UP_MSK BIT(0) + +#define ADF4377_001D_EN_CPTEST_OFF 0x0 +#define ADF4377_001D_EN_CPTEST_ON 0x1 + +#define ADF4377_001D_CP_DOWN_OFF 0x0 +#define ADF4377_001D_CP_DOWN_ON 0x1 + +#define ADF4377_001D_CP_UP_OFF 0x0 +#define ADF4377_001D_CP_UP_ON 0x1 + +/* ADF4377 REG001F Map */ +#define ADF4377_001F_BST_REF_MSK BIT(7) +#define ADF4377_001F_FILT_REF_MSK BIT(6) +#define ADF4377_001F_REF_SEL_MSK BIT(5) +#define ADF4377_001F_R01F_RSV1_MSK GENMASK(4, 0) + +/* ADF4377 REG001F Bit Definition */ +#define ADF4377_001F_BST_LARGE_REF_IN 0x0 +#define ADF4377_001F_BST_SMALL_REF_IN 0x1 + +#define ADF4377_001F_FILT_REF_OFF 0x0 +#define ADF4377_001F_FILT_REF_ON 0x1 + +#define ADF4377_001F_REF_SEL_DMA 0x0 +#define ADF4377_001F_REF_SEL_LNA 0x1 + +#define ADF4377_001F_R01F_RSV1 0x7 + +/* ADF4377 REG0020 Map */ +#define ADF4377_0020_RST_SYS_MSK BIT(4) +#define ADF4377_0020_EN_ADC_CLK_MSK BIT(3) +#define ADF4377_0020_R020_RSV1_MSK BIT(0) + +/* ADF4377 REG0021 Bit Definition */ +#define ADF4377_0021_R021_RSV1 0xD3 + +/* ADF4377 REG0022 Bit Definition */ +#define ADF4377_0022_R022_RSV1 0x32 + +/* ADF4377 REG0023 Map */ +#define ADF4377_0023_CAT_CT_SEL BIT(7) +#define ADF4377_0023_R023_RSV1_MSK GENMASK(6, 0) + +/* ADF4377 REG0023 Bit Definition */ +#define ADF4377_0023_R023_RSV1 0x18 + +/* ADF4377 REG0024 Map */ +#define ADF4377_0024_DCLK_MODE_MSK BIT(2) + +/* ADF4377 REG0025 Map */ +#define ADF4377_0025_CLKODIV_DB_MSK BIT(7) +#define ADF4377_0025_DCLK_DB_MSK BIT(6) +#define ADF4377_0025_R025_RSV1_MSK GENMASK(5, 0) + +/* ADF4377 REG0025 Bit Definition */ +#define ADF4377_0025_R025_RSV1 0x16 + +/* ADF4377 REG0026 Map */ +#define ADF4377_0026_VCO_BAND_DIV_MSK GENMASK(7, 0) + +/* ADF4377 REG0027 Map */ +#define ADF4377_0027_SYNTH_LOCK_TO_LSB_MSK GENMASK(7, 0) + +/* ADF4377 REG0028 Map */ +#define ADF4377_0028_O_VCO_DB_MSK BIT(7) +#define ADF4377_0028_SYNTH_LOCK_TO_MSB_MSK GENMASK(6, 0) + +/* ADF4377 REG0029 Map */ +#define ADF4377_0029_VCO_ALC_TO_LSB_MSK GENMASK(7, 0) + +/* ADF4377 REG002A Map */ +#define ADF4377_002A_DEL_CTRL_DB_MSK BIT(7) +#define ADF4377_002A_VCO_ALC_TO_MSB_MSK GENMASK(6, 0) + +/* ADF4377 REG002C Map */ +#define ADF4377_002C_R02C_RSV1 0xC0 + +/* ADF4377 REG002D Map */ +#define ADF4377_002D_ADC_CLK_DIV_MSK GENMASK(7, 0) + +/* ADF4377 REG002E Map */ +#define ADF4377_002E_EN_ADC_CNV_MSK BIT(7) +#define ADF4377_002E_EN_ADC_MSK BIT(1) +#define ADF4377_002E_ADC_A_CONV_MSK BIT(0) + +/* ADF4377 REG002E Bit Definition */ +#define ADF4377_002E_ADC_A_CONV_ADC_ST_CNV 0x0 +#define ADF4377_002E_ADC_A_CONV_VCO_CALIB 0x1 + +/* ADF4377 REG002F Map */ +#define ADF4377_002F_DCLK_DIV1_MSK GENMASK(1, 0) + +/* ADF4377 REG002F Bit Definition */ +#define ADF4377_002F_DCLK_DIV1_1 0x0 +#define ADF4377_002F_DCLK_DIV1_2 0x1 +#define ADF4377_002F_DCLK_DIV1_8 0x2 +#define ADF4377_002F_DCLK_DIV1_32 0x3 + +/* ADF4377 REG0031 Bit Definition */ +#define ADF4377_0031_R031_RSV1 0x09 + +/* ADF4377 REG0032 Map */ +#define ADF4377_0032_ADC_CLK_SEL_MSK BIT(6) +#define ADF4377_0032_R032_RSV1_MSK GENMASK(5, 0) + +/* ADF4377 REG0032 Bit Definition */ +#define ADF4377_0032_ADC_CLK_SEL_N_OP 0x0 +#define ADF4377_0032_ADC_CLK_SEL_SPI_CLK 0x1 + +#define ADF4377_0032_R032_RSV1 0x9 + +/* ADF4377 REG0033 Bit Definition */ +#define ADF4377_0033_R033_RSV1 0x18 + +/* ADF4377 REG0034 Bit Definition */ +#define ADF4377_0034_R034_RSV1 0x08 + +/* ADF4377 REG003A Bit Definition */ +#define ADF4377_003A_R03A_RSV1 0x5D + +/* ADF4377 REG003B Bit Definition */ +#define ADF4377_003B_R03B_RSV1 0x2B + +/* ADF4377 REG003D Map */ +#define ADF4377_003D_O_VCO_BAND_MSK BIT(3) +#define ADF4377_003D_O_VCO_CORE_MSK BIT(2) +#define ADF4377_003D_O_VCO_BIAS_MSK BIT(1) + +/* ADF4377 REG003D Bit Definition */ +#define ADF4377_003D_O_VCO_BAND_VCO_CALIB 0x0 +#define ADF4377_003D_O_VCO_BAND_M_VCO 0x1 + +#define ADF4377_003D_O_VCO_CORE_VCO_CALIB 0x0 +#define ADF4377_003D_O_VCO_CORE_M_VCO 0x1 + +#define ADF4377_003D_O_VCO_BIAS_VCO_CALIB 0x0 +#define ADF4377_003D_O_VCO_BIAS_M_VCO 0x1 + +/* ADF4377 REG0042 Map */ +#define ADF4377_0042_R042_RSV1 0x05 + +/* ADF4377 REG0045 Map */ +#define ADF4377_0045_ADC_ST_CNV_MSK BIT(0) + +/* ADF4377 REG0049 Map */ +#define ADF4377_0049_EN_CLK2_MSK BIT(7) +#define ADF4377_0049_EN_CLK1_MSK BIT(6) +#define ADF4377_0049_REF_OK_MSK BIT(3) +#define ADF4377_0049_ADC_BUSY_MSK BIT(2) +#define ADF4377_0049_FSM_BUSY_MSK BIT(1) +#define ADF4377_0049_LOCKED_MSK BIT(0) + +/* ADF4377 REG004B Map */ +#define ADF4377_004B_VCO_CORE_MSK GENMASK(1, 0) + +/* ADF4377 REG004C Map */ +#define ADF4377_004C_CHIP_TEMP_LSB_MSK GENMASK(7, 0) + +/* ADF4377 REG004D Map */ +#define ADF4377_004D_CHIP_TEMP_MSB_MSK BIT(0) + +/* ADF4377 REG004F Map */ +#define ADF4377_004F_VCO_BAND_MSK GENMASK(7, 0) + +/* ADF4377 REG0051 Map */ +#define ADF4377_0051_VCO_BIAS_MSK GENMASK(3, 0) + +/* ADF4377 REG0054 Map */ +#define ADF4377_0054_CHIP_VERSION_MSK GENMASK(7, 0) + +/* Specifications */ +#define ADF4377_SPI_READ_CMD BIT(7) +#define ADF4377_MAX_VCO_FREQ (12800ULL * HZ_PER_MHZ) +#define ADF4377_MIN_VCO_FREQ (6400ULL * HZ_PER_MHZ) +#define ADF4377_MAX_REFIN_FREQ (1000 * HZ_PER_MHZ) +#define ADF4377_MIN_REFIN_FREQ (10 * HZ_PER_MHZ) +#define ADF4377_MAX_FREQ_PFD (500 * HZ_PER_MHZ) +#define ADF4377_MIN_FREQ_PFD (3 * HZ_PER_MHZ) +#define ADF4377_MAX_CLKPN_FREQ ADF4377_MAX_VCO_FREQ +#define ADF4377_MIN_CLKPN_FREQ (ADF4377_MIN_VCO_FREQ / 8) +#define ADF4377_FREQ_PFD_80MHZ (80 * HZ_PER_MHZ) +#define ADF4377_FREQ_PFD_125MHZ (125 * HZ_PER_MHZ) +#define ADF4377_FREQ_PFD_160MHZ (160 * HZ_PER_MHZ) +#define ADF4377_FREQ_PFD_250MHZ (250 * HZ_PER_MHZ) +#define ADF4377_FREQ_PFD_320MHZ (320 * HZ_PER_MHZ) + +enum { + ADF4377_FREQ, +}; + +enum muxout_select_mode { + ADF4377_MUXOUT_HIGH_Z = 0x0, + ADF4377_MUXOUT_LKDET = 0x1, + ADF4377_MUXOUT_LOW = 0x2, + ADF4377_MUXOUT_DIV_RCLK_2 = 0x4, + ADF4377_MUXOUT_DIV_NCLK_2 = 0x5, + ADF4377_MUXOUT_HIGH = 0x8, +}; + +struct adf4377_state { + struct spi_device *spi; + struct regmap *regmap; + struct clk *clkin; + /* Protect against concurrent accesses to the device and data content */ + struct mutex lock; + struct notifier_block nb; + /* Reference Divider */ + unsigned int ref_div_factor; + /* PFD Frequency */ + unsigned int f_pfd; + /* Input Reference Clock */ + unsigned int clkin_freq; + /* CLKOUT Divider */ + u8 clkout_div_sel; + /* Feedback Divider (N) */ + u16 n_int; + u16 synth_lock_timeout; + u16 vco_alc_timeout; + u16 adc_clk_div; + u16 vco_band_div; + u8 dclk_div1; + u8 dclk_div2; + u8 dclk_mode; + unsigned int f_div_rclk; + enum muxout_select_mode muxout_select; + struct gpio_desc *gpio_ce; + struct gpio_desc *gpio_enclk1; + struct gpio_desc *gpio_enclk2; + u8 buf[2] __aligned(IIO_DMA_MINALIGN); +}; + +static const char * const adf4377_muxout_modes[] = { + [ADF4377_MUXOUT_HIGH_Z] = "high_z", + [ADF4377_MUXOUT_LKDET] = "lock_detect", + [ADF4377_MUXOUT_LOW] = "muxout_low", + [ADF4377_MUXOUT_DIV_RCLK_2] = "f_div_rclk_2", + [ADF4377_MUXOUT_DIV_NCLK_2] = "f_div_nclk_2", + [ADF4377_MUXOUT_HIGH] = "muxout_high", +}; + +static const struct reg_sequence adf4377_reg_defaults[] = { + { 0x42, ADF4377_0042_R042_RSV1 }, + { 0x3B, ADF4377_003B_R03B_RSV1 }, + { 0x3A, ADF4377_003A_R03A_RSV1 }, + { 0x34, ADF4377_0034_R034_RSV1 }, + { 0x33, ADF4377_0033_R033_RSV1 }, + { 0x32, ADF4377_0032_R032_RSV1 }, + { 0x31, ADF4377_0031_R031_RSV1 }, + { 0x2C, ADF4377_002C_R02C_RSV1 }, + { 0x25, ADF4377_0025_R025_RSV1 }, + { 0x23, ADF4377_0023_R023_RSV1 }, + { 0x22, ADF4377_0022_R022_RSV1 }, + { 0x21, ADF4377_0021_R021_RSV1 }, + { 0x1f, ADF4377_001F_R01F_RSV1 }, + { 0x1c, ADF4377_001C_R01C_RSV1 }, +}; + +static const struct regmap_config adf4377_regmap_config = { + .reg_bits = 16, + .val_bits = 8, + .read_flag_mask = BIT(7), + .max_register = 0x54, +}; + +static int adf4377_reg_access(struct iio_dev *indio_dev, + unsigned int reg, + unsigned int write_val, + unsigned int *read_val) +{ + struct adf4377_state *st = iio_priv(indio_dev); + + if (read_val) + return regmap_read(st->regmap, reg, read_val); + + return regmap_write(st->regmap, reg, write_val); +} + +static const struct iio_info adf4377_info = { + .debugfs_reg_access = &adf4377_reg_access, +}; + +static int adf4377_soft_reset(struct adf4377_state *st) +{ + unsigned int read_val; + int ret; + + ret = regmap_update_bits(st->regmap, 0x0, ADF4377_0000_SOFT_RESET_MSK | + ADF4377_0000_SOFT_RESET_R_MSK, + FIELD_PREP(ADF4377_0000_SOFT_RESET_MSK, 1) | + FIELD_PREP(ADF4377_0000_SOFT_RESET_R_MSK, 1)); + if (ret) + return ret; + + return regmap_read_poll_timeout(st->regmap, 0x0, read_val, + !(read_val & (ADF4377_0000_SOFT_RESET_R_MSK | + ADF4377_0000_SOFT_RESET_R_MSK)), 200, 200 * 100); +} + +static int adf4377_get_freq(struct adf4377_state *st, u64 *freq) +{ + unsigned int ref_div_factor, n_int; + u64 clkin_freq; + int ret; + + mutex_lock(&st->lock); + ret = regmap_read(st->regmap, 0x12, &ref_div_factor); + if (ret) + goto exit; + + ret = regmap_bulk_read(st->regmap, 0x10, st->buf, sizeof(st->buf)); + if (ret) + goto exit; + + clkin_freq = clk_get_rate(st->clkin); + ref_div_factor = FIELD_GET(ADF4377_0012_R_DIV_MSK, ref_div_factor); + n_int = FIELD_GET(ADF4377_0010_N_INT_LSB_MSK | ADF4377_0011_N_INT_MSB_MSK, + get_unaligned_le16(&st->buf)); + + *freq = div_u64(clkin_freq, ref_div_factor) * n_int; +exit: + mutex_unlock(&st->lock); + + return ret; +} + +static int adf4377_set_freq(struct adf4377_state *st, u64 freq) +{ + unsigned int read_val; + u64 f_vco; + int ret; + + mutex_lock(&st->lock); + + if (freq > ADF4377_MAX_CLKPN_FREQ || freq < ADF4377_MIN_CLKPN_FREQ) { + ret = -EINVAL; + goto exit; + } + + ret = regmap_update_bits(st->regmap, 0x1C, ADF4377_001C_EN_DNCLK_MSK | + ADF4377_001C_EN_DRCLK_MSK, + FIELD_PREP(ADF4377_001C_EN_DNCLK_MSK, 1) | + FIELD_PREP(ADF4377_001C_EN_DRCLK_MSK, 1)); + if (ret) + goto exit; + + ret = regmap_update_bits(st->regmap, 0x11, ADF4377_0011_EN_AUTOCAL_MSK | + ADF4377_0011_DCLK_DIV2_MSK, + FIELD_PREP(ADF4377_0011_EN_AUTOCAL_MSK, 1) | + FIELD_PREP(ADF4377_0011_DCLK_DIV2_MSK, st->dclk_div2)); + if (ret) + goto exit; + + ret = regmap_update_bits(st->regmap, 0x2E, ADF4377_002E_EN_ADC_CNV_MSK | + ADF4377_002E_EN_ADC_MSK | + ADF4377_002E_ADC_A_CONV_MSK, + FIELD_PREP(ADF4377_002E_EN_ADC_CNV_MSK, 1) | + FIELD_PREP(ADF4377_002E_EN_ADC_MSK, 1) | + FIELD_PREP(ADF4377_002E_ADC_A_CONV_MSK, + ADF4377_002E_ADC_A_CONV_VCO_CALIB)); + if (ret) + goto exit; + + ret = regmap_update_bits(st->regmap, 0x20, ADF4377_0020_EN_ADC_CLK_MSK, + FIELD_PREP(ADF4377_0020_EN_ADC_CLK_MSK, 1)); + if (ret) + goto exit; + + ret = regmap_update_bits(st->regmap, 0x2F, ADF4377_002F_DCLK_DIV1_MSK, + FIELD_PREP(ADF4377_002F_DCLK_DIV1_MSK, st->dclk_div1)); + if (ret) + goto exit; + + ret = regmap_update_bits(st->regmap, 0x24, ADF4377_0024_DCLK_MODE_MSK, + FIELD_PREP(ADF4377_0024_DCLK_MODE_MSK, st->dclk_mode)); + if (ret) + goto exit; + + ret = regmap_write(st->regmap, 0x27, + FIELD_PREP(ADF4377_0027_SYNTH_LOCK_TO_LSB_MSK, + st->synth_lock_timeout)); + if (ret) + goto exit; + + ret = regmap_update_bits(st->regmap, 0x28, ADF4377_0028_SYNTH_LOCK_TO_MSB_MSK, + FIELD_PREP(ADF4377_0028_SYNTH_LOCK_TO_MSB_MSK, + st->synth_lock_timeout >> 8)); + if (ret) + goto exit; + + ret = regmap_write(st->regmap, 0x29, + FIELD_PREP(ADF4377_0029_VCO_ALC_TO_LSB_MSK, + st->vco_alc_timeout)); + if (ret) + goto exit; + + ret = regmap_update_bits(st->regmap, 0x2A, ADF4377_002A_VCO_ALC_TO_MSB_MSK, + FIELD_PREP(ADF4377_002A_VCO_ALC_TO_MSB_MSK, + st->vco_alc_timeout >> 8)); + if (ret) + goto exit; + + ret = regmap_write(st->regmap, 0x26, + FIELD_PREP(ADF4377_0026_VCO_BAND_DIV_MSK, st->vco_band_div)); + if (ret) + goto exit; + + ret = regmap_write(st->regmap, 0x2D, + FIELD_PREP(ADF4377_002D_ADC_CLK_DIV_MSK, st->adc_clk_div)); + if (ret) + goto exit; + + st->clkout_div_sel = 0; + + f_vco = freq; + + while (f_vco < ADF4377_MIN_VCO_FREQ) { + f_vco <<= 1; + st->clkout_div_sel++; + } + + st->n_int = div_u64(freq, st->f_pfd); + + ret = regmap_update_bits(st->regmap, 0x11, ADF4377_0011_EN_RDBLR_MSK | + ADF4377_0011_N_INT_MSB_MSK, + FIELD_PREP(ADF4377_0011_EN_RDBLR_MSK, 0) | + FIELD_PREP(ADF4377_0011_N_INT_MSB_MSK, st->n_int >> 8)); + if (ret) + goto exit; + + ret = regmap_update_bits(st->regmap, 0x12, ADF4377_0012_R_DIV_MSK | + ADF4377_0012_CLKOUT_DIV_MSK, + FIELD_PREP(ADF4377_0012_CLKOUT_DIV_MSK, st->clkout_div_sel) | + FIELD_PREP(ADF4377_0012_R_DIV_MSK, st->ref_div_factor)); + if (ret) + goto exit; + + ret = regmap_write(st->regmap, 0x10, + FIELD_PREP(ADF4377_0010_N_INT_LSB_MSK, st->n_int)); + if (ret) + goto exit; + + ret = regmap_read_poll_timeout(st->regmap, 0x49, read_val, + !(read_val & (ADF4377_0049_FSM_BUSY_MSK)), 200, 200 * 100); + if (ret) + goto exit; + + /* Disable EN_DNCLK, EN_DRCLK */ + ret = regmap_update_bits(st->regmap, 0x1C, ADF4377_001C_EN_DNCLK_MSK | + ADF4377_001C_EN_DRCLK_MSK, + FIELD_PREP(ADF4377_001C_EN_DNCLK_MSK, 0) | + FIELD_PREP(ADF4377_001C_EN_DRCLK_MSK, 0)); + if (ret) + goto exit; + + /* Disable EN_ADC_CLK */ + ret = regmap_update_bits(st->regmap, 0x20, ADF4377_0020_EN_ADC_CLK_MSK, + FIELD_PREP(ADF4377_0020_EN_ADC_CLK_MSK, 0)); + if (ret) + goto exit; + + /* Set output Amplitude */ + ret = regmap_update_bits(st->regmap, 0x19, ADF4377_0019_CLKOUT2_OP_MSK | + ADF4377_0019_CLKOUT1_OP_MSK, + FIELD_PREP(ADF4377_0019_CLKOUT1_OP_MSK, + ADF4377_0019_CLKOUT_420MV) | + FIELD_PREP(ADF4377_0019_CLKOUT2_OP_MSK, + ADF4377_0019_CLKOUT_420MV)); + +exit: + mutex_unlock(&st->lock); + + return ret; +} + +static void adf4377_gpio_init(struct adf4377_state *st) +{ + if (st->gpio_ce) { + gpiod_set_value(st->gpio_ce, 1); + + /* Delay for SPI register bits to settle to their power-on reset state */ + fsleep(200); + } + + if (st->gpio_enclk1) + gpiod_set_value(st->gpio_enclk1, 1); + + if (st->gpio_enclk2) + gpiod_set_value(st->gpio_enclk2, 1); +} + +static int adf4377_init(struct adf4377_state *st) +{ + struct spi_device *spi = st->spi; + int ret; + + adf4377_gpio_init(st); + + ret = adf4377_soft_reset(st); + if (ret) { + dev_err(&spi->dev, "Failed to soft reset.\n"); + return ret; + } + + ret = regmap_multi_reg_write(st->regmap, adf4377_reg_defaults, + ARRAY_SIZE(adf4377_reg_defaults)); + if (ret) { + dev_err(&spi->dev, "Failed to set default registers.\n"); + return ret; + } + + ret = regmap_update_bits(st->regmap, 0x00, + ADF4377_0000_SDO_ACTIVE_MSK | ADF4377_0000_SDO_ACTIVE_R_MSK, + FIELD_PREP(ADF4377_0000_SDO_ACTIVE_MSK, + ADF4377_0000_SDO_ACTIVE_SPI_4W) | + FIELD_PREP(ADF4377_0000_SDO_ACTIVE_R_MSK, + ADF4377_0000_SDO_ACTIVE_SPI_4W)); + if (ret) { + dev_err(&spi->dev, "Failed to set 4-Wire Operation.\n"); + return ret; + } + + st->clkin_freq = clk_get_rate(st->clkin); + + /* Power Up */ + ret = regmap_write(st->regmap, 0x1a, + FIELD_PREP(ADF4377_001A_PD_ALL_MSK, 0) | + FIELD_PREP(ADF4377_001A_PD_RDIV_MSK, 0) | + FIELD_PREP(ADF4377_001A_PD_NDIV_MSK, 0) | + FIELD_PREP(ADF4377_001A_PD_VCO_MSK, 0) | + FIELD_PREP(ADF4377_001A_PD_LD_MSK, 0) | + FIELD_PREP(ADF4377_001A_PD_PFDCP_MSK, 0) | + FIELD_PREP(ADF4377_001A_PD_CLKOUT1_MSK, 0) | + FIELD_PREP(ADF4377_001A_PD_CLKOUT2_MSK, 0)); + if (ret) { + dev_err(&spi->dev, "Failed to set power down registers.\n"); + return ret; + } + + /* Set Mux Output */ + ret = regmap_update_bits(st->regmap, 0x1D, + ADF4377_001D_MUXOUT_MSK, + FIELD_PREP(ADF4377_001D_MUXOUT_MSK, st->muxout_select)); + if (ret) + return ret; + + /* Compute PFD */ + st->ref_div_factor = 0; + do { + st->ref_div_factor++; + st->f_pfd = st->clkin_freq / st->ref_div_factor; + } while (st->f_pfd > ADF4377_MAX_FREQ_PFD); + + if (st->f_pfd > ADF4377_MAX_FREQ_PFD || st->f_pfd < ADF4377_MIN_FREQ_PFD) + return -EINVAL; + + st->f_div_rclk = st->f_pfd; + + if (st->f_pfd <= ADF4377_FREQ_PFD_80MHZ) { + st->dclk_div1 = ADF4377_002F_DCLK_DIV1_1; + st->dclk_div2 = ADF4377_0011_DCLK_DIV2_1; + st->dclk_mode = 0; + } else if (st->f_pfd <= ADF4377_FREQ_PFD_125MHZ) { + st->dclk_div1 = ADF4377_002F_DCLK_DIV1_1; + st->dclk_div2 = ADF4377_0011_DCLK_DIV2_1; + st->dclk_mode = 1; + } else if (st->f_pfd <= ADF4377_FREQ_PFD_160MHZ) { + st->dclk_div1 = ADF4377_002F_DCLK_DIV1_2; + st->dclk_div2 = ADF4377_0011_DCLK_DIV2_1; + st->dclk_mode = 0; + st->f_div_rclk /= 2; + } else if (st->f_pfd <= ADF4377_FREQ_PFD_250MHZ) { + st->dclk_div1 = ADF4377_002F_DCLK_DIV1_2; + st->dclk_div2 = ADF4377_0011_DCLK_DIV2_1; + st->dclk_mode = 1; + st->f_div_rclk /= 2; + } else if (st->f_pfd <= ADF4377_FREQ_PFD_320MHZ) { + st->dclk_div1 = ADF4377_002F_DCLK_DIV1_2; + st->dclk_div2 = ADF4377_0011_DCLK_DIV2_2; + st->dclk_mode = 0; + st->f_div_rclk /= 4; + } else { + st->dclk_div1 = ADF4377_002F_DCLK_DIV1_2; + st->dclk_div2 = ADF4377_0011_DCLK_DIV2_2; + st->dclk_mode = 1; + st->f_div_rclk /= 4; + } + + st->synth_lock_timeout = DIV_ROUND_UP(st->f_div_rclk, 50000); + st->vco_alc_timeout = DIV_ROUND_UP(st->f_div_rclk, 20000); + st->vco_band_div = DIV_ROUND_UP(st->f_div_rclk, 150000 * 16 * (1 << st->dclk_mode)); + st->adc_clk_div = DIV_ROUND_UP((st->f_div_rclk / 400000 - 2), 4); + + return 0; +} + +static ssize_t adf4377_read(struct iio_dev *indio_dev, uintptr_t private, + const struct iio_chan_spec *chan, char *buf) +{ + struct adf4377_state *st = iio_priv(indio_dev); + u64 val = 0; + int ret; + + switch ((u32)private) { + case ADF4377_FREQ: + ret = adf4377_get_freq(st, &val); + if (ret) + return ret; + + return sysfs_emit(buf, "%llu\n", val); + default: + return -EINVAL; + } +} + +static ssize_t adf4377_write(struct iio_dev *indio_dev, uintptr_t private, + const struct iio_chan_spec *chan, const char *buf, + size_t len) +{ + struct adf4377_state *st = iio_priv(indio_dev); + unsigned long long freq; + int ret; + + switch ((u32)private) { + case ADF4377_FREQ: + ret = kstrtoull(buf, 10, &freq); + if (ret) + return ret; + + ret = adf4377_set_freq(st, freq); + if (ret) + return ret; + + return len; + default: + return -EINVAL; + } +} + +#define _ADF4377_EXT_INFO(_name, _shared, _ident) { \ + .name = _name, \ + .read = adf4377_read, \ + .write = adf4377_write, \ + .private = _ident, \ + .shared = _shared, \ + } + +static const struct iio_chan_spec_ext_info adf4377_ext_info[] = { + /* + * Usually we use IIO_CHAN_INFO_FREQUENCY, but there are + * values > 2^32 in order to support the entire frequency range + * in Hz. + */ + _ADF4377_EXT_INFO("frequency", IIO_SEPARATE, ADF4377_FREQ), + { } +}; + +static const struct iio_chan_spec adf4377_channels[] = { + { + .type = IIO_ALTVOLTAGE, + .indexed = 1, + .output = 1, + .channel = 0, + .ext_info = adf4377_ext_info, + }, +}; + +static int adf4377_properties_parse(struct adf4377_state *st) +{ + struct spi_device *spi = st->spi; + const char *str; + int ret; + + st->clkin = devm_clk_get_enabled(&spi->dev, "ref_in"); + if (IS_ERR(st->clkin)) + return dev_err_probe(&spi->dev, PTR_ERR(st->clkin), + "failed to get the reference input clock\n"); + + st->gpio_ce = devm_gpiod_get_optional(&st->spi->dev, "chip-enable", + GPIOD_OUT_LOW); + if (IS_ERR(st->gpio_ce)) + return dev_err_probe(&spi->dev, PTR_ERR(st->gpio_ce), + "failed to get the CE GPIO\n"); + + st->gpio_enclk1 = devm_gpiod_get_optional(&st->spi->dev, "clk1-enable", + GPIOD_OUT_LOW); + if (IS_ERR(st->gpio_enclk1)) + return dev_err_probe(&spi->dev, PTR_ERR(st->gpio_enclk1), + "failed to get the CE GPIO\n"); + + st->gpio_enclk2 = devm_gpiod_get_optional(&st->spi->dev, "clk2-enable", + GPIOD_OUT_LOW); + if (IS_ERR(st->gpio_enclk2)) + return dev_err_probe(&spi->dev, PTR_ERR(st->gpio_enclk2), + "failed to get the CE GPIO\n"); + + ret = device_property_read_string(&spi->dev, "adi,muxout-select", &str); + if (ret) { + st->muxout_select = ADF4377_MUXOUT_HIGH_Z; + } else { + ret = match_string(adf4377_muxout_modes, ARRAY_SIZE(adf4377_muxout_modes), str); + if (ret < 0) + return ret; + + st->muxout_select = ret; + } + + return 0; +} + +static int adf4377_freq_change(struct notifier_block *nb, unsigned long action, void *data) +{ + struct adf4377_state *st = container_of(nb, struct adf4377_state, nb); + int ret; + + if (action == POST_RATE_CHANGE) { + mutex_lock(&st->lock); + ret = notifier_from_errno(adf4377_init(st)); + mutex_unlock(&st->lock); + return ret; + } + + return NOTIFY_OK; +} + +static int adf4377_probe(struct spi_device *spi) +{ + struct iio_dev *indio_dev; + struct regmap *regmap; + struct adf4377_state *st; + int ret; + + indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*st)); + if (!indio_dev) + return -ENOMEM; + + regmap = devm_regmap_init_spi(spi, &adf4377_regmap_config); + if (IS_ERR(regmap)) + return PTR_ERR(regmap); + + st = iio_priv(indio_dev); + + indio_dev->info = &adf4377_info; + indio_dev->name = "adf4377"; + indio_dev->channels = adf4377_channels; + indio_dev->num_channels = ARRAY_SIZE(adf4377_channels); + + st->regmap = regmap; + st->spi = spi; + mutex_init(&st->lock); + + ret = adf4377_properties_parse(st); + if (ret) + return ret; + + st->nb.notifier_call = adf4377_freq_change; + ret = devm_clk_notifier_register(&spi->dev, st->clkin, &st->nb); + if (ret) + return ret; + + ret = adf4377_init(st); + if (ret) + return ret; + + return devm_iio_device_register(&spi->dev, indio_dev); +} + +static const struct spi_device_id adf4377_id[] = { + { "adf4377", 0 }, + {} +}; +MODULE_DEVICE_TABLE(spi, adf4377_id); + +static const struct of_device_id adf4377_of_match[] = { + { .compatible = "adi,adf4377" }, + {} +}; +MODULE_DEVICE_TABLE(of, adf4377_of_match); + +static struct spi_driver adf4377_driver = { + .driver = { + .name = "adf4377", + .of_match_table = adf4377_of_match, + }, + .probe = adf4377_probe, + .id_table = adf4377_id, +}; +module_spi_driver(adf4377_driver); + +MODULE_AUTHOR("Antoniu Miclaus "); +MODULE_DESCRIPTION("Analog Devices ADF4377"); +MODULE_LICENSE("GPL"); -- cgit v1.2.3 From 3a042fda8813dcb1012347665a69572adbaef1f1 Mon Sep 17 00:00:00 2001 From: Lorenzo Bianconi Date: Thu, 24 Nov 2022 09:49:27 +0100 Subject: iio: imu: st_lsm6dsx: add support to ISM330IS Add support to STM ISM330IS (accelerometer and gyroscope) Mems sensor. The ISM330IS sensor can use LSM6DSO16IS as fallback device since it implements all the ISM330IS features currently implemented in st_lsm6dsx. Datasheet: https://www.st.com/resource/en/datasheet/ism330is.pdf Signed-off-by: Lorenzo Bianconi Link: https://lore.kernel.org/r/4cd1614060e06f49cd92f5930d8fd40117c07920.1669279604.git.lorenzo@kernel.org Signed-off-by: Jonathan Cameron --- drivers/iio/imu/st_lsm6dsx/Kconfig | 4 ++-- drivers/iio/imu/st_lsm6dsx/st_lsm6dsx.h | 2 ++ drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c | 8 ++++++-- drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_i2c.c | 5 +++++ drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_spi.c | 5 +++++ 5 files changed, 20 insertions(+), 4 deletions(-) (limited to 'drivers/iio') diff --git a/drivers/iio/imu/st_lsm6dsx/Kconfig b/drivers/iio/imu/st_lsm6dsx/Kconfig index 0096035728cd..f6660847fb58 100644 --- a/drivers/iio/imu/st_lsm6dsx/Kconfig +++ b/drivers/iio/imu/st_lsm6dsx/Kconfig @@ -13,8 +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, - lsm6dsv, lsm6dsv16x, lsm6dso16is, 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 abf14a2ce0e9..5b6f195748fc 100644 --- a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx.h +++ b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx.h @@ -36,6 +36,7 @@ #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, @@ -59,6 +60,7 @@ enum st_lsm6dsx_hw_id { ST_LSM6DSV_ID, ST_LSM6DSV16X_ID, ST_LSM6DSO16IS_ID, + ST_ISM330IS_ID, ST_LSM6DSX_MAX_ID, }; diff --git a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c index 57a79bf35bba..3f6060c64f32 100644 --- a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c +++ b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c @@ -27,7 +27,7 @@ * - FIFO size: 4KB * * - LSM6DSO/LSM6DSOX/ASM330LHH/ASM330LHHX/LSM6DSR/ISM330DHCX/LSM6DST/LSM6DSOP/ - * LSM6DSTX/LSM6DSO16IS: + * 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 @@ -1393,7 +1393,11 @@ static const struct st_lsm6dsx_settings st_lsm6dsx_sensor_settings[] = { .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] = { diff --git a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_i2c.c b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_i2c.c index c34ccc85e4c7..df5f60925260 100644 --- a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_i2c.c +++ b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_i2c.c @@ -121,6 +121,10 @@ static const struct of_device_id st_lsm6dsx_i2c_of_match[] = { .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); @@ -147,6 +151,7 @@ static const struct i2c_device_id st_lsm6dsx_i2c_id_table[] = { { 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); diff --git a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_spi.c b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_spi.c index 24d5e51a8662..974584bda875 100644 --- a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_spi.c +++ b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_spi.c @@ -121,6 +121,10 @@ static const struct of_device_id st_lsm6dsx_spi_of_match[] = { .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); @@ -147,6 +151,7 @@ static const struct spi_device_id st_lsm6dsx_spi_id_table[] = { { 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); -- cgit v1.2.3 From f1e24342401a69da0519b289f0942fcd69e7db55 Mon Sep 17 00:00:00 2001 From: Cosmin Tanislav Date: Thu, 24 Nov 2022 17:25:59 +0200 Subject: iio: addac: ad74115: remove unused ad74115_dac_slew_rate_hz_tbl This table was supposed to be used for handling the DAC rate, but it ended up being unused. Remove it. Signed-off-by: Cosmin Tanislav Reported-by: kernel test robot Link: https://lore.kernel.org/r/20221124152559.7895-1-cosmin.tanislav@analog.com Signed-off-by: Jonathan Cameron --- drivers/iio/addac/ad74115.c | 4 ---- 1 file changed, 4 deletions(-) (limited to 'drivers/iio') diff --git a/drivers/iio/addac/ad74115.c b/drivers/iio/addac/ad74115.c index 383b92e7b682..e6bc5eb3788d 100644 --- a/drivers/iio/addac/ad74115.c +++ b/drivers/iio/addac/ad74115.c @@ -317,10 +317,6 @@ static const unsigned int ad74115_dac_rate_step_tbl[][3] = { { AD74115_SLEW_MODE_LINEAR, AD74115_SLEW_STEP_22_2_PERCENT, AD74115_SLEW_RATE_240KHZ }, }; -static const unsigned int ad74115_dac_slew_rate_hz_tbl[] = { - 4000, 64000, 150000, 240000 -}; - static const unsigned int ad74115_rtd_excitation_current_ua_tbl[] = { 250, 500, 750, 1000 }; -- cgit v1.2.3 From f84eec02b7248b6ae3bd8ef18a66f6f64eeab971 Mon Sep 17 00:00:00 2001 From: Cosmin Tanislav Date: Thu, 24 Nov 2022 17:30:49 +0200 Subject: iio: addac: ad74413r: fix blank line after declaration warning Checkpatch wants a blank line after all declarations. Add it now, even though the patch has already been submitted. Signed-off-by: Cosmin Tanislav Link: https://lore.kernel.org/r/20221124153049.8851-1-cosmin.tanislav@analog.com Signed-off-by: Jonathan Cameron --- drivers/iio/addac/ad74413r.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers/iio') diff --git a/drivers/iio/addac/ad74413r.c b/drivers/iio/addac/ad74413r.c index 61030053cbea..f32c8c2fb26d 100644 --- a/drivers/iio/addac/ad74413r.c +++ b/drivers/iio/addac/ad74413r.c @@ -1315,6 +1315,7 @@ static int ad74413r_probe(struct spi_device *spi) st->chip_info = device_get_match_data(&spi->dev); if (!st->chip_info) { const struct spi_device_id *id = spi_get_device_id(spi); + if (id) st->chip_info = (struct ad74413r_chip_info *)id->driver_data; -- cgit v1.2.3