Re: [PATCH v3 6/8] iio: adc: add ti-ads112c14 driver
From: Andy Shevchenko
Date: Sun Jul 12 2026 - 05:43:09 EST
On Fri, Jul 10, 2026 at 05:50:39PM -0500, David Lechner (TI) wrote:
> Add a new driver for the TI ADS112C14/ADS122C14 ADC chips.
>
> This first step is adding a very basic driver that only supports power
> on/reset and reading the system monitor channels.
>
> ADS112C14_SYS_MON_CHANNEL_SHORT is the last channel rather than being in
> logical order by address to keep the voltage channels together and in
> case we find we need to add variants of this channel with different
> voltage reference later.
...
> +static int ads112c14_probe(struct i2c_client *client)
> +{
> + struct device *dev = &client->dev;
> + const struct ads112c14_chip_info *info;
> + struct iio_dev *indio_dev;
> + struct ads112c14_data *data;
> + u32 reg_val;
> + int ret;
> +
> + info = i2c_get_match_data(client);
> + if (!info)
> + return dev_err_probe(dev, -EINVAL, "missing match data\n");
I think -ENODEV suits better here.
> + indio_dev = devm_iio_device_alloc(dev, sizeof(*data));
> + if (!indio_dev)
> + return -ENOMEM;
> +
> + data = iio_priv(indio_dev);
> + data->chip_info = info;
> +
> + ret = devm_regulator_get_enable(dev, "dvdd");
> + if (ret)
> + return dev_err_probe(dev, ret, "failed to get dvdd regulator\n");
> +
> + ret = devm_regulator_get_enable(dev, "avdd");
> + if (ret)
> + return dev_err_probe(dev, ret, "failed to get avdd regulator\n");
> +
> + data->regmap = devm_regmap_init_i2c(client, &ads112c14_regmap_config);
> + if (IS_ERR(data->regmap))
> + return dev_err_probe(dev, PTR_ERR(data->regmap),
> + "failed to init regmap\n");
Do we have a guarantee that device is powered on here?
> + /* Write magic reset value (0x16) to ensure known state. */
> + ret = regmap_write(data->regmap, ADS112C14_REG_CONVERSION_CTRL,
> + FIELD_PREP(ADS112C14_CONVERSION_CTRL_RESET, 0x16));
> + /*
> + * The reset may cause an -EREMOTEIO error because of failing to get the
> + * I2C ACK at the end of the message. The device still gets reset so it
> + * is safe to ignore this error.
> + */
> + if (ret == -EREMOTEIO)
> + ret = 0;
> + if (ret)
> + return ret;
> +
> + fsleep(ADS112C14_DELAY_RESET_US);
> +
> + ret = regmap_read(data->regmap, ADS112C14_REG_STATUS_MSB, ®_val);
> + if (ret)
> + return ret;
> +
> + if (FIELD_GET(ADS112C14_STATUS_MSB_RESETN, reg_val))
> + return dev_err_probe(dev, -EIO, "reset failed\n");
> +
> + /*
> + * Clear reset bit to prepare for next probe. And clear AVDD fault since
> + * that happens on every reset.
> + */
> + ret = regmap_write(data->regmap, ADS112C14_REG_STATUS_MSB,
> + ADS112C14_STATUS_MSB_RESETN |
> + ADS112C14_STATUS_MSB_AVDD_UVN);
> + if (ret)
> + return ret;
> +
> + ret = regmap_read(data->regmap, ADS112C14_REG_DEVICE_ID, ®_val);
> + if (ret)
> + return ret;
> +
> + if (FIELD_GET(ADS112C14_DEVICE_ID_BITS, reg_val) != info->device_id)
> + dev_info(dev, "device ID mismatch, expected 0xX%X, got 0x%lX\n",
> + info->device_id,
> + FIELD_GET(ADS112C14_DEVICE_ID_BITS, reg_val));
> +
> + /* Place in single-shot conversion mode to make ready for raw read. */
> + ret = regmap_set_bits(data->regmap, ADS112C14_REG_DEVICE_CFG,
> + ADS112C14_DEVICE_CFG_CONV_MODE);
> + if (ret)
> + return ret;
> +
> + indio_dev->name = info->name;
> + indio_dev->modes = INDIO_DIRECT_MODE;
> + indio_dev->channels = ads112c14_sys_mon_channels;
> + indio_dev->num_channels = ARRAY_SIZE(ads112c14_sys_mon_channels);
> + indio_dev->info = &ads112c14_info;
> +
> + return devm_iio_device_register(dev, indio_dev);
> +}
--
With Best Regards,
Andy Shevchenko