iio: temperature: mlx90635 Driver for MLX90635 IR temperature sensor
Subsystems (3)
Crt Mori
maintainerv3 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
Crt Mori
maintainerPATCH 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
@@ -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
@@ -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
@@ -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
Jonathan Cameron
maintainerRe: [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.
Signed-off-by Crt Mori<[email protected]>
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
@@ -306,7 +306,7 @@ static int mlx90635_read_ee_ambient(struct regmap *regmap, s16 *PG, s16 *PO, s16return 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, u32return 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+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; +}
Crt Mori
maintainerPATCH v3 2/2 dt-bindings: iio: temperature: add MLX90635 device
In reply to Crt MoriAdd 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
@@ -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