public inbox for devicetree@vger.kernel.org
 help / color / mirror / Atom feed
* [PATCH v3 1/6] dt-bindings: iio: temperature: melexis,mlx90614: Document MLX90615 support
@ 2023-05-10 10:22 Marek Vasut
  2023-05-10 10:22 ` [PATCH v3 2/6] iio: mlx90614: Sort headers Marek Vasut
                   ` (5 more replies)
  0 siblings, 6 replies; 9+ messages in thread
From: Marek Vasut @ 2023-05-10 10:22 UTC (permalink / raw)
  To: linux-iio
  Cc: Marek Vasut, Crt Mori, Krzysztof Kozlowski, Jonathan Cameron,
	Krzysztof Kozlowski, Lars-Peter Clausen, Peter Meerwald,
	Rob Herring, devicetree

Document support for MLX90615 Infra Red Thermometer, which seems to
be the predecesor of MLX90614 . There are significant differences in
the register layout compared to MLX90614, but the functionality of
the device is virtually identical.

Acked-by: Crt Mori <cmo@melexis.com>
Acked-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
Signed-off-by: Marek Vasut <marex@denx.de>
---
Cc: Crt Mori <cmo@melexis.com>
Cc: Jonathan Cameron <jic23@kernel.org>
Cc: Krzysztof Kozlowski <krzysztof.kozlowski+dt@linaro.org>
Cc: Lars-Peter Clausen <lars@metafoo.de>
Cc: Marek Vasut <marex@denx.de>
Cc: Peter Meerwald <pmeerw@pmeerw.net>
Cc: Rob Herring <robh+dt@kernel.org>
Cc: devicetree@vger.kernel.org
Cc: linux-iio@vger.kernel.org
---
V2: - Add spaces to subject tags
    - Add AB from Krzysztof
V3: Add AB from Crt
---
 .../bindings/iio/temperature/melexis,mlx90614.yaml          | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/Documentation/devicetree/bindings/iio/temperature/melexis,mlx90614.yaml b/Documentation/devicetree/bindings/iio/temperature/melexis,mlx90614.yaml
index d6965a0c1cf30..654d31f65d360 100644
--- a/Documentation/devicetree/bindings/iio/temperature/melexis,mlx90614.yaml
+++ b/Documentation/devicetree/bindings/iio/temperature/melexis,mlx90614.yaml
@@ -4,7 +4,7 @@
 $id: http://devicetree.org/schemas/iio/temperature/melexis,mlx90614.yaml#
 $schema: http://devicetree.org/meta-schemas/core.yaml#
 
-title: Melexis MLX90614 contactless IR temperature sensor
+title: Melexis MLX90614/MLX90615 contactless IR temperature sensor
 
 maintainers:
   - Peter Meerwald <pmeerw@pmeerw.net>
@@ -15,7 +15,9 @@ description: |
 
 properties:
   compatible:
-    const: melexis,mlx90614
+    enum:
+      - melexis,mlx90614
+      - melexis,mlx90615
 
   reg:
     maxItems: 1
-- 
2.39.2


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [PATCH v3 2/6] iio: mlx90614: Sort headers
  2023-05-10 10:22 [PATCH v3 1/6] dt-bindings: iio: temperature: melexis,mlx90614: Document MLX90615 support Marek Vasut
@ 2023-05-10 10:22 ` Marek Vasut
  2023-05-10 10:22 ` [PATCH v3 3/6] iio: mlx90614: Drop unused register macros Marek Vasut
                   ` (4 subsequent siblings)
  5 siblings, 0 replies; 9+ messages in thread
From: Marek Vasut @ 2023-05-10 10:22 UTC (permalink / raw)
  To: linux-iio
  Cc: Marek Vasut, Crt Mori, Jonathan Cameron, Krzysztof Kozlowski,
	Lars-Peter Clausen, Peter Meerwald, Rob Herring, devicetree

Sort the headers alphabetically. No functional change.

Acked-by: Crt Mori <cmo@melexis.com>
Signed-off-by: Marek Vasut <marex@denx.de>
---
Cc: Crt Mori <cmo@melexis.com>
Cc: Jonathan Cameron <jic23@kernel.org>
Cc: Krzysztof Kozlowski <krzysztof.kozlowski+dt@linaro.org>
Cc: Lars-Peter Clausen <lars@metafoo.de>
Cc: Marek Vasut <marex@denx.de>
Cc: Peter Meerwald <pmeerw@pmeerw.net>
Cc: Rob Herring <robh+dt@kernel.org>
Cc: devicetree@vger.kernel.org
Cc: linux-iio@vger.kernel.org
---
V2: New patch
V3: Add AB from Crt
---
 drivers/iio/temperature/mlx90614.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/iio/temperature/mlx90614.c b/drivers/iio/temperature/mlx90614.c
index 909fadb623491..bd92b24918253 100644
--- a/drivers/iio/temperature/mlx90614.c
+++ b/drivers/iio/temperature/mlx90614.c
@@ -19,12 +19,12 @@
  * the "wakeup" GPIO is not given, power management will be disabled.
  */
 
+#include <linux/delay.h>
 #include <linux/err.h>
+#include <linux/gpio/consumer.h>
 #include <linux/i2c.h>
-#include <linux/module.h>
-#include <linux/delay.h>
 #include <linux/jiffies.h>
-#include <linux/gpio/consumer.h>
+#include <linux/module.h>
 #include <linux/pm_runtime.h>
 
 #include <linux/iio/iio.h>
-- 
2.39.2


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [PATCH v3 3/6] iio: mlx90614: Drop unused register macros
  2023-05-10 10:22 [PATCH v3 1/6] dt-bindings: iio: temperature: melexis,mlx90614: Document MLX90615 support Marek Vasut
  2023-05-10 10:22 ` [PATCH v3 2/6] iio: mlx90614: Sort headers Marek Vasut
