All of lore.kernel.org
 help / color / mirror / Atom feed
From: Jakob Hauser <jahau@rocketmail.com>
To: Jonathan Cameron <jic23@kernel.org>
Cc: Lars-Peter Clausen <lars@metafoo.de>,
	Linus Walleij <linus.walleij@linaro.org>,
	Andy Shevchenko <andy.shevchenko@gmail.com>,
	Hans de Goede <hdegoede@redhat.com>,
	linux-iio@vger.kernel.org, devicetree@vger.kernel.org,
	phone-devel@vger.kernel.org,
	~postmarketos/upstreaming@lists.sr.ht,
	Jakob Hauser <jahau@rocketmail.com>
Subject: [PATCH v5 04/14] iio: magnetometer: yas530: Correct temperature handling
Date: Mon,  8 Aug 2022 01:02:09 +0200	[thread overview]
Message-ID: <cc21392ec84ec93c5e58659585cacb9e7c9831a9.1659909060.git.jahau@rocketmail.com> (raw)
In-Reply-To: <cover.1659909060.git.jahau@rocketmail.com>

The raw temperature value is a number of counts from a certain starting
point. The resolution of the temperature counts is different for the YAS
variants.

Temperature compensation for YAS532 version AC seems to be handled differently.
It uses the deviation from 20 degree Celsius [1] whereas YAS530 and older
versions of YAS532 apply solely the t value as a multiplier [2][3].

In funtion yas5xx_read_raw(), add case IIO_CHAN_INFO_PROCESSED. Remove scale
of temperature as this isn't applied.

Additionally correct sign of temperature channel in iio_chan_spec. It's already
defined that way in the yas5xx_get_measure() function.

[1] https://github.com/msm8916-mainline/android_kernel_qcom_msm8916/blob/GT-I9195I/drivers/iio/magnetometer/yas_mag_drv-yas532.c#L442
[2] https://github.com/NovaFusion/android_kernel_samsung_golden/blob/cm-12.1/drivers/sensor/compass/yas_mag_driver-yas530.c#L881-L883
[3] https://github.com/LineageOS/android_kernel_samsung_msm8930-common/blob/lineage-18.1/drivers/sensors/geomagnetic/yas_mag_driver-yas53x.c#L856-L858

Signed-off-by: Jakob Hauser <jahau@rocketmail.com>
Reviewed-by: Linus Walleij <linus.walleij@linaro.org>
Reviewed-by: Andy Shevchenko <andy.shevchenko@gmail.com>
---
 drivers/iio/magnetometer/yamaha-yas530.c | 99 ++++++++++++++++++------
 1 file changed, 76 insertions(+), 23 deletions(-)

diff --git a/drivers/iio/magnetometer/yamaha-yas530.c b/drivers/iio/magnetometer/yamaha-yas530.c
index 8cad724fb328..c6889a30a1b5 100644
--- a/drivers/iio/magnetometer/yamaha-yas530.c
+++ b/drivers/iio/magnetometer/yamaha-yas530.c
@@ -77,6 +77,7 @@
 #define YAS530_DATA_BITS		12
 #define YAS530_DATA_CENTER		BIT(YAS530_DATA_BITS - 1)
 #define YAS530_DATA_OVERFLOW		(BIT(YAS530_DATA_BITS) - 1)
+#define YAS530_20DEGREES		182 /* Counts starting at -62 °C */
 
 #define YAS532_DEVICE_ID		0x02 /* YAS532/YAS533 (MS-3R/F) */
 #define YAS532_VERSION_AB		0 /* YAS532/533 AB (MS-3R/F AB) */
@@ -88,7 +89,7 @@
 #define YAS532_DATA_BITS		13
 #define YAS532_DATA_CENTER		BIT(YAS532_DATA_BITS - 1)
 #define YAS532_DATA_OVERFLOW		(BIT(YAS532_DATA_BITS) - 1)
-#define YAS532_20DEGREES		390 /* Looks like Kelvin */
+#define YAS532_20DEGREES		390 /* Counts starting at -50 °C */
 
 /* These variant IDs are known from code dumps */
 #define YAS537_DEVICE_ID		0x07 /* YAS537 (MS-3T) */
