brintos

brintos / linux-shallow public Read only

0
0
Text · 30.0 KiB · f7f8849 Raw
1098 lines · c
1// SPDX-License-Identifier: GPL-2.02/*3 * mlx90635.c - Melexis MLX90635 contactless IR temperature sensor4 *5 * Copyright (c) 2023 Melexis <cmo@melexis.com>6 *7 * Driver for the Melexis MLX90635 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 28/* Memory sections addresses */29#define MLX90635_ADDR_RAM	0x0000 /* Start address of ram */30#define MLX90635_ADDR_EEPROM	0x0018 /* Start address of user eeprom */31 32/* EEPROM addresses - used at startup */33#define MLX90635_EE_I2C_CFG	0x0018 /* I2C address register initial value */34#define MLX90635_EE_CTRL1	0x001A /* Control register1 initial value */35#define MLX90635_EE_CTRL2	0x001C /* Control register2 initial value */36 37#define MLX90635_EE_Ha		0x001E /* Ha customer calib value reg 16bit */38#define MLX90635_EE_Hb		0x0020 /* Hb customer calib value reg 16bit */39#define MLX90635_EE_Fa		0x0026 /* Fa calibration register 32bit */40#define MLX90635_EE_FASCALE	0x002A /* Scaling coefficient for Fa register 16bit */41#define MLX90635_EE_Ga		0x002C /* Ga calibration register 16bit */42#define MLX90635_EE_Fb		0x002E /* Fb calibration register 16bit */43#define MLX90635_EE_Ea		0x0030 /* Ea calibration register 32bit */44#define MLX90635_EE_Eb		0x0034 /* Eb calibration register 32bit */45#define MLX90635_EE_P_G		0x0038 /* P_G calibration register 16bit */46#define MLX90635_EE_P_O		0x003A /* P_O calibration register 16bit */47#define MLX90635_EE_Aa		0x003C /* Aa calibration register 16bit */48#define MLX90635_EE_VERSION	0x003E /* Version bits 4:7 and 12:15 */49#define MLX90635_EE_Gb		0x0040 /* Gb calibration register 16bit */50 51/* Device status register - volatile */52#define MLX90635_REG_STATUS	0x000053#define   MLX90635_STAT_BUSY BIT(6) /* Device busy indicator */54#define   MLX90635_STAT_BRST BIT(5) /* Brown out reset indicator */55#define   MLX90635_STAT_CYCLE_POS GENMASK(4, 2) /* Data position */56#define   MLX90635_STAT_END_CONV BIT(1) /* End of conversion indicator */57#define   MLX90635_STAT_DATA_RDY BIT(0) /* Data ready indicator */58 59/* EEPROM control register address - volatile */60#define MLX90635_REG_EE		0x000C61#define   MLX90635_EE_ACTIVE BIT(4) /* Power-on EEPROM */62#define   MLX90635_EE_BUSY_MASK	BIT(15)63 64#define MLX90635_REG_CMD	0x0010 /* Command register address */65 66/* Control register1 address - volatile */67#define MLX90635_REG_CTRL1	0x001468#define   MLX90635_CTRL1_REFRESH_RATE_MASK GENMASK(2, 0)69#define   MLX90635_CTRL1_RES_CTRL_MASK GENMASK(4, 3)70#define   MLX90635_CTRL1_TABLE_MASK BIT(15) /* Table select */71 72/* Control register2 address - volatile */73#define   MLX90635_REG_CTRL2	0x001674#define   MLX90635_CTRL2_BURST_CNT_MASK GENMASK(10, 6) /* Burst count */75#define   MLX90635_CTRL2_MODE_MASK GENMASK(12, 11) /* Power mode */76#define   MLX90635_CTRL2_SOB_MASK BIT(15)77 78/* PowerModes statuses */79#define MLX90635_PWR_STATUS_HALT 080#define MLX90635_PWR_STATUS_SLEEP_STEP 181#define MLX90635_PWR_STATUS_STEP 282#define MLX90635_PWR_STATUS_CONTINUOUS 383 84/* Measurement data addresses */85#define MLX90635_RESULT_1   0x000286#define MLX90635_RESULT_2   0x000487#define MLX90635_RESULT_3   0x000688#define MLX90635_RESULT_4   0x000889#define MLX90635_RESULT_5   0x000A90 91/* Timings (ms) */92#define MLX90635_TIMING_RST_MIN 200 /* Minimum time after addressed reset command */93#define MLX90635_TIMING_RST_MAX 250 /* Maximum time after addressed reset command */94#define MLX90635_TIMING_POLLING 10000 /* Time between bit polling*/95#define MLX90635_TIMING_EE_ACTIVE_MIN 100 /* Minimum time after activating the EEPROM for read */96#define MLX90635_TIMING_EE_ACTIVE_MAX 150 /* Maximum time after activating the EEPROM for read */97 98/* Magic constants */99#define MLX90635_ID_DSPv1 0x01 /* EEPROM DSP version */100#define MLX90635_RESET_CMD  0x0006 /* Reset sensor (address or global) */101#define MLX90635_MAX_MEAS_NUM   31 /* Maximum number of measurements in list */102#define MLX90635_PTAT_DIV 12   /* Used to divide the PTAT value in pre-processing */103#define MLX90635_IR_DIV 24   /* Used to divide the IR value in pre-processing */104#define MLX90635_SLEEP_DELAY_MS 6000 /* Autosleep delay */105#define MLX90635_MEAS_MAX_TIME 2000 /* Max measurement time in ms for the lowest refresh rate */106#define MLX90635_READ_RETRIES 100 /* Number of read retries before quitting with timeout error */107#define MLX90635_VERSION_MASK (GENMASK(15, 12) | GENMASK(7, 4))108#define MLX90635_DSP_VERSION(reg) (((reg & GENMASK(14, 12)) >> 9) | ((reg & GENMASK(6, 4)) >> 4))109#define MLX90635_DSP_FIXED BIT(15)110 111 112/**113 * struct mlx90635_data - private data for the MLX90635 device114 * @client: I2C client of the device115 * @lock: Internal mutex because multiple reads are needed for single triggered116 *	  measurement to ensure data consistency117 * @regmap: Regmap of the device registers118 * @regmap_ee: Regmap of the device EEPROM which can be cached119 * @emissivity: Object emissivity from 0 to 1000 where 1000 = 1120 * @regulator: Regulator of the device121 * @powerstatus: Current POWER status of the device122 * @interaction_ts: Timestamp of the last temperature read that is used123 *		    for power management in jiffies124 */125struct mlx90635_data {126	struct i2c_client *client;127	struct mutex lock;128	struct regmap *regmap;129	struct regmap *regmap_ee;130	u16 emissivity;131	struct regulator *regulator;132	int powerstatus;133	unsigned long interaction_ts;134};135 136static const struct regmap_range mlx90635_volatile_reg_range[] = {137	regmap_reg_range(MLX90635_REG_STATUS, MLX90635_REG_STATUS),138	regmap_reg_range(MLX90635_RESULT_1, MLX90635_RESULT_5),139	regmap_reg_range(MLX90635_REG_EE, MLX90635_REG_EE),140	regmap_reg_range(MLX90635_REG_CMD, MLX90635_REG_CMD),141	regmap_reg_range(MLX90635_REG_CTRL1, MLX90635_REG_CTRL2),142};143 144static const struct regmap_access_table mlx90635_volatile_regs_tbl = {145	.yes_ranges = mlx90635_volatile_reg_range,146	.n_yes_ranges = ARRAY_SIZE(mlx90635_volatile_reg_range),147};148 149static const struct regmap_range mlx90635_read_reg_range[] = {150	regmap_reg_range(MLX90635_REG_STATUS, MLX90635_REG_STATUS),151	regmap_reg_range(MLX90635_RESULT_1, MLX90635_RESULT_5),152	regmap_reg_range(MLX90635_REG_EE, MLX90635_REG_EE),153	regmap_reg_range(MLX90635_REG_CMD, MLX90635_REG_CMD),154	regmap_reg_range(MLX90635_REG_CTRL1, MLX90635_REG_CTRL2),155};156 157static const struct regmap_access_table mlx90635_readable_regs_tbl = {158	.yes_ranges = mlx90635_read_reg_range,159	.n_yes_ranges = ARRAY_SIZE(mlx90635_read_reg_range),160};161 162static const struct regmap_range mlx90635_no_write_reg_range[] = {163	regmap_reg_range(MLX90635_RESULT_1, MLX90635_RESULT_5),164};165 166static const struct regmap_access_table mlx90635_writeable_regs_tbl = {167	.no_ranges = mlx90635_no_write_reg_range,168	.n_no_ranges = ARRAY_SIZE(mlx90635_no_write_reg_range),169};170 171static const struct regmap_config mlx90635_regmap = {172	.name = "mlx90635-registers",173	.reg_stride = 1,174	.reg_bits = 16,175	.val_bits = 16,176 177	.volatile_table = &mlx90635_volatile_regs_tbl,178	.rd_table = &mlx90635_readable_regs_tbl,179	.wr_table = &mlx90635_writeable_regs_tbl,180 181	.use_single_read = true,182	.use_single_write = true,183	.can_multi_write = false,184	.reg_format_endian = REGMAP_ENDIAN_BIG,185	.val_format_endian = REGMAP_ENDIAN_BIG,186	.cache_type = REGCACHE_RBTREE,187};188 189static const struct regmap_range mlx90635_read_ee_range[] = {190	regmap_reg_range(MLX90635_EE_I2C_CFG, MLX90635_EE_CTRL2),191	regmap_reg_range(MLX90635_EE_Ha, MLX90635_EE_Gb),192};193 194static const struct regmap_access_table mlx90635_readable_ees_tbl = {195	.yes_ranges = mlx90635_read_ee_range,196	.n_yes_ranges = ARRAY_SIZE(mlx90635_read_ee_range),197};198 199static const struct regmap_range mlx90635_no_write_ee_range[] = {200	regmap_reg_range(MLX90635_ADDR_EEPROM, MLX90635_EE_Gb),201};202 203static const struct regmap_access_table mlx90635_writeable_ees_tbl = {204	.no_ranges = mlx90635_no_write_ee_range,205	.n_no_ranges = ARRAY_SIZE(mlx90635_no_write_ee_range),206};207 208static const struct regmap_config mlx90635_regmap_ee = {209	.name = "mlx90635-eeprom",210	.reg_stride = 1,211	.reg_bits = 16,212	.val_bits = 16,213 214	.volatile_table = NULL,215	.rd_table = &mlx90635_readable_ees_tbl,216	.wr_table = &mlx90635_writeable_ees_tbl,217 218	.use_single_read = true,219	.use_single_write = true,220	.can_multi_write = false,221	.reg_format_endian = REGMAP_ENDIAN_BIG,222	.val_format_endian = REGMAP_ENDIAN_BIG,223	.cache_type = REGCACHE_RBTREE,224};225 226/**227 * mlx90635_reset_delay() - Give the mlx90635 some time to reset properly228 * If this is not done, the following I2C command(s) will not be accepted.229 */230static void mlx90635_reset_delay(void)231{232	usleep_range(MLX90635_TIMING_RST_MIN, MLX90635_TIMING_RST_MAX);233}234 235static int mlx90635_pwr_sleep_step(struct mlx90635_data *data)236{237	int ret;238 239	if (data->powerstatus == MLX90635_PWR_STATUS_SLEEP_STEP)240		return 0;241 242	ret = regmap_write_bits(data->regmap, MLX90635_REG_CTRL2, MLX90635_CTRL2_MODE_MASK,243				FIELD_PREP(MLX90635_CTRL2_MODE_MASK, MLX90635_PWR_STATUS_SLEEP_STEP));244	if (ret < 0)245		return ret;246 247	data->powerstatus = MLX90635_PWR_STATUS_SLEEP_STEP;248	return 0;249}250 251static int mlx90635_pwr_continuous(struct mlx90635_data *data)252{253	int ret;254 255	if (data->powerstatus == MLX90635_PWR_STATUS_CONTINUOUS)256		return 0;257 258	ret = regmap_write_bits(data->regmap, MLX90635_REG_CTRL2, MLX90635_CTRL2_MODE_MASK,259				FIELD_PREP(MLX90635_CTRL2_MODE_MASK, MLX90635_PWR_STATUS_CONTINUOUS));260	if (ret < 0)261		return ret;262 263	data->powerstatus = MLX90635_PWR_STATUS_CONTINUOUS;264	return 0;265}266 267static int mlx90635_read_ee_register(struct regmap *regmap, u16 reg_lsb,268				     s32 *reg_value)269{270	unsigned int read;271	u32 value;272	int ret;273 274	ret = regmap_read(regmap, reg_lsb + 2, &read);275	if (ret < 0)276		return ret;277 278	value = read;279 280	ret = regmap_read(regmap, reg_lsb, &read);281	if (ret < 0)282		return ret;283 284	*reg_value = (read << 16) | (value & 0xffff);285 286	return 0;287}288 289static int mlx90635_read_ee_ambient(struct regmap *regmap, s16 *PG, s16 *PO, s16 *Gb)290{291	unsigned int read_tmp;292	int ret;293 294	ret = regmap_read(regmap, MLX90635_EE_P_O, &read_tmp);295	if (ret < 0)296		return ret;297	*PO = (s16)read_tmp;298 299	ret = regmap_read(regmap, MLX90635_EE_P_G, &read_tmp);300	if (ret < 0)301		return ret;302	*PG = (s16)read_tmp;303 304	ret = regmap_read(regmap, MLX90635_EE_Gb, &read_tmp);305	if (ret < 0)306		return ret;307	*Gb = (u16)read_tmp;308 309	return 0;310}311 312static int mlx90635_read_ee_object(struct regmap *regmap, u32 *Ea, u32 *Eb, u32 *Fa, s16 *Fb,313				   s16 *Ga, s16 *Gb, s16 *Ha, s16 *Hb, u16 *Fa_scale)314{315	unsigned int read_tmp;316	int ret;317 318	ret = mlx90635_read_ee_register(regmap, MLX90635_EE_Ea, Ea);319	if (ret < 0)320		return ret;321 322	ret = mlx90635_read_ee_register(regmap, MLX90635_EE_Eb, Eb);323	if (ret < 0)324		return ret;325 326	ret = mlx90635_read_ee_register(regmap, MLX90635_EE_Fa, Fa);327	if (ret < 0)328		return ret;329 330	ret = regmap_read(regmap, MLX90635_EE_Ha, &read_tmp);331	if (ret < 0)332		return ret;333	*Ha = (s16)read_tmp;334 335	ret = regmap_read(regmap, MLX90635_EE_Hb, &read_tmp);336	if (ret < 0)337		return ret;338	*Hb = (s16)read_tmp;339 340	ret = regmap_read(regmap, MLX90635_EE_Ga, &read_tmp);341	if (ret < 0)342		return ret;343	*Ga = (s16)read_tmp;344 345	ret = regmap_read(regmap, MLX90635_EE_Gb, &read_tmp);346	if (ret < 0)347		return ret;348	*Gb = (s16)read_tmp;349 350	ret = regmap_read(regmap, MLX90635_EE_Fb, &read_tmp);351	if (ret < 0)352		return ret;353	*Fb = (s16)read_tmp;354 355	ret = regmap_read(regmap, MLX90635_EE_FASCALE, &read_tmp);356	if (ret < 0)357		return ret;358	*Fa_scale = (u16)read_tmp;359 360	return 0;361}362 363static int mlx90635_calculate_dataset_ready_time(struct mlx90635_data *data, int *refresh_time)364{365	unsigned int reg;366	int ret;367 368	ret = regmap_read(data->regmap, MLX90635_REG_CTRL1, &reg);369	if (ret < 0)370		return ret;371 372	*refresh_time = 2 * (MLX90635_MEAS_MAX_TIME >> FIELD_GET(MLX90635_CTRL1_REFRESH_RATE_MASK, reg)) + 80;373 374	return 0;375}376 377static int mlx90635_perform_measurement_burst(struct mlx90635_data *data)378{379	unsigned int reg_status;380	int refresh_time;381	int ret;382 383	ret = regmap_write_bits(data->regmap, MLX90635_REG_STATUS,384				MLX90635_STAT_END_CONV, MLX90635_STAT_END_CONV);385	if (ret < 0)386		return ret;387 388	ret = mlx90635_calculate_dataset_ready_time(data, &refresh_time);389	if (ret < 0)390		return ret;391 392	ret = regmap_write_bits(data->regmap, MLX90635_REG_CTRL2,393				FIELD_PREP(MLX90635_CTRL2_SOB_MASK, 1),394				FIELD_PREP(MLX90635_CTRL2_SOB_MASK, 1));395	if (ret < 0)396		return ret;397 398	msleep(refresh_time); /* Wait minimum time for dataset to be ready */399 400	ret = regmap_read_poll_timeout(data->regmap, MLX90635_REG_STATUS, reg_status,401				       (!(reg_status & MLX90635_STAT_END_CONV)) == 0,402				       MLX90635_TIMING_POLLING, MLX90635_READ_RETRIES * 10000);403	if (ret < 0) {404		dev_err(&data->client->dev, "data not ready");405		return -ETIMEDOUT;406	}407 408	return 0;409}410 411static int mlx90635_read_ambient_raw(struct regmap *regmap,412				     s16 *ambient_new_raw, s16 *ambient_old_raw)413{414	unsigned int read_tmp;415	int ret;416 417	ret = regmap_read(regmap, MLX90635_RESULT_2, &read_tmp);418	if (ret < 0)419		return ret;420	*ambient_new_raw = (s16)read_tmp;421 422	ret = regmap_read(regmap, MLX90635_RESULT_3, &read_tmp);423	if (ret < 0)424		return ret;425	*ambient_old_raw = (s16)read_tmp;426 427	return 0;428}429 430static int mlx90635_read_object_raw(struct regmap *regmap, s16 *object_raw)431{432	unsigned int read_tmp;433	s16 read;434	int ret;435 436	ret = regmap_read(regmap, MLX90635_RESULT_1, &read_tmp);437	if (ret < 0)438		return ret;439 440	read = (s16)read_tmp;441 442	ret = regmap_read(regmap, MLX90635_RESULT_4, &read_tmp);443	if (ret < 0)444		return ret;445	*object_raw = (read - (s16)read_tmp) / 2;446 447	return 0;448}449 450static int mlx90635_read_all_channel(struct mlx90635_data *data,451				     s16 *ambient_new_raw, s16 *ambient_old_raw,452				     s16 *object_raw)453{454	int ret;455 456	mutex_lock(&data->lock);457	if (data->powerstatus == MLX90635_PWR_STATUS_SLEEP_STEP) {458		/* Trigger measurement in Sleep Step mode */459		ret = mlx90635_perform_measurement_burst(data);460		if (ret < 0)461			goto read_unlock;462	}463 464	ret = mlx90635_read_ambient_raw(data->regmap, ambient_new_raw,465					ambient_old_raw);466	if (ret < 0)467		goto read_unlock;468 469	ret = mlx90635_read_object_raw(data->regmap, object_raw);470read_unlock:471	mutex_unlock(&data->lock);472	return ret;473}474 475static s64 mlx90635_preprocess_temp_amb(s16 ambient_new_raw,476					s16 ambient_old_raw, s16 Gb)477{478	s64 VR_Ta, kGb, tmp;479 480	kGb = ((s64)Gb * 1000LL) >> 10ULL;481	VR_Ta = (s64)ambient_old_raw * 1000000LL +482		kGb * div64_s64(((s64)ambient_new_raw * 1000LL),483			(MLX90635_PTAT_DIV));484	tmp = div64_s64(485			 div64_s64(((s64)ambient_new_raw * 1000000000000LL),486				   (MLX90635_PTAT_DIV)), VR_Ta);487	return div64_s64(tmp << 19ULL, 1000LL);488}489 490static s64 mlx90635_preprocess_temp_obj(s16 object_raw,491					s16 ambient_new_raw,492					s16 ambient_old_raw, s16 Gb)493{494	s64 VR_IR, kGb, tmp;495 496	kGb = ((s64)Gb * 1000LL) >> 10ULL;497	VR_IR = (s64)ambient_old_raw * 1000000LL +498		kGb * (div64_s64((s64)ambient_new_raw * 1000LL,499			MLX90635_PTAT_DIV));500	tmp = div64_s64(501			div64_s64((s64)(object_raw * 1000000LL),502				   MLX90635_IR_DIV) * 1000000LL,503			VR_IR);504	return div64_s64((tmp << 19ULL), 1000LL);505}506 507static s32 mlx90635_calc_temp_ambient(s16 ambient_new_raw, s16 ambient_old_raw,508				      u16 P_G, u16 P_O, s16 Gb)509{510	s64 kPG, kPO, AMB;511 512	AMB = mlx90635_preprocess_temp_amb(ambient_new_raw, ambient_old_raw,513					   Gb);514	kPG = ((s64)P_G * 1000000LL) >> 9ULL;515	kPO = AMB - (((s64)P_O * 1000LL) >> 1ULL);516 517	return 30 * 1000LL + div64_s64(kPO * 1000000LL, kPG);518}519 520static s32 mlx90635_calc_temp_object_iteration(s32 prev_object_temp, s64 object,521					       s64 TAdut, s64 TAdut4, s16 Ga,522					       u32 Fa, u16 Fa_scale, s16 Fb,523					       s16 Ha, s16 Hb, u16 emissivity)524{525	s64 calcedGa, calcedGb, calcedFa, Alpha_corr;526	s64 Ha_customer, Hb_customer;527 528	Ha_customer = ((s64)Ha * 1000000LL) >> 14ULL;529	Hb_customer = ((s64)Hb * 100) >> 10ULL;530 531	calcedGa = ((s64)((s64)Ga * (prev_object_temp - 35 * 1000LL)532			     * 1000LL)) >> 24LL;533	calcedGb = ((s64)(Fb * (TAdut - 30 * 1000000LL))) >> 24LL;534 535	Alpha_corr = ((s64)((s64)Fa * Ha_customer * 10000LL) >> Fa_scale);536	Alpha_corr *= ((s64)(1 * 1000000LL + calcedGa + calcedGb));537 538	Alpha_corr = div64_s64(Alpha_corr, 1000LL);539	Alpha_corr *= emissivity;540	Alpha_corr = div64_s64(Alpha_corr, 100LL);541	calcedFa = div64_s64((s64)object * 100000000000LL, Alpha_corr);542 543	return (int_sqrt64(int_sqrt64(calcedFa * 100000000LL + TAdut4))544		- 27315 - Hb_customer) * 10;545}546 547static s64 mlx90635_calc_ta4(s64 TAdut, s64 scale)548{549	return (div64_s64(TAdut, scale) + 27315) *550		(div64_s64(TAdut, scale) + 27315) *551		(div64_s64(TAdut, scale) + 27315) *552		(div64_s64(TAdut, scale) + 27315);553}554 555static s32 mlx90635_calc_temp_object(s64 object, s64 ambient, u32 Ea, u32 Eb,556				     s16 Ga, u32 Fa, u16 Fa_scale, s16 Fb, s16 Ha, s16 Hb,557				     u16 tmp_emi)558{559	s64 kTA, kTA0, TAdut, TAdut4;560	s64 temp = 35000;561	s8 i;562 563	kTA = (Ea * 1000LL) >> 16LL;564	kTA0 = (Eb * 1000LL) >> 8LL;565	TAdut = div64_s64(((ambient - kTA0) * 1000000LL), kTA) + 30 * 1000000LL;566	TAdut4 = mlx90635_calc_ta4(TAdut, 10000LL);567 568	/* Iterations of calculation as described in datasheet */569	for (i = 0; i < 5; ++i) {570		temp = mlx90635_calc_temp_object_iteration(temp, object, TAdut, TAdut4,571							   Ga, Fa, Fa_scale, Fb, Ha, Hb,572							   tmp_emi);573	}574	return temp;575}576 577static int mlx90635_calc_object(struct mlx90635_data *data, int *val)578{579	s16 ambient_new_raw, ambient_old_raw, object_raw;580	s16 Fb, Ga, Gb, Ha, Hb;581	s64 object, ambient;582	u32 Ea, Eb, Fa;583	u16 Fa_scale;584	int ret;585 586	ret = mlx90635_read_ee_object(data->regmap_ee, &Ea, &Eb, &Fa, &Fb, &Ga, &Gb, &Ha, &Hb, &Fa_scale);587	if (ret < 0)588		return ret;589 590	ret = mlx90635_read_all_channel(data,591					&ambient_new_raw, &ambient_old_raw,592					&object_raw);593	if (ret < 0)594		return ret;595 596	ambient = mlx90635_preprocess_temp_amb(ambient_new_raw,597					       ambient_old_raw, Gb);598	object = mlx90635_preprocess_temp_obj(object_raw,599					      ambient_new_raw,600					      ambient_old_raw, Gb);601 602	*val = mlx90635_calc_temp_object(object, ambient, Ea, Eb, Ga, Fa, Fa_scale, Fb,603					 Ha, Hb, data->emissivity);604	return 0;605}606 607static int mlx90635_calc_ambient(struct mlx90635_data *data, int *val)608{609	s16 ambient_new_raw, ambient_old_raw;610	s16 PG, PO, Gb;611	int ret;612 613	ret = mlx90635_read_ee_ambient(data->regmap_ee, &PG, &PO, &Gb);614	if (ret < 0)615		return ret;616 617	mutex_lock(&data->lock);618	if (data->powerstatus == MLX90635_PWR_STATUS_SLEEP_STEP) {619		ret = mlx90635_perform_measurement_burst(data);620		if (ret < 0)621			goto read_ambient_unlock;622	}623 624	ret = mlx90635_read_ambient_raw(data->regmap, &ambient_new_raw,625					&ambient_old_raw);626read_ambient_unlock:627	mutex_unlock(&data->lock);628	if (ret < 0)629		return ret;630 631	*val = mlx90635_calc_temp_ambient(ambient_new_raw, ambient_old_raw,632					  PG, PO, Gb);633	return ret;634}635 636static int mlx90635_get_refresh_rate(struct mlx90635_data *data,637				     unsigned int *refresh_rate)638{639	unsigned int reg;640	int ret;641 642	ret = regmap_read(data->regmap, MLX90635_REG_CTRL1, &reg);643	if (ret < 0)644		return ret;645 646	*refresh_rate = FIELD_GET(MLX90635_CTRL1_REFRESH_RATE_MASK, reg);647 648	return 0;649}650 651static const struct {652	int val;653	int val2;654} mlx90635_freqs[] = {655	{ 0, 200000 },656	{ 0, 500000 },657	{ 0, 900000 },658	{ 1, 700000 },659	{ 3, 0 },660	{ 4, 800000 },661	{ 6, 900000 },662	{ 8, 900000 }663};664 665/**666 * mlx90635_pm_interaction_wakeup() - Measure time between user interactions to change powermode667 * @data: pointer to mlx90635_data object containing interaction_ts information668 *669 * Switch to continuous mode when interaction is faster than MLX90635_MEAS_MAX_TIME. Update the670 * interaction_ts for each function call with the jiffies to enable measurement between function671 * calls. Initial value of the interaction_ts needs to be set before this function call.672 */673static int mlx90635_pm_interaction_wakeup(struct mlx90635_data *data)674{675	unsigned long now;676	int ret;677 678	now = jiffies;679	if (time_in_range(now, data->interaction_ts,680			  data->interaction_ts +681			  msecs_to_jiffies(MLX90635_MEAS_MAX_TIME + 100))) {682		ret = mlx90635_pwr_continuous(data);683		if (ret < 0)684			return ret;685	}686 687	data->interaction_ts = now;688 689	return 0;690}691 692static int mlx90635_read_raw(struct iio_dev *indio_dev,693			     struct iio_chan_spec const *channel, int *val,694			     int *val2, long mask)695{696	struct mlx90635_data *data = iio_priv(indio_dev);697	int ret;698	int cr;699 700	pm_runtime_get_sync(&data->client->dev);701	ret = mlx90635_pm_interaction_wakeup(data);702	if (ret < 0)703		goto mlx90635_read_raw_pm;704 705	switch (mask) {706	case IIO_CHAN_INFO_PROCESSED:707		switch (channel->channel2) {708		case IIO_MOD_TEMP_AMBIENT:709			ret = mlx90635_calc_ambient(data, val);710			if (ret < 0)711				goto mlx90635_read_raw_pm;712 713			ret = IIO_VAL_INT;714			break;715		case IIO_MOD_TEMP_OBJECT:716			ret = mlx90635_calc_object(data, val);717			if (ret < 0)718				goto mlx90635_read_raw_pm;719 720			ret = IIO_VAL_INT;721			break;722		default:723			ret = -EINVAL;724			break;725		}726		break;727	case IIO_CHAN_INFO_CALIBEMISSIVITY:728		if (data->emissivity == 1000) {729			*val = 1;730			*val2 = 0;731		} else {732			*val = 0;733			*val2 = data->emissivity * 1000;734		}735		ret = IIO_VAL_INT_PLUS_MICRO;736		break;737	case IIO_CHAN_INFO_SAMP_FREQ:738		ret = mlx90635_get_refresh_rate(data, &cr);739		if (ret < 0)740			goto mlx90635_read_raw_pm;741 742		*val = mlx90635_freqs[cr].val;743		*val2 = mlx90635_freqs[cr].val2;744		ret = IIO_VAL_INT_PLUS_MICRO;745		break;746	default:747		ret = -EINVAL;748		break;749	}750 751mlx90635_read_raw_pm:752	pm_runtime_mark_last_busy(&data->client->dev);753	pm_runtime_put_autosuspend(&data->client->dev);754	return ret;755}756 757static int mlx90635_write_raw(struct iio_dev *indio_dev,758			      struct iio_chan_spec const *channel, int val,759			      int val2, long mask)760{761	struct mlx90635_data *data = iio_priv(indio_dev);762	int ret;763	int i;764 765	switch (mask) {766	case IIO_CHAN_INFO_CALIBEMISSIVITY:767		/* Confirm we are within 0 and 1.0 */768		if (val < 0 || val2 < 0 || val > 1 ||769		    (val == 1 && val2 != 0))770			return -EINVAL;771		data->emissivity = val * 1000 + val2 / 1000;772		return 0;773	case IIO_CHAN_INFO_SAMP_FREQ:774		for (i = 0; i < ARRAY_SIZE(mlx90635_freqs); i++) {775			if (val == mlx90635_freqs[i].val &&776			    val2 == mlx90635_freqs[i].val2)777				break;778		}779		if (i == ARRAY_SIZE(mlx90635_freqs))780			return -EINVAL;781 782		ret = regmap_write_bits(data->regmap, MLX90635_REG_CTRL1,783					MLX90635_CTRL1_REFRESH_RATE_MASK, i);784 785		return ret;786	default:787		return -EINVAL;788	}789}790 791static int mlx90635_read_avail(struct iio_dev *indio_dev,792			       struct iio_chan_spec const *chan,793			       const int **vals, int *type, int *length,794			       long mask)795{796	switch (mask) {797	case IIO_CHAN_INFO_SAMP_FREQ:798		*vals = (int *)mlx90635_freqs;799		*type = IIO_VAL_INT_PLUS_MICRO;800		*length = 2 * ARRAY_SIZE(mlx90635_freqs);801		return IIO_AVAIL_LIST;802	default:803		return -EINVAL;804	}805}806 807static const struct iio_chan_spec mlx90635_channels[] = {808	{809		.type = IIO_TEMP,810		.modified = 1,811		.channel2 = IIO_MOD_TEMP_AMBIENT,812		.info_mask_separate = BIT(IIO_CHAN_INFO_PROCESSED),813		.info_mask_shared_by_all = BIT(IIO_CHAN_INFO_SAMP_FREQ),814		.info_mask_shared_by_all_available = BIT(IIO_CHAN_INFO_SAMP_FREQ),815	},816	{817		.type = IIO_TEMP,818		.modified = 1,819		.channel2 = IIO_MOD_TEMP_OBJECT,820		.info_mask_separate = BIT(IIO_CHAN_INFO_PROCESSED) |821			BIT(IIO_CHAN_INFO_CALIBEMISSIVITY),822		.info_mask_shared_by_all = BIT(IIO_CHAN_INFO_SAMP_FREQ),823		.info_mask_shared_by_all_available = BIT(IIO_CHAN_INFO_SAMP_FREQ),824	},825};826 827static const struct iio_info mlx90635_info = {828	.read_raw = mlx90635_read_raw,829	.write_raw = mlx90635_write_raw,830	.read_avail = mlx90635_read_avail,831};832 833static void mlx90635_sleep(void *_data)834{835	struct mlx90635_data *data = _data;836 837	mlx90635_pwr_sleep_step(data);838}839 840static int mlx90635_suspend(struct mlx90635_data *data)841{842	return mlx90635_pwr_sleep_step(data);843}844 845static int mlx90635_wakeup(struct mlx90635_data *data)846{847	s16 Fb, Ga, Gb, Ha, Hb, PG, PO;848	unsigned int dsp_version;849	u32 Ea, Eb, Fa;850	u16 Fa_scale;851	int ret;852 853	regcache_cache_bypass(data->regmap_ee, false);854	regcache_cache_only(data->regmap_ee, false);855	regcache_cache_only(data->regmap, false);856 857	ret = mlx90635_pwr_continuous(data);858	if (ret < 0) {859		dev_err(&data->client->dev, "Switch to continuous mode failed\n");860		return ret;861	}862	ret = regmap_write_bits(data->regmap, MLX90635_REG_EE,863				MLX90635_EE_ACTIVE, MLX90635_EE_ACTIVE);864	if (ret < 0) {865		dev_err(&data->client->dev, "Powering EEPROM failed\n");866		return ret;867	}868	usleep_range(MLX90635_TIMING_EE_ACTIVE_MIN, MLX90635_TIMING_EE_ACTIVE_MAX);869 870	regcache_mark_dirty(data->regmap_ee);871 872	ret = regcache_sync(data->regmap_ee);873	if (ret < 0) {874		dev_err(&data->client->dev,875			"Failed to sync cache: %d\n", ret);876		return ret;877	}878 879	ret = mlx90635_read_ee_ambient(data->regmap_ee, &PG, &PO, &Gb);880	if (ret < 0) {881		dev_err(&data->client->dev,882			"Failed to read to cache Ambient coefficients EEPROM region: %d\n", ret);883		return ret;884	}885 886	ret = mlx90635_read_ee_object(data->regmap_ee, &Ea, &Eb, &Fa, &Fb, &Ga, &Gb, &Ha, &Hb, &Fa_scale);887	if (ret < 0) {888		dev_err(&data->client->dev,889			"Failed to read to cache Object coefficients EEPROM region: %d\n", ret);890		return ret;891	}892 893	ret = regmap_read(data->regmap_ee, MLX90635_EE_VERSION, &dsp_version);894	if (ret < 0) {895		dev_err(&data->client->dev,896			"Failed to read to cache of EEPROM version: %d\n", ret);897		return ret;898	}899 900	regcache_cache_only(data->regmap_ee, true);901 902	return ret;903}904 905static void mlx90635_disable_regulator(void *_data)906{907	struct mlx90635_data *data = _data;908	int ret;909 910	ret = regulator_disable(data->regulator);911	if (ret < 0)912		dev_err(regmap_get_device(data->regmap),913			"Failed to disable power regulator: %d\n", ret);914}915 916static int mlx90635_enable_regulator(struct mlx90635_data *data)917{918	int ret;919 920	ret = regulator_enable(data->regulator);921	if (ret < 0) {922		dev_err(regmap_get_device(data->regmap), "Failed to enable power regulator!\n");923		return ret;924	}925 926	mlx90635_reset_delay();927 928	return ret;929}930 931static int mlx90635_probe(struct i2c_client *client)932{933	struct mlx90635_data *mlx90635;934	struct iio_dev *indio_dev;935	unsigned int dsp_version;936	struct regmap *regmap;937	struct regmap *regmap_ee;938	int ret;939 940	indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*mlx90635));941	if (!indio_dev)942		return dev_err_probe(&client->dev, -ENOMEM, "failed to allocate device\n");943 944	regmap = devm_regmap_init_i2c(client, &mlx90635_regmap);945	if (IS_ERR(regmap))946		return dev_err_probe(&client->dev, PTR_ERR(regmap),947				     "failed to allocate regmap\n");948 949	regmap_ee = devm_regmap_init_i2c(client, &mlx90635_regmap_ee);950	if (IS_ERR(regmap_ee))951		return dev_err_probe(&client->dev, PTR_ERR(regmap_ee),952				     "failed to allocate EEPROM regmap\n");953 954	mlx90635 = iio_priv(indio_dev);955	i2c_set_clientdata(client, indio_dev);956	mlx90635->client = client;957	mlx90635->regmap = regmap;958	mlx90635->regmap_ee = regmap_ee;959	mlx90635->powerstatus = MLX90635_PWR_STATUS_SLEEP_STEP;960 961	mutex_init(&mlx90635->lock);962	indio_dev->name = "mlx90635";963	indio_dev->modes = INDIO_DIRECT_MODE;964	indio_dev->info = &mlx90635_info;965	indio_dev->channels = mlx90635_channels;966	indio_dev->num_channels = ARRAY_SIZE(mlx90635_channels);967 968	mlx90635->regulator = devm_regulator_get(&client->dev, "vdd");969	if (IS_ERR(mlx90635->regulator))970		return dev_err_probe(&client->dev, PTR_ERR(mlx90635->regulator),971				     "failed to get vdd regulator");972 973	ret = mlx90635_enable_regulator(mlx90635);974	if (ret < 0)975		return ret;976 977	ret = devm_add_action_or_reset(&client->dev, mlx90635_disable_regulator,978				       mlx90635);979	if (ret < 0)980		return dev_err_probe(&client->dev, ret,981				     "failed to setup regulator cleanup action\n");982 983	ret = mlx90635_wakeup(mlx90635);984	if (ret < 0)985		return dev_err_probe(&client->dev, ret, "wakeup failed\n");986 987	ret = devm_add_action_or_reset(&client->dev, mlx90635_sleep, mlx90635);988	if (ret < 0)989		return dev_err_probe(&client->dev, ret,990				     "failed to setup low power cleanup\n");991 992	ret = regmap_read(mlx90635->regmap_ee, MLX90635_EE_VERSION, &dsp_version);993	if (ret < 0)994		return dev_err_probe(&client->dev, ret, "read of version failed\n");995 996	dsp_version = dsp_version & MLX90635_VERSION_MASK;997 998	if (FIELD_GET(MLX90635_DSP_FIXED, dsp_version)) {999		if (MLX90635_DSP_VERSION(dsp_version) == MLX90635_ID_DSPv1) {1000			dev_dbg(&client->dev,1001				"Detected DSP v1 calibration %x\n", dsp_version);1002		} else {1003			dev_dbg(&client->dev,1004				"Detected Unknown EEPROM calibration %lx\n",1005				MLX90635_DSP_VERSION(dsp_version));1006		}1007	} else {1008		return dev_err_probe(&client->dev, -EPROTONOSUPPORT,1009			"Wrong fixed top bit %x (expected 0x8X0X)\n",1010			dsp_version);1011	}1012 1013	mlx90635->emissivity = 1000;1014	mlx90635->interaction_ts = jiffies; /* Set initial value */1015 1016	pm_runtime_get_noresume(&client->dev);1017	pm_runtime_set_active(&client->dev);1018 1019	ret = devm_pm_runtime_enable(&client->dev);1020	if (ret)1021		return dev_err_probe(&client->dev, ret,1022				     "failed to enable powermanagement\n");1023 1024	pm_runtime_set_autosuspend_delay(&client->dev, MLX90635_SLEEP_DELAY_MS);1025	pm_runtime_use_autosuspend(&client->dev);1026	pm_runtime_put_autosuspend(&client->dev);1027 1028	return devm_iio_device_register(&client->dev, indio_dev);1029}1030 1031static const struct i2c_device_id mlx90635_id[] = {1032	{ "mlx90635" },1033	{ }1034};1035MODULE_DEVICE_TABLE(i2c, mlx90635_id);1036 1037static const struct of_device_id mlx90635_of_match[] = {1038	{ .compatible = "melexis,mlx90635" },1039	{ }1040};1041MODULE_DEVICE_TABLE(of, mlx90635_of_match);1042 1043static int mlx90635_pm_suspend(struct device *dev)1044{1045	struct mlx90635_data *data = iio_priv(dev_get_drvdata(dev));1046	int ret;1047 1048	ret = mlx90635_suspend(data);1049	if (ret < 0)1050		return ret;1051 1052	ret = regulator_disable(data->regulator);1053	if (ret < 0)1054		dev_err(regmap_get_device(data->regmap),1055			"Failed to disable power regulator: %d\n", ret);1056 1057	return ret;1058}1059 1060static int mlx90635_pm_resume(struct device *dev)1061{1062	struct mlx90635_data *data = iio_priv(dev_get_drvdata(dev));1063	int ret;1064 1065	ret = mlx90635_enable_regulator(data);1066	if (ret < 0)1067		return ret;1068 1069	return mlx90635_wakeup(data);1070}1071 1072static int mlx90635_pm_runtime_suspend(struct device *dev)1073{1074	struct mlx90635_data *data = iio_priv(dev_get_drvdata(dev));1075 1076	return mlx90635_pwr_sleep_step(data);1077}1078 1079static const struct dev_pm_ops mlx90635_pm_ops = {1080	SYSTEM_SLEEP_PM_OPS(mlx90635_pm_suspend, mlx90635_pm_resume)1081	RUNTIME_PM_OPS(mlx90635_pm_runtime_suspend, NULL, NULL)1082};1083 1084static struct i2c_driver mlx90635_driver = {1085	.driver = {1086		.name	= "mlx90635",1087		.of_match_table = mlx90635_of_match,1088		.pm	= pm_ptr(&mlx90635_pm_ops),1089	},1090	.probe = mlx90635_probe,1091	.id_table = mlx90635_id,1092};1093module_i2c_driver(mlx90635_driver);1094 1095MODULE_AUTHOR("Crt Mori <cmo@melexis.com>");1096MODULE_DESCRIPTION("Melexis MLX90635 contactless Infra Red temperature sensor driver");1097MODULE_LICENSE("GPL");1098