@ 2023-05-10 10:22 ` Marek Vasut
  2023-05-10 10:22 ` [PATCH v3 4/6] iio: mlx90614: Drop MLX90614_CONST_EMISSIVITY_RESOLUTION Marek Vasut
                   ` (3 subsequent siblings)
  5 siblings, 0 replies; 9+ messages in thread
From: Marek Vasut @ 2023-05-10 10:22 UTC (permalink / raw)
  To: linux-iio
  Cc: Marek Vasut, Crt Mori, Jonathan Cameron, Krzysztof Kozlowski,
	Lars-Peter Clausen, Peter Meerwald, Rob Herring, devicetree

To simplify addition of support for new parts, drop unused register macros.
No functional change.

Acked-by: Crt Mori <cmo@melexis.com>
Signed-off-by: Marek Vasut <marex@denx.de>
---
Cc: Crt Mori <cmo@melexis.com>
Cc: Jonathan Cameron <jic23@kernel.org>
Cc: Krzysztof Kozlowski <krzysztof.kozlowski+dt@linaro.org>
Cc: Lars-Peter Clausen <lars@metafoo.de>
Cc: Marek Vasut <marex@denx.de>
Cc: Peter Meerwald <pmeerw@pmeerw.net>
Cc: Rob Herring <robh+dt@kernel.org>
Cc: devicetree@vger.kernel.org
Cc: linux-iio@vger.kernel.org
---
V2: New patch
V3: Add AB from Crt
---
 drivers/iio/temperature/mlx90614.c | 4 ----
 1 file changed, 4 deletions(-)

diff --git a/drivers/iio/temperature/mlx90614.c b/drivers/iio/temperature/mlx90614.c
index bd92b24918253..b0f69a7b05abc 100644
--- a/drivers/iio/temperature/mlx90614.c
+++ b/drivers/iio/temperature/mlx90614.c
@@ -35,8 +35,6 @@
 #define MLX90614_OP_SLEEP	0xff
 
 /* RAM offsets with 16-bit data, MSB first */
-#define MLX90614_RAW1	(MLX90614_OP_RAM | 0x04) /* raw data IR channel 1 */
-#define MLX90614_RAW2	(MLX90614_OP_RAM | 0x05) /* raw data IR channel 2 */
 #define MLX90614_TA	(MLX90614_OP_RAM | 0x06) /* ambient temperature */
 #define MLX90614_TOBJ1	(MLX90614_OP_RAM | 0x07) /* object 1 temperature */
 #define MLX90614_TOBJ2	(MLX90614_OP_RAM | 0x08) /* object 2 temperature */
@@ -52,8 +50,6 @@
 #define MLX90614_CONFIG_DUAL_MASK (1 << MLX90614_CONFIG_DUAL_SHIFT)
 #define MLX90614_CONFIG_FIR_SHIFT 8 /* FIR coefficient */
 #define MLX90614_CONFIG_FIR_MASK (0x7 << MLX90614_CONFIG_FIR_SHIFT)
-#define MLX90614_CONFIG_GAIN_SHIFT 11 /* gain */
-#define MLX90614_CONFIG_GAIN_MASK (0x7 << MLX90614_CONFIG_GAIN_SHIFT)
 
 /* Timings (in ms) */
 #define MLX90614_TIMING_EEPROM 20 /* time for EEPROM write/erase to complete */
-- 
2.39.2


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [PATCH v3 4/6] iio: mlx90614: Drop MLX90614_CONST_EMISSIVITY_RESOLUTION
  2023-05-10 10:22 [PATCH v3 1/6] dt-bindings: iio: temperature: melexis,mlx90614: Document MLX90615 support Marek Vasut
  2023-05-10 10:22 ` [PATCH v3 2/6] iio: mlx90614: Sort headers Marek Vasut
  2023-05-10 10:22 ` [PATCH v3 3/6] iio: mlx90614: Drop unused register macros Marek Vasut
@ 2023-05-10 10:22 ` Marek Vasut
  2023-05-11  7:21   ` Crt Mori
  2023-05-10 10:22 ` [PATCH v3 5/6] iio: mlx90614: Factor our register IO and constants into model specific descriptor Marek Vasut
                   ` (2 subsequent siblings)
  5 siblings, 1 reply; 9+ messages in thread
From: Marek Vasut @ 2023-05-10 10:22 UTC (permalink / raw)
  To: linux-iio
  Cc: Marek Vasut, Crt Mori, Jonathan Cameron, Krzysztof Kozlowski,
	Lars-Peter Clausen, Peter Meerwald, Rob Herring, devicetree

The MLX90614_CONST_EMISSIVITY_RESOLUTION can be calculated from
MLX90614_CONST_RAW_EMISSIVITY_MAX, perform the calculation inline
and drio the MLX90614_CONST_EMISSIVITY_RESOLUTION.

Signed-off-by: Marek Vasut <marex@denx.de>
---
Cc: Crt Mori <cmo@melexis.com>
Cc: Jonathan Cameron <jic23@kernel.org>
Cc: Krzysztof Kozlowski <krzysztof.kozlowski+dt@linaro.org>
Cc: Lars-Peter Clausen <lars@metafoo.de>
Cc: Marek Vasut <marex@denx.de>
Cc: Peter Meerwald <pmeerw@pmeerw.net>
Cc: Rob Herring <robh+dt@kernel.org>
Cc: devicetree@vger.kernel.org
Cc: linux-iio@vger.kernel.org
---
V3: New patch
---
 drivers/iio/temperature/mlx90614.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/iio/temperature/mlx90614.c b/drivers/iio/temperature/mlx90614.c
index b0f69a7b05abc..ecd27fe0c8666 100644
--- a/drivers/iio/temperature/mlx90614.c
+++ b/drivers/iio/temperature/mlx90614.c
@@ -63,7 +63,6 @@
 #define MLX90614_CONST_OFFSET_REM 500000 /* remainder of offset (273.15*50) */
 #define MLX90614_CONST_SCALE 20 /* Scale in milliKelvin (0.02 * 1000) */
 #define MLX90614_CONST_RAW_EMISSIVITY_MAX 65535 /* max value for emissivity */
-#define MLX90614_CONST_EMISSIVITY_RESOLUTION 15259 /* 1/65535 ~ 0.000015259 */
 #define MLX90614_CONST_FIR 0x7 /* Fixed value for FIR part of low pass filter */
 
 struct mlx90614_data {
@@ -283,7 +282,8 @@ static int mlx90614_read_raw(struct iio_dev *indio_dev,
 			*val2 = 0;
 		} else {
 			*val = 0;
-			*val2 = ret * MLX90614_CONST_EMISSIVITY_RESOLUTION;
+			*val2 = ret * NSEC_PER_SEC /
+				MLX90614_CONST_RAW_EMISSIVITY_MAX;
 		}
 		return IIO_VAL_INT_PLUS_NANO;
 	case IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY: /* IIR setting with
@@ -321,7 +321,7 @@ static int mlx90614_write_raw(struct iio_dev *indio_dev,
 		if (val < 0 || val2 < 0 || val > 1 || (val == 1 && val2 != 0))
 			return -EINVAL;
 		val = val * MLX90614_CONST_RAW_EMISSIVITY_MAX +
-			val2 / MLX90614_CONST_EMISSIVITY_RESOLUTION;
+		      val2 * MLX90614_CONST_RAW_EMISSIVITY_MAX / NSEC_PER_SEC;
 
 		ret = mlx90614_power_get(data, false);
 		if (ret < 0)
-- 
2.39.2


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [PATCH v3 5/6] iio: mlx90614: Factor our register IO and constants into model specific descriptor
  2023-05-10 10:22 [PATCH v3 1/6] dt-bindings: iio: temperature: melexis,mlx90614: Document MLX90615 support Marek Vasut
                   ` (2 preceding siblings ...)
  2023-05-10 10:22 ` [PATCH v3 4/6] iio: mlx90614: Drop MLX90614_CONST_EMISSIVITY_RESOLUTION Marek Vasut
@ 2023-05-10 10:22 ` Marek Vasut
  2023-05-10 10:22 ` [PATCH v3 6/6] iio: mlx90614: Add MLX90615 support Marek Vasut
  2023-05-20 16:28 ` [PATCH v3 1/6] dt-bindings: iio: temperature: melexis,mlx90614: Document " Jonathan Cameron
  5 siblings, 0 replies; 9+ messages in thread
From: Marek Vasut @ 2023-05-10 10:22 UTC (permalink / raw)
  To: linux-iio
  Cc: Marek Vasut, Crt Mori, Jonathan Cameron, Krzysztof Kozlowski,
	Lars-Peter Clausen, Peter Meerwald, Rob Herring, devicetree

Factor out all the differences between MLX90614 and other similar chips
into a structure which describes the chip and allows abstracting out the
differences from the driver code. No functional change.

This patch moves all the RAM and EEPROM IO opcodes into the descriptor
structure and combines them, instead of combining the opcode and offset
in macros.

Acked-by: Crt Mori <cmo@melexis.com>
Tested-by: Crt Mori <cmo@melexis.com>
Signed-off-by: Marek Vasut <marex@denx.de>
---
Cc: Crt Mori <cmo@melexis.com>
Cc: Jonathan Cameron <jic23@kernel.org>
Cc: Krzysztof Kozlowski <krzysztof.kozlowski+dt@linaro.org>
Cc: Lars-Peter Clausen <lars@metafoo.de>
Cc: Marek Vasut <marex@denx.de>
Cc: Peter Meerwald <pmeerw@pmeerw.net>
Cc: Rob Herring <robh+dt@kernel.org>
Cc: devicetree@vger.kernel.org
Cc: linux-iio@vger.kernel.org
---
V2: New patch
V3: Add AB/TB from Crt
---
 drivers/iio/temperature/mlx90614.c | 181 +++++++++++++++++++----------
 1 file changed, 122 insertions(+), 59 deletions(-)

