Re: [PATCH v5 08/14] iio: adc: ad7768-1: add regulator to control VCM output

David Lechner
2025-04-11T21:44:58Z

On 4/11/25 10:57 AM, Jonathan Santos wrote:
> The VCM output voltage can be used as a common-mode voltage within the
> amplifier preconditioning circuits external to the AD7768-1.
>
> This change allows the user to configure VCM output using the regulator
> framework.
>
> Acked-by: Marcelo Schmitt <marcelo.schmitt@analog.com>
> Signed-off-by: Jonathan Santos <Jonathan.Santos@analog.com>
> ---

...

> +static int ad7768_vcm_is_enabled(struct regulator_dev *rdev)
> +{
> + struct iio_dev *indio_dev = rdev_get_drvdata(rdev);
> + struct ad7768_state *st = iio_priv(indio_dev);
> + int ret, val;
> +
> + if (!indio_dev)
> + return -EINVAL;
> +
> + if (!iio_device_claim_direct(indio_dev))
> + return -EBUSY;
> +
> + ret = regmap_read(st->regmap, AD7768_REG_ANALOG2, &val);

If we put iio_device_release_direct(indio_dev); here, we can avoid
the goto.

> + if (ret)
> + goto err_release;
> +
> + ret = FIELD_GET(AD7768_REG_ANALOG2_VCM_MSK, val) != AD7768_VCM_OFF;
> +err_release:
> + iio_device_release_direct(indio_dev);
> +
> + return ret;
> +}
> +
> +static int ad7768_set_voltage_sel(struct regulator_dev *rdev,
> + unsigned int selector)
> +{
> + unsigned int regval = AD7768_REG_ANALOG2_VCM(selector + 1);
> + struct iio_dev *indio_dev = rdev_get_drvdata(rdev);
> + struct ad7768_state *st = iio_priv(indio_dev);
> + int ret;
> +
> + if (!indio_dev)
> + return -EINVAL;
> +
> + if (!iio_device_claim_direct(indio_dev))
> + return -EBUSY;
> +
> + ret = regmap_update_bits(st->regmap, AD7768_REG_ANALOG2,
> + AD7768_REG_ANALOG2_VCM_MSK, regval);
> + iio_device_release_direct(indio_dev);
> + st->vcm_output_sel = selector;

Do we still want to make this assignment if there is an error?

> +
> + return ret;
> +}
> +
> +static int ad7768_get_voltage_sel(struct regulator_dev *rdev)
> +{
> + struct iio_dev *indio_dev = rdev_get_drvdata(rdev);
> + struct ad7768_state *st = iio_priv(indio_dev);
> + int ret, val;
> +
> + if (!indio_dev)
> + return -EINVAL;
> +
> + if (!iio_device_claim_direct(indio_dev))
> + return -EBUSY;
> +
> + ret = regmap_read(st->regmap, AD7768_REG_ANALOG2, &val);
> + if (ret)
> + goto err_release;

Can rearrange to avoid goto here too.

> +
> + val = FIELD_GET(AD7768_REG_ANALOG2_VCM_MSK, val);
> + ret = clamp(val, 1, (int)rdev->desc->n_voltages) - 1;
> +err_release:
> + iio_device_release_direct(indio_dev);
> +
> + return ret;
> +}
> +

...

> +static int ad7768_register_regulators(struct device *dev, struct ad7768_state *st,
> + struct iio_dev *indio_dev)
> +{
> + struct regulator_config config = {
> + .dev = dev,
> + .driver_data = indio_dev,
> + };
> + int ret;
> +
> + /* Disable the regulator before registering it */
> + ret = regmap_update_bits(st->regmap, AD7768_REG_ANALOG2,
> + AD7768_REG_ANALOG2_VCM_MSK, AD7768_VCM_OFF);
> + if (ret)
> + return -EINVAL;

Why not return ret; ?

> +
> + st->vcm_rdev = devm_regulator_register(dev, &vcm_desc, &config);
> + if (IS_ERR(st->vcm_rdev))
> + return dev_err_probe(dev, PTR_ERR(st->vcm_rdev),
> + "failed to register VCM regulator\n");
> +
> + return 0;
> +}
> +