Skip to contentSkip to conversation

iio: temperature: mlx90635 Driver for MLX90635 IR temperature sensor

PATCH In review Crt Mori 2 participants 4 messages Dec 6, 2023 – Dec 10, 2023

Subsystems (3)
lore
Share & tools
lore

Crt Mori

author maintainer
#0 lore raw

v3 cover iio: temperature: mlx90635 Driver for MLX90635 IR temperature sensor

Hi everybody,

There is a new contactless sensor in Melexis portfolio. MLX90635 is just 1.8x1.8mm in size, but with factory calibration offers instant usage in every project. It offers wide refresh rate range that is configurable between 100ms and 4s.

Driver currently provides temperature calculations, power management and changes to the refresh rate. Since sensor is aimed towards the consumer market there is really low number of EEPROM write cycles available, so driver changes refresh rate only in run time registers to avoid writing to EEPROM. Reading EEPROM is not available in Sleep Step mode, so I am using caching at the driver initialization to ensure that measurements can still be taken in Sleep Step mode.

Changes v2 -> v3:

- add separate regmap for eeprom to make caching more obvious
- fix some style comments from Jonathan Cameron

Changes v1 -> v2:
- dt-bindings are now enum according to the comments from Krzysztof Kozlowski
- expand the path recipient list for the patches using get_maintainers.pl
- driver cache and probe (and some style) adjusted according to comments from Jonathan Cameron
- improve DSP version detection (make it clearer)

Crt Mori (2):
iio: temperature: mlx90635 MLX90635 IR Temperature sensor
dt-bindings: iio: temperature: add MLX90635 device

 .../iio/temperature/melexis,mlx90632.yaml     |   19 +-
 MAINTAINERS                                   |    7 +
 drivers/iio/temperature/Kconfig               |   12 +
 drivers/iio/temperature/Makefile              |    1 +
 drivers/iio/temperature/mlx90635.c            | 1097 +++++++++++++++++
 5 files changed, 1134 insertions(+), 2 deletions(-)
 create mode 100644 drivers/iio/temperature/mlx90635.c
Signature · 1 line
2.40.1
author maintainer
#1 lore raw

PATCH v3 1/2 iio: temperature: mlx90635 MLX90635 IR Temperature sensor

MLX90635 is an Infra Red contactless temperature sensor most suitable for consumer applications where measured object temperature is in range between -20 to 100 degrees Celsius. It has improved accuracy for measurements within temperature range of human body and can operate in ambient temperature range between -20 to 85 degrees Celsius.

Driver provides simple power management possibility as it returns to lowest possible power mode (Step sleep mode) in which temperature measurements can still be performed, yet for continuous measuring it switches to Continuous power mode where measurements constantly change without triggering.

---
 MAINTAINERS                        |    7 +
 drivers/iio/temperature/Kconfig    |   12 +
 drivers/iio/temperature/Makefile   |    1 +
 drivers/iio/temperature/mlx90635.c | 1097 ++++++++++++++++++++++++++++
 4 files changed, 1117 insertions(+)
 create mode 100644 drivers/iio/temperature/mlx90635.c
MAINTAINERS +7 -0
index 8e0a91dc8251..ad77cdd1c08e 100644
@@ -13725,6 +13725,13 @@ S:	Supported
 W:	http://www.melexis.com
 F:	drivers/iio/temperature/mlx90632.c
 
+MELEXIS MLX90635 DRIVER
+M:	Crt Mori <[email protected]>
+L:	[email protected]
+S:	Supported
+W:	http://www.melexis.com
+F:	drivers/iio/temperature/mlx90635.c
+
 MELFAS MIP4 TOUCHSCREEN DRIVER
 M:	Sangwon Jee <[email protected]>
 S:	Supported
drivers/iio/temperature/Kconfig +12 -0
index ea2ce364b2e9..ed0e4963362f 100644
@@ -76,6 +76,18 @@ config MLX90632
 	  This driver can also be built as a module. If so, the module will
 	  be called mlx90632.
 
+config MLX90635
+	tristate "MLX90635 contact-less infrared sensor with medical accuracy"
+	depends on I2C
+	select REGMAP_I2C
+	help
+	  If you say yes here you get support for the Melexis
+	  MLX90635 contact-less infrared sensor with medical accuracy
+	  connected with I2C.
+
+	  This driver can also be built as a module. If so, the module will
+	  be called mlx90635.
+
 config TMP006
 	tristate "TMP006 infrared thermopile sensor"
 	depends on I2C
drivers/iio/temperature/Makefile +1 -0
index 9330d4a39598..07d6e65709f7 100644
@@ -13,6 +13,7 @@ obj-$(CONFIG_MAX31865) += max31865.o
 obj-$(CONFIG_MCP9600) += mcp9600.o
 obj-$(CONFIG_MLX90614) += mlx90614.o
 obj-$(CONFIG_MLX90632) += mlx90632.o