@@ -314,7 +315,7 @@ static s32 yas5xx_linearize(struct yas5xx *yas5xx, u16 val, int axis)
 static int yas5xx_get_measure(struct yas5xx *yas5xx, s32 *to, s32 *xo, s32 *yo, s32 *zo)
 {
 	struct yas5xx_calibration *c = &yas5xx->calibration;
-	u16 t, x, y1, y2;
+	u16 t_ref, t, x, y1, y2;
 	/* These are "signed x, signed y1 etc */
 	s32 sx, sy1, sy2, sy, sz;
 	int ret;
@@ -329,16 +330,46 @@ static int yas5xx_get_measure(struct yas5xx *yas5xx, s32 *to, s32 *xo, s32 *yo,
 	sy1 = yas5xx_linearize(yas5xx, y1, 1);
 	sy2 = yas5xx_linearize(yas5xx, y2, 2);
 
-	/*
-	 * Temperature compensation for x, y1, y2 respectively:
-	 *
-	 *          Cx * t
-	 * x' = x - ------
-	 *           100
-	 */
-	sx = sx - (c->Cx * t) / 100;
-	sy1 = sy1 - (c->Cy1 * t) / 100;
-	sy2 = sy2 - (c->Cy2 * t) / 100;
+	/* Set the temperature reference value (unit: counts) */
+	switch (yas5xx->devid) {
+	case YAS530_DEVICE_ID:
+		t_ref = YAS530_20DEGREES;
+		break;
+	case YAS532_DEVICE_ID:
+		t_ref = YAS532_20DEGREES;
+		break;
+	default:
+		dev_err(yas5xx->dev, "unknown device type\n");
+		return -EINVAL;
+	}
+
+	/* Temperature compensation for x, y1, y2 respectively */
+	if (yas5xx->devid == YAS532_DEVICE_ID &&
+	    yas5xx->version == YAS532_VERSION_AC) {
+		/*
+		 * YAS532 version AC uses the temperature deviation as a
+		 * multiplier.
+		 *
+		 *          Cx * (t - t_ref)
+		 * x' = x - ----------------
+		 *                100
+		 */
+		sx = sx - (c->Cx * (t - t_ref)) / 100;
+		sy1 = sy1 - (c->Cy1 * (t - t_ref)) / 100;
+		sy2 = sy2 - (c->Cy2 * (t - t_ref)) / 100;
+	} else {
+		/*
+		 * YAS530 and YAS532 version AB use solely the t value as a
+		 * multiplier.
+		 *
+		 *          Cx * t
+		 * x' = x - ------
+		 *           100
+		 */
+		sx = sx - (c->Cx * t) / 100;
+		sy1 = sy1 - (c->Cy1 * t) / 100;
+		sy2 = sy2 - (c->Cy2 * t) / 100;
+	}
 
 	/*
 	 * Break y1 and y2 into y and z, y1 and y2 are apparently encoding
@@ -347,11 +378,37 @@ static int yas5xx_get_measure(struct yas5xx *yas5xx, s32 *to, s32 *xo, s32 *yo,
 	sy = sy1 - sy2;
 	sz = -sy1 - sy2;
 
-	/*
-	 * FIXME: convert to Celsius? Just guessing this is given
-	 * as 1/10:s of degrees so multiply by 100 to get millicentigrades.
-	 */
-	*to = t * 100;
+	/* Process temperature readout */
+	switch (yas5xx->devid) {
+	case YAS530_DEVICE_ID:
+		/*
+		 * Raw temperature value t is the number of counts starting
+		 * at -62 °C. Reference value t_ref is the number of counts
+		 * between -62 °C and 20 °C (82 °C range).
+		 *
+		 * Temperature in °C would be (82 / t_ref * t) - 62.
+		 *
+		 * Contrary to this, perform multiplication first and division
+		 * second due to calculating with integers.
+		 *
+		 * To get a nicer result, calculate with 1/10:s degrees Celsius
+		 * and finally multiply by 100 to return millidegrees Celsius.
+		 */
+		*to = ((820 * t / t_ref) - 620) * 100;
+		break;
+	case YAS532_DEVICE_ID:
+		/*
+		 * Actually same procedure for YAS532 but the starting point is
+		 * at -50 °C. Reference value t_ref is the number of counts
+		 * between -50 °C and 20 °C (70 °C range).
+		 */
+		*to = ((700 * t / t_ref) - 500) * 100;
+		break;
+	default:
+		dev_err(yas5xx->dev, "unknown device type\n");
+		return -EINVAL;
+	}
+
 	/*
 	 * Calibrate [x,y,z] with some formulas like this:
 	 *
@@ -384,6 +441,7 @@ static int yas5xx_read_raw(struct iio_dev *indio_dev,
 	int ret;
 
 	switch (mask) {
+	case IIO_CHAN_INFO_PROCESSED:
 	case IIO_CHAN_INFO_RAW:
 		pm_runtime_get_sync(yas5xx->dev);
 		ret = yas5xx_get_measure(yas5xx, &t, &x, &y, &z);
@@ -410,11 +468,6 @@ static int yas5xx_read_raw(struct iio_dev *indio_dev,
 		}
 		return IIO_VAL_INT;
 	case IIO_CHAN_INFO_SCALE:
-		if (chan->address == 0) {
-			/* Temperature is unscaled */
-			*val = 1;
-			return IIO_VAL_INT;
-		}
 		switch (yas5xx->devid) {
 		case YAS530_DEVICE_ID:
 			/*
@@ -516,7 +569,7 @@ static const struct iio_chan_spec yas5xx_channels[] = {
 		.address = 0,
 		.scan_index = 0,
 		.scan_type = {
-			.sign = 'u',
+			.sign = 's',
 			.realbits = 32,
 			.storagebits = 32,
 			.endianness = IIO_CPU,
-- 
2.35.1


  parent reply	other threads:[~2022-08-07 23:04 UTC|newest]

Thread overview: 46+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
     [not found] <cover.1659909060.git.jahau.ref@rocketmail.com>
2022-08-07 23:02 ` [PATCH v5 00/14] Add support for magnetometer Yamaha YAS537 Jakob Hauser
2022-08-07 23:02   ` [PATCH v5 01/14] iio: magnetometer: yas530: Change data type of hard_offsets to signed Jakob Hauser
2022-08-07 23:02   ` [PATCH v5 02/14] iio: magnetometer: yas530: Change range of data in volatile register Jakob Hauser
2022-08-07 23:02   ` [PATCH v5 03/14] iio: magnetometer: yas530: Correct scaling of magnetic axes Jakob Hauser
2022-08-07 23:02   ` Jakob Hauser [this message]
2022-08-07 23:02   ` [PATCH v5 05/14] iio: magnetometer: yas530: Change data type of calibration coefficients Jakob Hauser
2022-08-07 23:02   ` [PATCH v5 06/14] iio: magnetometer: yas530: Rename functions and registers Jakob Hauser
2022-08-08 11:08     ` Andy Shevchenko
2022-08-09 23:23       ` Jakob Hauser
2022-08-07 23:06   ` [PATCH v5 07/14] iio: magnetometer: yas530: Move printk %*ph parameters out from stack Jakob Hauser
2022-08-08 11:10     ` Andy Shevchenko
2022-08-09 23:24       ` Jakob Hauser
2022-08-07 23:06   ` [PATCH v5 08/14] iio: magnetometer: yas530: Apply documentation and style fixes Jakob Hauser
2022-08-07 23:06   ` [PATCH v5 09/14] iio: magnetometer: yas530: Introduce "chip_info" structure Jakob Hauser
2022-08-08  5:39     ` kernel test robot
2022-08-08 11:18       ` Andy Shevchenko
2022-08-08 11:18         ` Andy Shevchenko
2022-08-08 11:24         ` Andy Shevchenko
2022-08-08 11:24           ` Andy Shevchenko
2022-08-08 15:59         ` Nathan Chancellor
2022-08-08 15:59           ` Nathan Chancellor
2022-08-08 18:04           ` Andy Shevchenko
2022-08-08 18:04             ` Andy Shevchenko
2022-08-08 19:48             ` Nathan Chancellor
2022-08-08 19:48               ` Nathan Chancellor
2022-08-09 23:26             ` Jakob Hauser
2022-08-09 23:26               ` Jakob Hauser
2022-08-08 11:22     ` Andy Shevchenko
2022-08-09 23:29       ` Jakob Hauser
2022-08-08 11:32     ` Andy Shevchenko
2022-08-09 23:32       ` Jakob Hauser
2022-08-07 23:06   ` [PATCH v5 10/14] iio: magnetometer: yas530: Add volatile registers to "chip_info" Jakob Hauser
2022-08-08 11:33     ` Andy Shevchenko
2022-08-07 23:06   ` [PATCH v5 11/14] iio: magnetometer: yas530: Add IIO scaling " Jakob Hauser
2022-08-08 11:33     ` Andy Shevchenko
2022-08-07 23:06   ` [PATCH v5 12/14] iio: magnetometer: yas530: Add temperature calculation " Jakob Hauser
2022-08-08 11:36     ` Andy Shevchenko
2022-08-09 23:36       ` Jakob Hauser
2022-08-07 23:06   ` [PATCH v5 13/14] iio: magnetometer: yas530: Add function pointers " Jakob Hauser
2022-08-08 11:37     ` Andy Shevchenko
2022-08-09 23:38       ` Jakob Hauser
2022-08-07 23:12   ` [PATCH v5 14/14] iio: magnetometer: yas530: Add YAS537 variant Jakob Hauser
2022-08-08 11:47     ` Andy Shevchenko
2022-08-09 23:41       ` Jakob Hauser
2022-08-12 21:43         ` Linus Walleij
2022-08-12 21:49           ` Andy Shevchenko

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=cc21392ec84ec93c5e58659585cacb9e7c9831a9.1659909060.git.jahau@rocketmail.com \
    --to=jahau@rocketmail.com \
    --cc=andy.shevchenko@gmail.com \
    --cc=devicetree@vger.kernel.org \
    --cc=hdegoede@redhat.com \
    --cc=jic23@kernel.org \
    --cc=lars@metafoo.de \
    --cc=linus.walleij@linaro.org \
    --cc=linux-iio@vger.kernel.org \
    --cc=phone-devel@vger.kernel.org \
    --cc=~postmarketos/upstreaming@lists.sr.ht \
    /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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.