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