1348 lines · c
1// SPDX-License-Identifier: GPL-2.02/*3 * mlx90632.c - Melexis MLX90632 contactless IR temperature sensor4 *5 * Copyright (c) 2017 Melexis <cmo@melexis.com>6 *7 * Driver for the Melexis MLX90632 I2C 16-bit IR thermopile sensor8 */9#include <linux/bitfield.h>10#include <linux/delay.h>11#include <linux/device.h>12#include <linux/err.h>13#include <linux/gpio/consumer.h>14#include <linux/i2c.h>15#include <linux/iopoll.h>16#include <linux/jiffies.h>17#include <linux/kernel.h>18#include <linux/limits.h>19#include <linux/mod_devicetable.h>20#include <linux/module.h>21#include <linux/math64.h>22#include <linux/pm_runtime.h>23#include <linux/regmap.h>24#include <linux/regulator/consumer.h>25 26#include <linux/iio/iio.h>27#include <linux/iio/sysfs.h>28 29/* Memory sections addresses */30#define MLX90632_ADDR_RAM 0x4000 /* Start address of ram */31#define MLX90632_ADDR_EEPROM 0x2480 /* Start address of user eeprom */32 33/* EEPROM addresses - used at startup */34#define MLX90632_EE_CTRL 0x24d4 /* Control register initial value */35#define MLX90632_EE_I2C_ADDR 0x24d5 /* I2C address register initial value */36#define MLX90632_EE_VERSION 0x240b /* EEPROM version reg address */37#define MLX90632_EE_P_R 0x240c /* P_R calibration register 32bit */38#define MLX90632_EE_P_G 0x240e /* P_G calibration register 32bit */39#define MLX90632_EE_P_T 0x2410 /* P_T calibration register 32bit */40#define MLX90632_EE_P_O 0x2412 /* P_O calibration register 32bit */41#define MLX90632_EE_Aa 0x2414 /* Aa calibration register 32bit */42#define MLX90632_EE_Ab 0x2416 /* Ab calibration register 32bit */43#define MLX90632_EE_Ba 0x2418 /* Ba calibration register 32bit */44#define MLX90632_EE_Bb 0x241a /* Bb calibration register 32bit */45#define MLX90632_EE_Ca 0x241c /* Ca calibration register 32bit */46#define MLX90632_EE_Cb 0x241e /* Cb calibration register 32bit */47#define MLX90632_EE_Da 0x2420 /* Da calibration register 32bit */48#define MLX90632_EE_Db 0x2422 /* Db calibration register 32bit */49#define MLX90632_EE_Ea 0x2424 /* Ea calibration register 32bit */50#define MLX90632_EE_Eb 0x2426 /* Eb calibration register 32bit */51#define MLX90632_EE_Fa 0x2428 /* Fa calibration register 32bit */52#define MLX90632_EE_Fb 0x242a /* Fb calibration register 32bit */53#define MLX90632_EE_Ga 0x242c /* Ga calibration register 32bit */54 55#define MLX90632_EE_Gb 0x242e /* Gb calibration register 16bit */56#define MLX90632_EE_Ka 0x242f /* Ka calibration register 16bit */57 58#define MLX90632_EE_Ha 0x2481 /* Ha customer calib value reg 16bit */59#define MLX90632_EE_Hb 0x2482 /* Hb customer calib value reg 16bit */60 61#define MLX90632_EE_MEDICAL_MEAS1 0x24E1 /* Medical measurement 1 16bit */62#define MLX90632_EE_MEDICAL_MEAS2 0x24E2 /* Medical measurement 2 16bit */63#define MLX90632_EE_EXTENDED_MEAS1 0x24F1 /* Extended measurement 1 16bit */64#define MLX90632_EE_EXTENDED_MEAS2 0x24F2 /* Extended measurement 2 16bit */65#define MLX90632_EE_EXTENDED_MEAS3 0x24F3 /* Extended measurement 3 16bit */66 67/* Register addresses - volatile */68#define MLX90632_REG_I2C_ADDR 0x3000 /* Chip I2C address register */69 70/* Control register address - volatile */71#define MLX90632_REG_CONTROL 0x3001 /* Control Register address */72#define MLX90632_CFG_PWR_MASK GENMASK(2, 1) /* PowerMode Mask */73#define MLX90632_CFG_MTYP_MASK GENMASK(8, 4) /* Meas select Mask */74#define MLX90632_CFG_SOB_MASK BIT(11)75 76/* PowerModes statuses */77#define MLX90632_PWR_STATUS(ctrl_val) (ctrl_val << 1)78#define MLX90632_PWR_STATUS_HALT MLX90632_PWR_STATUS(0) /* hold */79#define MLX90632_PWR_STATUS_SLEEP_STEP MLX90632_PWR_STATUS(1) /* sleep step */80#define MLX90632_PWR_STATUS_STEP MLX90632_PWR_STATUS(2) /* step */81#define MLX90632_PWR_STATUS_CONTINUOUS MLX90632_PWR_STATUS(3) /* continuous */82 83#define MLX90632_EE_RR GENMASK(10, 8) /* Only Refresh Rate bits */84#define MLX90632_REFRESH_RATE(ee_val) FIELD_GET(MLX90632_EE_RR, ee_val)85 /* Extract Refresh Rate from ee register */86#define MLX90632_REFRESH_RATE_STATUS(refresh_rate) (refresh_rate << 8)87 88/* Measurement types */89#define MLX90632_MTYP_MEDICAL 090#define MLX90632_MTYP_EXTENDED 1791 92/* Measurement type select*/93#define MLX90632_MTYP_STATUS(ctrl_val) (ctrl_val << 4)94#define MLX90632_MTYP_STATUS_MEDICAL MLX90632_MTYP_STATUS(MLX90632_MTYP_MEDICAL)95#define MLX90632_MTYP_STATUS_EXTENDED MLX90632_MTYP_STATUS(MLX90632_MTYP_EXTENDED)96 97/* I2C command register - volatile */98#define MLX90632_REG_I2C_CMD 0x3005 /* I2C command Register address */99 100/* Device status register - volatile */101#define MLX90632_REG_STATUS 0x3fff /* Device status register */102#define MLX90632_STAT_BUSY BIT(10) /* Device busy indicator */103#define MLX90632_STAT_EE_BUSY BIT(9) /* EEPROM busy indicator */104#define MLX90632_STAT_BRST BIT(8) /* Brown out reset indicator */105#define MLX90632_STAT_CYCLE_POS GENMASK(6, 2) /* Data position */106#define MLX90632_STAT_DATA_RDY BIT(0) /* Data ready indicator */107 108/* RAM_MEAS address-es for each channel */109#define MLX90632_RAM_1(meas_num) (MLX90632_ADDR_RAM + 3 * meas_num)110#define MLX90632_RAM_2(meas_num) (MLX90632_ADDR_RAM + 3 * meas_num + 1)111#define MLX90632_RAM_3(meas_num) (MLX90632_ADDR_RAM + 3 * meas_num + 2)112 113/* Name important RAM_MEAS channels */114#define MLX90632_RAM_DSP5_EXTENDED_AMBIENT_1 MLX90632_RAM_3(17)115#define MLX90632_RAM_DSP5_EXTENDED_AMBIENT_2 MLX90632_RAM_3(18)116#define MLX90632_RAM_DSP5_EXTENDED_OBJECT_1 MLX90632_RAM_1(17)117#define MLX90632_RAM_DSP5_EXTENDED_OBJECT_2 MLX90632_RAM_2(17)118#define MLX90632_RAM_DSP5_EXTENDED_OBJECT_3 MLX90632_RAM_1(18)119#define MLX90632_RAM_DSP5_EXTENDED_OBJECT_4 MLX90632_RAM_2(18)120#define MLX90632_RAM_DSP5_EXTENDED_OBJECT_5 MLX90632_RAM_1(19)121#define MLX90632_RAM_DSP5_EXTENDED_OBJECT_6 MLX90632_RAM_2(19)122 123/* Magic constants */124#define MLX90632_ID_MEDICAL 0x0105 /* EEPROM DSPv5 Medical device id */125#define MLX90632_ID_CONSUMER 0x0205 /* EEPROM DSPv5 Consumer device id */126#define MLX90632_ID_EXTENDED 0x0505 /* EEPROM DSPv5 Extended range device id */127#define MLX90632_ID_MASK GENMASK(14, 0) /* DSP version and device ID in EE_VERSION */128#define MLX90632_DSP_VERSION 5 /* DSP version */129#define MLX90632_DSP_MASK GENMASK(7, 0) /* DSP version in EE_VERSION */130#define MLX90632_RESET_CMD 0x0006 /* Reset sensor (address or global) */131#define MLX90632_REF_12 12LL /* ResCtrlRef value of Ch 1 or Ch 2 */132#define MLX90632_REF_3 12LL /* ResCtrlRef value of Channel 3 */133#define MLX90632_MAX_MEAS_NUM 31 /* Maximum measurements in list */134#define MLX90632_SLEEP_DELAY_MS 6000 /* Autosleep delay */135#define MLX90632_EXTENDED_LIMIT 27000 /* Extended mode raw value limit */136#define MLX90632_MEAS_MAX_TIME 2000 /* Max measurement time in ms for the lowest refresh rate */137 138/**139 * struct mlx90632_data - private data for the MLX90632 device140 * @client: I2C client of the device141 * @lock: Internal mutex for multiple reads for single measurement142 * @regmap: Regmap of the device143 * @emissivity: Object emissivity from 0 to 1000 where 1000 = 1.144 * @mtyp: Measurement type physical sensor configuration for extended range145 * calculations146 * @object_ambient_temperature: Ambient temperature at object (might differ of147 * the ambient temperature of sensor.148 * @regulator: Regulator of the device149 * @powerstatus: Current POWER status of the device150 * @interaction_ts: Timestamp of the last temperature read that is used151 * for power management in jiffies152 */153struct mlx90632_data {154 struct i2c_client *client;155 struct mutex lock;156 struct regmap *regmap;157 u16 emissivity;158 u8 mtyp;159 u32 object_ambient_temperature;160 struct regulator *regulator;161 int powerstatus;162 unsigned long interaction_ts;163};164 165static const struct regmap_range mlx90632_volatile_reg_range[] = {166 regmap_reg_range(MLX90632_REG_I2C_ADDR, MLX90632_REG_CONTROL),167 regmap_reg_range(MLX90632_REG_I2C_CMD, MLX90632_REG_I2C_CMD),168 regmap_reg_range(MLX90632_REG_STATUS, MLX90632_REG_STATUS),169 regmap_reg_range(MLX90632_RAM_1(0),170 MLX90632_RAM_3(MLX90632_MAX_MEAS_NUM)),171};172 173static const struct regmap_access_table mlx90632_volatile_regs_tbl = {174 .yes_ranges = mlx90632_volatile_reg_range,175 .n_yes_ranges = ARRAY_SIZE(mlx90632_volatile_reg_range),176};177 178static const struct regmap_range mlx90632_read_reg_range[] = {179 regmap_reg_range(MLX90632_EE_VERSION, MLX90632_EE_Ka),180 regmap_reg_range(MLX90632_EE_CTRL, MLX90632_EE_I2C_ADDR),181 regmap_reg_range(MLX90632_EE_Ha, MLX90632_EE_Hb),182 regmap_reg_range(MLX90632_EE_MEDICAL_MEAS1, MLX90632_EE_MEDICAL_MEAS2),183 regmap_reg_range(MLX90632_EE_EXTENDED_MEAS1, MLX90632_EE_EXTENDED_MEAS3),184 regmap_reg_range(MLX90632_REG_I2C_ADDR, MLX90632_REG_CONTROL),185 regmap_reg_range(MLX90632_REG_I2C_CMD, MLX90632_REG_I2C_CMD),186 regmap_reg_range(MLX90632_REG_STATUS, MLX90632_REG_STATUS),187 regmap_reg_range(MLX90632_RAM_1(0),188 MLX90632_RAM_3(MLX90632_MAX_MEAS_NUM)),189};190 191static const struct regmap_access_table mlx90632_readable_regs_tbl = {192 .yes_ranges = mlx90632_read_reg_range,193 .n_yes_ranges = ARRAY_SIZE(mlx90632_read_reg_range),194};195 196static const struct regmap_range mlx90632_no_write_reg_range[] = {197 regmap_reg_range(MLX90632_EE_VERSION, MLX90632_EE_Ka),198 regmap_reg_range(MLX90632_RAM_1(0),199 MLX90632_RAM_3(MLX90632_MAX_MEAS_NUM)),200};201 202static const struct regmap_access_table mlx90632_writeable_regs_tbl = {203 .no_ranges = mlx90632_no_write_reg_range,204 .n_no_ranges = ARRAY_SIZE(mlx90632_no_write_reg_range),205};206 207static const struct regmap_config mlx90632_regmap = {208 .reg_bits = 16,209 .val_bits = 16,210 211 .volatile_table = &mlx90632_volatile_regs_tbl,212 .rd_table = &mlx90632_readable_regs_tbl,213 .wr_table = &mlx90632_writeable_regs_tbl,214 215 .use_single_read = true,216 .use_single_write = true,217 .reg_format_endian = REGMAP_ENDIAN_BIG,218 .val_format_endian = REGMAP_ENDIAN_BIG,219 .cache_type = REGCACHE_RBTREE,220};221 222static int mlx90632_pwr_set_sleep_step(struct regmap *regmap)223{224 struct mlx90632_data *data =225 iio_priv(dev_get_drvdata(regmap_get_device(regmap)));226 int ret;227 228 if (data->powerstatus == MLX90632_PWR_STATUS_SLEEP_STEP)229 return 0;230 231 ret = regmap_write_bits(regmap, MLX90632_REG_CONTROL, MLX90632_CFG_PWR_MASK,232 MLX90632_PWR_STATUS_SLEEP_STEP);233 if (ret < 0)234 return ret;235 236 data->powerstatus = MLX90632_PWR_STATUS_SLEEP_STEP;237 return 0;238}239 240static int mlx90632_pwr_continuous(struct regmap *regmap)241{242 struct mlx90632_data *data =243 iio_priv(dev_get_drvdata(regmap_get_device(regmap)));244 int ret;245 246 if (data->powerstatus == MLX90632_PWR_STATUS_CONTINUOUS)247 return 0;248 249 ret = regmap_write_bits(regmap, MLX90632_REG_CONTROL, MLX90632_CFG_PWR_MASK,250 MLX90632_PWR_STATUS_CONTINUOUS);251 if (ret < 0)252 return ret;253 254 data->powerstatus = MLX90632_PWR_STATUS_CONTINUOUS;255 return 0;256}257 258/**259 * mlx90632_reset_delay() - Give the mlx90632 some time to reset properly260 * If this is not done, the following I2C command(s) will not be accepted.261 */262static void mlx90632_reset_delay(void)263{264 usleep_range(150, 200);265}266 267static int mlx90632_get_measurement_time(struct regmap *regmap, u16 meas)268{269 unsigned int reg;270 int ret;271 272 ret = regmap_read(regmap, meas, ®);273 if (ret < 0)274 return ret;275 276 return MLX90632_MEAS_MAX_TIME >> FIELD_GET(MLX90632_EE_RR, reg);277}278 279static int mlx90632_calculate_dataset_ready_time(struct mlx90632_data *data)280{281 unsigned int refresh_time;282 int ret;283 284 if (data->mtyp == MLX90632_MTYP_MEDICAL) {285 ret = mlx90632_get_measurement_time(data->regmap,286 MLX90632_EE_MEDICAL_MEAS1);287 if (ret < 0)288 return ret;289 290 refresh_time = ret;291 292 ret = mlx90632_get_measurement_time(data->regmap,293 MLX90632_EE_MEDICAL_MEAS2);294 if (ret < 0)295 return ret;296 297 refresh_time += ret;298 } else {299 ret = mlx90632_get_measurement_time(data->regmap,300 MLX90632_EE_EXTENDED_MEAS1);301 if (ret < 0)302 return ret;303 304 refresh_time = ret;305 306 ret = mlx90632_get_measurement_time(data->regmap,307 MLX90632_EE_EXTENDED_MEAS2);308 if (ret < 0)309 return ret;310 311 refresh_time += ret;312 313 ret = mlx90632_get_measurement_time(data->regmap,314 MLX90632_EE_EXTENDED_MEAS3);315 if (ret < 0)316 return ret;317 318 refresh_time += ret;319 }320 321 return refresh_time;322}323 324/**325 * mlx90632_perform_measurement() - Trigger and retrieve current measurement cycle326 * @data: pointer to mlx90632_data object containing regmap information327 *328 * Perform a measurement and return latest measurement cycle position reported329 * by sensor. This is a blocking function for 500ms, as that is default sensor330 * refresh rate.331 */332static int mlx90632_perform_measurement(struct mlx90632_data *data)333{334 unsigned int reg_status;335 int ret;336 337 ret = regmap_clear_bits(data->regmap, MLX90632_REG_STATUS,338 MLX90632_STAT_DATA_RDY);339 if (ret < 0)340 return ret;341 342 ret = regmap_read_poll_timeout(data->regmap, MLX90632_REG_STATUS, reg_status,343 !(reg_status & MLX90632_STAT_DATA_RDY), 10000,344 100 * 10000);345 346 if (ret < 0) {347 dev_err(&data->client->dev, "data not ready");348 return -ETIMEDOUT;349 }350 351 return (reg_status & MLX90632_STAT_CYCLE_POS) >> 2;352}353 354/**355 * mlx90632_perform_measurement_burst() - Trigger and retrieve current measurement356 * cycle in step sleep mode357 * @data: pointer to mlx90632_data object containing regmap information358 *359 * Perform a measurement and return 2 as measurement cycle position reported360 * by sensor. This is a blocking function for amount dependent on the sensor361 * refresh rate.362 */363static int mlx90632_perform_measurement_burst(struct mlx90632_data *data)364{365 unsigned int reg_status;366 int ret;367 368 ret = regmap_write_bits(data->regmap, MLX90632_REG_CONTROL,369 MLX90632_CFG_SOB_MASK, MLX90632_CFG_SOB_MASK);370 if (ret < 0)371 return ret;372 373 ret = mlx90632_calculate_dataset_ready_time(data);374 if (ret < 0)375 return ret;376 377 msleep(ret); /* Wait minimum time for dataset to be ready */378 379 ret = regmap_read_poll_timeout(data->regmap, MLX90632_REG_STATUS,380 reg_status,381 (reg_status & MLX90632_STAT_BUSY) == 0,382 10000, 100 * 10000);383 if (ret < 0) {384 dev_err(&data->client->dev, "data not ready");385 return -ETIMEDOUT;386 }387 388 return 2;389}390 391static int mlx90632_set_meas_type(struct mlx90632_data *data, u8 type)392{393 int current_powerstatus;394 int ret;395 396 if (data->mtyp == type)397 return 0;398 399 current_powerstatus = data->powerstatus;400 ret = mlx90632_pwr_continuous(data->regmap);401 if (ret < 0)402 return ret;403 404 ret = regmap_write(data->regmap, MLX90632_REG_I2C_CMD, MLX90632_RESET_CMD);405 if (ret < 0)406 return ret;407 408 mlx90632_reset_delay();409 410 ret = regmap_update_bits(data->regmap, MLX90632_REG_CONTROL,411 (MLX90632_CFG_MTYP_MASK | MLX90632_CFG_PWR_MASK),412 (MLX90632_MTYP_STATUS(type) | MLX90632_PWR_STATUS_HALT));413 if (ret < 0)414 return ret;415 416 data->mtyp = type;417 data->powerstatus = MLX90632_PWR_STATUS_HALT;418 419 if (current_powerstatus == MLX90632_PWR_STATUS_SLEEP_STEP)420 return mlx90632_pwr_set_sleep_step(data->regmap);421 422 return mlx90632_pwr_continuous(data->regmap);423}424 425static int mlx90632_channel_new_select(int perform_ret, uint8_t *channel_new,426 uint8_t *channel_old)427{428 switch (perform_ret) {429 case 1:430 *channel_new = 1;431 *channel_old = 2;432 break;433 case 2:434 *channel_new = 2;435 *channel_old = 1;436 break;437 default:438 return -ECHRNG;439 }440 441 return 0;442}443 444static int mlx90632_read_ambient_raw(struct regmap *regmap,445 s16 *ambient_new_raw, s16 *ambient_old_raw)446{447 unsigned int read_tmp;448 int ret;449 450 ret = regmap_read(regmap, MLX90632_RAM_3(1), &read_tmp);451 if (ret < 0)452 return ret;453 *ambient_new_raw = (s16)read_tmp;454 455 ret = regmap_read(regmap, MLX90632_RAM_3(2), &read_tmp);456 if (ret < 0)457 return ret;458 *ambient_old_raw = (s16)read_tmp;459 460 return ret;461}462 463static int mlx90632_read_object_raw(struct regmap *regmap,464 int perform_measurement_ret,465 s16 *object_new_raw, s16 *object_old_raw)466{467 unsigned int read_tmp;468 u8 channel_old = 0;469 u8 channel = 0;470 s16 read;471 int ret;472 473 ret = mlx90632_channel_new_select(perform_measurement_ret, &channel,474 &channel_old);475 if (ret != 0)476 return ret;477 478 ret = regmap_read(regmap, MLX90632_RAM_2(channel), &read_tmp);479 if (ret < 0)480 return ret;481 482 read = (s16)read_tmp;483 484 ret = regmap_read(regmap, MLX90632_RAM_1(channel), &read_tmp);485 if (ret < 0)486 return ret;487 *object_new_raw = (read + (s16)read_tmp) / 2;488 489 ret = regmap_read(regmap, MLX90632_RAM_2(channel_old), &read_tmp);490 if (ret < 0)491 return ret;492 read = (s16)read_tmp;493 494 ret = regmap_read(regmap, MLX90632_RAM_1(channel_old), &read_tmp);495 if (ret < 0)496 return ret;497 *object_old_raw = (read + (s16)read_tmp) / 2;498 499 return ret;500}501 502static int mlx90632_read_all_channel(struct mlx90632_data *data,503 s16 *ambient_new_raw, s16 *ambient_old_raw,504 s16 *object_new_raw, s16 *object_old_raw)505{506 s32 measurement;507 int ret;508 509 mutex_lock(&data->lock);510 ret = mlx90632_set_meas_type(data, MLX90632_MTYP_MEDICAL);511 if (ret < 0)512 goto read_unlock;513 514 switch (data->powerstatus) {515 case MLX90632_PWR_STATUS_CONTINUOUS:516 ret = mlx90632_perform_measurement(data);517 if (ret < 0)518 goto read_unlock;519 520 break;521 case MLX90632_PWR_STATUS_SLEEP_STEP:522 ret = mlx90632_perform_measurement_burst(data);523 if (ret < 0)524 goto read_unlock;525 526 break;527 default:528 ret = -EOPNOTSUPP;529 goto read_unlock;530 }531 532 measurement = ret; /* If we came here ret holds the measurement position */533 534 ret = mlx90632_read_ambient_raw(data->regmap, ambient_new_raw,535 ambient_old_raw);536 if (ret < 0)537 goto read_unlock;538 539 ret = mlx90632_read_object_raw(data->regmap, measurement,540 object_new_raw, object_old_raw);541read_unlock:542 mutex_unlock(&data->lock);543 return ret;544}545 546static int mlx90632_read_ambient_raw_extended(struct regmap *regmap,547 s16 *ambient_new_raw, s16 *ambient_old_raw)548{549 unsigned int read_tmp;550 int ret;551 552 ret = regmap_read(regmap, MLX90632_RAM_DSP5_EXTENDED_AMBIENT_1, &read_tmp);553 if (ret < 0)554 return ret;555 *ambient_new_raw = (s16)read_tmp;556 557 ret = regmap_read(regmap, MLX90632_RAM_DSP5_EXTENDED_AMBIENT_2, &read_tmp);558 if (ret < 0)559 return ret;560 *ambient_old_raw = (s16)read_tmp;561 562 return 0;563}564 565static int mlx90632_read_object_raw_extended(struct regmap *regmap, s16 *object_new_raw)566{567 unsigned int read_tmp;568 s32 read;569 int ret;570 571 ret = regmap_read(regmap, MLX90632_RAM_DSP5_EXTENDED_OBJECT_1, &read_tmp);572 if (ret < 0)573 return ret;574 read = (s16)read_tmp;575 576 ret = regmap_read(regmap, MLX90632_RAM_DSP5_EXTENDED_OBJECT_2, &read_tmp);577 if (ret < 0)578 return ret;579 read = read - (s16)read_tmp;580 581 ret = regmap_read(regmap, MLX90632_RAM_DSP5_EXTENDED_OBJECT_3, &read_tmp);582 if (ret < 0)583 return ret;584 read = read - (s16)read_tmp;585 586 ret = regmap_read(regmap, MLX90632_RAM_DSP5_EXTENDED_OBJECT_4, &read_tmp);587 if (ret < 0)588 return ret;589 read = (read + (s16)read_tmp) / 2;590 591 ret = regmap_read(regmap, MLX90632_RAM_DSP5_EXTENDED_OBJECT_5, &read_tmp);592 if (ret < 0)593 return ret;594 read = read + (s16)read_tmp;595 596 ret = regmap_read(regmap, MLX90632_RAM_DSP5_EXTENDED_OBJECT_6, &read_tmp);597 if (ret < 0)598 return ret;599 read = read + (s16)read_tmp;600 601 if (read > S16_MAX || read < S16_MIN)602 return -ERANGE;603 604 *object_new_raw = read;605 606 return 0;607}608 609static int mlx90632_read_all_channel_extended(struct mlx90632_data *data, s16 *object_new_raw,610 s16 *ambient_new_raw, s16 *ambient_old_raw)611{612 s32 ret, meas;613 614 mutex_lock(&data->lock);615 ret = mlx90632_set_meas_type(data, MLX90632_MTYP_EXTENDED);616 if (ret < 0)617 goto read_unlock;618 619 switch (data->powerstatus) {620 case MLX90632_PWR_STATUS_CONTINUOUS:621 ret = read_poll_timeout(mlx90632_perform_measurement, meas, meas == 19,622 50000, 800000, false, data);623 if (ret)624 goto read_unlock;625 break;626 case MLX90632_PWR_STATUS_SLEEP_STEP:627 ret = mlx90632_perform_measurement_burst(data);628 if (ret < 0)629 goto read_unlock;630 break;631 default:632 ret = -EOPNOTSUPP;633 goto read_unlock;634 }635 636 ret = mlx90632_read_object_raw_extended(data->regmap, object_new_raw);637 if (ret < 0)638 goto read_unlock;639 640 ret = mlx90632_read_ambient_raw_extended(data->regmap, ambient_new_raw, ambient_old_raw);641 642read_unlock:643 mutex_unlock(&data->lock);644 return ret;645}646 647static int mlx90632_read_ee_register(struct regmap *regmap, u16 reg_lsb,648 s32 *reg_value)649{650 unsigned int read;651 u32 value;652 int ret;653 654 ret = regmap_read(regmap, reg_lsb, &read);655 if (ret < 0)656 return ret;657 658 value = read;659 660 ret = regmap_read(regmap, reg_lsb + 1, &read);661 if (ret < 0)662 return ret;663 664 *reg_value = (read << 16) | (value & 0xffff);665 666 return 0;667}668 669static s64 mlx90632_preprocess_temp_amb(s16 ambient_new_raw,670 s16 ambient_old_raw, s16 Gb)671{672 s64 VR_Ta, kGb, tmp;673 674 kGb = ((s64)Gb * 1000LL) >> 10ULL;675 VR_Ta = (s64)ambient_old_raw * 1000000LL +676 kGb * div64_s64(((s64)ambient_new_raw * 1000LL),677 (MLX90632_REF_3));678 tmp = div64_s64(679 div64_s64(((s64)ambient_new_raw * 1000000000000LL),680 (MLX90632_REF_3)), VR_Ta);681 return div64_s64(tmp << 19ULL, 1000LL);682}683 684static s64 mlx90632_preprocess_temp_obj(s16 object_new_raw, s16 object_old_raw,685 s16 ambient_new_raw,686 s16 ambient_old_raw, s16 Ka)687{688 s64 VR_IR, kKa, tmp;689 690 kKa = ((s64)Ka * 1000LL) >> 10ULL;691 VR_IR = (s64)ambient_old_raw * 1000000LL +692 kKa * div64_s64(((s64)ambient_new_raw * 1000LL),693 (MLX90632_REF_3));694 tmp = div64_s64(695 div64_s64(((s64)((object_new_raw + object_old_raw) / 2)696 * 1000000000000LL), (MLX90632_REF_12)),697 VR_IR);698 return div64_s64((tmp << 19ULL), 1000LL);699}700 701static s64 mlx90632_preprocess_temp_obj_extended(s16 object_new_raw, s16 ambient_new_raw,702 s16 ambient_old_raw, s16 Ka)703{704 s64 VR_IR, kKa, tmp;705 706 kKa = ((s64)Ka * 1000LL) >> 10ULL;707 VR_IR = (s64)ambient_old_raw * 1000000LL +708 kKa * div64_s64((s64)ambient_new_raw * 1000LL,709 MLX90632_REF_3);710 tmp = div64_s64(711 div64_s64((s64) object_new_raw * 1000000000000LL, MLX90632_REF_12),712 VR_IR);713 return div64_s64(tmp << 19ULL, 1000LL);714}715 716static s32 mlx90632_calc_temp_ambient(s16 ambient_new_raw, s16 ambient_old_raw,717 s32 P_T, s32 P_R, s32 P_G, s32 P_O, s16 Gb)718{719 s64 Asub, Bsub, Ablock, Bblock, Cblock, AMB, sum;720 721 AMB = mlx90632_preprocess_temp_amb(ambient_new_raw, ambient_old_raw,722 Gb);723 Asub = ((s64)P_T * 10000000000LL) >> 44ULL;724 Bsub = AMB - (((s64)P_R * 1000LL) >> 8ULL);725 Ablock = Asub * (Bsub * Bsub);726 Bblock = (div64_s64(Bsub * 10000000LL, P_G)) << 20ULL;727 Cblock = ((s64)P_O * 10000000000LL) >> 8ULL;728 729 sum = div64_s64(Ablock, 1000000LL) + Bblock + Cblock;730 731 return div64_s64(sum, 10000000LL);732}733 734static s32 mlx90632_calc_temp_object_iteration(s32 prev_object_temp, s64 object,735 s64 TAdut, s64 TAdut4, s32 Fa, s32 Fb,736 s32 Ga, s16 Ha, s16 Hb,737 u16 emissivity)738{739 s64 calcedKsTO, calcedKsTA, ir_Alpha, Alpha_corr;740 s64 Ha_customer, Hb_customer;741 742 Ha_customer = ((s64)Ha * 1000000LL) >> 14ULL;743 Hb_customer = ((s64)Hb * 100) >> 10ULL;744 745 calcedKsTO = ((s64)((s64)Ga * (prev_object_temp - 25 * 1000LL)746 * 1000LL)) >> 36LL;747 calcedKsTA = ((s64)(Fb * (TAdut - 25 * 1000000LL))) >> 36LL;748 Alpha_corr = div64_s64((((s64)(Fa * 10000000000LL) >> 46LL)749 * Ha_customer), 1000LL);750 Alpha_corr *= ((s64)(1 * 1000000LL + calcedKsTO + calcedKsTA));751 Alpha_corr = emissivity * div64_s64(Alpha_corr, 100000LL);752 Alpha_corr = div64_s64(Alpha_corr, 1000LL);753 ir_Alpha = div64_s64((s64)object * 10000000LL, Alpha_corr);754 755 return (int_sqrt64(int_sqrt64(ir_Alpha * 1000000000000LL + TAdut4))756 - 27315 - Hb_customer) * 10;757}758 759static s64 mlx90632_calc_ta4(s64 TAdut, s64 scale)760{761 return (div64_s64(TAdut, scale) + 27315) *762 (div64_s64(TAdut, scale) + 27315) *763 (div64_s64(TAdut, scale) + 27315) *764 (div64_s64(TAdut, scale) + 27315);765}766 767static s32 mlx90632_calc_temp_object(s64 object, s64 ambient, s32 Ea, s32 Eb,768 s32 Fa, s32 Fb, s32 Ga, s16 Ha, s16 Hb,769 u16 tmp_emi)770{771 s64 kTA, kTA0, TAdut, TAdut4;772 s64 temp = 25000;773 s8 i;774 775 kTA = (Ea * 1000LL) >> 16LL;776 kTA0 = (Eb * 1000LL) >> 8LL;777 TAdut = div64_s64(((ambient - kTA0) * 1000000LL), kTA) + 25 * 1000000LL;778 TAdut4 = mlx90632_calc_ta4(TAdut, 10000LL);779 780 /* Iterations of calculation as described in datasheet */781 for (i = 0; i < 5; ++i) {782 temp = mlx90632_calc_temp_object_iteration(temp, object, TAdut, TAdut4,783 Fa, Fb, Ga, Ha, Hb,784 tmp_emi);785 }786 return temp;787}788 789static s32 mlx90632_calc_temp_object_extended(s64 object, s64 ambient, s64 reflected,790 s32 Ea, s32 Eb, s32 Fa, s32 Fb, s32 Ga,791 s16 Ha, s16 Hb, u16 tmp_emi)792{793 s64 kTA, kTA0, TAdut, TAdut4, Tr4, TaTr4;794 s64 temp = 25000;795 s8 i;796 797 kTA = (Ea * 1000LL) >> 16LL;798 kTA0 = (Eb * 1000LL) >> 8LL;799 TAdut = div64_s64((ambient - kTA0) * 1000000LL, kTA) + 25 * 1000000LL;800 Tr4 = mlx90632_calc_ta4(reflected, 10);801 TAdut4 = mlx90632_calc_ta4(TAdut, 10000LL);802 TaTr4 = Tr4 - div64_s64(Tr4 - TAdut4, tmp_emi) * 1000;803 804 /* Iterations of calculation as described in datasheet */805 for (i = 0; i < 5; ++i) {806 temp = mlx90632_calc_temp_object_iteration(temp, object, TAdut, TaTr4,807 Fa / 2, Fb, Ga, Ha, Hb,808 tmp_emi);809 }810 811 return temp;812}813 814static int mlx90632_calc_object_dsp105(struct mlx90632_data *data, int *val)815{816 s16 ambient_new_raw, ambient_old_raw, object_new_raw, object_old_raw;817 s32 Ea, Eb, Fa, Fb, Ga;818 unsigned int read_tmp;819 s64 object, ambient;820 s16 Ha, Hb, Gb, Ka;821 int ret;822 823 ret = mlx90632_read_ee_register(data->regmap, MLX90632_EE_Ea, &Ea);824 if (ret < 0)825 return ret;826 ret = mlx90632_read_ee_register(data->regmap, MLX90632_EE_Eb, &Eb);827 if (ret < 0)828 return ret;829 ret = mlx90632_read_ee_register(data->regmap, MLX90632_EE_Fa, &Fa);830 if (ret < 0)831 return ret;832 ret = mlx90632_read_ee_register(data->regmap, MLX90632_EE_Fb, &Fb);833 if (ret < 0)834 return ret;835 ret = mlx90632_read_ee_register(data->regmap, MLX90632_EE_Ga, &Ga);836 if (ret < 0)837 return ret;838 ret = regmap_read(data->regmap, MLX90632_EE_Ha, &read_tmp);839 if (ret < 0)840 return ret;841 Ha = (s16)read_tmp;842 ret = regmap_read(data->regmap, MLX90632_EE_Hb, &read_tmp);843 if (ret < 0)844 return ret;845 Hb = (s16)read_tmp;846 ret = regmap_read(data->regmap, MLX90632_EE_Gb, &read_tmp);847 if (ret < 0)848 return ret;849 Gb = (s16)read_tmp;850 ret = regmap_read(data->regmap, MLX90632_EE_Ka, &read_tmp);851 if (ret < 0)852 return ret;853 Ka = (s16)read_tmp;854 855 ret = mlx90632_read_all_channel(data,856 &ambient_new_raw, &ambient_old_raw,857 &object_new_raw, &object_old_raw);858 if (ret < 0)859 return ret;860 861 if (object_new_raw > MLX90632_EXTENDED_LIMIT &&862 data->mtyp == MLX90632_MTYP_EXTENDED) {863 ret = mlx90632_read_all_channel_extended(data, &object_new_raw,864 &ambient_new_raw, &ambient_old_raw);865 if (ret < 0)866 return ret;867 868 /* Use extended mode calculations */869 ambient = mlx90632_preprocess_temp_amb(ambient_new_raw,870 ambient_old_raw, Gb);871 object = mlx90632_preprocess_temp_obj_extended(object_new_raw,872 ambient_new_raw,873 ambient_old_raw, Ka);874 *val = mlx90632_calc_temp_object_extended(object, ambient,875 data->object_ambient_temperature,876 Ea, Eb, Fa, Fb, Ga,877 Ha, Hb, data->emissivity);878 return 0;879 }880 881 ambient = mlx90632_preprocess_temp_amb(ambient_new_raw,882 ambient_old_raw, Gb);883 object = mlx90632_preprocess_temp_obj(object_new_raw,884 object_old_raw,885 ambient_new_raw,886 ambient_old_raw, Ka);887 888 *val = mlx90632_calc_temp_object(object, ambient, Ea, Eb, Fa, Fb, Ga,889 Ha, Hb, data->emissivity);890 return 0;891}892 893static int mlx90632_calc_ambient_dsp105(struct mlx90632_data *data, int *val)894{895 s16 ambient_new_raw, ambient_old_raw;896 unsigned int read_tmp;897 s32 PT, PR, PG, PO;898 int ret;899 s16 Gb;900 901 ret = mlx90632_read_ee_register(data->regmap, MLX90632_EE_P_R, &PR);902 if (ret < 0)903 return ret;904 ret = mlx90632_read_ee_register(data->regmap, MLX90632_EE_P_G, &PG);905 if (ret < 0)906 return ret;907 ret = mlx90632_read_ee_register(data->regmap, MLX90632_EE_P_T, &PT);908 if (ret < 0)909 return ret;910 ret = mlx90632_read_ee_register(data->regmap, MLX90632_EE_P_O, &PO);911 if (ret < 0)912 return ret;913 ret = regmap_read(data->regmap, MLX90632_EE_Gb, &read_tmp);914 if (ret < 0)915 return ret;916 Gb = (s16)read_tmp;917 918 ret = mlx90632_read_ambient_raw(data->regmap, &ambient_new_raw,919 &ambient_old_raw);920 if (ret < 0)921 return ret;922 *val = mlx90632_calc_temp_ambient(ambient_new_raw, ambient_old_raw,923 PT, PR, PG, PO, Gb);924 return ret;925}926 927static int mlx90632_get_refresh_rate(struct mlx90632_data *data,928 int *refresh_rate)929{930 unsigned int meas1;931 int ret;932 933 ret = regmap_read(data->regmap, MLX90632_EE_MEDICAL_MEAS1, &meas1);934 if (ret < 0)935 return ret;936 937 *refresh_rate = MLX90632_REFRESH_RATE(meas1);938 939 return ret;940}941 942static const int mlx90632_freqs[][2] = {943 {0, 500000},944 {1, 0},945 {2, 0},946 {4, 0},947 {8, 0},948 {16, 0},949 {32, 0},950 {64, 0}951};952 953/**954 * mlx90632_pm_interraction_wakeup() - Measure time between user interactions to change powermode955 * @data: pointer to mlx90632_data object containing interaction_ts information956 *957 * Switch to continuous mode when interaction is faster than MLX90632_MEAS_MAX_TIME. Update the958 * interaction_ts for each function call with the jiffies to enable measurement between function959 * calls. Initial value of the interaction_ts needs to be set before this function call.960 */961static int mlx90632_pm_interraction_wakeup(struct mlx90632_data *data)962{963 unsigned long now;964 int ret;965 966 now = jiffies;967 if (time_in_range(now, data->interaction_ts,968 data->interaction_ts +969 msecs_to_jiffies(MLX90632_MEAS_MAX_TIME + 100))) {970 if (data->powerstatus == MLX90632_PWR_STATUS_SLEEP_STEP) {971 ret = mlx90632_pwr_continuous(data->regmap);972 if (ret < 0)973 return ret;974 }975 }976 977 data->interaction_ts = now;978 979 return 0;980}981 982static int mlx90632_read_raw(struct iio_dev *indio_dev,983 struct iio_chan_spec const *channel, int *val,984 int *val2, long mask)985{986 struct mlx90632_data *data = iio_priv(indio_dev);987 int ret;988 int cr;989 990 pm_runtime_get_sync(&data->client->dev);991 ret = mlx90632_pm_interraction_wakeup(data);992 if (ret < 0)993 goto mlx90632_read_raw_pm;994 995 switch (mask) {996 case IIO_CHAN_INFO_PROCESSED:997 switch (channel->channel2) {998 case IIO_MOD_TEMP_AMBIENT:999 ret = mlx90632_calc_ambient_dsp105(data, val);1000 if (ret < 0)1001 goto mlx90632_read_raw_pm;1002 1003 ret = IIO_VAL_INT;1004 break;1005 case IIO_MOD_TEMP_OBJECT:1006 ret = mlx90632_calc_object_dsp105(data, val);1007 if (ret < 0)1008 goto mlx90632_read_raw_pm;1009 1010 ret = IIO_VAL_INT;1011 break;1012 default:1013 ret = -EINVAL;1014 break;1015 }1016 break;1017 case IIO_CHAN_INFO_CALIBEMISSIVITY:1018 if (data->emissivity == 1000) {1019 *val = 1;1020 *val2 = 0;1021 } else {1022 *val = 0;1023 *val2 = data->emissivity * 1000;1024 }1025 ret = IIO_VAL_INT_PLUS_MICRO;1026 break;1027 case IIO_CHAN_INFO_CALIBAMBIENT:1028 *val = data->object_ambient_temperature;1029 ret = IIO_VAL_INT;1030 break;1031 case IIO_CHAN_INFO_SAMP_FREQ:1032 ret = mlx90632_get_refresh_rate(data, &cr);1033 if (ret < 0)1034 goto mlx90632_read_raw_pm;1035 1036 *val = mlx90632_freqs[cr][0];1037 *val2 = mlx90632_freqs[cr][1];1038 ret = IIO_VAL_INT_PLUS_MICRO;1039 break;1040 default:1041 ret = -EINVAL;1042 break;1043 }1044 1045mlx90632_read_raw_pm:1046 pm_runtime_mark_last_busy(&data->client->dev);1047 pm_runtime_put_autosuspend(&data->client->dev);1048 return ret;1049}1050 1051static int mlx90632_write_raw(struct iio_dev *indio_dev,1052 struct iio_chan_spec const *channel, int val,1053 int val2, long mask)1054{1055 struct mlx90632_data *data = iio_priv(indio_dev);1056 1057 switch (mask) {1058 case IIO_CHAN_INFO_CALIBEMISSIVITY:1059 /* Confirm we are within 0 and 1.0 */1060 if (val < 0 || val2 < 0 || val > 1 ||1061 (val == 1 && val2 != 0))1062 return -EINVAL;1063 data->emissivity = val * 1000 + val2 / 1000;1064 return 0;1065 case IIO_CHAN_INFO_CALIBAMBIENT:1066 data->object_ambient_temperature = val;1067 return 0;1068 default:1069 return -EINVAL;1070 }1071}1072 1073static int mlx90632_read_avail(struct iio_dev *indio_dev,1074 struct iio_chan_spec const *chan,1075 const int **vals, int *type, int *length,1076 long mask)1077{1078 switch (mask) {1079 case IIO_CHAN_INFO_SAMP_FREQ:1080 *vals = (int *)mlx90632_freqs;1081 *type = IIO_VAL_INT_PLUS_MICRO;1082 *length = 2 * ARRAY_SIZE(mlx90632_freqs);1083 return IIO_AVAIL_LIST;1084 default:1085 return -EINVAL;1086 }1087}1088 1089static const struct iio_chan_spec mlx90632_channels[] = {1090 {1091 .type = IIO_TEMP,1092 .modified = 1,1093 .channel2 = IIO_MOD_TEMP_AMBIENT,1094 .info_mask_separate = BIT(IIO_CHAN_INFO_PROCESSED),1095 .info_mask_shared_by_all = BIT(IIO_CHAN_INFO_SAMP_FREQ),1096 .info_mask_shared_by_all_available = BIT(IIO_CHAN_INFO_SAMP_FREQ),1097 },1098 {1099 .type = IIO_TEMP,1100 .modified = 1,1101 .channel2 = IIO_MOD_TEMP_OBJECT,1102 .info_mask_separate = BIT(IIO_CHAN_INFO_PROCESSED) |1103 BIT(IIO_CHAN_INFO_CALIBEMISSIVITY) | BIT(IIO_CHAN_INFO_CALIBAMBIENT),1104 .info_mask_shared_by_all = BIT(IIO_CHAN_INFO_SAMP_FREQ),1105 .info_mask_shared_by_all_available = BIT(IIO_CHAN_INFO_SAMP_FREQ),1106 },1107};1108 1109static const struct iio_info mlx90632_info = {1110 .read_raw = mlx90632_read_raw,1111 .write_raw = mlx90632_write_raw,1112 .read_avail = mlx90632_read_avail,1113};1114 1115static void mlx90632_sleep(void *_data)1116{1117 struct mlx90632_data *data = _data;1118 1119 mlx90632_pwr_set_sleep_step(data->regmap);1120}1121 1122static int mlx90632_suspend(struct mlx90632_data *data)1123{1124 regcache_mark_dirty(data->regmap);1125 1126 dev_dbg(&data->client->dev, "Requesting suspend");1127 return mlx90632_pwr_set_sleep_step(data->regmap);1128}1129 1130static int mlx90632_wakeup(struct mlx90632_data *data)1131{1132 int ret;1133 1134 ret = regcache_sync(data->regmap);1135 if (ret < 0) {1136 dev_err(&data->client->dev,1137 "Failed to sync regmap registers: %d\n", ret);1138 return ret;1139 }1140 1141 dev_dbg(&data->client->dev, "Requesting wake-up\n");1142 return mlx90632_pwr_continuous(data->regmap);1143}1144 1145static void mlx90632_disable_regulator(void *_data)1146{1147 struct mlx90632_data *data = _data;1148 int ret;1149 1150 ret = regulator_disable(data->regulator);1151 if (ret < 0)1152 dev_err(regmap_get_device(data->regmap),1153 "Failed to disable power regulator: %d\n", ret);1154}1155 1156static int mlx90632_enable_regulator(struct mlx90632_data *data)1157{1158 int ret;1159 1160 ret = regulator_enable(data->regulator);1161 if (ret < 0) {1162 dev_err(regmap_get_device(data->regmap), "Failed to enable power regulator!\n");1163 return ret;1164 }1165 1166 mlx90632_reset_delay();1167 1168 return ret;1169}1170 1171static int mlx90632_probe(struct i2c_client *client)1172{1173 const struct i2c_device_id *id = i2c_client_get_device_id(client);1174 struct mlx90632_data *mlx90632;1175 struct iio_dev *indio_dev;1176 struct regmap *regmap;1177 unsigned int read;1178 int ret;1179 1180 indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*mlx90632));1181 if (!indio_dev) {1182 dev_err(&client->dev, "Failed to allocate device\n");1183 return -ENOMEM;1184 }1185 1186 regmap = devm_regmap_init_i2c(client, &mlx90632_regmap);1187 if (IS_ERR(regmap)) {1188 ret = PTR_ERR(regmap);1189 dev_err(&client->dev, "Failed to allocate regmap: %d\n", ret);1190 return ret;1191 }1192 1193 mlx90632 = iio_priv(indio_dev);1194 i2c_set_clientdata(client, indio_dev);1195 mlx90632->client = client;1196 mlx90632->regmap = regmap;1197 mlx90632->mtyp = MLX90632_MTYP_MEDICAL;1198 mlx90632->powerstatus = MLX90632_PWR_STATUS_HALT;1199 1200 mutex_init(&mlx90632->lock);1201 indio_dev->name = id->name;1202 indio_dev->modes = INDIO_DIRECT_MODE;1203 indio_dev->info = &mlx90632_info;1204 indio_dev->channels = mlx90632_channels;1205 indio_dev->num_channels = ARRAY_SIZE(mlx90632_channels);1206 1207 mlx90632->regulator = devm_regulator_get(&client->dev, "vdd");1208 if (IS_ERR(mlx90632->regulator))1209 return dev_err_probe(&client->dev, PTR_ERR(mlx90632->regulator),1210 "failed to get vdd regulator");1211 1212 ret = mlx90632_enable_regulator(mlx90632);1213 if (ret < 0)1214 return ret;1215 1216 ret = devm_add_action_or_reset(&client->dev, mlx90632_disable_regulator,1217 mlx90632);1218 if (ret < 0) {1219 dev_err(&client->dev, "Failed to setup regulator cleanup action %d\n",1220 ret);1221 return ret;1222 }1223 1224 ret = mlx90632_wakeup(mlx90632);1225 if (ret < 0) {1226 dev_err(&client->dev, "Wakeup failed: %d\n", ret);1227 return ret;1228 }1229 1230 ret = devm_add_action_or_reset(&client->dev, mlx90632_sleep, mlx90632);1231 if (ret < 0) {1232 dev_err(&client->dev, "Failed to setup low power cleanup action %d\n",1233 ret);1234 return ret;1235 }1236 1237 ret = regmap_read(mlx90632->regmap, MLX90632_EE_VERSION, &read);1238 if (ret < 0) {1239 dev_err(&client->dev, "read of version failed: %d\n", ret);1240 return ret;1241 }1242 read = read & MLX90632_ID_MASK;1243 if (read == MLX90632_ID_MEDICAL) {1244 dev_dbg(&client->dev,1245 "Detected Medical EEPROM calibration %x\n", read);1246 } else if (read == MLX90632_ID_CONSUMER) {1247 dev_dbg(&client->dev,1248 "Detected Consumer EEPROM calibration %x\n", read);1249 } else if (read == MLX90632_ID_EXTENDED) {1250 dev_dbg(&client->dev,1251 "Detected Extended range EEPROM calibration %x\n", read);1252 mlx90632->mtyp = MLX90632_MTYP_EXTENDED;1253 } else if ((read & MLX90632_DSP_MASK) == MLX90632_DSP_VERSION) {1254 dev_dbg(&client->dev,1255 "Detected Unknown EEPROM calibration %x\n", read);1256 } else {1257 dev_err(&client->dev,1258 "Wrong DSP version %x (expected %x)\n",1259 read, MLX90632_DSP_VERSION);1260 return -EPROTONOSUPPORT;1261 }1262 1263 mlx90632->emissivity = 1000;1264 mlx90632->object_ambient_temperature = 25000; /* 25 degrees milliCelsius */1265 mlx90632->interaction_ts = jiffies; /* Set initial value */1266 1267 pm_runtime_get_noresume(&client->dev);1268 pm_runtime_set_active(&client->dev);1269 1270 ret = devm_pm_runtime_enable(&client->dev);1271 if (ret)1272 return ret;1273 1274 pm_runtime_set_autosuspend_delay(&client->dev, MLX90632_SLEEP_DELAY_MS);1275 pm_runtime_use_autosuspend(&client->dev);1276 pm_runtime_put_autosuspend(&client->dev);1277 1278 return devm_iio_device_register(&client->dev, indio_dev);1279}1280 1281static const struct i2c_device_id mlx90632_id[] = {1282 { "mlx90632" },1283 { }1284};1285MODULE_DEVICE_TABLE(i2c, mlx90632_id);1286 1287static const struct of_device_id mlx90632_of_match[] = {1288 { .compatible = "melexis,mlx90632" },1289 { }1290};1291MODULE_DEVICE_TABLE(of, mlx90632_of_match);1292 1293static int mlx90632_pm_suspend(struct device *dev)1294{1295 struct mlx90632_data *data = iio_priv(dev_get_drvdata(dev));1296 int ret;1297 1298 ret = mlx90632_suspend(data);1299 if (ret < 0)1300 return ret;1301 1302 ret = regulator_disable(data->regulator);1303 if (ret < 0)1304 dev_err(regmap_get_device(data->regmap),1305 "Failed to disable power regulator: %d\n", ret);1306 1307 return ret;1308}1309 1310static int mlx90632_pm_resume(struct device *dev)1311{1312 struct mlx90632_data *data = iio_priv(dev_get_drvdata(dev));1313 int ret;1314 1315 ret = mlx90632_enable_regulator(data);1316 if (ret < 0)1317 return ret;1318 1319 return mlx90632_wakeup(data);1320}1321 1322static int mlx90632_pm_runtime_suspend(struct device *dev)1323{1324 struct mlx90632_data *data = iio_priv(dev_get_drvdata(dev));1325 1326 return mlx90632_pwr_set_sleep_step(data->regmap);1327}1328 1329static const struct dev_pm_ops mlx90632_pm_ops = {1330 SYSTEM_SLEEP_PM_OPS(mlx90632_pm_suspend, mlx90632_pm_resume)1331 RUNTIME_PM_OPS(mlx90632_pm_runtime_suspend, NULL, NULL)1332};1333 1334static struct i2c_driver mlx90632_driver = {1335 .driver = {1336 .name = "mlx90632",1337 .of_match_table = mlx90632_of_match,1338 .pm = pm_ptr(&mlx90632_pm_ops),1339 },1340 .probe = mlx90632_probe,1341 .id_table = mlx90632_id,1342};1343module_i2c_driver(mlx90632_driver);1344 1345MODULE_AUTHOR("Crt Mori <cmo@melexis.com>");1346MODULE_DESCRIPTION("Melexis MLX90632 contactless Infra Red temperature sensor driver");1347MODULE_LICENSE("GPL v2");1348