+obj-$(CONFIG_MLX90632) += mlx90635.o
 obj-$(CONFIG_TMP006) += tmp006.o
 obj-$(CONFIG_TMP007) += tmp007.o
 obj-$(CONFIG_TMP117) += tmp117.o
drivers/iio/temperature/mlx90635.c new file +1097 -0

1,097 lines not on this page · raw message

Signature · 1 line
2.40.1
maintainer
#2 lore raw

Re: [PATCH v3 1/2] iio: temperature: mlx90635 MLX90635 IR Temperature sensor

Quoted 6 lines · On Wed, 6 Dec 2023 21:49:33 +0100 Crt Mori <[email protected]> wrote:

MLX90635 is an Infra Red contactless temperature sensor most suitable for consumer applications where measured object temperature is in range between -20 to 100 degrees Celsius. It has improved accuracy for measurements within temperature range of human body and can operate in ambient temperature range between -20 to 85 degrees Celsius.

Quoted 7 lines

Driver provides simple power management possibility as it returns to lowest possible power mode (Step sleep mode) in which temperature measurements can still be performed, yet for continuous measuring it switches to Continuous power mode where measurements constantly change without triggering.

Nice work

I've made a few comments inline for future possible improvements, but given the cleanup.h stuff is fairly new I'll not block this merging based on that.

I made some tiny tweak for readability whilst applying. Please sanity check that. diff was all about return values that must be 0 as they come out of regmap and we've already checked for error cases.

drivers/iio/temperature/mlx90635.c +5 -5
index 1b3bde36f18a..1f5c962c1818 100644
@@ -306,7 +306,7 @@ static int mlx90635_read_ee_ambient(struct regmap *regmap, s16 *PG, s16 *PO, s16
                return ret;
        *Gb = (u16)read_tmp;
 
-       return ret;
+       return 0;
 }
 
 static int mlx90635_read_ee_object(struct regmap *regmap, u32 *Ea, u32 *Eb, u32 *Fa, s16 *Fb,
@@ -357,7 +357,7 @@ static int mlx90635_read_ee_object(struct regmap *regmap, u32 *Ea, u32 *Eb, u32
                return ret;
        *Fa_scale = (u16)read_tmp;
 
-       return ret;
+       return 0;
 }
 
 static int mlx90635_calculate_dataset_ready_time(struct mlx90635_data *data, int *refresh_time)
@@ -405,7 +405,7 @@ static int mlx90635_perform_measurement_burst(struct mlx90635_data *data)
                return -ETIMEDOUT;
        }
 
-       return ret;
+       return 0;
 }
 
 static int mlx90635_read_ambient_raw(struct regmap *regmap,
@@ -424,7 +424,7 @@ static int mlx90635_read_ambient_raw(struct regmap *regmap,
                return ret;
        *ambient_old_raw = (s16)read_tmp;
 
-       return ret;
+       return 0;
 }
 
 static int mlx90635_read_object_raw(struct regmap *regmap, s16 *object_raw)
@@ -444,7 +444,7 @@ static int mlx90635_read_object_raw(struct regmap *regmap, s16 *object_raw)
                return ret;
        *object_raw = (read - (s16)read_tmp) / 2;
 
-       return ret;
+       return 0;
 }
 
 

Applied to the togreg branch of iio.git and pushed out as testing for all the normal reasons.

Quoted 29 lines
drivers/iio/temperature/mlx90635.c new file +22 -0
new file mode 100644
index 000000000000..1b3bde36f18a
 
 
+static int mlx90635_perform_measurement_burst(struct mlx90635_data *data)
+{
+	unsigned int reg_status;
+	int refresh_time;
+	int ret;
+
+	ret = regmap_write_bits(data->regmap, MLX90635_REG_STATUS,
+				MLX90635_STAT_END_CONV, MLX90635_STAT_END_CONV);
+	if (ret < 0)
+		return ret;
+
+	ret = mlx90635_calculate_dataset_ready_time(data, &refresh_time);
+	if (ret < 0)
+		return ret;
+
+	ret = regmap_write_bits(data->regmap, MLX90635_REG_CTRL2,
+				FIELD_PREP(MLX90635_CTRL2_SOB_MASK, 1),
+				FIELD_PREP(MLX90635_CTRL2_SOB_MASK, 1));
+	if (ret < 0)
+		return ret;
+
+	msleep(refresh_time); /* Wait minimum time for dataset to be ready */

drivers/iio/temperature/mlx90635.c

Quoted 10 lines
drivers/iio/temperature/mlx90635.c new file +10 -0
+
+	ret = regmap_read_poll_timeout(data->regmap, MLX90635_REG_STATUS, reg_status,
+				       (!(reg_status & MLX90635_STAT_END_CONV)) == 0,
+				       MLX90635_TIMING_POLLING, MLX90635_READ_RETRIES * 10000);
+	if (ret < 0) {
+		dev_err(&data->client->dev, "data not ready");
+		return -ETIMEDOUT;
+	}
+
+	return ret;

I'll tweak this one to return 0 to make it explicit that no postive values are returned.

Quoted 15 lines
drivers/iio/temperature/mlx90635.c new file +13 -0
+}
 
 
+static int mlx90635_read_all_channel(struct mlx90635_data *data,
+				     s16 *ambient_new_raw, s16 *ambient_old_raw,
+				     s16 *object_raw)
+{
+	int ret;
+
+	mutex_lock(&data->lock);
+	if (data->powerstatus == MLX90635_PWR_STATUS_SLEEP_STEP) {
+		/* Trigger measurement in Sleep Step mode */
+		ret = mlx90635_perform_measurement_burst(data);
+		if (ret < 0)
+			goto read_unlock;

drivers/iio/temperature/mlx90635.c

Quoted 10 lines
drivers/iio/temperature/mlx90635.c new file +10 -0
+	}
+
+	ret = mlx90635_read_ambient_raw(data->regmap, ambient_new_raw,
+					ambient_old_raw);
+	if (ret < 0)
+		goto read_unlock;
+
+	ret = mlx90635_read_object_raw(data->regmap, object_raw);
+read_unlock:
+	mutex_unlock(&data->lock);

A good function to use guard(mutex)(&data->lock)

Quoted 5 lines
drivers/iio/temperature/mlx90635.c new file +4 -0
+	return ret;
+}
+
 
