linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Jonathan Cameron <Jonathan.Cameron@Huawei.com>
To: Caleb Connolly <caleb.connolly@linaro.org>
Cc: Jonathan Cameron <jic23@jic23.retrosnub.co.uk>,
	Lars-Peter Clausen <lars@metafoo.de>,
	Rob Herring <robh+dt@kernel.org>, Andy Gross <agross@kernel.org>,
	Bjorn Andersson <bjorn.andersson@linaro.org>,
	"Lee Jones" <lee.jones@linaro.org>, <linux-iio@vger.kernel.org>,
	<devicetree@vger.kernel.org>, <linux-kernel@vger.kernel.org>,
	<linux-arm-msm@vger.kernel.org>, <sumit.semwal@linaro.org>,
	<amit.pundir@linaro.org>, <john.stultz@linaro.org>
Subject: Re: [PATCH v3 3/7] iio: adc: qcom-spmi-rradc: introduce round robin adc
Date: Fri, 21 Jan 2022 13:45:31 +0000	[thread overview]
Message-ID: <20220121134531.00006a7b@Huawei.com> (raw)
In-Reply-To: <d0d42804-f437-e964-1c0d-4eb65e76db6c@linaro.org>

On Wed, 19 Jan 2022 17:42:51 +0000
Caleb Connolly <caleb.connolly@linaro.org> wrote:

> On 09/01/2022 17:29, Jonathan Cameron wrote:
> > On Thu,  6 Jan 2022 17:31:27 +0000
> > 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 in jacks, it can also read the battery
> >> ID (resistence) and some temperatures. It is found on the PMI8998 and
> >> PM660 Qualcomm PMICs.
> >>
> >> Signed-off-by: Caleb Connolly <caleb.connolly@linaro.org>  
> > Hi Calib,  
> Hi Jonathan,
> 
> I've spent some time on this and mostly reworked things, thanks a lot for
> your feedback, it's been quite interesting to learn about IIO. :)
> 
> Quite a few of the channels fit well into the (adc_code + offset) * scale format,
> however the one you commented on "rradc_post_process_chg_temp()" doesn't seem to
> fit, it requires multiple steps of applying offsets and scale and I haven't been
> able to re-arrange it to work sensibly.

I had a go below. Not trivial but may still be worth doing.  It seems to be linear
though the maths is a bit nasty!  This depends on that fab_coeff() returning
a constant value for a particular part which I haven't checked.

> 
> I noticed the calibbias properties which seems like something I should expose
> for "rradc_get_fab_coeff()"?
calibbias is usually an internal tweak factor that in hardware corrects for
inaccuracies - something like a DAC tweaking something in the analog front end.

Here it doesn't feel like it's useful to expose a software tweak to userspace
as it would have no idea what to do with it.

> 
> Could you point me in the right direction here? For reference my WIP tree can be
> found here: https://github.com/aospm/linux/commits/upstreaming/spmi-rradc
> 
> I also tried switching to labels, but I found that when I drop the extend_name
> property the driver fails to probe because multiple channels end up with the same
> name in sysfs (e.g. "in_temp_raw"). I've read through the docs and looked at a few
> other drivers but I wasn't able to find out what I'm missing for this to work.

Set channel and indexed for the channel. You should have in_temp0_raw, in_temp1_raw etc
Extend name was never meant to replace the index as it isn't visible in things
like event codes if you ever need to implement that stuff.  So they should all
have and unique index values anyway.

