mbox series

[v14,00/10] iio: adc: introduce Qualcomm SPMI Round Robin ADC

Message ID 20220429220904.137297-1-caleb.connolly@linaro.org
Headers show
Series iio: adc: introduce Qualcomm SPMI Round Robin ADC | expand

Message

Caleb Connolly April 29, 2022, 10:08 p.m. UTC
The RRADC is responsible for reading data about the current and
voltage from the USB or DC in jacks, it can also read the battery
ID (resistence) and some temperatures. It is found on the PMI8998 and
PM660 Qualcomm PMICs.

The RRADC has to calibrate some ADC values based on which chip fab
the PMIC was produced in, to facilitate this the patches
("mfd: qcom-spmi-pmic: expose the PMIC revid information to clients")
and ("mfd: qcom-spmi-pmic: read fab id on supported PMICs")
expose the PMIC revision information and fab_id as a struct and register
them as driver data in the Qualcomm SPMI PMIC driver so that it can be
read by the RRADC.

The first 3 patches add support for looking up an SPMI device from a
struct device_node, as well as introducing support for looking up the
base USID of a Qcom PMIC, see patch comments for more details. These
Address Bjorns comments on v2.

Changes since v13:
 * Address Lee Jones' feedback on the SPMI patches.
 * Pick up Jami's patch to enable the RRADC on the OnePlus 5

Changes since v12:
 * Apply Krzysztof's suggestions to rradc DT binding docs.

Changes since v11:
 * Remove debug logging which was left in ("mfd: qcom-spmi-pmic: expose the PMIC revid information to clients")
 * Picked up Dmitry's Tested-by and Reviewed-by tags.

Changes since v10:
 * Don't inline spmi_device_from_of()

Changes since v9:
 * Add back missing copyright, this driver is originally derived from
   downstream (Thanks Manivannan).

Changes since v8:
 * Drop Reported-by for the bugfix on previous revision reported by LKP
 * Apply Jonathans suggestions
 * Rework patch 2 ("expose the PMIC revid information to clients") to
   handle PMICs with a single USID (thanks Dmitry)

Changes since v7:
 * Addressed Jonathans comments
 * Fixed bug reported by LKP

Changes since v6:
 * Fix printf format warning in rradc

Changes since v5:
 * Add missing EXPORT_SYMBOL_GPL() to
   ("spmi: add a helper to look up an SPMI device from a device node")

Changes since v4:
 * Addressed Jonathan's comments on v4
 * Reworked the qcom-spmi-pmic patches to properly walk the devicetree
   to find the base USID. I've tested this on SDM845 which has two PMICs
   (pm8998 and pmi8998) and I'm able to look up the PMIC revid from all
   4 USIDs.

Changes since v3:
 * Split PMIC patch in two, rework to support function drivers on a
   sibling USID
 * Completely rework RRADC driver to make use of the modern IIO
   framework. This required re-arranging a lot of the equations and
   results in some lost precision, where relevant I've left comments to
   explain this. I don't think any of it is significant enough to
   justify doing post-processing in driver.
   Thanks a lot Jonathan and John Stultz for helping me out with
   this

Changes since v2:
 * Add missing include (thanks kernel test robot :D)
 * Rework some confusing function return values, specifically
   rradc_read_status_in_cont_mode and rradc_prepare_batt_id_conversion
   both of which didn't correctly handle "ret". This also bought up an
   issue as the previous implementation didn't actually wait for the
   channel to be ready. It doesn't seem like that's strictly necessary
   (same data is reported if I wait for the status to be good or not)
   but I've included it anyway for good measure.

Changes since v1:
 * Rework the RRADC driver based on Jonathan's feedback
 * Pick up Rob's reviewed by for the dt-binding patch.
 ---
Caleb Connolly (9):
  spmi: add a helper to look up an SPMI device from a device node
  mfd: qcom-spmi-pmic: expose the PMIC revid information to clients
  mfd: qcom-spmi-pmic: read fab id on supported PMICs
  dt-bindings: iio: adc: document qcom-spmi-rradc
  iio: adc: qcom-spmi-rradc: introduce round robin adc
  arm64: dts: qcom: pmi8998: add rradc node
  arm64: dts: qcom: sdm845-oneplus: enable rradc
  arm64: dts: qcom: sdm845-db845c: enable rradc
  arm64: dts: qcom: sdm845-xiaomi-beryllium: enable rradc

Jami Kettunen (1):
  arm64: dts: qcom: msm8998-oneplus-common: enable RRADC

 .../bindings/iio/adc/qcom,spmi-rradc.yaml     |   51 +
 .../boot/dts/qcom/msm8998-oneplus-common.dtsi |    4 +
 arch/arm64/boot/dts/qcom/pmi8998.dtsi         |    8 +
 arch/arm64/boot/dts/qcom/sdm845-db845c.dts    |    4 +
 .../boot/dts/qcom/sdm845-oneplus-common.dtsi  |    4 +
 .../boot/dts/qcom/sdm845-xiaomi-beryllium.dts |    4 +
 drivers/iio/adc/Kconfig                       |   12 +
 drivers/iio/adc/Makefile                      |    1 +
 drivers/iio/adc/qcom-spmi-rradc.c             | 1021 +++++++++++++++++
 drivers/mfd/qcom-spmi-pmic.c                  |  272 +++--
 drivers/spmi/spmi.c                           |   17 +
 include/linux/spmi.h                          |    3 +
 include/soc/qcom/qcom-spmi-pmic.h             |   61 +
 13 files changed, 1372 insertions(+), 90 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/iio/adc/qcom,spmi-rradc.yaml
 create mode 100644 drivers/iio/adc/qcom-spmi-rradc.c
 create mode 100644 include/soc/qcom/qcom-spmi-pmic.h

Comments

Jonathan Cameron May 1, 2022, 5:23 p.m. UTC | #1
On Fri, 29 Apr 2022 23:08:56 +0100
Caleb Connolly <caleb.connolly@linaro.org> wrote:

> The helper function spmi_device_from_of() takes a device node and
> returns the SPMI device associated with it.
> This is like of_find_device_by_node but for SPMI devices.
> 
> Signed-off-by: Caleb Connolly <caleb.connolly@linaro.org> 

Stephen, are you fine with this addition to spmi?

Given bulk of this series in in IIO I'm planning to pick up once
everyone is happy with it.

Thanks,

Jonathan


> ---
>  drivers/spmi/spmi.c  | 17 +++++++++++++++++
>  include/linux/spmi.h |  3 +++
>  2 files changed, 20 insertions(+)
> 
> diff --git a/drivers/spmi/spmi.c b/drivers/spmi/spmi.c
> index b37ead9e2fad..a456ce5141e1 100644
> --- a/drivers/spmi/spmi.c
> +++ b/drivers/spmi/spmi.c
> @@ -386,6 +386,23 @@ static struct bus_type spmi_bus_type = {
>  	.uevent		= spmi_drv_uevent,
>  };
>  
> +/**
> + * spmi_device_from_of() - get the associated SPMI device from a device node
> + *
> + * @np:		device node
> + *
> + * Returns the struct spmi_device associated with a device node or NULL.
> + */
> +struct spmi_device *spmi_device_from_of(struct device_node *np)
> +{
> +	struct device *dev = bus_find_device_by_of_node(&spmi_bus_type, np);
> +
> +	if (dev)
> +		return to_spmi_device(dev);
> +	return NULL;
> +}
> +EXPORT_SYMBOL_GPL(spmi_device_from_of);
> +
>  /**
>   * spmi_controller_alloc() - Allocate a new SPMI device
>   * @ctrl:	associated controller
> diff --git a/include/linux/spmi.h b/include/linux/spmi.h
> index 729bcbf9f5ad..eac1956a8727 100644
> --- a/include/linux/spmi.h
> +++ b/include/linux/spmi.h
> @@ -164,6 +164,9 @@ static inline void spmi_driver_unregister(struct spmi_driver *sdrv)
>  	module_driver(__spmi_driver, spmi_driver_register, \
>  			spmi_driver_unregister)
>  
> +struct device_node;
> +
> +struct spmi_device *spmi_device_from_of(struct device_node *np);
>  int spmi_register_read(struct spmi_device *sdev, u8 addr, u8 *buf);
>  int spmi_ext_register_read(struct spmi_device *sdev, u8 addr, u8 *buf,
>  			   size_t len);
Jonathan Cameron May 1, 2022, 5:28 p.m. UTC | #2
On Fri, 29 Apr 2022 23:08:57 +0100
Caleb Connolly <caleb.connolly@linaro.org> wrote:

> Some PMIC functions such as the RRADC need to be aware of the PMIC
> chip revision information to implement errata or otherwise adjust
> behaviour, export the PMIC information to enable this.
> 
> This is specifically required to enable the RRADC to adjust
> coefficients based on which chip fab the PMIC was produced in,
> this can vary per unique device and therefore has to be read at
> runtime.
> 
> Signed-off-by: Caleb Connolly <caleb.connolly@linaro.org>
> Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
> Tested-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>

...

> +/**
> + * qcom_pmic_get() - Get a pointer to the base PMIC device
> + *
> + * This function takes a struct device for a driver which is a child of a PMIC.
> + * And locates the PMIC revision information for it.
> + *
> + * @dev: the pmic function device
> + * @return: the struct qcom_spmi_pmic* pointer associated with the function device
> + */
> +inline const struct qcom_spmi_pmic *qcom_pmic_get(struct device *dev)
> +{
> +	struct spmi_device *sdev;
> +	struct qcom_spmi_dev *spmi;
> +
> +	/*
> +	 * Make sure the device is actually a child of a PMIC
> +	 */
> +	if (!of_match_device(pmic_spmi_id_table, dev->parent))
> +		return ERR_PTR(-EINVAL);
> +
> +	sdev = qcom_pmic_get_base_usid(dev->parent);
>  
> -	if (subtype == PM8110_SUBTYPE)
> -		minor = rev2;
> +	if (IS_ERR(sdev))
> +		return ERR_CAST(sdev);
>  
> -	dev_dbg(dev, "%x: %s v%d.%d\n", subtype, name, major, minor);
> +	spmi = (struct qcom_spmi_dev *)dev_get_drvdata(&sdev->dev);

Shouldn't need the cast as dev_get_drvdata() returns void * and you can
implicitly cast that to any other pointer type.

If this is all that comes up in the series I can fixup whilst applying.

Jonathan


> +
> +	return &spmi->pmic;
>  }
> +EXPORT_SYMBOL(qcom_pmic_get);
>
Jonathan Cameron May 1, 2022, 5:38 p.m. UTC | #3
On Fri, 29 Apr 2022 23:09:00 +0100
Caleb Connolly <caleb.connolly@linaro.org> wrote:

