Re: [PATCH v7 4/4] iio: cdc: add Texas Instruments FDC1004 driver

From: Andy Shevchenko

Date: Mon Nov 09 2026 - 18:40:07 EST


On Sun, Nov 08, 2026 at 02:08:29PM -0600, Victor Chernyakin wrote:
> The FDC1004 is a high-precision 4-channel capacitive sensor that talks
> over I2C. It can report the values of each of its 4 channels individually,
> as well as the difference between any two of them.
>
> This initial driver allows performing single reads and configuring
> the sensor's various settings (sample frequency, calibration
> gain/offset, etc.). It could be extended with support for triggered
> buffers, repeated measurement mode, and/or power management.

...

> +static int fdc1004_write_raw(struct iio_dev *indio_dev,
> + const struct iio_chan_spec *chan,
> + int val, int val2, long mask)
> +{
> + struct fdc1004_data *data = iio_priv(indio_dev);
> + struct regmap *map = data->regmap;
> + s64 val64;
> +
> + switch (mask) {
> + case IIO_CHAN_INFO_SAMP_FREQ:
> + for (unsigned int i = 0; i < ARRAY_SIZE(fdc1004_samp_freqs); i++) {
> + if (fdc1004_samp_freqs[i] == val) {
> + guard(mutex)(&data->lock);
> +
> + data->samp_freq_index = i;
> + return 0;
> + }
> + }
> +
> + return -EINVAL;
> + case IIO_CHAN_INFO_OFFSET: {
> + if (val < fdc1004_offset[0] || val > fdc1004_offset[2] ||
> + val % fdc1004_offset[1])
> + return -EINVAL;
> +
> + guard(mutex)(&data->lock);
> +
> + data->offsets[chan->channel] = val / fdc1004_offset[1];

Make a temporary variables to have division and modulo operations coupled
together. The rationale is explained here:
9b3cd5c7099f ("regmap: place foo / 8 and foo % 8 closer to each other")

> + return 0;
> + }
> + case IIO_CHAN_INFO_CALIBBIAS:
> + val64 = iio_val_s64_compose(val, val2);
> + if (val64 < fdc1004_calibbias[0] || val64 > fdc1004_calibbias[2])
> + return -EINVAL;
> +
> + return regmap_write(map, FDC1004_REG_OFFSET_CAL_CINn(chan->channel),
> + (u16)DIV_S64_ROUND_CLOSEST(val64, fdc1004_calibbias[1]));

Why casting? Shouldn't it be handled on the regmap_write() stage based on
the register / field description?

> + case IIO_CHAN_INFO_CALIBSCALE:
> + val64 = iio_val_s64_compose(val, val2);
> + if (val64 < fdc1004_calibscale[0] || val64 > fdc1004_calibscale[2])
> + return -EINVAL;
> +
> + return regmap_write(map, FDC1004_REG_GAIN_CAL_CINn(chan->channel),
> + DIV64_U64_ROUND_CLOSEST(val64, fdc1004_calibscale[1]));
> + default:
> + return -EINVAL;
> + }
> +}

--
With Best Regards,
Andy Shevchenko