From: Jonathan Cameron <jic23@kernel.org>
To: Hartmut Knaack <knaack.h@gmx.de>, Vlad Dogaru <vlad.dogaru@intel.com>
Cc: IIO <linux-iio@vger.kernel.org>
Subject: Re: [PATCH 3/3]iio:pressure:bmp280: read compensation data only at init
Date: Sat, 15 Nov 2014 16:06:37 +0000 [thread overview]
Message-ID: <54677A0D.2090604@kernel.org> (raw)
In-Reply-To: <5461462F.5040500@gmx.de>
On 10/11/14 23:11, Hartmut Knaack wrote:
> Vlad Dogaru schrieb am 06.11.2014 14:02:
>> On Wed, Nov 05, 2014 at 03:53:20PM +0000, Jonathan Cameron wrote:
>>> On 31/10/14 19:16, Hartmut Knaack wrote:
>>>> Vlad Dogaru schrieb am 31.10.2014 12:47:
>>>>> On Fri, Oct 31, 2014 at 02:25:22AM +0100, Hartmut Knaack wrote:
>>>>>> Compensation data is hard coded into the sensors, so it is sufficient to just
>>>>>> read it once during device initialization. Therefor struct bmp280_comp should be
>>>>>> part of bmp280_data (since the elements of bmp280_comp_temp and
>>>>>> bmp280_comp_press have distinct names, they could be merged into bmp280_comp).
>>>>>
>>>>> My first version of the patch did this, but Jonathan suggested [1] that,
>>>>> since we're using regmap, we can rely on it for caching the calibration
>>>>> parameters. I have no preference for either approach.
>>>>>
>>>> Indeed, I missed to have a closer look at that version, as I discarded it when your second or third version came out.
>>>> So, one question remaining is, if your implementation was, what Jonathan had in mind when he gave the hint about using the regmap cache. I mainly see the disadvantage of copying to the buffer and from there to the variables (and depending on endianness even a conversion) for every single measurement.
>>> Gah. Now I have to remember what I was thinking!
>>>
>>> Anyhow, I just didn't much like the double cache of these values.
>>> The little endian conversions are pretty trivial...
>>> The code only ended up a little involved because of the
>>> structures to pass this data around. Why not just have an enum saying what
>>> data is where and pass the buffer. Then do the little endian on demand and
>>> let the compiler filter out the repeats?
>>>
>>> So combine bmp280_read_compensation_press and bmp280_compensate_press
>>> to something like...
>>> enum {
>>> P1,
>>> P2,
>>> P3,
>>> P4,
>>> P5,
>>> P6,
>>> P7,
>>> P8,
>>> P9
>>> }; // a rare occasion where maybe all on one line would be good ;)
>>>
>>> int bmp280_compensate_press(struct bmp280_data *data)
>>> {
>>> __le16 buf[BMP280_COMP_PRESS_REG_COUNT / 2];
>>> s64 var1, var2, p;
>>>
>>> ret = regmap_bulk_read(data->regmap, BMP280_REG_COMP_PRESS_START,
>>> buf, BMP280_COMP_PRESS_REG_COUNT);
>>> if (ret < 0) {
>>> dev_err(&data->client->dev,
>>> "failed to read pressure calibration parameters\n");
>>> return ret;
>>> }
>>>
>>> var1 = ((s64) data->t_fine) - 128000;
>>> var2 = var1 * var1 * (s64) le16_to_cpu(buf[P6]);
>>> var2 = var2 + ((var1 * (s64) le16_to_cpu(buf[P5])) << 17);
>>> var2 = var2 + (((s64) le16_to_cpu(buf[P4])) << 35);
>>> var1 = ((var1 * var1 * (s64) le16_to_cpu(buf[P3])) >> 8) +
>>> ((var1 * (s64) le16_to_cpu(buf[P2])) << 12);
>>> var1 = (((((s64) 1) << 47) + var1)) * ((s64) le16_to_cpu(buf[P1])) >> 33;
>>>
>>> if (var1 == 0)
>>> return 0;
>>>
>>> p = ((((s64) 1048576 - adc_press) << 31) - var2) * 3125;
>>> p = div64_s64(p, var1);
>>> var1 = (((s64) le16_to_cpu(buf[P9]) * (p >> 13) * (p >> 13)) >> 25;
>>> var2 = (((s64) le16_to_cpu[buf[P8]) * p) >> 19;
>>> p = ((p + var1 + var2) >> 8) + (((s64) le16_to_cpu(buf[P7])) << 4);
>>>
>>> return (u32) p;
>>> }
>>>
>>> Just a thought. I was never terribly fussed about this other than disliking
>>> data duplication!
>>>>> [1] http://www.spinics.net/lists/linux-iio/msg15099.html
>>
>> I don't think the enum helps readability too much here. At least it
>> doesn't help me :)
>>
>> How about reading data straight to the (packed) calibration struct and
>> doing the endinanness conversions inline? Something like this:
>>
>> int bmp280_compensate_press(struct bmp280_data *data)
>> {
>> struct bmp280_comp_press comp;
>> s64 var1, var2, p;
>>
>> ret = regmap_bulk_read(data->regmap, BMP280_REG_COMP_PRESS_START,
>> &comp, sizeof (comp));
>> if (ret < 0) {
>> dev_err(&data->client->dev,
>> "failed to read pressure calibration parameters\n");
>> return ret;
>> }
>>
>> var1 = ((s64) data->t_fine) - 128000;
>> var2 = var1 * var1 * (s64) le16_to_cpu(comp.dig_p6);
>> var2 = var2 + ((var1 * (s64) le16_to_cpu(comp.dig_p5)) << 17);
>>
>> /* etc */
>>
>> This saves us the extra copying of parameters from buffer to structure,
>> and is a bit more clear than indexing the buffer with enum members, IMO.
>>
>> Thanks,
>> Vlad
> I compile tested several solutions, and Jonathans' resulted in the lowest module size. Downside of course are the increased complexity of the equations introduced by the endianness conversion and that copying from regmap cache to buf costs some resources.
> But I think that memory footprint has a higher importance, so I slightly favor Jonathans solution.
>
> Jonathan, do you like to send a patch with your solution?
Err. not really :) Bit snowed under so whilst I'll probably get to it one
day it might not be anytime soon.
Anyone else who happens to want to do it then feel free ;)
>> --
>> To unsubscribe from this list: send the line "unsubscribe linux-iio" in
>> the body of a message to majordomo@vger.kernel.org
>> More majordomo info at http://vger.kernel.org/majordomo-info.html
>>
>
next prev parent reply other threads:[~2014-11-15 16:06 UTC|newest]
Thread overview: 13+ messages / expand[flat|nested] mbox.gz Atom feed top
2014-10-31 1:25 [PATCH 3/3]iio:pressure:bmp280: read compensation data only at init Hartmut Knaack
2014-10-31 11:47 ` Vlad Dogaru
2014-10-31 19:16 ` Hartmut Knaack
2014-11-05 15:53 ` Jonathan Cameron
2014-11-06 13:02 ` Vlad Dogaru
2014-11-10 23:11 ` Hartmut Knaack
2014-11-15 16:06 ` Jonathan Cameron [this message]
2014-11-17 15:16 ` Vlad Dogaru
2014-11-20 12:00 ` [PATCH] iio: bmp280: refactor compensation code Vlad Dogaru
2014-11-22 12:05 ` Jonathan Cameron
2014-11-22 20:33 ` Hartmut Knaack
2014-11-22 20:27 ` Hartmut Knaack
2014-11-22 20:43 ` Jonathan Cameron
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=54677A0D.2090604@kernel.org \
--to=jic23@kernel.org \
--cc=knaack.h@gmx.de \
--cc=linux-iio@vger.kernel.org \
--cc=vlad.dogaru@intel.com \
/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).