> The Round Robin ADC is responsible for reading data about the rate of
> charge from the USB or DC input ports, it can also read the battery
> ID (resistence), skin temperature and the die temperature of the pmic.
> It is found on the PMI8998 and PM660 Qualcomm PMICs.
> 
> Signed-off-by: Caleb Connolly <caleb.connolly@linaro.org>
Hi Caleb,

I took another quick read through of this and noticed that the battery channel
is providing on IIO_INFO_RAW but there is code for IIO_INFO_PROCESSED.

Something gone wrong along the way?  If all we need is to change it to
BIT(IIO_INFO_PROCESSED) I can do that whilst applying or you can do a v15 if
you prefer.

Thanks,

Jonathan

> ---

> diff --git a/drivers/iio/adc/qcom-spmi-rradc.c b/drivers/iio/adc/qcom-spmi-rradc.c
> new file mode 100644
> index 000000000000..c437546d8a4c
> --- /dev/null
> +++ b/drivers/iio/adc/qcom-spmi-rradc.c


..

> +
> +/*
> + * These functions explicitly cast int64_t to int.
> + * They will never overflow, as the values are small enough.

See below. I don't think this gets used...

> + */
> +static int rradc_post_process_batt_id(struct rradc_chip *chip, u16 adc_code,
> +				      int *result_ohms)
> +{
> +	uint32_t current_value;
> +	int64_t r_id;
> +
> +	current_value = chip->batt_id_data;
> +	r_id = ((int64_t)adc_code * RR_ADC_FS_VOLTAGE_MV);
> +	r_id = div64_s64(r_id, (RR_ADC_CHAN_MSB * current_value));
> +	*result_ohms = (int)(r_id * MILLI);
> +
> +	return 0;
> +}
> +


> +
> +static int rradc_read_raw(struct iio_dev *indio_dev,
> +			  struct iio_chan_spec const *chan_spec, int *val,
> +			  int *val2, long mask)
> +{
> +	struct rradc_chip *chip = iio_priv(indio_dev);
> +	const struct rradc_channel *chan;
> +	int ret;
> +	u16 adc_code;
> +
> +	if (chan_spec->address >= RR_ADC_CHAN_MAX) {
> +		dev_err(chip->dev, "Invalid channel index:%lu\n",
> +			chan_spec->address);
> +		return -EINVAL;
> +	}
> +
> +	switch (mask) {
> +	case IIO_CHAN_INFO_SCALE:
> +		return rradc_read_scale(chip, chan_spec->address, val, val2);
> +	case IIO_CHAN_INFO_OFFSET:
> +		return rradc_read_offset(chip, chan_spec->address, val);
> +	case IIO_CHAN_INFO_RAW:
> +		ret = rradc_do_conversion(chip, chan_spec->address, &adc_code);
> +		if (ret < 0)
> +			return ret;
> +
> +		*val = adc_code;
> +		return IIO_VAL_INT;
> +	case IIO_CHAN_INFO_PROCESSED:

This doesn't seem to apply to any channels....

> +		chan = &rradc_chans[chan_spec->address];
> +		if (!chan->scale_fn)
> +			return -EINVAL;
> +		ret = rradc_do_conversion(chip, chan_spec->address, &adc_code);
> +		if (ret < 0)
> +			return ret;
> +
> +		*val = chan->scale_fn(chip, adc_code, val);
> +		return IIO_VAL_INT;
> +	default:
> +		return -EINVAL;
> +	}
> +}
> +
> +static int rradc_read_label(struct iio_dev *indio_dev,
> +			    struct iio_chan_spec const *chan, char *label)
> +{
> +	return snprintf(label, PAGE_SIZE, "%s\n",
> +			rradc_chans[chan->address].label);
> +}
> +
> +static const struct iio_info rradc_info = {
> +	.read_raw = rradc_read_raw,
> +	.read_label = rradc_read_label,
> +};
> +
> +static const struct rradc_channel rradc_chans[RR_ADC_CHAN_MAX] = {
> +	{
> +		.label = "batt_id",
> +		.scale_fn = rradc_post_process_batt_id,
> +		.lsb = RR_ADC_BATT_ID_5_LSB,
> +		.status = RR_ADC_BATT_ID_STS,
> +		.size = 6,
> +		.trigger_addr = RR_ADC_BATT_ID_TRIGGER,
> +		.trigger_mask = BIT(0),
> +	}, {
> +		.label = "batt",
> +		.lsb = RR_ADC_BATT_THERM_LSB,
> +		.status = RR_ADC_BATT_THERM_STS,
> +		.size = 2,
> +		.trigger_addr = RR_ADC_BATT_THERM_TRIGGER,
> +	}, {
> +		.label = "pmi8998_skin",
> +		.lsb = RR_ADC_SKIN_TEMP_LSB,
> +		.status = RR_ADC_AUX_THERM_STS,
> +		.size = 2,
> +		.trigger_addr = RR_ADC_AUX_THERM_TRIGGER,
> +	}, {
> +		.label = "usbin_i",
> +		.lsb = RR_ADC_USB_IN_I_LSB,
> +		.status = RR_ADC_USB_IN_I_STS,
> +		.size = 2,
> +		.trigger_addr = RR_ADC_USB_IN_I_TRIGGER,
> +	}, {
> +		.label = "usbin_v",
> +		.lsb = RR_ADC_USB_IN_V_LSB,
> +		.status = RR_ADC_USB_IN_V_STS,
> +		.size = 2,
> +		.trigger_addr = RR_ADC_USB_IN_V_TRIGGER,
> +		.trigger_mask = BIT(7),
> +	}, {
> +		.label = "dcin_i",
> +		.lsb = RR_ADC_DC_IN_I_LSB,
> +		.status = RR_ADC_DC_IN_I_STS,
> +		.size = 2,
> +		.trigger_addr = RR_ADC_DC_IN_I_TRIGGER,
> +	}, {
> +		.label = "dcin_v",
> +		.lsb = RR_ADC_DC_IN_V_LSB,
> +		.status = RR_ADC_DC_IN_V_STS,
> +		.size = 2,
> +		.trigger_addr = RR_ADC_DC_IN_V_TRIGGER,
> +	}, {
> +		.label = "pmi8998_die",
> +		.lsb = RR_ADC_PMI_DIE_TEMP_LSB,
> +		.status = RR_ADC_PMI_DIE_TEMP_STS,
> +		.size = 2,
> +		.trigger_addr = RR_ADC_PMI_DIE_TEMP_TRIGGER,
> +		.trigger_mask = RR_ADC_TRIGGER_EVERY_CYCLE,
> +	}, {
> +		.label = "chg",
> +		.lsb = RR_ADC_CHARGER_TEMP_LSB,
> +		.status = RR_ADC_CHARGER_TEMP_STS,
> +		.size = 2,
> +		.trigger_addr = RR_ADC_CHARGER_TEMP_TRIGGER,
> +	}, {
> +		.label = "gpio",
> +		.lsb = RR_ADC_GPIO_LSB,
> +		.status = RR_ADC_GPIO_STS,
> +		.size = 2,
> +		.trigger_addr = RR_ADC_GPIO_TRIGGER,
> +	},
> +};
> +
> +static const struct iio_chan_spec rradc_iio_chans[RR_ADC_CHAN_MAX] = {
> +	{
> +		.type = IIO_RESISTANCE,
> +		.info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
> +		.address = RR_ADC_BATT_ID,
> +		.channel = 0,
> +		.indexed = 1,
> +	}, {
> +		.type = IIO_TEMP,
> +		.info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
> +		.address = RR_ADC_BATT_THERM,
> +		.channel = 0,
> +		.indexed = 1,
> +	}, {
> +		.type = IIO_TEMP,
> +		.info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
> +				      BIT(IIO_CHAN_INFO_SCALE) |
> +				      BIT(IIO_CHAN_INFO_OFFSET),
> +		.address = RR_ADC_SKIN_TEMP,
> +		.channel = 1,
> +		.indexed = 1,
> +	}, {
> +		.type = IIO_CURRENT,
> +		.info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
> +				      BIT(IIO_CHAN_INFO_SCALE),
> +		.address = RR_ADC_USBIN_I,
> +		.channel = 0,
> +		.indexed = 1,
> +	}, {
> +		.type = IIO_VOLTAGE,
> +		.info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
> +				      BIT(IIO_CHAN_INFO_SCALE),
> +		.address = RR_ADC_USBIN_V,
> +		.channel = 0,
> +		.indexed = 1,
> +	}, {
> +		.type = IIO_CURRENT,
> +		.info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
> +				      BIT(IIO_CHAN_INFO_SCALE),
> +		.address = RR_ADC_DCIN_I,
> +		.channel = 1,
> +		.indexed = 1,
> +	}, {
> +		.type = IIO_VOLTAGE,
> +		.info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
> +				      BIT(IIO_CHAN_INFO_SCALE),
> +		.address = RR_ADC_DCIN_V,
> +		.channel = 1,
> +		.indexed = 1,
> +	}, {
> +		.type = IIO_TEMP,
> +		.info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
> +				      BIT(IIO_CHAN_INFO_SCALE) |
> +				      BIT(IIO_CHAN_INFO_OFFSET),
> +		.address = RR_ADC_DIE_TEMP,
> +		.channel = 2,
> +		.indexed = 1,
> +	}, {
> +		.type = IIO_TEMP,
> +		.info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
> +				      BIT(IIO_CHAN_INFO_OFFSET) |
> +				      BIT(IIO_CHAN_INFO_SCALE),
> +		.address = RR_ADC_CHG_TEMP,
> +		.channel = 3,
> +		.indexed = 1,
> +	}, {
> +		.type = IIO_VOLTAGE,
> +		.info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
> +				      BIT(IIO_CHAN_INFO_SCALE),
> +		.address = RR_ADC_GPIO,
> +		.channel = 2,
> +		.indexed = 1,
> +	},
> +};
> +
Caleb Connolly May 9, 2022, 11:53 a.m. UTC | #4
On 01/05/2022 18:38, Jonathan Cameron wrote:
> On Fri, 29 Apr 2022 23:09:00 +0100
> Caleb Connolly <caleb.connolly@linaro.org> wrote:
> 
>> The Round Robin ADC is responsible for reading data about the rate of
>> charge from the USB or DC input ports, it can also read the battery
>> ID (resistence), skin temperature and the die temperature of the pmic.
>> It is found on the PMI8998 and PM660 Qualcomm PMICs.
>>
>> Signed-off-by: Caleb Connolly <caleb.connolly@linaro.org>
> Hi Caleb,
Hi Jonathan,