+static int mlx90635_calc_ambient(struct mlx90635_data *data, int *val)

drivers/iio/temperature/mlx90635.c

Quoted 10 lines
drivers/iio/temperature/mlx90635.c new file +10 -0
+{
+	s16 ambient_new_raw, ambient_old_raw;
+	s16 PG, PO, Gb;
+	int ret;
+
+	ret = mlx90635_read_ee_ambient(data->regmap_ee, &PG, &PO, &Gb);
+	if (ret < 0)
+		return ret;
+
+	mutex_lock(&data->lock);

I don't mind this not changing for now, but this is exactly the sort of place for scoped_guard()
Something like:

	scoped_guard(mutex, &data->lock) {
		if (data->powerstatus == MLX90635_PWR_STATUS_SLEEP_STEP) {
			ret = mlx90635_perform_measurement_burst(data);
			if (ret < 0)
				return ret;
		}
	
		ret = mlx90635_read_ambient_raw(data->regmap, &ambient_new_raw,
					&ambient_old_raw);
		if (ret < 0)
			return ret;
	}
Quoted 17 lines
drivers/iio/temperature/mlx90635.c new file +17 -0
+	if (data->powerstatus == MLX90635_PWR_STATUS_SLEEP_STEP) {
+		ret = mlx90635_perform_measurement_burst(data);
+		if (ret < 0)
+			goto read_ambient_unlock;
+	}
+
+	ret = mlx90635_read_ambient_raw(data->regmap, &ambient_new_raw,
+					&ambient_old_raw);
+read_ambient_unlock:
+	mutex_unlock(&data->lock);
+	if (ret < 0)
+		return ret;
+
+	*val = mlx90635_calc_temp_ambient(ambient_new_raw, ambient_old_raw,
+					  PG, PO, Gb);
+	return ret;
+}
author maintainer
#3 lore raw

PATCH v3 2/2 dt-bindings: iio: temperature: add MLX90635 device

In reply to Crt Mori

Add device tree bindings for MLX90635 Infra Red contactless temperature sensor.

---
 .../iio/temperature/melexis,mlx90632.yaml     | 19 +++++++++++++++++--
 1 file changed, 17 insertions(+), 2 deletions(-)
Documentation/devicetree/bindings/iio/temperature/melexis,mlx90632.yaml +17 -2
index 4a55e7f25ae7..03bb5d4fa8b5 100644
@@ -4,7 +4,7 @@
 $id: http://devicetree.org/schemas/iio/temperature/melexis,mlx90632.yaml#
 $schema: http://devicetree.org/meta-schemas/core.yaml#
 
-title: Melexis MLX90632 contactless Infra Red temperature sensor
+title: Melexis MLX90632 and MLX90635 contactless Infra Red temperature sensor
 
 maintainers:
   - Crt Mori <[email protected]>
@@ -27,9 +27,24 @@ description: |
   Since measured object emissivity effects Infra Red energy emitted,
   emissivity should be set before requesting the object temperature.
 
+  https://www.melexis.com/en/documents/documentation/datasheets/datasheet-mlx90635
+
+  MLX90635 is most suitable for consumer applications where
+  measured object temperature is in range between -20 to 100 degrees
+  Celsius with relative error of measurement 2 degree Celsius in
+  object temperature range for industrial applications, while just 0.2
+  degree Celsius for human body measurement applications. Since it can
+  operate and measure ambient temperature in range of -20 to 85 degrees
+  Celsius it is suitable also for outdoor use.
+
+  Since measured object emissivity effects Infra Red energy emitted,
+  emissivity should be set before requesting the object temperature.
+
 properties:
   compatible:
-    const: melexis,mlx90632
+    enum:
+      - melexis,mlx90632
+      - melexis,mlx90635
 
   reg:
     maxItems: 1
Signature · 1 line
2.40.1