Re: [PATCH v2 13/14] regulator: add pm8008 pmic regulator driver

From: Andy Shevchenko
Date: Wed May 29 2024 - 16:03:49 EST


On Wed, May 29, 2024 at 7:30 PM Johan Hovold <johan+linaro@xxxxxxxxxx> wrote:
>
> The Qualcomm PM8008 is an I2C-controlled PMIC containing seven LDO
> regulators.
>
> The driver is based on a driver submitted by Satya Priya, but it has
> been cleaned up and reworked to match the new devicetree binding which
> no longer describes each regulator as a separate device.
>
> This avoids describing internal details like register offsets in the
> devicetree and allows for extending the implementation with features
> like over-current protection without having to update the binding.
>
> Specifically note that the regulator interrupts are shared between all
> regulators.
>
> Note that the secondary regmap is looked up by name and that if the
> driver ever needs to be generalised to support regulators provided by
> the primary regmap (I2C address) such information could be added to the
> device-id table.
>
> This also fixes the original implementation, which looked up regulators
> by 'regulator-name' property rather than devicetree node name and which
> prevented the regulators from being named to match board schematics.

..

> +#include <linux/array_size.h>
> +#include <linux/bits.h>
> +#include <linux/device.h>
> +#include <linux/math.h>
> +#include <linux/module.h>

> +#include <linux/of.h>
> +#include <linux/platform_device.h>
> +#include <linux/regmap.h>
> +#include <linux/regulator/driver.h>

+ types.h

+ asm/byteorder.h

..

> +static int pm8008_regulator_set_voltage_sel(struct regulator_dev *rdev, unsigned int sel)
> +{
> + struct pm8008_regulator *preg = rdev_get_drvdata(rdev);
> + unsigned int mV;
> + __le16 val;
> + int ret;
> +
> + ret = regulator_list_voltage_linear_range(rdev, sel);
> + if (ret < 0)
> + return ret;
> +
> + mV = DIV_ROUND_UP(ret, 1000);

MILLI from units.h ?

> + val = cpu_to_le16(mV);

> + ret = regmap_bulk_write(preg->regmap, preg->base + LDO_VSET_LB_REG,
> + &val, sizeof(val));
> + if (ret < 0)
> + return ret;
> +
> + return 0;

May be written as

return regmap_bulk_write(...);

> +}
> +
> +static int pm8008_regulator_get_voltage_sel(struct regulator_dev *rdev)
> +{
> + struct pm8008_regulator *preg = rdev_get_drvdata(rdev);
> + unsigned int uV;
> + __le16 val;
> + int ret;
> +
> + ret = regmap_bulk_read(preg->regmap, preg->base + LDO_VSET_LB_REG,
> + &val, sizeof(val));
> + if (ret < 0)
> + return ret;
> +
> + uV = le16_to_cpu(val) * 1000;

MILLI ?

> + return (uV - preg->desc.min_uV) / preg->desc.uV_step;
> +}

..

> + rdev = devm_regulator_register(dev, desc, &config);
> + if (IS_ERR(rdev)) {
> + ret = PTR_ERR(rdev);
> + dev_err(dev, "failed to register regulator %s: %d\n",
> + desc->name, ret);
> + return ret;

It's possible to use

return dev_err_probe(...);

even for non-probe functions.

> + }
> + }


--
With Best Regards,
Andy Shevchenko