Thanks for spotting this, I completely missed it... Yeah this should be 
IIO_INFO_PROCESSED, the battery ID calculation doesn't fit in the 
raw/offset/scale format.
> 
> I took another quick read through of this and noticed that the battery channel
> is providing on IIO_INFO_RAW but there is code for IIO_INFO_PROCESSED.
> 
> Something gone wrong along the way?  If all we need is to change it to
> BIT(IIO_INFO_PROCESSED) I can do that whilst applying or you can do a v15 if
> you prefer.
That would be hugely appreciated, thanks a lot.
> 
> Thanks,
> 
> Jonathan
> 
>> ---
> 
>> diff --git a/drivers/iio/adc/qcom-spmi-rradc.c b/drivers/iio/adc/qcom-spmi-rradc.c
>> new file mode 100644
>> index 000000000000..c437546d8a4c
>> --- /dev/null
>> +++ b/drivers/iio/adc/qcom-spmi-rradc.c
> 
> 
> ..
> 
>> +
>> +/*
>> + * These functions explicitly cast int64_t to int.
>> + * They will never overflow, as the values are small enough.
> 
> See below. I don't think this gets used...
> 
>> + */
>> +static int rradc_post_process_batt_id(struct rradc_chip *chip, u16 adc_code,
>> +				      int *result_ohms)
>> +{
>> +	uint32_t current_value;
>> +	int64_t r_id;
>> +
>> +	current_value = chip->batt_id_data;
>> +	r_id = ((int64_t)adc_code * RR_ADC_FS_VOLTAGE_MV);
>> +	r_id = div64_s64(r_id, (RR_ADC_CHAN_MSB * current_value));
>> +	*result_ohms = (int)(r_id * MILLI);
>> +
>> +	return 0;
>> +}
>> +
> 
> 
>> +
>> +static int rradc_read_raw(struct iio_dev *indio_dev,
>> +			  struct iio_chan_spec const *chan_spec, int *val,
>> +			  int *val2, long mask)
>> +{
>> +	struct rradc_chip *chip = iio_priv(indio_dev);
>> +	const struct rradc_channel *chan;
>> +	int ret;
>> +	u16 adc_code;
>> +
>> +	if (chan_spec->address >= RR_ADC_CHAN_MAX) {
>> +		dev_err(chip->dev, "Invalid channel index:%lu\n",
>> +			chan_spec->address);
>> +		return -EINVAL;
>> +	}
>> +
>> +	switch (mask) {
>> +	case IIO_CHAN_INFO_SCALE:
>> +		return rradc_read_scale(chip, chan_spec->address, val, val2);
>> +	case IIO_CHAN_INFO_OFFSET:
>> +		return rradc_read_offset(chip, chan_spec->address, val);
>> +	case IIO_CHAN_INFO_RAW:
>> +		ret = rradc_do_conversion(chip, chan_spec->address, &adc_code);
>> +		if (ret < 0)
>> +			return ret;
>> +
>> +		*val = adc_code;
>> +		return IIO_VAL_INT;
>> +	case IIO_CHAN_INFO_PROCESSED:
> 
> This doesn't seem to apply to any channels....
> 
>> +		chan = &rradc_chans[chan_spec->address];
>> +		if (!chan->scale_fn)
>> +			return -EINVAL;
>> +		ret = rradc_do_conversion(chip, chan_spec->address, &adc_code);
>> +		if (ret < 0)
>> +			return ret;
>> +
>> +		*val = chan->scale_fn(chip, adc_code, val);
>> +		return IIO_VAL_INT;
>> +	default:
>> +		return -EINVAL;
>> +	}
>> +}
>> +
>> +static int rradc_read_label(struct iio_dev *indio_dev,
>> +			    struct iio_chan_spec const *chan, char *label)
>> +{
>> +	return snprintf(label, PAGE_SIZE, "%s\n",
>> +			rradc_chans[chan->address].label);
>> +}
>> +
>> +static const struct iio_info rradc_info = {
>> +	.read_raw = rradc_read_raw,
>> +	.read_label = rradc_read_label,
>> +};
>> +
>> +static const struct rradc_channel rradc_chans[RR_ADC_CHAN_MAX] = {
>> +	{
>> +		.label = "batt_id",
>> +		.scale_fn = rradc_post_process_batt_id,
>> +		.lsb = RR_ADC_BATT_ID_5_LSB,
>> +		.status = RR_ADC_BATT_ID_STS,
>> +		.size = 6,
>> +		.trigger_addr = RR_ADC_BATT_ID_TRIGGER,
>> +		.trigger_mask = BIT(0),
>> +	}, {
>> +		.label = "batt",
>> +		.lsb = RR_ADC_BATT_THERM_LSB,
>> +		.status = RR_ADC_BATT_THERM_STS,
>> +		.size = 2,
>> +		.trigger_addr = RR_ADC_BATT_THERM_TRIGGER,
>> +	}, {
>> +		.label = "pmi8998_skin",
>> +		.lsb = RR_ADC_SKIN_TEMP_LSB,
>> +		.status = RR_ADC_AUX_THERM_STS,
>> +		.size = 2,
>> +		.trigger_addr = RR_ADC_AUX_THERM_TRIGGER,
>> +	}, {
>> +		.label = "usbin_i",
>> +		.lsb = RR_ADC_USB_IN_I_LSB,
>> +		.status = RR_ADC_USB_IN_I_STS,
>> +		.size = 2,
>> +		.trigger_addr = RR_ADC_USB_IN_I_TRIGGER,
>> +	}, {
>> +		.label = "usbin_v",
>> +		.lsb = RR_ADC_USB_IN_V_LSB,
>> +		.status = RR_ADC_USB_IN_V_STS,
>> +		.size = 2,
>> +		.trigger_addr = RR_ADC_USB_IN_V_TRIGGER,
>> +		.trigger_mask = BIT(7),
>> +	}, {
>> +		.label = "dcin_i",
>> +		.lsb = RR_ADC_DC_IN_I_LSB,
>> +		.status = RR_ADC_DC_IN_I_STS,
>> +		.size = 2,
>> +		.trigger_addr = RR_ADC_DC_IN_I_TRIGGER,
>> +	}, {
>> +		.label = "dcin_v",
>> +		.lsb = RR_ADC_DC_IN_V_LSB,
>> +		.status = RR_ADC_DC_IN_V_STS,
>> +		.size = 2,
>> +		.trigger_addr = RR_ADC_DC_IN_V_TRIGGER,
>> +	}, {
>> +		.label = "pmi8998_die",
>> +		.lsb = RR_ADC_PMI_DIE_TEMP_LSB,
>> +		.status = RR_ADC_PMI_DIE_TEMP_STS,
>> +		.size = 2,
>> +		.trigger_addr = RR_ADC_PMI_DIE_TEMP_TRIGGER,
>> +		.trigger_mask = RR_ADC_TRIGGER_EVERY_CYCLE,
>> +	}, {
>> +		.label = "chg",
>> +		.lsb = RR_ADC_CHARGER_TEMP_LSB,
>> +		.status = RR_ADC_CHARGER_TEMP_STS,
>> +		.size = 2,
>> +		.trigger_addr = RR_ADC_CHARGER_TEMP_TRIGGER,
>> +	}, {
>> +		.label = "gpio",
>> +		.lsb = RR_ADC_GPIO_LSB,
>> +		.status = RR_ADC_GPIO_STS,
>> +		.size = 2,
>> +		.trigger_addr = RR_ADC_GPIO_TRIGGER,
>> +	},
>> +};
>> +
>> +static const struct iio_chan_spec rradc_iio_chans[RR_ADC_CHAN_MAX] = {
>> +	{
>> +		.type = IIO_RESISTANCE,
>> +		.info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
>> +		.address = RR_ADC_BATT_ID,
>> +		.channel = 0,
>> +		.indexed = 1,
>> +	}, {
>> +		.type = IIO_TEMP,
>> +		.info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
>> +		.address = RR_ADC_BATT_THERM,
>> +		.channel = 0,
>> +		.indexed = 1,
>> +	}, {
>> +		.type = IIO_TEMP,
>> +		.info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
>> +				      BIT(IIO_CHAN_INFO_SCALE) |
>> +				      BIT(IIO_CHAN_INFO_OFFSET),
>> +		.address = RR_ADC_SKIN_TEMP,
>> +		.channel = 1,
>> +		.indexed = 1,
>> +	}, {
>> +		.type = IIO_CURRENT,
>> +		.info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
>> +				      BIT(IIO_CHAN_INFO_SCALE),
>> +		.address = RR_ADC_USBIN_I,
>> +		.channel = 0,
>> +		.indexed = 1,
>> +	}, {
>> +		.type = IIO_VOLTAGE,
>> +		.info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
>> +				      BIT(IIO_CHAN_INFO_SCALE),
>> +		.address = RR_ADC_USBIN_V,
>> +		.channel = 0,
>> +		.indexed = 1,
>> +	}, {
>> +		.type = IIO_CURRENT,
>> +		.info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
>> +				      BIT(IIO_CHAN_INFO_SCALE),
>> +		.address = RR_ADC_DCIN_I,
>> +		.channel = 1,
>> +		.indexed = 1,
>> +	}, {
>> +		.type = IIO_VOLTAGE,
>> +		.info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
>> +				      BIT(IIO_CHAN_INFO_SCALE),
>> +		.address = RR_ADC_DCIN_V,
>> +		.channel = 1,
>> +		.indexed = 1,
>> +	}, {
>> +		.type = IIO_TEMP,
>> +		.info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
>> +				      BIT(IIO_CHAN_INFO_SCALE) |
>> +				      BIT(IIO_CHAN_INFO_OFFSET),
>> +		.address = RR_ADC_DIE_TEMP,
>> +		.channel = 2,
>> +		.indexed = 1,
>> +	}, {
>> +		.type = IIO_TEMP,
>> +		.info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
>> +				      BIT(IIO_CHAN_INFO_OFFSET) |
>> +				      BIT(IIO_CHAN_INFO_SCALE),
>> +		.address = RR_ADC_CHG_TEMP,
>> +		.channel = 3,
>> +		.indexed = 1,
>> +	}, {
>> +		.type = IIO_VOLTAGE,
>> +		.info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
>> +				      BIT(IIO_CHAN_INFO_SCALE),
>> +		.address = RR_ADC_GPIO,
>> +		.channel = 2,
>> +		.indexed = 1,
>> +	},
>> +};
>> +
>
Jonathan Cameron June 4, 2022, 4:29 p.m. UTC | #5
On Sun, 1 May 2022 18:23:23 +0100
Jonathan Cameron <jic23@kernel.org> wrote:

> On Fri, 29 Apr 2022 23:08:56 +0100
> Caleb Connolly <caleb.connolly@linaro.org> wrote:
> 
> > The helper function spmi_device_from_of() takes a device node and
> > returns the SPMI device associated with it.
> > This is like of_find_device_by_node but for SPMI devices.
> > 
> > Signed-off-by: Caleb Connolly <caleb.connolly@linaro.org>   
> 
> Stephen, are you fine with this addition to spmi?

Stephen.  This is still waiting for an SPMI ack.

Thanks,

Jonathan

> 
> Given bulk of this series in in IIO I'm planning to pick up once
> everyone is happy with it.
> 
> Thanks,
> 
> Jonathan
> 
> 
> > ---
> >  drivers/spmi/spmi.c  | 17 +++++++++++++++++
> >  include/linux/spmi.h |  3 +++
> >  2 files changed, 20 insertions(+)
> > 
> > diff --git a/drivers/spmi/spmi.c b/drivers/spmi/spmi.c
> > index b37ead9e2fad..a456ce5141e1 100644
> > --- a/drivers/spmi/spmi.c
> > +++ b/drivers/spmi/spmi.c
> > @@ -386,6 +386,23 @@ static struct bus_type spmi_bus_type = {
> >  	.uevent		= spmi_drv_uevent,
> >  };
> >  
> > +/**
> > + * spmi_device_from_of() - get the associated SPMI device from a device node
> > + *
> > + * @np:		device node
> > + *
> > + * Returns the struct spmi_device associated with a device node or NULL.
> > + */
> > +struct spmi_device *spmi_device_from_of(struct device_node *np)
> > +{
> > +	struct device *dev = bus_find_device_by_of_node(&spmi_bus_type, np);
> > +
> > +	if (dev)
> > +		return to_spmi_device(dev);
> > +	return NULL;
> > +}
> > +EXPORT_SYMBOL_GPL(spmi_device_from_of);
> > +
> >  /**
> >   * spmi_controller_alloc() - Allocate a new SPMI device
> >   * @ctrl:	associated controller
> > diff --git a/include/linux/spmi.h b/include/linux/spmi.h
> > index 729bcbf9f5ad..eac1956a8727 100644
> > --- a/include/linux/spmi.h
> > +++ b/include/linux/spmi.h
> > @@ -164,6 +164,9 @@ static inline void spmi_driver_unregister(struct spmi_driver *sdrv)
> >  	module_driver(__spmi_driver, spmi_driver_register, \
> >  			spmi_driver_unregister)
> >  
> > +struct device_node;
> > +
> > +struct spmi_device *spmi_device_from_of(struct device_node *np);
> >  int spmi_register_read(struct spmi_device *sdev, u8 addr, u8 *buf);
> >  int spmi_ext_register_read(struct spmi_device *sdev, u8 addr, u8 *buf,
> >  			   size_t len);  
>
Stephen Boyd June 14, 2022, 8:40 a.m. UTC | #6
Quoting Caleb Connolly (2022-04-29 15:08:56)
> The helper function spmi_device_from_of() takes a device node and
> returns the SPMI device associated with it.
> This is like of_find_device_by_node but for SPMI devices.
> 
> Signed-off-by: Caleb Connolly <caleb.connolly@linaro.org>
> ---

Acked-by: Stephen Boyd <sboyd@kernel.org>
Jonathan Cameron June 14, 2022, 10:42 a.m. UTC | #7
On Sun, 1 May 2022 18:28:29 +0100
Jonathan Cameron <jic23@kernel.org> wrote:

> On Fri, 29 Apr 2022 23:08:57 +0100
> Caleb Connolly <caleb.connolly@linaro.org> wrote:
> 
> > Some PMIC functions such as the RRADC need to be aware of the PMIC
> > chip revision information to implement errata or otherwise adjust
> > behaviour, export the PMIC information to enable this.
> > 
> > This is specifically required to enable the RRADC to adjust
> > coefficients based on which chip fab the PMIC was produced in,
> > this can vary per unique device and therefore has to be read at
> > runtime.
> > 
> > Signed-off-by: Caleb Connolly <caleb.connolly@linaro.org>
> > Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
> > Tested-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>  
> 
> ...
> 
> > +/**
> > + * qcom_pmic_get() - Get a pointer to the base PMIC device
> > + *
> > + * This function takes a struct device for a driver which is a child of a PMIC.
> > + * And locates the PMIC revision information for it.
> > + *
> > + * @dev: the pmic function device
> > + * @return: the struct qcom_spmi_pmic* pointer associated with the function device
> > + */
> > +inline const struct qcom_spmi_pmic *qcom_pmic_get(struct device *dev)
> > +{
> > +	struct spmi_device *sdev;
> > +	struct qcom_spmi_dev *spmi;
> > +
> > +	/*
> > +	 * Make sure the device is actually a child of a PMIC
> > +	 */
> > +	if (!of_match_device(pmic_spmi_id_table, dev->parent))
> > +		return ERR_PTR(-EINVAL);
> > +
> > +	sdev = qcom_pmic_get_base_usid(dev->parent);
> >  
> > -	if (subtype == PM8110_SUBTYPE)
> > -		minor = rev2;
> > +	if (IS_ERR(sdev))
> > +		return ERR_CAST(sdev);
> >  
> > -	dev_dbg(dev, "%x: %s v%d.%d\n", subtype, name, major, minor);
> > +	spmi = (struct qcom_spmi_dev *)dev_get_drvdata(&sdev->dev);  
> 
> Shouldn't need the cast as dev_get_drvdata() returns void * and you can
> implicitly cast that to any other pointer type.
> 
> If this is all that comes up in the series I can fixup whilst applying.
> 
> Jonathan

Hi Caleb,

Now Stephen has acked the spmi changes, only remaining ack needed
is Lee for mfd.  Given it's been a while, perhaps best bet is if you
do a v15 just wrapping up those minor tweaks and ping Lee to take a
look at it when he has time.  On off chance Lee just want's to pick it
up and push out an immutable branch (rather than me doing the same,
I'll give tags for the IIO effecting bits)

Thanks,

Jonathan

> 
> 
> > +
> > +	return &spmi->pmic;
> >  }
> > +EXPORT_SYMBOL(qcom_pmic_get);
> >    
>
Jonathan Cameron June 14, 2022, 10:44 a.m. UTC | #8
On Mon, 9 May 2022 12:53:12 +0100
Caleb Connolly <caleb.connolly@linaro.org> wrote:

> On 01/05/2022 18:38, Jonathan Cameron wrote:
> > On Fri, 29 Apr 2022 23:09:00 +0100
> > Caleb Connolly <caleb.connolly@linaro.org> wrote:
> >   
> >> The Round Robin ADC is responsible for reading data about the rate of
> >> charge from the USB or DC input ports, it can also read the battery
> >> ID (resistence), skin temperature and the die temperature of the pmic.
> >> It is found on the PMI8998 and PM660 Qualcomm PMICs.
> >>
> >> Signed-off-by: Caleb Connolly <caleb.connolly@linaro.org>  
> > Hi Caleb,  
> Hi Jonathan,
> 
> Thanks for spotting this, I completely missed it... Yeah this should be 
> IIO_INFO_PROCESSED, the battery ID calculation doesn't fit in the 
> raw/offset/scale format.
> > 
> > I took another quick read through of this and noticed that the battery channel
> > is providing on IIO_INFO_RAW but there is code for IIO_INFO_PROCESSED.
> > 
> > Something gone wrong along the way?  If all we need is to change it to
> > BIT(IIO_INFO_PROCESSED) I can do that whilst applying or you can do a v15 if
> > you prefer.  
> That would be hugely appreciated, thanks a lot.
> > 
Given other reply I just sent suggesting you do a v15 and Lee might
want to just pick up the series, with above fixed.

Reviewed-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>

Either way works as long as there is an immutable branch somewhere.

Thanks,

Jonathan

> > Thanks,
> > 
> > Jonathan
> >   
> >> ---  
> >   
> >> diff --git a/drivers/iio/adc/qcom-spmi-rradc.c b/drivers/iio/adc/qcom-spmi-rradc.c
> >> new file mode 100644
> >> index 000000000000..c437546d8a4c
> >> --- /dev/null
> >> +++ b/drivers/iio/adc/qcom-spmi-rradc.c  
> > 
> > 
> > ..
> >   
> >> +
> >> +/*
> >> + * These functions explicitly cast int64_t to int.
> >> + * They will never overflow, as the values are small enough.  
> > 
> > See below. I don't think this gets used...
> >   
> >> + */
> >> +static int rradc_post_process_batt_id(struct rradc_chip *chip, u16 adc_code,
> >> +				      int *result_ohms)
> >> +{
> >> +	uint32_t current_value;
> >> +	int64_t r_id;
> >> +
> >> +	current_value = chip->batt_id_data;
> >> +	r_id = ((int64_t)adc_code * RR_ADC_FS_VOLTAGE_MV);
> >> +	r_id = div64_s64(r_id, (RR_ADC_CHAN_MSB * current_value));
> >> +	*result_ohms = (int)(r_id * MILLI);
> >> +
> >> +	return 0;
> >> +}
> >> +  
> > 
> >   
> >> +
> >> +static int rradc_read_raw(struct iio_dev *indio_dev,
> >> +			  struct iio_chan_spec const *chan_spec, int *val,
> >> +			  int *val2, long mask)
> >> +{
> >> +	struct rradc_chip *chip = iio_priv(indio_dev);
> >> +	const struct rradc_channel *chan;
> >> +	int ret;
> >> +	u16 adc_code;
> >> +
> >> +	if (chan_spec->address >= RR_ADC_CHAN_MAX) {
> >> +		dev_err(chip->dev, "Invalid channel index:%lu\n",
> >> +			chan_spec->address);
> >> +		return -EINVAL;
> >> +	}
> >> +
> >> +	switch (mask) {
> >> +	case IIO_CHAN_INFO_SCALE:
> >> +		return rradc_read_scale(chip, chan_spec->address, val, val2);
> >> +	case IIO_CHAN_INFO_OFFSET:
> >> +		return rradc_read_offset(chip, chan_spec->address, val);
> >> +	case IIO_CHAN_INFO_RAW:
> >> +		ret = rradc_do_conversion(chip, chan_spec->address, &adc_code);
> >> +		if (ret < 0)
> >> +			return ret;
> >> +
> >> +		*val = adc_code;
> >> +		return IIO_VAL_INT;
> >> +	case IIO_CHAN_INFO_PROCESSED:  
> > 
> > This doesn't seem to apply to any channels....
> >   
> >> +		chan = &rradc_chans[chan_spec->address];
> >> +		if (!chan->scale_fn)
> >> +			return -EINVAL;
> >> +		ret = rradc_do_conversion(chip, chan_spec->address, &adc_code);
> >> +		if (ret < 0)
> >> +			return ret;
> >> +
> >> +		*val = chan->scale_fn(chip, adc_code, val);
> >> +		return IIO_VAL_INT;
> >> +	default:
> >> +		return -EINVAL;
> >> +	}
> >> +}
> >> +
> >> +static int rradc_read_label(struct iio_dev *indio_dev,
> >> +			    struct iio_chan_spec const *chan, char *label)
> >> +{
> >> +	return snprintf(label, PAGE_SIZE, "%s\n",
> >> +			rradc_chans[chan->address].label);
> >> +}
> >> +
> >> +static const struct iio_info rradc_info = {
> >> +	.read_raw = rradc_read_raw,
> >> +	.read_label = rradc_read_label,
> >> +};
> >> +
> >> +static const struct rradc_channel rradc_chans[RR_ADC_CHAN_MAX] = {
> >> +	{
> >> +		.label = "batt_id",
> >> +		.scale_fn = rradc_post_process_batt_id,
> >> +		.lsb = RR_ADC_BATT_ID_5_LSB,
> >> +		.status = RR_ADC_BATT_ID_STS,
> >> +		.size = 6,
> >> +		.trigger_addr = RR_ADC_BATT_ID_TRIGGER,
> >> +		.trigger_mask = BIT(0),
> >> +	}, {
> >> +		.label = "batt",
> >> +		.lsb = RR_ADC_BATT_THERM_LSB,
> >> +		.status = RR_ADC_BATT_THERM_STS,
> >> +		.size = 2,
> >> +		.trigger_addr = RR_ADC_BATT_THERM_TRIGGER,
> >> +	}, {
> >> +		.label = "pmi8998_skin",
> >> +		.lsb = RR_ADC_SKIN_TEMP_LSB,
> >> +		.status = RR_ADC_AUX_THERM_STS,
> >> +		.size = 2,
> >> +		.trigger_addr = RR_ADC_AUX_THERM_TRIGGER,
> >> +	}, {
> >> +		.label = "usbin_i",
> >> +		.lsb = RR_ADC_USB_IN_I_LSB,
> >> +		.status = RR_ADC_USB_IN_I_STS,
> >> +		.size = 2,
> >> +		.trigger_addr = RR_ADC_USB_IN_I_TRIGGER,
> >> +	}, {
> >> +		.label = "usbin_v",
> >> +		.lsb = RR_ADC_USB_IN_V_LSB,
> >> +		.status = RR_ADC_USB_IN_V_STS,
> >> +		.size = 2,
> >> +		.trigger_addr = RR_ADC_USB_IN_V_TRIGGER,
> >> +		.trigger_mask = BIT(7),
> >> +	}, {
> >> +		.label = "dcin_i",
> >> +		.lsb = RR_ADC_DC_IN_I_LSB,
> >> +		.status = RR_ADC_DC_IN_I_STS,
> >> +		.size = 2,
> >> +		.trigger_addr = RR_ADC_DC_IN_I_TRIGGER,
> >> +	}, {
> >> +		.label = "dcin_v",
> >> +		.lsb = RR_ADC_DC_IN_V_LSB,
> >> +		.status = RR_ADC_DC_IN_V_STS,
> >> +		.size = 2,
> >> +		.trigger_addr = RR_ADC_DC_IN_V_TRIGGER,
> >> +	}, {
> >> +		.label = "pmi8998_die",
> >> +		.lsb = RR_ADC_PMI_DIE_TEMP_LSB,
> >> +		.status = RR_ADC_PMI_DIE_TEMP_STS,
> >> +		.size = 2,
> >> +		.trigger_addr = RR_ADC_PMI_DIE_TEMP_TRIGGER,
> >> +		.trigger_mask = RR_ADC_TRIGGER_EVERY_CYCLE,
> >> +	}, {
> >> +		.label = "chg",
> >> +		.lsb = RR_ADC_CHARGER_TEMP_LSB,
> >> +		.status = RR_ADC_CHARGER_TEMP_STS,
> >> +		.size = 2,
> >> +		.trigger_addr = RR_ADC_CHARGER_TEMP_TRIGGER,
> >> +	}, {
> >> +		.label = "gpio",
> >> +		.lsb = RR_ADC_GPIO_LSB,
> >> +		.status = RR_ADC_GPIO_STS,
> >> +		.size = 2,
> >> +		.trigger_addr = RR_ADC_GPIO_TRIGGER,
> >> +	},
> >> +};
> >> +
> >> +static const struct iio_chan_spec rradc_iio_chans[RR_ADC_CHAN_MAX] = {
> >> +	{
> >> +		.type = IIO_RESISTANCE,
> >> +		.info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
> >> +		.address = RR_ADC_BATT_ID,
> >> +		.channel = 0,
> >> +		.indexed = 1,
> >> +	}, {
> >> +		.type = IIO_TEMP,
> >> +		.info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
> >> +		.address = RR_ADC_BATT_THERM,
> >> +		.channel = 0,
> >> +		.indexed = 1,
> >> +	}, {
> >> +		.type = IIO_TEMP,
> >> +		.info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
> >> +				      BIT(IIO_CHAN_INFO_SCALE) |
> >> +				      BIT(IIO_CHAN_INFO_OFFSET),
> >> +		.address = RR_ADC_SKIN_TEMP,
> >> +		.channel = 1,
> >> +		.indexed = 1,
> >> +	}, {
> >> +		.type = IIO_CURRENT,
> >> +		.info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
> >> +				      BIT(IIO_CHAN_INFO_SCALE),
> >> +		.address = RR_ADC_USBIN_I,
> >> +		.channel = 0,
> >> +		.indexed = 1,
> >> +	}, {
> >> +		.type = IIO_VOLTAGE,
> >> +		.info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
> >> +				      BIT(IIO_CHAN_INFO_SCALE),
> >> +		.address = RR_ADC_USBIN_V,
> >> +		.channel = 0,
> >> +		.indexed = 1,
> >> +	}, {
> >> +		.type = IIO_CURRENT,
> >> +		.info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
> >> +				      BIT(IIO_CHAN_INFO_SCALE),
> >> +		.address = RR_ADC_DCIN_I,
> >> +		.channel = 1,
> >> +		.indexed = 1,
> >> +	}, {
> >> +		.type = IIO_VOLTAGE,
> >> +		.info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
> >> +				      BIT(IIO_CHAN_INFO_SCALE),
> >> +		.address = RR_ADC_DCIN_V,
> >> +		.channel = 1,
> >> +		.indexed = 1,
> >> +	}, {
> >> +		.type = IIO_TEMP,
> >> +		.info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
> >> +				      BIT(IIO_CHAN_INFO_SCALE) |
> >> +				      BIT(IIO_CHAN_INFO_OFFSET),
> >> +		.address = RR_ADC_DIE_TEMP,
> >> +		.channel = 2,
> >> +		.indexed = 1,
> >> +	}, {
> >> +		.type = IIO_TEMP,
> >> +		.info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
> >> +				      BIT(IIO_CHAN_INFO_OFFSET) |
> >> +				      BIT(IIO_CHAN_INFO_SCALE),
> >> +		.address = RR_ADC_CHG_TEMP,
> >> +		.channel = 3,
> >> +		.indexed = 1,
> >> +	}, {
> >> +		.type = IIO_VOLTAGE,
> >> +		.info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
> >> +				      BIT(IIO_CHAN_INFO_SCALE),
> >> +		.address = RR_ADC_GPIO,
> >> +		.channel = 2,
> >> +		.indexed = 1,
> >> +	},
> >> +};
> >> +  
> >   
>
Lee Jones June 15, 2022, 9:40 p.m. UTC | #9
On Fri, 29 Apr 2022, Caleb Connolly wrote:

> The PMI8998 and PM660 expose the fab_id, this is needed by drivers like
> the RRADC to calibrate ADC values.
> 
> Signed-off-by: Caleb Connolly <caleb.connolly@linaro.org>
> Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
> Tested-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
> ---
>  drivers/mfd/qcom-spmi-pmic.c      | 7 +++++++
>  include/soc/qcom/qcom-spmi-pmic.h | 1 +
>  2 files changed, 8 insertions(+)

Acked-by: Lee Jones <lee.jones@linaro.org>
Lee Jones June 15, 2022, 9:41 p.m. UTC | #10
On Fri, 29 Apr 2022, Caleb Connolly wrote:

> Some PMIC functions such as the RRADC need to be aware of the PMIC
> chip revision information to implement errata or otherwise adjust
> behaviour, export the PMIC information to enable this.
> 
> This is specifically required to enable the RRADC to adjust
> coefficients based on which chip fab the PMIC was produced in,
> this can vary per unique device and therefore has to be read at
> runtime.
> 
> Signed-off-by: Caleb Connolly <caleb.connolly@linaro.org>
> Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
> Tested-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
> ---
>  drivers/mfd/qcom-spmi-pmic.c      | 265 ++++++++++++++++++++----------
>  include/soc/qcom/qcom-spmi-pmic.h |  60 +++++++
>  2 files changed, 235 insertions(+), 90 deletions(-)
>  create mode 100644 include/soc/qcom/qcom-spmi-pmic.h

Once Jonathan's comments have been resolved:

Acked-by: Lee Jones <lee.jones@linaro.org>
Jonathan Cameron June 18, 2022, 12:58 p.m. UTC | #11
On Fri, 29 Apr 2022 23:08:57 +0100
Caleb Connolly <caleb.connolly@linaro.org> wrote:

> Some PMIC functions such as the RRADC need to be aware of the PMIC
> chip revision information to implement errata or otherwise adjust
> behaviour, export the PMIC information to enable this.
> 
> This is specifically required to enable the RRADC to adjust
> coefficients based on which chip fab the PMIC was produced in,
> this can vary per unique device and therefore has to be read at
> runtime.
> 
> Signed-off-by: Caleb Connolly <caleb.connolly@linaro.org>
> Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
> Tested-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
> ---


> +/**
> + * qcom_pmic_get() - Get a pointer to the base PMIC device
> + *
> + * This function takes a struct device for a driver which is a child of a PMIC.
> + * And locates the PMIC revision information for it.
> + *
> + * @dev: the pmic function device
> + * @return: the struct qcom_spmi_pmic* pointer associated with the function device
> + */
> +inline const struct qcom_spmi_pmic *qcom_pmic_get(struct device *dev)
Missed this in review, but build test of the rradc patch threw it up.
this should defintely not be inline as it's exported.
Same for the header definition.

I'm doing a quick test to see if I can apply this series with relevant
tweaks. Will get rid of this inline as well.

Thanks,

Jonathan

> +{
> +	struct spmi_device *sdev;
> +	struct qcom_spmi_dev *spmi;
> +
> +	/*
> +	 * Make sure the device is actually a child of a PMIC
> +	 */
> +	if (!of_match_device(pmic_spmi_id_table, dev->parent))
> +		return ERR_PTR(-EINVAL);
> +
> +	sdev = qcom_pmic_get_base_usid(dev->parent);
>  
> -	if (subtype == PM8110_SUBTYPE)
> -		minor = rev2;
> +	if (IS_ERR(sdev))
> +		return ERR_CAST(sdev);
>  
> -	dev_dbg(dev, "%x: %s v%d.%d\n", subtype, name, major, minor);
> +	spmi = (struct qcom_spmi_dev *)dev_get_drvdata(&sdev->dev);
> +
> +	return &spmi->pmic;
>  }
> +EXPORT_SYMBOL(qcom_pmic_get);
Jonathan Cameron June 18, 2022, 1:09 p.m. UTC | #12
On Fri, 29 Apr 2022 23:08:55 +0100
Caleb Connolly <caleb.connolly@linaro.org> wrote:

> The RRADC is responsible for reading data about the current and
> voltage from the USB or DC in jacks, it can also read the battery
> ID (resistence) and some temperatures. It is found on the PMI8998 and
> PM660 Qualcomm PMICs.
> 
> The RRADC has to calibrate some ADC values based on which chip fab
> the PMIC was produced in, to facilitate this the patches
> ("mfd: qcom-spmi-pmic: expose the PMIC revid information to clients")
> and ("mfd: qcom-spmi-pmic: read fab id on supported PMICs")
> expose the PMIC revision information and fab_id as a struct and register
> them as driver data in the Qualcomm SPMI PMIC driver so that it can be
> read by the RRADC.
> 
> The first 3 patches add support for looking up an SPMI device from a
> struct device_node, as well as introducing support for looking up the
> base USID of a Qcom PMIC, see patch comments for more details. These
> Address Bjorns comments on v2.

Hi Caleb / All

Rather than waste time going for a v15 for the 3 minor issues in reviews
I've just fixed them up whilst applying.

As spmi or mfd maintainers may want an immutable branch I've
just pushed one out at
https://git.kernel.org/pub/scm/linux/kernel/git/jic23/iio.git immutable-qcom-spmi-rradc
that has the first 5 patches. I assume the dts changes will go via qcom -> arm-soc
as normal.

0-day should run on that branch shortly but I'll be optimistic and pull it
into my testing branch in the meantime (mostly so I don't forget about it and
can mark it applied in patchwork :)

Thanks,

Jonathan


> 
> Changes since v13:
>  * Address Lee Jones' feedback on the SPMI patches.
>  * Pick up Jami's patch to enable the RRADC on the OnePlus 5
> 
> Changes since v12:
>  * Apply Krzysztof's suggestions to rradc DT binding docs.
> 
> Changes since v11:
>  * Remove debug logging which was left in ("mfd: qcom-spmi-pmic: expose the PMIC revid information to clients")
>  * Picked up Dmitry's Tested-by and Reviewed-by tags.
> 
> Changes since v10:
>  * Don't inline spmi_device_from_of()
> 
> Changes since v9:
>  * Add back missing copyright, this driver is originally derived from
>    downstream (Thanks Manivannan).
> 
> Changes since v8:
>  * Drop Reported-by for the bugfix on previous revision reported by LKP
>  * Apply Jonathans suggestions
>  * Rework patch 2 ("expose the PMIC revid information to clients") to
>    handle PMICs with a single USID (thanks Dmitry)
> 
> Changes since v7:
>  * Addressed Jonathans comments
>  * Fixed bug reported by LKP
> 
> Changes since v6:
>  * Fix printf format warning in rradc
> 
> Changes since v5:
>  * Add missing EXPORT_SYMBOL_GPL() to
>    ("spmi: add a helper to look up an SPMI device from a device node")
> 
> Changes since v4:
>  * Addressed Jonathan's comments on v4
>  * Reworked the qcom-spmi-pmic patches to properly walk the devicetree
>    to find the base USID. I've tested this on SDM845 which has two PMICs
>    (pm8998 and pmi8998) and I'm able to look up the PMIC revid from all
>    4 USIDs.
> 
> Changes since v3:
>  * Split PMIC patch in two, rework to support function drivers on a
>    sibling USID
>  * Completely rework RRADC driver to make use of the modern IIO
>    framework. This required re-arranging a lot of the equations and
>    results in some lost precision, where relevant I've left comments to
>    explain this. I don't think any of it is significant enough to
>    justify doing post-processing in driver.
>    Thanks a lot Jonathan and John Stultz for helping me out with
>    this
> 
> Changes since v2:
>  * Add missing include (thanks kernel test robot :D)
>  * Rework some confusing function return values, specifically
>    rradc_read_status_in_cont_mode and rradc_prepare_batt_id_conversion
>    both of which didn't correctly handle "ret". This also bought up an
>    issue as the previous implementation didn't actually wait for the
>    channel to be ready. It doesn't seem like that's strictly necessary
>    (same data is reported if I wait for the status to be good or not)
>    but I've included it anyway for good measure.
> 
> Changes since v1:
>  * Rework the RRADC driver based on Jonathan's feedback
>  * Pick up Rob's reviewed by for the dt-binding patch.
>  ---
> Caleb Connolly (9):
>   spmi: add a helper to look up an SPMI device from a device node
>   mfd: qcom-spmi-pmic: expose the PMIC revid information to clients
>   mfd: qcom-spmi-pmic: read fab id on supported PMICs
>   dt-bindings: iio: adc: document qcom-spmi-rradc
>   iio: adc: qcom-spmi-rradc: introduce round robin adc
>   arm64: dts: qcom: pmi8998: add rradc node
>   arm64: dts: qcom: sdm845-oneplus: enable rradc
>   arm64: dts: qcom: sdm845-db845c: enable rradc
>   arm64: dts: qcom: sdm845-xiaomi-beryllium: enable rradc
> 
> Jami Kettunen (1):
>   arm64: dts: qcom: msm8998-oneplus-common: enable RRADC
> 
>  .../bindings/iio/adc/qcom,spmi-rradc.yaml     |   51 +
>  .../boot/dts/qcom/msm8998-oneplus-common.dtsi |    4 +
>  arch/arm64/boot/dts/qcom/pmi8998.dtsi         |    8 +
>  arch/arm64/boot/dts/qcom/sdm845-db845c.dts    |    4 +
>  .../boot/dts/qcom/sdm845-oneplus-common.dtsi  |    4 +
>  .../boot/dts/qcom/sdm845-xiaomi-beryllium.dts |    4 +
>  drivers/iio/adc/Kconfig                       |   12 +
>  drivers/iio/adc/Makefile                      |    1 +
>  drivers/iio/adc/qcom-spmi-rradc.c             | 1021 +++++++++++++++++
>  drivers/mfd/qcom-spmi-pmic.c                  |  272 +++--
>  drivers/spmi/spmi.c                           |   17 +
>  include/linux/spmi.h                          |    3 +
>  include/soc/qcom/qcom-spmi-pmic.h             |   61 +
>  13 files changed, 1372 insertions(+), 90 deletions(-)
>  create mode 100644 Documentation/devicetree/bindings/iio/adc/qcom,spmi-rradc.yaml
>  create mode 100644 drivers/iio/adc/qcom-spmi-rradc.c
>  create mode 100644 include/soc/qcom/qcom-spmi-pmic.h
>
Jonathan Cameron June 18, 2022, 1:17 p.m. UTC | #13
On Sat, 18 Jun 2022 14:09:13 +0100
Jonathan Cameron <jic23@kernel.org> wrote:

> On Fri, 29 Apr 2022 23:08:55 +0100
> Caleb Connolly <caleb.connolly@linaro.org> wrote:
> 
> > The RRADC is responsible for reading data about the current and
> > voltage from the USB or DC in jacks, it can also read the battery
> > ID (resistence) and some temperatures. It is found on the PMI8998 and
> > PM660 Qualcomm PMICs.
> > 
> > The RRADC has to calibrate some ADC values based on which chip fab
> > the PMIC was produced in, to facilitate this the patches
> > ("mfd: qcom-spmi-pmic: expose the PMIC revid information to clients")
> > and ("mfd: qcom-spmi-pmic: read fab id on supported PMICs")
> > expose the PMIC revision information and fab_id as a struct and register
> > them as driver data in the Qualcomm SPMI PMIC driver so that it can be
> > read by the RRADC.
> > 
> > The first 3 patches add support for looking up an SPMI device from a
> > struct device_node, as well as introducing support for looking up the
> > base USID of a Qcom PMIC, see patch comments for more details. These
> > Address Bjorns comments on v2.  
> 
> Hi Caleb / All
> 
> Rather than waste time going for a v15 for the 3 minor issues in reviews
> I've just fixed them up whilst applying.
> 
> As spmi or mfd maintainers may want an immutable branch I've
> just pushed one out at
> https://git.kernel.org/pub/scm/linux/kernel/git/jic23/iio.git immutable-qcom-spmi-rradc
> that has the first 5 patches. I assume the dts changes will go via qcom -> arm-soc
> as normal.
> 
> 0-day should run on that branch shortly but I'll be optimistic and pull it
> into my testing branch in the meantime (mostly so I don't forget about it and
> can mark it applied in patchwork :)

Gah.  Merge into IIO doesn't build because of dropping of.h from includes
in iio.h.  This driver should directly include property.h directly.

New 'immutable' branch with same name pushed out.  Guessing no one picked
it up in the minute or so previous version was available for!

I'd advise that Lee / Stephen don't merge this for a few days at least so
any other issues have become visible and I can fix them up without making
for complex history.

Thanks,

Jonathan

> 
> Thanks,
> 
> Jonathan
> 
> 
> > 
> > Changes since v13:
> >  * Address Lee Jones' feedback on the SPMI patches.
> >  * Pick up Jami's patch to enable the RRADC on the OnePlus 5
> > 
> > Changes since v12:
> >  * Apply Krzysztof's suggestions to rradc DT binding docs.
> > 
> > Changes since v11:
> >  * Remove debug logging which was left in ("mfd: qcom-spmi-pmic: expose the PMIC revid information to clients")
> >  * Picked up Dmitry's Tested-by and Reviewed-by tags.
> > 
> > Changes since v10:
> >  * Don't inline spmi_device_from_of()
> > 
> > Changes since v9:
> >  * Add back missing copyright, this driver is originally derived from
> >    downstream (Thanks Manivannan).
> > 
> > Changes since v8:
> >  * Drop Reported-by for the bugfix on previous revision reported by LKP
> >  * Apply Jonathans suggestions
> >  * Rework patch 2 ("expose the PMIC revid information to clients") to
> >    handle PMICs with a single USID (thanks Dmitry)
> > 
> > Changes since v7:
> >  * Addressed Jonathans comments
> >  * Fixed bug reported by LKP
> > 
> > Changes since v6:
> >  * Fix printf format warning in rradc
> > 
> > Changes since v5:
> >  * Add missing EXPORT_SYMBOL_GPL() to
> >    ("spmi: add a helper to look up an SPMI device from a device node")
> > 
> > Changes since v4:
> >  * Addressed Jonathan's comments on v4
> >  * Reworked the qcom-spmi-pmic patches to properly walk the devicetree
> >    to find the base USID. I've tested this on SDM845 which has two PMICs
> >    (pm8998 and pmi8998) and I'm able to look up the PMIC revid from all
> >    4 USIDs.
> > 
> > Changes since v3:
> >  * Split PMIC patch in two, rework to support function drivers on a
> >    sibling USID
> >  * Completely rework RRADC driver to make use of the modern IIO
> >    framework. This required re-arranging a lot of the equations and
> >    results in some lost precision, where relevant I've left comments to
> >    explain this. I don't think any of it is significant enough to
> >    justify doing post-processing in driver.
> >    Thanks a lot Jonathan and John Stultz for helping me out with
> >    this
> > 
> > Changes since v2:
> >  * Add missing include (thanks kernel test robot :D)
> >  * Rework some confusing function return values, specifically
> >    rradc_read_status_in_cont_mode and rradc_prepare_batt_id_conversion
> >    both of which didn't correctly handle "ret". This also bought up an
> >    issue as the previous implementation didn't actually wait for the
> >    channel to be ready. It doesn't seem like that's strictly necessary
> >    (same data is reported if I wait for the status to be good or not)
> >    but I've included it anyway for good measure.
> > 
> > Changes since v1:
> >  * Rework the RRADC driver based on Jonathan's feedback
> >  * Pick up Rob's reviewed by for the dt-binding patch.
> >  ---
> > Caleb Connolly (9):
> >   spmi: add a helper to look up an SPMI device from a device node
> >   mfd: qcom-spmi-pmic: expose the PMIC revid information to clients
> >   mfd: qcom-spmi-pmic: read fab id on supported PMICs
> >   dt-bindings: iio: adc: document qcom-spmi-rradc
> >   iio: adc: qcom-spmi-rradc: introduce round robin adc
> >   arm64: dts: qcom: pmi8998: add rradc node
> >   arm64: dts: qcom: sdm845-oneplus: enable rradc
> >   arm64: dts: qcom: sdm845-db845c: enable rradc
> >   arm64: dts: qcom: sdm845-xiaomi-beryllium: enable rradc
> > 
> > Jami Kettunen (1):
> >   arm64: dts: qcom: msm8998-oneplus-common: enable RRADC
> > 
> >  .../bindings/iio/adc/qcom,spmi-rradc.yaml     |   51 +
> >  .../boot/dts/qcom/msm8998-oneplus-common.dtsi |    4 +
> >  arch/arm64/boot/dts/qcom/pmi8998.dtsi         |    8 +
> >  arch/arm64/boot/dts/qcom/sdm845-db845c.dts    |    4 +
> >  .../boot/dts/qcom/sdm845-oneplus-common.dtsi  |    4 +
> >  .../boot/dts/qcom/sdm845-xiaomi-beryllium.dts |    4 +
> >  drivers/iio/adc/Kconfig                       |   12 +
> >  drivers/iio/adc/Makefile                      |    1 +
> >  drivers/iio/adc/qcom-spmi-rradc.c             | 1021 +++++++++++++++++
> >  drivers/mfd/qcom-spmi-pmic.c                  |  272 +++--
> >  drivers/spmi/spmi.c                           |   17 +
> >  include/linux/spmi.h                          |    3 +
> >  include/soc/qcom/qcom-spmi-pmic.h             |   61 +
> >  13 files changed, 1372 insertions(+), 90 deletions(-)
> >  create mode 100644 Documentation/devicetree/bindings/iio/adc/qcom,spmi-rradc.yaml
> >  create mode 100644 drivers/iio/adc/qcom-spmi-rradc.c
> >  create mode 100644 include/soc/qcom/qcom-spmi-pmic.h
> >   
>
Caleb Connolly June 18, 2022, 4:13 p.m. UTC | #14
On 18/06/2022 14:17, Jonathan Cameron wrote:
> On Sat, 18 Jun 2022 14:09:13 +0100
> Jonathan Cameron <jic23@kernel.org> wrote:
> 
>> On Fri, 29 Apr 2022 23:08:55 +0100
>> Caleb Connolly <caleb.connolly@linaro.org> wrote:
>>
>>> The RRADC is responsible for reading data about the current and
>>> voltage from the USB or DC in jacks, it can also read the battery
>>> ID (resistence) and some temperatures. It is found on the PMI8998 and
>>> PM660 Qualcomm PMICs.
>>>
>>> The RRADC has to calibrate some ADC values based on which chip fab
>>> the PMIC was produced in, to facilitate this the patches
>>> ("mfd: qcom-spmi-pmic: expose the PMIC revid information to clients")
>>> and ("mfd: qcom-spmi-pmic: read fab id on supported PMICs")
>>> expose the PMIC revision information and fab_id as a struct and register
>>> them as driver data in the Qualcomm SPMI PMIC driver so that it can be
>>> read by the RRADC.
>>>
>>> The first 3 patches add support for looking up an SPMI device from a
>>> struct device_node, as well as introducing support for looking up the
>>> base USID of a Qcom PMIC, see patch comments for more details. These
>>> Address Bjorns comments on v2.
>>
>> Hi Caleb / All
>>
>> Rather than waste time going for a v15 for the 3 minor issues in reviews
>> I've just fixed them up whilst applying.
>>
>> As spmi or mfd maintainers may want an immutable branch I've
>> just pushed one out at
>> https://git.kernel.org/pub/scm/linux/kernel/git/jic23/iio.git immutable-qcom-spmi-rradc
>> that has the first 5 patches. I assume the dts changes will go via qcom -> arm-soc
>> as normal.
>>
>> 0-day should run on that branch shortly but I'll be optimistic and pull it
>> into my testing branch in the meantime (mostly so I don't forget about it and
>> can mark it applied in patchwork :)
> 
> Gah.  Merge into IIO doesn't build because of dropping of.h from includes
> in iio.h.  This driver should directly include property.h directly.
> 
> New 'immutable' branch with same name pushed out.  Guessing no one picked
> it up in the minute or so previous version was available for!
> 
> I'd advise that Lee / Stephen don't merge this for a few days at least so
> any other issues have become visible and I can fix them up without making
> for complex history.
Hi Jonathan,

Thanks so much for picking this up and fixing those last few issues. And 
thanks for all your help with this series, I really appreciate the time 
you've taken to help me get this to a mergeable state and teach me about 
IIO.

You've really made my week with this :)

Kind Regards,
Caleb
> 
> Thanks,
> 
> Jonathan
> 
>>
>> Thanks,
>>
>> Jonathan
>>
>>
>>>
>>> Changes since v13:
>>>   * Address Lee Jones' feedback on the SPMI patches.
>>>   * Pick up Jami's patch to enable the RRADC on the OnePlus 5
>>>
>>> Changes since v12:
>>>   * Apply Krzysztof's suggestions to rradc DT binding docs.
>>>
>>> Changes since v11:
>>>   * Remove debug logging which was left in ("mfd: qcom-spmi-pmic: expose the PMIC revid information to clients")
>>>   * Picked up Dmitry's Tested-by and Reviewed-by tags.
>>>
>>> Changes since v10:
>>>   * Don't inline spmi_device_from_of()
>>>
>>> Changes since v9:
>>>   * Add back missing copyright, this driver is originally derived from
>>>     downstream (Thanks Manivannan).
>>>
>>> Changes since v8:
>>>   * Drop Reported-by for the bugfix on previous revision reported by LKP
>>>   * Apply Jonathans suggestions
>>>   * Rework patch 2 ("expose the PMIC revid information to clients") to
>>>     handle PMICs with a single USID (thanks Dmitry)
>>>
>>> Changes since v7:
>>>   * Addressed Jonathans comments
>>>   * Fixed bug reported by LKP
>>>
>>> Changes since v6:
>>>   * Fix printf format warning in rradc
>>>
>>> Changes since v5:
>>>   * Add missing EXPORT_SYMBOL_GPL() to
>>>     ("spmi: add a helper to look up an SPMI device from a device node")
>>>
>>> Changes since v4:
>>>   * Addressed Jonathan's comments on v4
>>>   * Reworked the qcom-spmi-pmic patches to properly walk the devicetree
>>>     to find the base USID. I've tested this on SDM845 which has two PMICs
>>>     (pm8998 and pmi8998) and I'm able to look up the PMIC revid from all
>>>     4 USIDs.
>>>
>>> Changes since v3:
>>>   * Split PMIC patch in two, rework to support function drivers on a
>>>     sibling USID
>>>   * Completely rework RRADC driver to make use of the modern IIO
>>>     framework. This required re-arranging a lot of the equations and
>>>     results in some lost precision, where relevant I've left comments to
>>>     explain this. I don't think any of it is significant enough to
>>>     justify doing post-processing in driver.
>>>     Thanks a lot Jonathan and John Stultz for helping me out with
>>>     this
>>>
>>> Changes since v2:
>>>   * Add missing include (thanks kernel test robot :D)
>>>   * Rework some confusing function return values, specifically
>>>     rradc_read_status_in_cont_mode and rradc_prepare_batt_id_conversion
>>>     both of which didn't correctly handle "ret". This also bought up an
>>>     issue as the previous implementation didn't actually wait for the
>>>     channel to be ready. It doesn't seem like that's strictly necessary
>>>     (same data is reported if I wait for the status to be good or not)
>>>     but I've included it anyway for good measure.
>>>
>>> Changes since v1:
>>>   * Rework the RRADC driver based on Jonathan's feedback
>>>   * Pick up Rob's reviewed by for the dt-binding patch.
>>>   ---
>>> Caleb Connolly (9):
>>>    spmi: add a helper to look up an SPMI device from a device node
>>>    mfd: qcom-spmi-pmic: expose the PMIC revid information to clients
>>>    mfd: qcom-spmi-pmic: read fab id on supported PMICs
>>>    dt-bindings: iio: adc: document qcom-spmi-rradc
>>>    iio: adc: qcom-spmi-rradc: introduce round robin adc
>>>    arm64: dts: qcom: pmi8998: add rradc node
>>>    arm64: dts: qcom: sdm845-oneplus: enable rradc
>>>    arm64: dts: qcom: sdm845-db845c: enable rradc
>>>    arm64: dts: qcom: sdm845-xiaomi-beryllium: enable rradc
>>>
>>> Jami Kettunen (1):
>>>    arm64: dts: qcom: msm8998-oneplus-common: enable RRADC
>>>
>>>   .../bindings/iio/adc/qcom,spmi-rradc.yaml     |   51 +
>>>   .../boot/dts/qcom/msm8998-oneplus-common.dtsi |    4 +
>>>   arch/arm64/boot/dts/qcom/pmi8998.dtsi         |    8 +
>>>   arch/arm64/boot/dts/qcom/sdm845-db845c.dts    |    4 +
>>>   .../boot/dts/qcom/sdm845-oneplus-common.dtsi  |    4 +
>>>   .../boot/dts/qcom/sdm845-xiaomi-beryllium.dts |    4 +
>>>   drivers/iio/adc/Kconfig                       |   12 +
>>>   drivers/iio/adc/Makefile                      |    1 +
>>>   drivers/iio/adc/qcom-spmi-rradc.c             | 1021 +++++++++++++++++
>>>   drivers/mfd/qcom-spmi-pmic.c                  |  272 +++--
>>>   drivers/spmi/spmi.c                           |   17 +
>>>   include/linux/spmi.h                          |    3 +
>>>   include/soc/qcom/qcom-spmi-pmic.h             |   61 +
>>>   13 files changed, 1372 insertions(+), 90 deletions(-)
>>>   create mode 100644 Documentation/devicetree/bindings/iio/adc/qcom,spmi-rradc.yaml
>>>   create mode 100644 drivers/iio/adc/qcom-spmi-rradc.c
>>>   create mode 100644 include/soc/qcom/qcom-spmi-pmic.h
>>>    
>>
>