> 
> I've snipped to the relevant bits below.
> 
> Kind regards,
> Caleb
> > 
> > Various things inline but biggest is probably that in IIO we prefer
> > if possible to make application of offsets and scales a job for the caller,
> > either userspace or in kernel callers. This allows them to maintain precision
> > better if they need to further transform the data.
> > 
> > Jonathan
> >   
> >> ---
> >>   drivers/iio/adc/Kconfig           |   13 +
> >>   drivers/iio/adc/Makefile          |    1 +
> >>   drivers/iio/adc/qcom-spmi-rradc.c | 1070 +++++++++++++++++++++++++++++
> >>   3 files changed, 1084 insertions(+)
> >>   create mode 100644 drivers/iio/adc/qcom-spmi-rradc.c
> >>  
> 
> [snip]
> 
> >> +static int rradc_post_process_chg_temp(struct rradc_chip *chip, u16 adc_code,
> >> +				       int *result_millidegc)
> >> +{
> >> +	int64_t uv, offset, slope;
> >> +	int ret;
> >> +
> >> +	ret = rradc_get_fab_coeff(chip, &offset, &slope);
> >> +	if (ret < 0) {
> >> +		dev_err(chip->dev, "Unable to get fab id coefficients\n");
> >> +		return -EINVAL;
> >> +	}
> >> +
> >> +	uv = ((int64_t)adc_code * RR_ADC_TEMP_FS_VOLTAGE_NUM);
> >> +	uv = div64_s64(uv,
> >> +		       (RR_ADC_TEMP_FS_VOLTAGE_DEN * RR_ADC_CHAN_MAX_VALUE));
> >> +	uv = offset - uv;
> >> +	uv = div64_s64((uv * MILLI), slope);
> >> +	uv += RR_ADC_CHG_TEMP_OFFSET_MILLI_DEGC;
> >> +	*result_millidegc = (int)uv;  
> > 
> > Marginally harder than the one below, but this is still looking like it can
> > be well expressed as an offset + scale.  Thus making the tedious maths
> > userspaces or callers problem.  I'm working backwards hence won't comment on
> > similar before this point. Key is to transform whatever maths you have into
> > 
> > (adc_code + offset) * scale then expose offset and scale as well as the
> > raw value.  The right maths will get done for in kernel users and
> > userspace can do it nicely with floating point.

So I think this is: 

([fab_offset - (adc_code * FS_N )/ (FS_DEN * MAX_VAL)] * MILI / fab_slope + offset

Let A= FS_N/(FS_N * MAX_VAL)
    B = MILLI/fab_slope

= (fab_ofset - adc_code * A)*B + offset
= [((fab_offset / A - adc_code)*A + (offset / B)] * B
= [fab_offset/A - adc_code + offset / AB] * AB
= [adc_code - fab_offset/A - offset/AB]* -AB
= (a + offset) * scale)

where a is the adc_code,
offset = - fab_offset * FS_N * MAX_VAL/ FS_N - offset * FS_N * MAX_VAL * fab_slow / (MILLI  * FS_N)
scale = (FS_N * MILLI) / (FS_N * MAX_VAL * FAB_SLOPE)

So I think it can can done.  Quest then becomes whether sufficient precision can be
maintained for it to make sense to do the fixed point maths in the kernel to establish
those two coefficients and push it out to userspace as a constant that can then be
applied to the channel.

Note this assume that rradc_get_fab_coeff() returns a fixed value for a given device.

> >   
> >> +
> >> +	return 0;
> >> +}  
> 
> [snip]
> 
> >> +static const struct iio_chan_spec rradc_iio_chans[RR_ADC_CHAN_MAX] = {
> >> +	{
> >> +		.extend_name = "batt_id",  
> > 
> > We recently introduced channel labels to try and avoid the need for
> > extend_name.  The problem with extend_name is that generic software then
> > has trouble parsing the resulting sysfs files as they can have very
> > freeform naming.  Moving it to label makes that much easier.  Note that
> > there is code to give a default label of extend_name to work around
> > this problem for older drivers.
> >   
> >> +		.type = IIO_RESISTANCE,
> >> +		.info_mask_separate = BIT(IIO_CHAN_INFO_PROCESSED),
> >> +		.address = RR_ADC_BATT_ID,
> >> +	},  
> 
> > 
> > Thanks,
> > 
> > Jonathan  
> 


  reply	other threads:[~2022-01-21 13:45 UTC|newest]

Thread overview: 15+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-01-06 17:31 [PATCH v3 0/7] iio: adc: introduce Qualcomm SPMI Round Robin ADC Caleb Connolly
2022-01-06 17:31 ` [PATCH v3 1/7] mfd: qcom-spmi-pmic: expose the PMIC revid information to clients Caleb Connolly
2022-01-09 16:57   ` Jonathan Cameron
2022-01-10 11:46     ` Caleb Connolly
2022-01-15 13:06       ` Jonathan Cameron
2022-01-10 18:41   ` Bjorn Andersson
2022-01-06 17:31 ` [PATCH v3 2/7] dt-bindings: iio: adc: document qcom-spmi-rradc Caleb Connolly
2022-01-06 17:31 ` [PATCH v3 3/7] iio: adc: qcom-spmi-rradc: introduce round robin adc Caleb Connolly
2022-01-09 17:29   ` Jonathan Cameron
2022-01-19 17:42     ` Caleb Connolly
2022-01-21 13:45       ` Jonathan Cameron [this message]
2022-01-06 17:31 ` [PATCH v3 4/7] arm64: dts: qcom: pmi8998: add rradc node Caleb Connolly
2022-01-06 17:31 ` [PATCH v3 5/7] arm64: dts: qcom: sdm845-oneplus: enable rradc Caleb Connolly
2022-01-06 17:31 ` [PATCH v3 6/7] arm64: dts: qcom: sdm845-db845c: " Caleb Connolly
2022-01-06 17:31 ` [PATCH v3 7/7] arm64: dts: qcom: sdm845-xiaomi-beryllium: enable RRADC Caleb Connolly

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20220121134531.00006a7b@Huawei.com \
    --to=jonathan.cameron@huawei.com \
    --cc=agross@kernel.org \
    --cc=amit.pundir@linaro.org \
    --cc=bjorn.andersson@linaro.org \
    --cc=caleb.connolly@linaro.org \
    --cc=devicetree@vger.kernel.org \
    --cc=jic23@jic23.retrosnub.co.uk \
    --cc=john.stultz@linaro.org \
    --cc=lars@metafoo.de \
    --cc=lee.jones@linaro.org \
    --cc=linux-arm-msm@vger.kernel.org \
    --cc=linux-iio@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=robh+dt@kernel.org \
    --cc=sumit.semwal@linaro.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).