diff --git a/drivers/iio/temperature/mlx90614.c b/drivers/iio/temperature/mlx90614.c
index ecd27fe0c8666..3aa108a652bb4 100644
--- a/drivers/iio/temperature/mlx90614.c
+++ b/drivers/iio/temperature/mlx90614.c
@@ -25,6 +25,7 @@
 #include <linux/i2c.h>
 #include <linux/jiffies.h>
 #include <linux/module.h>
+#include <linux/of_device.h>
 #include <linux/pm_runtime.h>
 
 #include <linux/iio/iio.h>
@@ -34,15 +35,6 @@
 #define MLX90614_OP_EEPROM	0x20
 #define MLX90614_OP_SLEEP	0xff
 
-/* RAM offsets with 16-bit data, MSB first */
-#define MLX90614_TA	(MLX90614_OP_RAM | 0x06) /* ambient temperature */
-#define MLX90614_TOBJ1	(MLX90614_OP_RAM | 0x07) /* object 1 temperature */
-#define MLX90614_TOBJ2	(MLX90614_OP_RAM | 0x08) /* object 2 temperature */
-
-/* EEPROM offsets with 16-bit data, MSB first */
-#define MLX90614_EMISSIVITY	(MLX90614_OP_EEPROM | 0x04) /* emissivity correction coefficient */
-#define MLX90614_CONFIG		(MLX90614_OP_EEPROM | 0x05) /* configuration register */
-
 /* Control bits in configuration register */
 #define MLX90614_CONFIG_IIR_SHIFT 0 /* IIR coefficient */
 #define MLX90614_CONFIG_IIR_MASK (0x7 << MLX90614_CONFIG_IIR_SHIFT)
@@ -62,29 +54,44 @@
 #define MLX90614_CONST_OFFSET_DEC -13657 /* decimal part of the Kelvin offset */
 #define MLX90614_CONST_OFFSET_REM 500000 /* remainder of offset (273.15*50) */
 #define MLX90614_CONST_SCALE 20 /* Scale in milliKelvin (0.02 * 1000) */
-#define MLX90614_CONST_RAW_EMISSIVITY_MAX 65535 /* max value for emissivity */
 #define MLX90614_CONST_FIR 0x7 /* Fixed value for FIR part of low pass filter */
 
+/* Non-constant mask variant of FIELD_GET() and FIELD_PREP() */
+#define field_get(_mask, _reg)	(((_reg) & (_mask)) >> (ffs(_mask) - 1))
+#define field_prep(_mask, _val)	(((_val) << (ffs(_mask) - 1)) & (_mask))
+
+struct mlx_chip_info {
+	/* EEPROM offsets with 16-bit data, MSB first */
+	/* emissivity correction coefficient */
+	u8			op_eeprom_emissivity;
+	u8			op_eeprom_config1;
+	/* RAM offsets with 16-bit data, MSB first */
+	/* ambient temperature */
+	u8			op_ram_ta;
+	/* object 1 temperature */
+	u8			op_ram_tobj1;
+	/* object 2 temperature */
+	u8			op_ram_tobj2;
+	u8			op_sleep;
+	/* support for two input channels (MLX90614 only) */
+	u8			dual_channel;
+	u8			wakeup_delay_ms;
+	u16			emissivity_max;
+	u16			fir_config_mask;
+	u16			iir_config_mask;
+	int			iir_valid_offset;
+	u16			iir_values[8];
+	int			iir_freqs[8][2];
+};
+
 struct mlx90614_data {
 	struct i2c_client *client;
 	struct mutex lock; /* for EEPROM access only */
 	struct gpio_desc *wakeup_gpio; /* NULL to disable sleep/wake-up */
+	const struct mlx_chip_info *chip_info; /* Chip hardware details */
 	unsigned long ready_timestamp; /* in jiffies */
 };
 
-/* Bandwidth values for IIR filtering */
-static const int mlx90614_iir_values[] = {77, 31, 20, 15, 723, 153, 110, 86};
-static const int mlx90614_freqs[][2] = {
-	{0, 150000},
-	{0, 200000},
-	{0, 310000},
-	{0, 770000},
-	{0, 860000},
-	{1, 100000},
-	{1, 530000},
-	{7, 230000}
-};
-
 /*
  * Erase an address and write word.
  * The mutex must be locked before calling.
@@ -124,21 +131,26 @@ static s32 mlx90614_write_word(const struct i2c_client *client, u8 command,
 }
 
 /*
- * Find the IIR value inside mlx90614_iir_values array and return its position
+ * Find the IIR value inside iir_values array and return its position
  * which is equivalent to the bit value in sensor register
  */
 static inline s32 mlx90614_iir_search(const struct i2c_client *client,
 				      int value)
 {
+	struct iio_dev *indio_dev = i2c_get_clientdata(client);
+	struct mlx90614_data *data = iio_priv(indio_dev);
+	const struct mlx_chip_info *chip_info = data->chip_info;
 	int i;
 	s32 ret;
 
-	for (i = 0; i < ARRAY_SIZE(mlx90614_iir_values); ++i) {
-		if (value == mlx90614_iir_values[i])
+	for (i = chip_info->iir_valid_offset;
+	     i < ARRAY_SIZE(chip_info->iir_values);
+	     i++) {
+		if (value == chip_info->iir_values[i])
 			break;
 	}
 
-	if (i == ARRAY_SIZE(mlx90614_iir_values))
+	if (i == ARRAY_SIZE(chip_info->iir_values))
 		return -EINVAL;
 
 	/*
@@ -146,17 +158,21 @@ static inline s32 mlx90614_iir_search(const struct i2c_client *client,
 	 * we must read them before we actually write
 	 * changes
 	 */
-	ret = i2c_smbus_read_word_data(client, MLX90614_CONFIG);
+	ret = i2c_smbus_read_word_data(client, chip_info->op_eeprom_config1);
 	if (ret < 0)
 		return ret;
 
-	ret &= ~MLX90614_CONFIG_FIR_MASK;
-	ret |= MLX90614_CONST_FIR << MLX90614_CONFIG_FIR_SHIFT;
-	ret &= ~MLX90614_CONFIG_IIR_MASK;
-	ret |= i << MLX90614_CONFIG_IIR_SHIFT;
+	/* Modify FIR on parts which have configurable FIR filter */
+	if (chip_info->fir_config_mask) {
+		ret &= ~chip_info->fir_config_mask;
+		ret |= field_prep(chip_info->fir_config_mask, MLX90614_CONST_FIR);
+	}
+
+	ret &= ~chip_info->iir_config_mask;
+	ret |= field_prep(chip_info->iir_config_mask, i);
 
 	/* Write changed values */
-	ret = mlx90614_write_word(client, MLX90614_CONFIG, ret);
+	ret = mlx90614_write_word(client, chip_info->op_eeprom_config1, ret);
 	return ret;
 }
 
@@ -216,22 +232,26 @@ static int mlx90614_read_raw(struct iio_dev *indio_dev,
 			    int *val2, long mask)
 {
 	struct mlx90614_data *data = iio_priv(indio_dev);
-	u8 cmd;
+	const struct mlx_chip_info *chip_info = data->chip_info;
+	u8 cmd, idx;
 	s32 ret;
 
 	switch (mask) {
 	case IIO_CHAN_INFO_RAW: /* 0.02K / LSB */
 		switch (channel->channel2) {
 		case IIO_MOD_TEMP_AMBIENT:
-			cmd = MLX90614_TA;
+			cmd = chip_info->op_ram_ta;
 			break;
 		case IIO_MOD_TEMP_OBJECT:
+			if (chip_info->dual_channel && channel->channel)
+				return -EINVAL;
+
 			switch (channel->channel) {
 			case 0:
-				cmd = MLX90614_TOBJ1;
+				cmd = chip_info->op_ram_tobj1;
 				break;
 			case 1:
-				cmd = MLX90614_TOBJ2;
+				cmd = chip_info->op_ram_tobj2;
 				break;
 			default:
 				return -EINVAL;
@@ -263,27 +283,26 @@ static int mlx90614_read_raw(struct iio_dev *indio_dev,
 	case IIO_CHAN_INFO_SCALE:
 		*val = MLX90614_CONST_SCALE;
 		return IIO_VAL_INT;
-	case IIO_CHAN_INFO_CALIBEMISSIVITY: /* 1/65535 / LSB */
+	case IIO_CHAN_INFO_CALIBEMISSIVITY: /* 1/emissivity_max / LSB */
 		ret = mlx90614_power_get(data, false);
 		if (ret < 0)
 			return ret;
 
 		mutex_lock(&data->lock);
 		ret = i2c_smbus_read_word_data(data->client,
-					       MLX90614_EMISSIVITY);
+					       chip_info->op_eeprom_emissivity);
 		mutex_unlock(&data->lock);
 		mlx90614_power_put(data);
 
 		if (ret < 0)
 			return ret;
 
-		if (ret == MLX90614_CONST_RAW_EMISSIVITY_MAX) {
+		if (ret == chip_info->emissivity_max) {
 			*val = 1;
 			*val2 = 0;
 		} else {
 			*val = 0;
-			*val2 = ret * NSEC_PER_SEC /
-				MLX90614_CONST_RAW_EMISSIVITY_MAX;
+			*val2 = ret * NSEC_PER_SEC / chip_info->emissivity_max;
 		}
 		return IIO_VAL_INT_PLUS_NANO;
 	case IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY: /* IIR setting with
@@ -293,16 +312,19 @@ static int mlx90614_read_raw(struct iio_dev *indio_dev,
 			return ret;
 
 		mutex_lock(&data->lock);
-		ret = i2c_smbus_read_word_data(data->client, MLX90614_CONFIG);
+		ret = i2c_smbus_read_word_data(data->client,
+					       chip_info->op_eeprom_config1);
 		mutex_unlock(&data->lock);
 		mlx90614_power_put(data);
 
 		if (ret < 0)
 			return ret;
 
-		*val = mlx90614_iir_values[ret & MLX90614_CONFIG_IIR_MASK] / 100;
-		*val2 = (mlx90614_iir_values[ret & MLX90614_CONFIG_IIR_MASK] % 100) *
-			10000;
+		idx = field_get(chip_info->iir_config_mask, ret) -
+		      chip_info->iir_valid_offset;
+
+		*val = chip_info->iir_values[idx] / 100;
+		*val2 = (chip_info->iir_values[idx] % 100) * 10000;
 		return IIO_VAL_INT_PLUS_MICRO;
 	default:
 		return -EINVAL;
@@ -314,22 +336,23 @@ static int mlx90614_write_raw(struct iio_dev *indio_dev,
 			     int val2, long mask)
 {
 	struct mlx90614_data *data = iio_priv(indio_dev);
+	const struct mlx_chip_info *chip_info = data->chip_info;
 	s32 ret;
 
 	switch (mask) {
-	case IIO_CHAN_INFO_CALIBEMISSIVITY: /* 1/65535 / LSB */
+	case IIO_CHAN_INFO_CALIBEMISSIVITY: /* 1/emissivity_max / LSB */
 		if (val < 0 || val2 < 0 || val > 1 || (val == 1 && val2 != 0))
 			return -EINVAL;
-		val = val * MLX90614_CONST_RAW_EMISSIVITY_MAX +
-		      val2 * MLX90614_CONST_RAW_EMISSIVITY_MAX / NSEC_PER_SEC;
+		val = val * chip_info->emissivity_max +
+		      val2 * chip_info->emissivity_max / NSEC_PER_SEC;
 
 		ret = mlx90614_power_get(data, false);
 		if (ret < 0)
 			return ret;
 
 		mutex_lock(&data->lock);
-		ret = mlx90614_write_word(data->client, MLX90614_EMISSIVITY,
-					  val);
+		ret = mlx90614_write_word(data->client,
+					  chip_info->op_eeprom_emissivity, val);
 		mutex_unlock(&data->lock);
 		mlx90614_power_put(data);
 
@@ -373,11 +396,15 @@ static int mlx90614_read_avail(struct iio_dev *indio_dev,
 			       const int **vals, int *type, int *length,
 			       long mask)
 {
+	struct mlx90614_data *data = iio_priv(indio_dev);
+	const struct mlx_chip_info *chip_info = data->chip_info;
+
 	switch (mask) {
 	case IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY:
-		*vals = (int *)mlx90614_freqs;
+		*vals = (int *)chip_info->iir_freqs;
 		*type = IIO_VAL_INT_PLUS_MICRO;
-		*length = 2 * ARRAY_SIZE(mlx90614_freqs);
+		*length = 2 * (ARRAY_SIZE(chip_info->iir_freqs) -
+			       chip_info->iir_valid_offset);
 		return IIO_AVAIL_LIST;
 	default:
 		return -EINVAL;
@@ -431,6 +458,7 @@ static const struct iio_info mlx90614_info = {
 #ifdef CONFIG_PM
 static int mlx90614_sleep(struct mlx90614_data *data)
 {
+	const struct mlx_chip_info *chip_info = data->chip_info;
 	s32 ret;
 
 	if (!data->wakeup_gpio) {
@@ -443,7 +471,7 @@ static int mlx90614_sleep(struct mlx90614_data *data)
 	mutex_lock(&data->lock);
 	ret = i2c_smbus_xfer(data->client->adapter, data->client->addr,
 			     data->client->flags | I2C_CLIENT_PEC,
-			     I2C_SMBUS_WRITE, MLX90614_OP_SLEEP,
+			     I2C_SMBUS_WRITE, chip_info->op_sleep,
 			     I2C_SMBUS_BYTE, NULL);
 	mutex_unlock(&data->lock);
 
@@ -452,6 +480,8 @@ static int mlx90614_sleep(struct mlx90614_data *data)
 
 static int mlx90614_wakeup(struct mlx90614_data *data)
 {
+	const struct mlx_chip_info *chip_info = data->chip_info;
+
 	if (!data->wakeup_gpio) {
 		dev_dbg(&data->client->dev, "Wake-up disabled");
 		return -ENOSYS;
@@ -461,7 +491,7 @@ static int mlx90614_wakeup(struct mlx90614_data *data)
 
 	i2c_lock_bus(data->client->adapter, I2C_LOCK_ROOT_ADAPTER);
 	gpiod_direction_output(data->wakeup_gpio, 0);
-	msleep(MLX90614_TIMING_WAKEUP);
+	msleep(chip_info->wakeup_delay_ms);
 	gpiod_direction_input(data->wakeup_gpio);
 	i2c_unlock_bus(data->client->adapter, I2C_LOCK_ROOT_ADAPTER);
 
@@ -474,7 +504,7 @@ static int mlx90614_wakeup(struct mlx90614_data *data)
 	 * If the read fails, the controller will probably be reset so that
 	 * further reads will work.
 	 */
-	i2c_smbus_read_word_data(data->client, MLX90614_CONFIG);
+	i2c_smbus_read_word_data(data->client, chip_info->op_eeprom_config1);
 
 	return 0;
 }
@@ -523,9 +553,15 @@ static inline struct gpio_desc *mlx90614_probe_wakeup(struct i2c_client *client)
 /* Return 0 for single sensor, 1 for dual sensor, <0 on error. */
 static int mlx90614_probe_num_ir_sensors(struct i2c_client *client)
 {
+	struct iio_dev *indio_dev = i2c_get_clientdata(client);
+	struct mlx90614_data *data = iio_priv(indio_dev);
+	const struct mlx_chip_info *chip_info = data->chip_info;
 	s32 ret;
 
-	ret = i2c_smbus_read_word_data(client, MLX90614_CONFIG);
+	if (chip_info->dual_channel)
+		return 0;
+
+	ret = i2c_smbus_read_word_data(client, chip_info->op_eeprom_config1);
 
 	if (ret < 0)
 		return ret;
@@ -552,6 +588,7 @@ static int mlx90614_probe(struct i2c_client *client)
 	data->client = client;
 	mutex_init(&data->lock);
 	data->wakeup_gpio = mlx90614_probe_wakeup(client);
+	data->chip_info = device_get_match_data(&client->dev);
 
 	mlx90614_wakeup(data);
 
@@ -601,14 +638,40 @@ static void mlx90614_remove(struct i2c_client *client)
 	}
 }
 
+static const struct mlx_chip_info mlx90614_chip_info = {
+	.op_eeprom_emissivity		= MLX90614_OP_EEPROM | 0x04,
+	.op_eeprom_config1		= MLX90614_OP_EEPROM | 0x05,
+	.op_ram_ta			= MLX90614_OP_RAM | 0x06,
+	.op_ram_tobj1			= MLX90614_OP_RAM | 0x07,
+	.op_ram_tobj2			= MLX90614_OP_RAM | 0x08,
+	.op_sleep			= MLX90614_OP_SLEEP,
+	.dual_channel			= true,
+	.wakeup_delay_ms		= MLX90614_TIMING_WAKEUP,
+	.emissivity_max			= 65535,
+	.fir_config_mask		= MLX90614_CONFIG_FIR_MASK,
+	.iir_config_mask		= MLX90614_CONFIG_IIR_MASK,
+	.iir_valid_offset		= 0,
+	.iir_values			= { 77, 31, 20, 15, 723, 153, 110, 86 },
+	.iir_freqs			= {
+		{ 0, 150000 },	/* 13% ~= 0.15 Hz */
+		{ 0, 200000 },	/* 17% ~= 0.20 Hz */
+		{ 0, 310000 },	/* 25% ~= 0.31 Hz */
+		{ 0, 770000 },	/* 50% ~= 0.77 Hz */
+		{ 0, 860000 },	/* 57% ~= 0.86 Hz */
+		{ 1, 100000 },	/* 67% ~= 1.10 Hz */
+		{ 1, 530000 },	/* 80% ~= 1.53 Hz */
+		{ 7, 230000 }	/* 100% ~= 7.23 Hz */
+	},
+};
+
 static const struct i2c_device_id mlx90614_id[] = {
-	{ "mlx90614", 0 },
+	{ "mlx90614", .driver_data = (kernel_ulong_t)&mlx90614_chip_info },
 	{ }
 };
 MODULE_DEVICE_TABLE(i2c, mlx90614_id);
 
 static const struct of_device_id mlx90614_of_match[] = {
-	{ .compatible = "melexis,mlx90614" },
+	{ .compatible = "melexis,mlx90614", .data = &mlx90614_chip_info },
 	{ }
 };
 MODULE_DEVICE_TABLE(of, mlx90614_of_match);
-- 
2.39.2


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [PATCH v3 6/6] iio: mlx90614: Add MLX90615 support
  2023-05-10 10:22 [PATCH v3 1/6] dt-bindings: iio: temperature: melexis,mlx90614: Document MLX90615 support Marek Vasut
                   ` (3 preceding siblings ...)
  2023-05-10 10:22 ` [PATCH v3 5/6] iio: mlx90614: Factor our register IO and constants into model specific descriptor Marek Vasut
@ 2023-05-10 10:22 ` Marek Vasut
  2023-05-11  7:22   ` Crt Mori
  2023-05-20 16:28 ` [PATCH v3 1/6] dt-bindings: iio: temperature: melexis,mlx90614: Document " Jonathan Cameron
  5 siblings, 1 reply; 9+ messages in thread
From: Marek Vasut @ 2023-05-10 10:22 UTC (permalink / raw)
  To: linux-iio
  Cc: Marek Vasut, Crt Mori, Jonathan Cameron, Krzysztof Kozlowski,
	Lars-Peter Clausen, Peter Meerwald, Rob Herring, devicetree

Add support for MLX90615 Infra Red Thermometer, which seems to be
the predecesor of MLX90614 . There are significant differences in
the register layout compared to MLX90614, but the functionality
of the device is virtually identical.

The following differences have been identified:
- RAM/EEPROM/SLEEP access opcodes are different
- RAM/EEPROM registers are at different offsets
- EEPROM emissivity and configuration registers are at different offsets
- EEPROM configuration register bits are shuffled around
- EEPROM emissivity settings are 14 bit on MLX90615 , 16 bit on MLX90614
- MLX90615 can only ever support one sensor, MLX90614 could support two
- FIR filter is set to fixed settings on MLX90615
- IIR filter coefficients are different

This patch fills in the MLX90615 specific description and quirk handling.

The IIR filter coefficients were provided by Melexis as follows:
0b0000 - Forbidden value
0b0001 - 100% - settling time = refresh rate = 205ms (around 5Hz)
0b0010 - 50% - settling time = 2050ms (around 0.5Hz)
0b0011 - 33% - settling time = 36900ms (around 0.3Hz)
0b0100 - 25% - settling time = 5125ms (around 0.2Hz)
0b0101 - 20% - settling time = 6355ms (around 0.15Hz)
0b0110 - 17% - settling time = 7790ms (around 0.13Hz)
0b0111 - 14% - settling time = 9225ms (around 0.1Hz)

Signed-off-by: Marek Vasut <marex@denx.de>
---
Cc: Crt Mori <cmo@melexis.com>
Cc: Jonathan Cameron <jic23@kernel.org>
Cc: Krzysztof Kozlowski <krzysztof.kozlowski+dt@linaro.org>
Cc: Lars-Peter Clausen <lars@metafoo.de>
Cc: Marek Vasut <marex@denx.de>
Cc: Peter Meerwald <pmeerw@pmeerw.net>
Cc: Rob Herring <robh+dt@kernel.org>
Cc: devicetree@vger.kernel.org
Cc: linux-iio@vger.kernel.org
---
V2: Split the patch up into cleanups, abstraction and MLX90615 addition
V3: Drop emissivity_res, update IIR filter coefficients per Melexis input
---
 drivers/iio/temperature/mlx90614.c | 48 +++++++++++++++++++++++++++---
 1 file changed, 44 insertions(+), 4 deletions(-)

diff --git a/drivers/iio/temperature/mlx90614.c b/drivers/iio/temperature/mlx90614.c
index 3aa108a652bb4..b2affcb795e00 100644
--- a/drivers/iio/temperature/mlx90614.c
+++ b/drivers/iio/temperature/mlx90614.c
@@ -1,12 +1,15 @@
 // SPDX-License-Identifier: GPL-2.0-only
 /*
- * mlx90614.c - Support for Melexis MLX90614 contactless IR temperature sensor
+ * mlx90614.c - Support for Melexis MLX90614/MLX90615 contactless IR temperature sensor
  *
  * Copyright (c) 2014 Peter Meerwald <pmeerw@pmeerw.net>
  * Copyright (c) 2015 Essensium NV
  * Copyright (c) 2015 Melexis
  *
- * Driver for the Melexis MLX90614 I2C 16-bit IR thermopile sensor
+ * Driver for the Melexis MLX90614/MLX90615 I2C 16-bit IR thermopile sensor
+ *
+ * MLX90614 - 17-bit ADC + MLX90302 DSP
+ * MLX90615 - 16-bit ADC + MLX90325 DSP
  *
  * (7-bit I2C slave address 0x5a, 100KHz bus speed only!)
  *
@@ -35,6 +38,10 @@
 #define MLX90614_OP_EEPROM	0x20
 #define MLX90614_OP_SLEEP	0xff
 
+#define MLX90615_OP_EEPROM	0x10
+#define MLX90615_OP_RAM		0x20
+#define MLX90615_OP_SLEEP	0xc6
+
 /* Control bits in configuration register */
 #define MLX90614_CONFIG_IIR_SHIFT 0 /* IIR coefficient */
 #define MLX90614_CONFIG_IIR_MASK (0x7 << MLX90614_CONFIG_IIR_SHIFT)
@@ -43,11 +50,16 @@
 #define MLX90614_CONFIG_FIR_SHIFT 8 /* FIR coefficient */
 #define MLX90614_CONFIG_FIR_MASK (0x7 << MLX90614_CONFIG_FIR_SHIFT)
 
+#define MLX90615_CONFIG_IIR_SHIFT 12 /* IIR coefficient */
+#define MLX90615_CONFIG_IIR_MASK (0x7 << MLX90615_CONFIG_IIR_SHIFT)
+
 /* Timings (in ms) */
 #define MLX90614_TIMING_EEPROM 20 /* time for EEPROM write/erase to complete */
 #define MLX90614_TIMING_WAKEUP 34 /* time to hold SDA low for wake-up */
 #define MLX90614_TIMING_STARTUP 250 /* time before first data after wake-up */
 
+#define MLX90615_TIMING_WAKEUP 22 /* time to hold SCL low for wake-up */
+
 #define MLX90614_AUTOSLEEP_DELAY 5000 /* default autosleep delay */
 
 /* Magic constants */
@@ -305,8 +317,8 @@ static int mlx90614_read_raw(struct iio_dev *indio_dev,
 			*val2 = ret * NSEC_PER_SEC / chip_info->emissivity_max;
 		}
 		return IIO_VAL_INT_PLUS_NANO;
-	case IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY: /* IIR setting with
-							     FIR = 1024 */
+	/* IIR setting with FIR=1024 (MLX90614) or FIR=65536 (MLX90615) */
+	case IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY:
 		ret = mlx90614_power_get(data, false);
 		if (ret < 0)
 			return ret;
@@ -664,14 +676,42 @@ static const struct mlx_chip_info mlx90614_chip_info = {
 	},
 };
 
+static const struct mlx_chip_info mlx90615_chip_info = {
+	.op_eeprom_emissivity		= MLX90615_OP_EEPROM | 0x03,
+	.op_eeprom_config1		= MLX90615_OP_EEPROM | 0x02,
+	.op_ram_ta			= MLX90615_OP_RAM | 0x06,
+	.op_ram_tobj1			= MLX90615_OP_RAM | 0x07,
+	.op_ram_tobj2			= MLX90615_OP_RAM | 0x08,
+	.op_sleep			= MLX90615_OP_SLEEP,
+	.dual_channel			= false,
+	.wakeup_delay_ms		= MLX90615_TIMING_WAKEUP,
+	.emissivity_max			= 16383,
+	.fir_config_mask		= 0,	/* MLX90615 FIR is fixed */
+	.iir_config_mask		= MLX90615_CONFIG_IIR_MASK,
+	/* IIR value 0 is FORBIDDEN COMBINATION on MLX90615 */
+	.iir_valid_offset		= 1,
+	.iir_values			= { 500, 50, 30, 20, 15, 13, 10 },
+	.iir_freqs			= {
+		{ 0, 100000 },	/* 14% ~= 0.10 Hz */
+		{ 0, 130000 },	/* 17% ~= 0.13 Hz */
+		{ 0, 150000 },	/* 20% ~= 0.15 Hz */
+		{ 0, 200000 },	/* 25% ~= 0.20 Hz */
+		{ 0, 300000 },	/* 33% ~= 0.30 Hz */
+		{ 0, 500000 },	/* 50% ~= 0.50 Hz */
+		{ 5, 000000 },	/* 100% ~= 5.00 Hz */
+	},
+};
+
 static const struct i2c_device_id mlx90614_id[] = {
 	{ "mlx90614", .driver_data = (kernel_ulong_t)&mlx90614_chip_info },
+	{ "mlx90615", .driver_data = (kernel_ulong_t)&mlx90615_chip_info },
 	{ }
 };
 MODULE_DEVICE_TABLE(i2c, mlx90614_id);
 
 static const struct of_device_id mlx90614_of_match[] = {
 	{ .compatible = "melexis,mlx90614", .data = &mlx90614_chip_info },
+	{ .compatible = "melexis,mlx90615", .data = &mlx90615_chip_info },
 	{ }
 };
 MODULE_DEVICE_TABLE(of, mlx90614_of_match);
-- 
2.39.2


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* Re: [PATCH v3 4/6] iio: mlx90614: Drop MLX90614_CONST_EMISSIVITY_RESOLUTION
  2023-05-10 10:22 ` [PATCH v3 4/6] iio: mlx90614: Drop MLX90614_CONST_EMISSIVITY_RESOLUTION Marek Vasut
@ 2023-05-11  7:21   ` Crt Mori
  0 siblings, 0 replies; 9+ messages in thread
From: Crt Mori @ 2023-05-11  7:21 UTC (permalink / raw)
  To: Marek Vasut
  Cc: linux-iio, Jonathan Cameron, Krzysztof Kozlowski,
	Lars-Peter Clausen, Peter Meerwald, Rob Herring, devicetree

Acked-by: Crt Mori <cmo@melexis.com>

On Wed, 10 May 2023 at 12:23, Marek Vasut <marex@denx.de> wrote:
>
> The MLX90614_CONST_EMISSIVITY_RESOLUTION can be calculated from
> MLX90614_CONST_RAW_EMISSIVITY_MAX, perform the calculation inline
> and drio the MLX90614_CONST_EMISSIVITY_RESOLUTION.
>
> Signed-off-by: Marek Vasut <marex@denx.de>
> ---
> Cc: Crt Mori <cmo@melexis.com>
> Cc: Jonathan Cameron <jic23@kernel.org>
> Cc: Krzysztof Kozlowski <krzysztof.kozlowski+dt@linaro.org>
> Cc: Lars-Peter Clausen <lars@metafoo.de>
> Cc: Marek Vasut <marex@denx.de>
> Cc: Peter Meerwald <pmeerw@pmeerw.net>
> Cc: Rob Herring <robh+dt@kernel.org>
> Cc: devicetree@vger.kernel.org
> Cc: linux-iio@vger.kernel.org
> ---
> V3: New patch
> ---
>  drivers/iio/temperature/mlx90614.c | 6 +++---
>  1 file changed, 3 insertions(+), 3 deletions(-)
>
> diff --git a/drivers/iio/temperature/mlx90614.c b/drivers/iio/temperature/mlx90614.c
> index b0f69a7b05abc..ecd27fe0c8666 100644
> --- a/drivers/iio/temperature/mlx90614.c
> +++ b/drivers/iio/temperature/mlx90614.c
> @@ -63,7 +63,6 @@
>  #define MLX90614_CONST_OFFSET_REM 500000 /* remainder of offset (273.15*50) */
>  #define MLX90614_CONST_SCALE 20 /* Scale in milliKelvin (0.02 * 1000) */
>  #define MLX90614_CONST_RAW_EMISSIVITY_MAX 65535 /* max value for emissivity */
> -#define MLX90614_CONST_EMISSIVITY_RESOLUTION 15259 /* 1/65535 ~ 0.000015259 */
>  #define MLX90614_CONST_FIR 0x7 /* Fixed value for FIR part of low pass filter */
>
>  struct mlx90614_data {
> @@ -283,7 +282,8 @@ static int mlx90614_read_raw(struct iio_dev *indio_dev,
>                         *val2 = 0;
>                 } else {
>                         *val = 0;
> -                       *val2 = ret * MLX90614_CONST_EMISSIVITY_RESOLUTION;
> +                       *val2 = ret * NSEC_PER_SEC /
> +                               MLX90614_CONST_RAW_EMISSIVITY_MAX;
>                 }
>                 return IIO_VAL_INT_PLUS_NANO;
>         case IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY: /* IIR setting with
> @@ -321,7 +321,7 @@ static int mlx90614_write_raw(struct iio_dev *indio_dev,
>                 if (val < 0 || val2 < 0 || val > 1 || (val == 1 && val2 != 0))
>                         return -EINVAL;
>                 val = val * MLX90614_CONST_RAW_EMISSIVITY_MAX +
> -                       val2 / MLX90614_CONST_EMISSIVITY_RESOLUTION;
> +                     val2 * MLX90614_CONST_RAW_EMISSIVITY_MAX / NSEC_PER_SEC;
>
>                 ret = mlx90614_power_get(data, false);
>                 if (ret < 0)
> --
> 2.39.2
>

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH v3 6/6] iio: mlx90614: Add MLX90615 support
  2023-05-10 10:22 ` [PATCH v3 6/6] iio: mlx90614: Add MLX90615 support Marek Vasut
@ 2023-05-11  7:22   ` Crt Mori
  0 siblings, 0 replies; 9+ messages in thread
From: Crt Mori @ 2023-05-11  7:22 UTC (permalink / raw)
  To: Marek Vasut
  Cc: linux-iio, Jonathan Cameron, Krzysztof Kozlowski,
	Lars-Peter Clausen, Peter Meerwald, Rob Herring, devicetree

Acked-by: Crt Mori <cmo@melexis.com>

On Wed, 10 May 2023 at 12:23, Marek Vasut <marex@denx.de> wrote:
>
> Add support for MLX90615 Infra Red Thermometer, which seems to be
> the predecesor of MLX90614 . There are significant differences in
> the register layout compared to MLX90614, but the functionality
> of the device is virtually identical.
>
> The following differences have been identified:
> - RAM/EEPROM/SLEEP access opcodes are different
> - RAM/EEPROM registers are at different offsets
> - EEPROM emissivity and configuration registers are at different offsets
> - EEPROM configuration register bits are shuffled around
> - EEPROM emissivity settings are 14 bit on MLX90615 , 16 bit on MLX90614
> - MLX90615 can only ever support one sensor, MLX90614 could support two
> - FIR filter is set to fixed settings on MLX90615
> - IIR filter coefficients are different
>
> This patch fills in the MLX90615 specific description and quirk handling.
>
> The IIR filter coefficients were provided by Melexis as follows:
> 0b0000 - Forbidden value
> 0b0001 - 100% - settling time = refresh rate = 205ms (around 5Hz)
> 0b0010 - 50% - settling time = 2050ms (around 0.5Hz)
> 0b0011 - 33% - settling time = 36900ms (around 0.3Hz)
> 0b0100 - 25% - settling time = 5125ms (around 0.2Hz)
> 0b0101 - 20% - settling time = 6355ms (around 0.15Hz)
> 0b0110 - 17% - settling time = 7790ms (around 0.13Hz)
> 0b0111 - 14% - settling time = 9225ms (around 0.1Hz)
>
> Signed-off-by: Marek Vasut <marex@denx.de>
> ---
> Cc: Crt Mori <cmo@melexis.com>
> Cc: Jonathan Cameron <jic23@kernel.org>
> Cc: Krzysztof Kozlowski <krzysztof.kozlowski+dt@linaro.org>
> Cc: Lars-Peter Clausen <lars@metafoo.de>
> Cc: Marek Vasut <marex@denx.de>
> Cc: Peter Meerwald <pmeerw@pmeerw.net>
> Cc: Rob Herring <robh+dt@kernel.org>
> Cc: devicetree@vger.kernel.org
> Cc: linux-iio@vger.kernel.org
> ---
> V2: Split the patch up into cleanups, abstraction and MLX90615 addition
> V3: Drop emissivity_res, update IIR filter coefficients per Melexis input
> ---
>  drivers/iio/temperature/mlx90614.c | 48 +++++++++++++++++++++++++++---
>  1 file changed, 44 insertions(+), 4 deletions(-)
>
> diff --git a/drivers/iio/temperature/mlx90614.c b/drivers/iio/temperature/mlx90614.c
> index 3aa108a652bb4..b2affcb795e00 100644
> --- a/drivers/iio/temperature/mlx90614.c
> +++ b/drivers/iio/temperature/mlx90614.c
> @@ -1,12 +1,15 @@
>  // SPDX-License-Identifier: GPL-2.0-only
>  /*
> - * mlx90614.c - Support for Melexis MLX90614 contactless IR temperature sensor
> + * mlx90614.c - Support for Melexis MLX90614/MLX90615 contactless IR temperature sensor
>   *
>   * Copyright (c) 2014 Peter Meerwald <pmeerw@pmeerw.net>
>   * Copyright (c) 2015 Essensium NV
>   * Copyright (c) 2015 Melexis
>   *
> - * Driver for the Melexis MLX90614 I2C 16-bit IR thermopile sensor
> + * Driver for the Melexis MLX90614/MLX90615 I2C 16-bit IR thermopile sensor
> + *
> + * MLX90614 - 17-bit ADC + MLX90302 DSP
> + * MLX90615 - 16-bit ADC + MLX90325 DSP
>   *
>   * (7-bit I2C slave address 0x5a, 100KHz bus speed only!)
>   *
> @@ -35,6 +38,10 @@
>  #define MLX90614_OP_EEPROM     0x20
>  #define MLX90614_OP_SLEEP      0xff
>
> +#define MLX90615_OP_EEPROM     0x10
> +#define MLX90615_OP_RAM                0x20
> +#define MLX90615_OP_SLEEP      0xc6
> +
>  /* Control bits in configuration register */
>  #define MLX90614_CONFIG_IIR_SHIFT 0 /* IIR coefficient */
>  #define MLX90614_CONFIG_IIR_MASK (0x7 << MLX90614_CONFIG_IIR_SHIFT)
> @@ -43,11 +50,16 @@
>  #define MLX90614_CONFIG_FIR_SHIFT 8 /* FIR coefficient */
>  #define MLX90614_CONFIG_FIR_MASK (0x7 << MLX90614_CONFIG_FIR_SHIFT)
>
> +#define MLX90615_CONFIG_IIR_SHIFT 12 /* IIR coefficient */
> +#define MLX90615_CONFIG_IIR_MASK (0x7 << MLX90615_CONFIG_IIR_SHIFT)
> +
>  /* Timings (in ms) */
>  #define MLX90614_TIMING_EEPROM 20 /* time for EEPROM write/erase to complete */
>  #define MLX90614_TIMING_WAKEUP 34 /* time to hold SDA low for wake-up */
>  #define MLX90614_TIMING_STARTUP 250 /* time before first data after wake-up */
>
> +#define MLX90615_TIMING_WAKEUP 22 /* time to hold SCL low for wake-up */
> +
>  #define MLX90614_AUTOSLEEP_DELAY 5000 /* default autosleep delay */
>
>  /* Magic constants */
> @@ -305,8 +317,8 @@ static int mlx90614_read_raw(struct iio_dev *indio_dev,
>                         *val2 = ret * NSEC_PER_SEC / chip_info->emissivity_max;
>                 }
>                 return IIO_VAL_INT_PLUS_NANO;
> -       case IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY: /* IIR setting with
> -                                                            FIR = 1024 */
> +       /* IIR setting with FIR=1024 (MLX90614) or FIR=65536 (MLX90615) */
> +       case IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY:
>                 ret = mlx90614_power_get(data, false);
>                 if (ret < 0)
>                         return ret;
> @@ -664,14 +676,42 @@ static const struct mlx_chip_info mlx90614_chip_info = {
>         },
>  };
>
> +static const struct mlx_chip_info mlx90615_chip_info = {
> +       .op_eeprom_emissivity           = MLX90615_OP_EEPROM | 0x03,
> +       .op_eeprom_config1              = MLX90615_OP_EEPROM | 0x02,
> +       .op_ram_ta                      = MLX90615_OP_RAM | 0x06,
> +       .op_ram_tobj1                   = MLX90615_OP_RAM | 0x07,
> +       .op_ram_tobj2                   = MLX90615_OP_RAM | 0x08,
> +       .op_sleep                       = MLX90615_OP_SLEEP,
> +       .dual_channel                   = false,
> +       .wakeup_delay_ms                = MLX90615_TIMING_WAKEUP,
> +       .emissivity_max                 = 16383,
> +       .fir_config_mask                = 0,    /* MLX90615 FIR is fixed */
> +       .iir_config_mask                = MLX90615_CONFIG_IIR_MASK,
> +       /* IIR value 0 is FORBIDDEN COMBINATION on MLX90615 */
> +       .iir_valid_offset               = 1,
> +       .iir_values                     = { 500, 50, 30, 20, 15, 13, 10 },
> +       .iir_freqs                      = {
> +               { 0, 100000 },  /* 14% ~= 0.10 Hz */
> +               { 0, 130000 },  /* 17% ~= 0.13 Hz */
> +               { 0, 150000 },  /* 20% ~= 0.15 Hz */
> +               { 0, 200000 },  /* 25% ~= 0.20 Hz */
> +               { 0, 300000 },  /* 33% ~= 0.30 Hz */
> +               { 0, 500000 },  /* 50% ~= 0.50 Hz */
> +               { 5, 000000 },  /* 100% ~= 5.00 Hz */
> +       },
> +};
> +
>  static const struct i2c_device_id mlx90614_id[] = {
>         { "mlx90614", .driver_data = (kernel_ulong_t)&mlx90614_chip_info },
> +       { "mlx90615", .driver_data = (kernel_ulong_t)&mlx90615_chip_info },
>         { }
>  };
>  MODULE_DEVICE_TABLE(i2c, mlx90614_id);
>
>  static const struct of_device_id mlx90614_of_match[] = {
>         { .compatible = "melexis,mlx90614", .data = &mlx90614_chip_info },
> +       { .compatible = "melexis,mlx90615", .data = &mlx90615_chip_info },
>         { }
>  };
>  MODULE_DEVICE_TABLE(of, mlx90614_of_match);
> --
> 2.39.2
>

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH v3 1/6] dt-bindings: iio: temperature: melexis,mlx90614: Document MLX90615 support
  2023-05-10 10:22 [PATCH v3 1/6] dt-bindings: iio: temperature: melexis,mlx90614: Document MLX90615 support Marek Vasut
                   ` (4 preceding siblings ...)
  2023-05-10 10:22 ` [PATCH v3 6/6] iio: mlx90614: Add MLX90615 support Marek Vasut
@ 2023-05-20 16:28 ` Jonathan Cameron
  5 siblings, 0 replies; 9+ messages in thread
From: Jonathan Cameron @ 2023-05-20 16:28 UTC (permalink / raw)
  To: Marek Vasut
  Cc: linux-iio, Crt Mori, Krzysztof Kozlowski, Krzysztof Kozlowski,
	Lars-Peter Clausen, Peter Meerwald, Rob Herring, devicetree

On Wed, 10 May 2023 12:22:46 +0200
Marek Vasut <marex@denx.de> wrote:

> Document support for MLX90615 Infra Red Thermometer, which seems to
> be the predecesor of MLX90614 . There are significant differences in
> the register layout compared to MLX90614, but the functionality of
> the device is virtually identical.
> 
> Acked-by: Crt Mori <cmo@melexis.com>
> Acked-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
> Signed-off-by: Marek Vasut <marex@denx.de>
Series applied to the togreg branch of iio.git and pushed out initially
as testing for 0-day to give it a whirl.

Thanks

Jonathan

> ---
> Cc: Crt Mori <cmo@melexis.com>
> Cc: Jonathan Cameron <jic23@kernel.org>
> Cc: Krzysztof Kozlowski <krzysztof.kozlowski+dt@linaro.org>
> Cc: Lars-Peter Clausen <lars@metafoo.de>
> Cc: Marek Vasut <marex@denx.de>
> Cc: Peter Meerwald <pmeerw@pmeerw.net>
> Cc: Rob Herring <robh+dt@kernel.org>
> Cc: devicetree@vger.kernel.org
> Cc: linux-iio@vger.kernel.org
> ---
> V2: - Add spaces to subject tags
>     - Add AB from Krzysztof
> V3: Add AB from Crt
> ---
>  .../bindings/iio/temperature/melexis,mlx90614.yaml          | 6 ++++--
>  1 file changed, 4 insertions(+), 2 deletions(-)
> 
> diff --git a/Documentation/devicetree/bindings/iio/temperature/melexis,mlx90614.yaml b/Documentation/devicetree/bindings/iio/temperature/melexis,mlx90614.yaml
> index d6965a0c1cf30..654d31f65d360 100644
> --- a/Documentation/devicetree/bindings/iio/temperature/melexis,mlx90614.yaml
> +++ b/Documentation/devicetree/bindings/iio/temperature/melexis,mlx90614.yaml
> @@ -4,7 +4,7 @@
>  $id: http://devicetree.org/schemas/iio/temperature/melexis,mlx90614.yaml#
>  $schema: http://devicetree.org/meta-schemas/core.yaml#
>  
> -title: Melexis MLX90614 contactless IR temperature sensor
> +title: Melexis MLX90614/MLX90615 contactless IR temperature sensor
>  
>  maintainers:
>    - Peter Meerwald <pmeerw@pmeerw.net>
> @@ -15,7 +15,9 @@ description: |
>  
>  properties:
>    compatible:
> -    const: melexis,mlx90614
> +    enum:
> +      - melexis,mlx90614
> +      - melexis,mlx90615
>  
>    reg:
>      maxItems: 1


^ permalink raw reply	[flat|nested] 9+ messages in thread

end of thread, other threads:[~2023-05-20 16:12 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2023-05-10 10:22 [PATCH v3 1/6] dt-bindings: iio: temperature: melexis,mlx90614: Document MLX90615 support Marek Vasut
2023-05-10 10:22 ` [PATCH v3 2/6] iio: mlx90614: Sort headers Marek Vasut
2023-05-10 10:22 ` [PATCH v3 3/6] iio: mlx90614: Drop unused register macros Marek Vasut
2023-05-10 10:22 ` [PATCH v3 4/6] iio: mlx90614: Drop MLX90614_CONST_EMISSIVITY_RESOLUTION Marek Vasut
2023-05-11  7:21   ` Crt Mori
2023-05-10 10:22 ` [PATCH v3 5/6] iio: mlx90614: Factor our register IO and constants into model specific descriptor Marek Vasut
2023-05-10 10:22 ` [PATCH v3 6/6] iio: mlx90614: Add MLX90615 support Marek Vasut
2023-05-11  7:22   ` Crt Mori
2023-05-20 16:28 ` [PATCH v3 1/6] dt-bindings: iio: temperature: melexis,mlx90614: Document " Jonathan Cameron

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox