xref: /OK3568_Linux_fs/kernel/drivers/iio/temperature/mlx90614.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun // SPDX-License-Identifier: GPL-2.0-only
2*4882a593Smuzhiyun /*
3*4882a593Smuzhiyun  * mlx90614.c - Support for Melexis MLX90614 contactless IR temperature sensor
4*4882a593Smuzhiyun  *
5*4882a593Smuzhiyun  * Copyright (c) 2014 Peter Meerwald <pmeerw@pmeerw.net>
6*4882a593Smuzhiyun  * Copyright (c) 2015 Essensium NV
7*4882a593Smuzhiyun  * Copyright (c) 2015 Melexis
8*4882a593Smuzhiyun  *
9*4882a593Smuzhiyun  * Driver for the Melexis MLX90614 I2C 16-bit IR thermopile sensor
10*4882a593Smuzhiyun  *
11*4882a593Smuzhiyun  * (7-bit I2C slave address 0x5a, 100KHz bus speed only!)
12*4882a593Smuzhiyun  *
13*4882a593Smuzhiyun  * To wake up from sleep mode, the SDA line must be held low while SCL is high
14*4882a593Smuzhiyun  * for at least 33ms.  This is achieved with an extra GPIO that can be connected
15*4882a593Smuzhiyun  * directly to the SDA line.  In normal operation, the GPIO is set as input and
16*4882a593Smuzhiyun  * will not interfere in I2C communication.  While the GPIO is driven low, the
17*4882a593Smuzhiyun  * i2c adapter is locked since it cannot be used by other clients.  The SCL line
18*4882a593Smuzhiyun  * always has a pull-up so we do not need an extra GPIO to drive it high.  If
19*4882a593Smuzhiyun  * the "wakeup" GPIO is not given, power management will be disabled.
20*4882a593Smuzhiyun  */
21*4882a593Smuzhiyun 
22*4882a593Smuzhiyun #include <linux/err.h>
23*4882a593Smuzhiyun #include <linux/i2c.h>
24*4882a593Smuzhiyun #include <linux/module.h>
25*4882a593Smuzhiyun #include <linux/delay.h>
26*4882a593Smuzhiyun #include <linux/jiffies.h>
27*4882a593Smuzhiyun #include <linux/gpio/consumer.h>
28*4882a593Smuzhiyun #include <linux/pm_runtime.h>
29*4882a593Smuzhiyun 
30*4882a593Smuzhiyun #include <linux/iio/iio.h>
31*4882a593Smuzhiyun #include <linux/iio/sysfs.h>
32*4882a593Smuzhiyun 
33*4882a593Smuzhiyun #define MLX90614_OP_RAM		0x00
34*4882a593Smuzhiyun #define MLX90614_OP_EEPROM	0x20
35*4882a593Smuzhiyun #define MLX90614_OP_SLEEP	0xff
36*4882a593Smuzhiyun 
37*4882a593Smuzhiyun /* RAM offsets with 16-bit data, MSB first */
38*4882a593Smuzhiyun #define MLX90614_RAW1	(MLX90614_OP_RAM | 0x04) /* raw data IR channel 1 */
39*4882a593Smuzhiyun #define MLX90614_RAW2	(MLX90614_OP_RAM | 0x05) /* raw data IR channel 2 */
40*4882a593Smuzhiyun #define MLX90614_TA	(MLX90614_OP_RAM | 0x06) /* ambient temperature */
41*4882a593Smuzhiyun #define MLX90614_TOBJ1	(MLX90614_OP_RAM | 0x07) /* object 1 temperature */
42*4882a593Smuzhiyun #define MLX90614_TOBJ2	(MLX90614_OP_RAM | 0x08) /* object 2 temperature */
43*4882a593Smuzhiyun 
44*4882a593Smuzhiyun /* EEPROM offsets with 16-bit data, MSB first */
45*4882a593Smuzhiyun #define MLX90614_EMISSIVITY	(MLX90614_OP_EEPROM | 0x04) /* emissivity correction coefficient */
46*4882a593Smuzhiyun #define MLX90614_CONFIG		(MLX90614_OP_EEPROM | 0x05) /* configuration register */
47*4882a593Smuzhiyun 
48*4882a593Smuzhiyun /* Control bits in configuration register */
49*4882a593Smuzhiyun #define MLX90614_CONFIG_IIR_SHIFT 0 /* IIR coefficient */
50*4882a593Smuzhiyun #define MLX90614_CONFIG_IIR_MASK (0x7 << MLX90614_CONFIG_IIR_SHIFT)
51*4882a593Smuzhiyun #define MLX90614_CONFIG_DUAL_SHIFT 6 /* single (0) or dual (1) IR sensor */
52*4882a593Smuzhiyun #define MLX90614_CONFIG_DUAL_MASK (1 << MLX90614_CONFIG_DUAL_SHIFT)
53*4882a593Smuzhiyun #define MLX90614_CONFIG_FIR_SHIFT 8 /* FIR coefficient */
54*4882a593Smuzhiyun #define MLX90614_CONFIG_FIR_MASK (0x7 << MLX90614_CONFIG_FIR_SHIFT)
55*4882a593Smuzhiyun #define MLX90614_CONFIG_GAIN_SHIFT 11 /* gain */
56*4882a593Smuzhiyun #define MLX90614_CONFIG_GAIN_MASK (0x7 << MLX90614_CONFIG_GAIN_SHIFT)
57*4882a593Smuzhiyun 
58*4882a593Smuzhiyun /* Timings (in ms) */
59*4882a593Smuzhiyun #define MLX90614_TIMING_EEPROM 20 /* time for EEPROM write/erase to complete */
60*4882a593Smuzhiyun #define MLX90614_TIMING_WAKEUP 34 /* time to hold SDA low for wake-up */
61*4882a593Smuzhiyun #define MLX90614_TIMING_STARTUP 250 /* time before first data after wake-up */
62*4882a593Smuzhiyun 
63*4882a593Smuzhiyun #define MLX90614_AUTOSLEEP_DELAY 5000 /* default autosleep delay */
64*4882a593Smuzhiyun 
65*4882a593Smuzhiyun /* Magic constants */
66*4882a593Smuzhiyun #define MLX90614_CONST_OFFSET_DEC -13657 /* decimal part of the Kelvin offset */
67*4882a593Smuzhiyun #define MLX90614_CONST_OFFSET_REM 500000 /* remainder of offset (273.15*50) */
68*4882a593Smuzhiyun #define MLX90614_CONST_SCALE 20 /* Scale in milliKelvin (0.02 * 1000) */
69*4882a593Smuzhiyun #define MLX90614_CONST_RAW_EMISSIVITY_MAX 65535 /* max value for emissivity */
70*4882a593Smuzhiyun #define MLX90614_CONST_EMISSIVITY_RESOLUTION 15259 /* 1/65535 ~ 0.000015259 */
71*4882a593Smuzhiyun #define MLX90614_CONST_FIR 0x7 /* Fixed value for FIR part of low pass filter */
72*4882a593Smuzhiyun 
73*4882a593Smuzhiyun struct mlx90614_data {
74*4882a593Smuzhiyun 	struct i2c_client *client;
75*4882a593Smuzhiyun 	struct mutex lock; /* for EEPROM access only */
76*4882a593Smuzhiyun 	struct gpio_desc *wakeup_gpio; /* NULL to disable sleep/wake-up */
77*4882a593Smuzhiyun 	unsigned long ready_timestamp; /* in jiffies */
78*4882a593Smuzhiyun };
79*4882a593Smuzhiyun 
80*4882a593Smuzhiyun /* Bandwidth values for IIR filtering */
81*4882a593Smuzhiyun static const int mlx90614_iir_values[] = {77, 31, 20, 15, 723, 153, 110, 86};
82*4882a593Smuzhiyun static IIO_CONST_ATTR(in_temp_object_filter_low_pass_3db_frequency_available,
83*4882a593Smuzhiyun 		      "0.15 0.20 0.31 0.77 0.86 1.10 1.53 7.23");
84*4882a593Smuzhiyun 
85*4882a593Smuzhiyun static struct attribute *mlx90614_attributes[] = {
86*4882a593Smuzhiyun 	&iio_const_attr_in_temp_object_filter_low_pass_3db_frequency_available.dev_attr.attr,
87*4882a593Smuzhiyun 	NULL,
88*4882a593Smuzhiyun };
89*4882a593Smuzhiyun 
90*4882a593Smuzhiyun static const struct attribute_group mlx90614_attr_group = {
91*4882a593Smuzhiyun 	.attrs = mlx90614_attributes,
92*4882a593Smuzhiyun };
93*4882a593Smuzhiyun 
94*4882a593Smuzhiyun /*
95*4882a593Smuzhiyun  * Erase an address and write word.
96*4882a593Smuzhiyun  * The mutex must be locked before calling.
97*4882a593Smuzhiyun  */
mlx90614_write_word(const struct i2c_client * client,u8 command,u16 value)98*4882a593Smuzhiyun static s32 mlx90614_write_word(const struct i2c_client *client, u8 command,
99*4882a593Smuzhiyun 			       u16 value)
100*4882a593Smuzhiyun {
101*4882a593Smuzhiyun 	/*
102*4882a593Smuzhiyun 	 * Note: The mlx90614 requires a PEC on writing but does not send us a
103*4882a593Smuzhiyun 	 * valid PEC on reading.  Hence, we cannot set I2C_CLIENT_PEC in
104*4882a593Smuzhiyun 	 * i2c_client.flags.  As a workaround, we use i2c_smbus_xfer here.
105*4882a593Smuzhiyun 	 */
106*4882a593Smuzhiyun 	union i2c_smbus_data data;
107*4882a593Smuzhiyun 	s32 ret;
108*4882a593Smuzhiyun 
109*4882a593Smuzhiyun 	dev_dbg(&client->dev, "Writing 0x%x to address 0x%x", value, command);
110*4882a593Smuzhiyun 
111*4882a593Smuzhiyun 	data.word = 0x0000; /* erase command */
112*4882a593Smuzhiyun 	ret = i2c_smbus_xfer(client->adapter, client->addr,
113*4882a593Smuzhiyun 			     client->flags | I2C_CLIENT_PEC,
114*4882a593Smuzhiyun 			     I2C_SMBUS_WRITE, command,
115*4882a593Smuzhiyun 			     I2C_SMBUS_WORD_DATA, &data);
116*4882a593Smuzhiyun 	if (ret < 0)
117*4882a593Smuzhiyun 		return ret;
118*4882a593Smuzhiyun 
119*4882a593Smuzhiyun 	msleep(MLX90614_TIMING_EEPROM);
120*4882a593Smuzhiyun 
121*4882a593Smuzhiyun 	data.word = value; /* actual write */
122*4882a593Smuzhiyun 	ret = i2c_smbus_xfer(client->adapter, client->addr,
123*4882a593Smuzhiyun 			     client->flags | I2C_CLIENT_PEC,
124*4882a593Smuzhiyun 			     I2C_SMBUS_WRITE, command,
125*4882a593Smuzhiyun 			     I2C_SMBUS_WORD_DATA, &data);
126*4882a593Smuzhiyun 
127*4882a593Smuzhiyun 	msleep(MLX90614_TIMING_EEPROM);
128*4882a593Smuzhiyun 
129*4882a593Smuzhiyun 	return ret;
130*4882a593Smuzhiyun }
131*4882a593Smuzhiyun 
132*4882a593Smuzhiyun /*
133*4882a593Smuzhiyun  * Find the IIR value inside mlx90614_iir_values array and return its position
134*4882a593Smuzhiyun  * which is equivalent to the bit value in sensor register
135*4882a593Smuzhiyun  */
mlx90614_iir_search(const struct i2c_client * client,int value)136*4882a593Smuzhiyun static inline s32 mlx90614_iir_search(const struct i2c_client *client,
137*4882a593Smuzhiyun 				      int value)
138*4882a593Smuzhiyun {
139*4882a593Smuzhiyun 	int i;
140*4882a593Smuzhiyun 	s32 ret;
141*4882a593Smuzhiyun 
142*4882a593Smuzhiyun 	for (i = 0; i < ARRAY_SIZE(mlx90614_iir_values); ++i) {
143*4882a593Smuzhiyun 		if (value == mlx90614_iir_values[i])
144*4882a593Smuzhiyun 			break;
145*4882a593Smuzhiyun 	}
146*4882a593Smuzhiyun 
147*4882a593Smuzhiyun 	if (i == ARRAY_SIZE(mlx90614_iir_values))
148*4882a593Smuzhiyun 		return -EINVAL;
149*4882a593Smuzhiyun 
150*4882a593Smuzhiyun 	/*
151*4882a593Smuzhiyun 	 * CONFIG register values must not be changed so
152*4882a593Smuzhiyun 	 * we must read them before we actually write
153*4882a593Smuzhiyun 	 * changes
154*4882a593Smuzhiyun 	 */
155*4882a593Smuzhiyun 	ret = i2c_smbus_read_word_data(client, MLX90614_CONFIG);
156*4882a593Smuzhiyun 	if (ret < 0)
157*4882a593Smuzhiyun 		return ret;
158*4882a593Smuzhiyun 
159*4882a593Smuzhiyun 	ret &= ~MLX90614_CONFIG_FIR_MASK;
160*4882a593Smuzhiyun 	ret |= MLX90614_CONST_FIR << MLX90614_CONFIG_FIR_SHIFT;
161*4882a593Smuzhiyun 	ret &= ~MLX90614_CONFIG_IIR_MASK;
162*4882a593Smuzhiyun 	ret |= i << MLX90614_CONFIG_IIR_SHIFT;
163*4882a593Smuzhiyun 
164*4882a593Smuzhiyun 	/* Write changed values */
165*4882a593Smuzhiyun 	ret = mlx90614_write_word(client, MLX90614_CONFIG, ret);
166*4882a593Smuzhiyun 	return ret;
167*4882a593Smuzhiyun }
168*4882a593Smuzhiyun 
169*4882a593Smuzhiyun #ifdef CONFIG_PM
170*4882a593Smuzhiyun /*
171*4882a593Smuzhiyun  * If @startup is true, make sure MLX90614_TIMING_STARTUP ms have elapsed since
172*4882a593Smuzhiyun  * the last wake-up.  This is normally only needed to get a valid temperature
173*4882a593Smuzhiyun  * reading.  EEPROM access does not need such delay.
174*4882a593Smuzhiyun  * Return 0 on success, <0 on error.
175*4882a593Smuzhiyun  */
mlx90614_power_get(struct mlx90614_data * data,bool startup)176*4882a593Smuzhiyun static int mlx90614_power_get(struct mlx90614_data *data, bool startup)
177*4882a593Smuzhiyun {
178*4882a593Smuzhiyun 	unsigned long now;
179*4882a593Smuzhiyun 
180*4882a593Smuzhiyun 	if (!data->wakeup_gpio)
181*4882a593Smuzhiyun 		return 0;
182*4882a593Smuzhiyun 
183*4882a593Smuzhiyun 	pm_runtime_get_sync(&data->client->dev);
184*4882a593Smuzhiyun 
185*4882a593Smuzhiyun 	if (startup) {
186*4882a593Smuzhiyun 		now = jiffies;
187*4882a593Smuzhiyun 		if (time_before(now, data->ready_timestamp) &&
188*4882a593Smuzhiyun 		    msleep_interruptible(jiffies_to_msecs(
189*4882a593Smuzhiyun 				data->ready_timestamp - now)) != 0) {
190*4882a593Smuzhiyun 			pm_runtime_put_autosuspend(&data->client->dev);
191*4882a593Smuzhiyun 			return -EINTR;
192*4882a593Smuzhiyun 		}
193*4882a593Smuzhiyun 	}
194*4882a593Smuzhiyun 
195*4882a593Smuzhiyun 	return 0;
196*4882a593Smuzhiyun }
197*4882a593Smuzhiyun 
mlx90614_power_put(struct mlx90614_data * data)198*4882a593Smuzhiyun static void mlx90614_power_put(struct mlx90614_data *data)
199*4882a593Smuzhiyun {
200*4882a593Smuzhiyun 	if (!data->wakeup_gpio)
201*4882a593Smuzhiyun 		return;
202*4882a593Smuzhiyun 
203*4882a593Smuzhiyun 	pm_runtime_mark_last_busy(&data->client->dev);
204*4882a593Smuzhiyun 	pm_runtime_put_autosuspend(&data->client->dev);
205*4882a593Smuzhiyun }
206*4882a593Smuzhiyun #else
mlx90614_power_get(struct mlx90614_data * data,bool startup)207*4882a593Smuzhiyun static inline int mlx90614_power_get(struct mlx90614_data *data, bool startup)
208*4882a593Smuzhiyun {
209*4882a593Smuzhiyun 	return 0;
210*4882a593Smuzhiyun }
211*4882a593Smuzhiyun 
mlx90614_power_put(struct mlx90614_data * data)212*4882a593Smuzhiyun static inline void mlx90614_power_put(struct mlx90614_data *data)
213*4882a593Smuzhiyun {
214*4882a593Smuzhiyun }
215*4882a593Smuzhiyun #endif
216*4882a593Smuzhiyun 
mlx90614_read_raw(struct iio_dev * indio_dev,struct iio_chan_spec const * channel,int * val,int * val2,long mask)217*4882a593Smuzhiyun static int mlx90614_read_raw(struct iio_dev *indio_dev,
218*4882a593Smuzhiyun 			    struct iio_chan_spec const *channel, int *val,
219*4882a593Smuzhiyun 			    int *val2, long mask)
220*4882a593Smuzhiyun {
221*4882a593Smuzhiyun 	struct mlx90614_data *data = iio_priv(indio_dev);
222*4882a593Smuzhiyun 	u8 cmd;
223*4882a593Smuzhiyun 	s32 ret;
224*4882a593Smuzhiyun 
225*4882a593Smuzhiyun 	switch (mask) {
226*4882a593Smuzhiyun 	case IIO_CHAN_INFO_RAW: /* 0.02K / LSB */
227*4882a593Smuzhiyun 		switch (channel->channel2) {
228*4882a593Smuzhiyun 		case IIO_MOD_TEMP_AMBIENT:
229*4882a593Smuzhiyun 			cmd = MLX90614_TA;
230*4882a593Smuzhiyun 			break;
231*4882a593Smuzhiyun 		case IIO_MOD_TEMP_OBJECT:
232*4882a593Smuzhiyun 			switch (channel->channel) {
233*4882a593Smuzhiyun 			case 0:
234*4882a593Smuzhiyun 				cmd = MLX90614_TOBJ1;
235*4882a593Smuzhiyun 				break;
236*4882a593Smuzhiyun 			case 1:
237*4882a593Smuzhiyun 				cmd = MLX90614_TOBJ2;
238*4882a593Smuzhiyun 				break;
239*4882a593Smuzhiyun 			default:
240*4882a593Smuzhiyun 				return -EINVAL;
241*4882a593Smuzhiyun 			}
242*4882a593Smuzhiyun 			break;
243*4882a593Smuzhiyun 		default:
244*4882a593Smuzhiyun 			return -EINVAL;
245*4882a593Smuzhiyun 		}
246*4882a593Smuzhiyun 
247*4882a593Smuzhiyun 		ret = mlx90614_power_get(data, true);
248*4882a593Smuzhiyun 		if (ret < 0)
249*4882a593Smuzhiyun 			return ret;
250*4882a593Smuzhiyun 		ret = i2c_smbus_read_word_data(data->client, cmd);
251*4882a593Smuzhiyun 		mlx90614_power_put(data);
252*4882a593Smuzhiyun 
253*4882a593Smuzhiyun 		if (ret < 0)
254*4882a593Smuzhiyun 			return ret;
255*4882a593Smuzhiyun 
256*4882a593Smuzhiyun 		/* MSB is an error flag */
257*4882a593Smuzhiyun 		if (ret & 0x8000)
258*4882a593Smuzhiyun 			return -EIO;
259*4882a593Smuzhiyun 
260*4882a593Smuzhiyun 		*val = ret;
261*4882a593Smuzhiyun 		return IIO_VAL_INT;
262*4882a593Smuzhiyun 	case IIO_CHAN_INFO_OFFSET:
263*4882a593Smuzhiyun 		*val = MLX90614_CONST_OFFSET_DEC;
264*4882a593Smuzhiyun 		*val2 = MLX90614_CONST_OFFSET_REM;
265*4882a593Smuzhiyun 		return IIO_VAL_INT_PLUS_MICRO;
266*4882a593Smuzhiyun 	case IIO_CHAN_INFO_SCALE:
267*4882a593Smuzhiyun 		*val = MLX90614_CONST_SCALE;
268*4882a593Smuzhiyun 		return IIO_VAL_INT;
269*4882a593Smuzhiyun 	case IIO_CHAN_INFO_CALIBEMISSIVITY: /* 1/65535 / LSB */
270*4882a593Smuzhiyun 		mlx90614_power_get(data, false);
271*4882a593Smuzhiyun 		mutex_lock(&data->lock);
272*4882a593Smuzhiyun 		ret = i2c_smbus_read_word_data(data->client,
273*4882a593Smuzhiyun 					       MLX90614_EMISSIVITY);
274*4882a593Smuzhiyun 		mutex_unlock(&data->lock);
275*4882a593Smuzhiyun 		mlx90614_power_put(data);
276*4882a593Smuzhiyun 
277*4882a593Smuzhiyun 		if (ret < 0)
278*4882a593Smuzhiyun 			return ret;
279*4882a593Smuzhiyun 
280*4882a593Smuzhiyun 		if (ret == MLX90614_CONST_RAW_EMISSIVITY_MAX) {
281*4882a593Smuzhiyun 			*val = 1;
282*4882a593Smuzhiyun 			*val2 = 0;
283*4882a593Smuzhiyun 		} else {
284*4882a593Smuzhiyun 			*val = 0;
285*4882a593Smuzhiyun 			*val2 = ret * MLX90614_CONST_EMISSIVITY_RESOLUTION;
286*4882a593Smuzhiyun 		}
287*4882a593Smuzhiyun 		return IIO_VAL_INT_PLUS_NANO;
288*4882a593Smuzhiyun 	case IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY: /* IIR setting with
289*4882a593Smuzhiyun 							     FIR = 1024 */
290*4882a593Smuzhiyun 		mlx90614_power_get(data, false);
291*4882a593Smuzhiyun 		mutex_lock(&data->lock);
292*4882a593Smuzhiyun 		ret = i2c_smbus_read_word_data(data->client, MLX90614_CONFIG);
293*4882a593Smuzhiyun 		mutex_unlock(&data->lock);
294*4882a593Smuzhiyun 		mlx90614_power_put(data);
295*4882a593Smuzhiyun 
296*4882a593Smuzhiyun 		if (ret < 0)
297*4882a593Smuzhiyun 			return ret;
298*4882a593Smuzhiyun 
299*4882a593Smuzhiyun 		*val = mlx90614_iir_values[ret & MLX90614_CONFIG_IIR_MASK] / 100;
300*4882a593Smuzhiyun 		*val2 = (mlx90614_iir_values[ret & MLX90614_CONFIG_IIR_MASK] % 100) *
301*4882a593Smuzhiyun 			10000;
302*4882a593Smuzhiyun 		return IIO_VAL_INT_PLUS_MICRO;
303*4882a593Smuzhiyun 	default:
304*4882a593Smuzhiyun 		return -EINVAL;
305*4882a593Smuzhiyun 	}
306*4882a593Smuzhiyun }
307*4882a593Smuzhiyun 
mlx90614_write_raw(struct iio_dev * indio_dev,struct iio_chan_spec const * channel,int val,int val2,long mask)308*4882a593Smuzhiyun static int mlx90614_write_raw(struct iio_dev *indio_dev,
309*4882a593Smuzhiyun 			     struct iio_chan_spec const *channel, int val,
310*4882a593Smuzhiyun 			     int val2, long mask)
311*4882a593Smuzhiyun {
312*4882a593Smuzhiyun 	struct mlx90614_data *data = iio_priv(indio_dev);
313*4882a593Smuzhiyun 	s32 ret;
314*4882a593Smuzhiyun 
315*4882a593Smuzhiyun 	switch (mask) {
316*4882a593Smuzhiyun 	case IIO_CHAN_INFO_CALIBEMISSIVITY: /* 1/65535 / LSB */
317*4882a593Smuzhiyun 		if (val < 0 || val2 < 0 || val > 1 || (val == 1 && val2 != 0))
318*4882a593Smuzhiyun 			return -EINVAL;
319*4882a593Smuzhiyun 		val = val * MLX90614_CONST_RAW_EMISSIVITY_MAX +
320*4882a593Smuzhiyun 			val2 / MLX90614_CONST_EMISSIVITY_RESOLUTION;
321*4882a593Smuzhiyun 
322*4882a593Smuzhiyun 		mlx90614_power_get(data, false);
323*4882a593Smuzhiyun 		mutex_lock(&data->lock);
324*4882a593Smuzhiyun 		ret = mlx90614_write_word(data->client, MLX90614_EMISSIVITY,
325*4882a593Smuzhiyun 					  val);
326*4882a593Smuzhiyun 		mutex_unlock(&data->lock);
327*4882a593Smuzhiyun 		mlx90614_power_put(data);
328*4882a593Smuzhiyun 
329*4882a593Smuzhiyun 		return ret;
330*4882a593Smuzhiyun 	case IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY: /* IIR Filter setting */
331*4882a593Smuzhiyun 		if (val < 0 || val2 < 0)
332*4882a593Smuzhiyun 			return -EINVAL;
333*4882a593Smuzhiyun 
334*4882a593Smuzhiyun 		mlx90614_power_get(data, false);
335*4882a593Smuzhiyun 		mutex_lock(&data->lock);
336*4882a593Smuzhiyun 		ret = mlx90614_iir_search(data->client,
337*4882a593Smuzhiyun 					  val * 100 + val2 / 10000);
338*4882a593Smuzhiyun 		mutex_unlock(&data->lock);
339*4882a593Smuzhiyun 		mlx90614_power_put(data);
340*4882a593Smuzhiyun 
341*4882a593Smuzhiyun 		return ret;
342*4882a593Smuzhiyun 	default:
343*4882a593Smuzhiyun 		return -EINVAL;
344*4882a593Smuzhiyun 	}
345*4882a593Smuzhiyun }
346*4882a593Smuzhiyun 
mlx90614_write_raw_get_fmt(struct iio_dev * indio_dev,struct iio_chan_spec const * channel,long mask)347*4882a593Smuzhiyun static int mlx90614_write_raw_get_fmt(struct iio_dev *indio_dev,
348*4882a593Smuzhiyun 				     struct iio_chan_spec const *channel,
349*4882a593Smuzhiyun 				     long mask)
350*4882a593Smuzhiyun {
351*4882a593Smuzhiyun 	switch (mask) {
352*4882a593Smuzhiyun 	case IIO_CHAN_INFO_CALIBEMISSIVITY:
353*4882a593Smuzhiyun 		return IIO_VAL_INT_PLUS_NANO;
354*4882a593Smuzhiyun 	case IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY:
355*4882a593Smuzhiyun 		return IIO_VAL_INT_PLUS_MICRO;
356*4882a593Smuzhiyun 	default:
357*4882a593Smuzhiyun 		return -EINVAL;
358*4882a593Smuzhiyun 	}
359*4882a593Smuzhiyun }
360*4882a593Smuzhiyun 
361*4882a593Smuzhiyun static const struct iio_chan_spec mlx90614_channels[] = {
362*4882a593Smuzhiyun 	{
363*4882a593Smuzhiyun 		.type = IIO_TEMP,
364*4882a593Smuzhiyun 		.modified = 1,
365*4882a593Smuzhiyun 		.channel2 = IIO_MOD_TEMP_AMBIENT,
366*4882a593Smuzhiyun 		.info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
367*4882a593Smuzhiyun 		.info_mask_shared_by_type = BIT(IIO_CHAN_INFO_OFFSET) |
368*4882a593Smuzhiyun 		    BIT(IIO_CHAN_INFO_SCALE),
369*4882a593Smuzhiyun 	},
370*4882a593Smuzhiyun 	{
371*4882a593Smuzhiyun 		.type = IIO_TEMP,
372*4882a593Smuzhiyun 		.modified = 1,
373*4882a593Smuzhiyun 		.channel2 = IIO_MOD_TEMP_OBJECT,
374*4882a593Smuzhiyun 		.info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
375*4882a593Smuzhiyun 		    BIT(IIO_CHAN_INFO_CALIBEMISSIVITY) |
376*4882a593Smuzhiyun 			BIT(IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY),
377*4882a593Smuzhiyun 		.info_mask_shared_by_type = BIT(IIO_CHAN_INFO_OFFSET) |
378*4882a593Smuzhiyun 		    BIT(IIO_CHAN_INFO_SCALE),
379*4882a593Smuzhiyun 	},
380*4882a593Smuzhiyun 	{
381*4882a593Smuzhiyun 		.type = IIO_TEMP,
382*4882a593Smuzhiyun 		.indexed = 1,
383*4882a593Smuzhiyun 		.modified = 1,
384*4882a593Smuzhiyun 		.channel = 1,
385*4882a593Smuzhiyun 		.channel2 = IIO_MOD_TEMP_OBJECT,
386*4882a593Smuzhiyun 		.info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
387*4882a593Smuzhiyun 		    BIT(IIO_CHAN_INFO_CALIBEMISSIVITY) |
388*4882a593Smuzhiyun 			BIT(IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY),
389*4882a593Smuzhiyun 		.info_mask_shared_by_type = BIT(IIO_CHAN_INFO_OFFSET) |
390*4882a593Smuzhiyun 		    BIT(IIO_CHAN_INFO_SCALE),
391*4882a593Smuzhiyun 	},
392*4882a593Smuzhiyun };
393*4882a593Smuzhiyun 
394*4882a593Smuzhiyun static const struct iio_info mlx90614_info = {
395*4882a593Smuzhiyun 	.read_raw = mlx90614_read_raw,
396*4882a593Smuzhiyun 	.write_raw = mlx90614_write_raw,
397*4882a593Smuzhiyun 	.write_raw_get_fmt = mlx90614_write_raw_get_fmt,
398*4882a593Smuzhiyun 	.attrs = &mlx90614_attr_group,
399*4882a593Smuzhiyun };
400*4882a593Smuzhiyun 
401*4882a593Smuzhiyun #ifdef CONFIG_PM
mlx90614_sleep(struct mlx90614_data * data)402*4882a593Smuzhiyun static int mlx90614_sleep(struct mlx90614_data *data)
403*4882a593Smuzhiyun {
404*4882a593Smuzhiyun 	s32 ret;
405*4882a593Smuzhiyun 
406*4882a593Smuzhiyun 	if (!data->wakeup_gpio) {
407*4882a593Smuzhiyun 		dev_dbg(&data->client->dev, "Sleep disabled");
408*4882a593Smuzhiyun 		return -ENOSYS;
409*4882a593Smuzhiyun 	}
410*4882a593Smuzhiyun 
411*4882a593Smuzhiyun 	dev_dbg(&data->client->dev, "Requesting sleep");
412*4882a593Smuzhiyun 
413*4882a593Smuzhiyun 	mutex_lock(&data->lock);
414*4882a593Smuzhiyun 	ret = i2c_smbus_xfer(data->client->adapter, data->client->addr,
415*4882a593Smuzhiyun 			     data->client->flags | I2C_CLIENT_PEC,
416*4882a593Smuzhiyun 			     I2C_SMBUS_WRITE, MLX90614_OP_SLEEP,
417*4882a593Smuzhiyun 			     I2C_SMBUS_BYTE, NULL);
418*4882a593Smuzhiyun 	mutex_unlock(&data->lock);
419*4882a593Smuzhiyun 
420*4882a593Smuzhiyun 	return ret;
421*4882a593Smuzhiyun }
422*4882a593Smuzhiyun 
mlx90614_wakeup(struct mlx90614_data * data)423*4882a593Smuzhiyun static int mlx90614_wakeup(struct mlx90614_data *data)
424*4882a593Smuzhiyun {
425*4882a593Smuzhiyun 	if (!data->wakeup_gpio) {
426*4882a593Smuzhiyun 		dev_dbg(&data->client->dev, "Wake-up disabled");
427*4882a593Smuzhiyun 		return -ENOSYS;
428*4882a593Smuzhiyun 	}
429*4882a593Smuzhiyun 
430*4882a593Smuzhiyun 	dev_dbg(&data->client->dev, "Requesting wake-up");
431*4882a593Smuzhiyun 
432*4882a593Smuzhiyun 	i2c_lock_bus(data->client->adapter, I2C_LOCK_ROOT_ADAPTER);
433*4882a593Smuzhiyun 	gpiod_direction_output(data->wakeup_gpio, 0);
434*4882a593Smuzhiyun 	msleep(MLX90614_TIMING_WAKEUP);
435*4882a593Smuzhiyun 	gpiod_direction_input(data->wakeup_gpio);
436*4882a593Smuzhiyun 	i2c_unlock_bus(data->client->adapter, I2C_LOCK_ROOT_ADAPTER);
437*4882a593Smuzhiyun 
438*4882a593Smuzhiyun 	data->ready_timestamp = jiffies +
439*4882a593Smuzhiyun 			msecs_to_jiffies(MLX90614_TIMING_STARTUP);
440*4882a593Smuzhiyun 
441*4882a593Smuzhiyun 	/*
442*4882a593Smuzhiyun 	 * Quirk: the i2c controller may get confused right after the
443*4882a593Smuzhiyun 	 * wake-up signal has been sent.  As a workaround, do a dummy read.
444*4882a593Smuzhiyun 	 * If the read fails, the controller will probably be reset so that
445*4882a593Smuzhiyun 	 * further reads will work.
446*4882a593Smuzhiyun 	 */
447*4882a593Smuzhiyun 	i2c_smbus_read_word_data(data->client, MLX90614_CONFIG);
448*4882a593Smuzhiyun 
449*4882a593Smuzhiyun 	return 0;
450*4882a593Smuzhiyun }
451*4882a593Smuzhiyun 
452*4882a593Smuzhiyun /* Return wake-up GPIO or NULL if sleep functionality should be disabled. */
mlx90614_probe_wakeup(struct i2c_client * client)453*4882a593Smuzhiyun static struct gpio_desc *mlx90614_probe_wakeup(struct i2c_client *client)
454*4882a593Smuzhiyun {
455*4882a593Smuzhiyun 	struct gpio_desc *gpio;
456*4882a593Smuzhiyun 
457*4882a593Smuzhiyun 	if (!i2c_check_functionality(client->adapter,
458*4882a593Smuzhiyun 						I2C_FUNC_SMBUS_WRITE_BYTE)) {
459*4882a593Smuzhiyun 		dev_info(&client->dev,
460*4882a593Smuzhiyun 			 "i2c adapter does not support SMBUS_WRITE_BYTE, sleep disabled");
461*4882a593Smuzhiyun 		return NULL;
462*4882a593Smuzhiyun 	}
463*4882a593Smuzhiyun 
464*4882a593Smuzhiyun 	gpio = devm_gpiod_get_optional(&client->dev, "wakeup", GPIOD_IN);
465*4882a593Smuzhiyun 
466*4882a593Smuzhiyun 	if (IS_ERR(gpio)) {
467*4882a593Smuzhiyun 		dev_warn(&client->dev,
468*4882a593Smuzhiyun 			 "gpio acquisition failed with error %ld, sleep disabled",
469*4882a593Smuzhiyun 			 PTR_ERR(gpio));
470*4882a593Smuzhiyun 		return NULL;
471*4882a593Smuzhiyun 	} else if (!gpio) {
472*4882a593Smuzhiyun 		dev_info(&client->dev,
473*4882a593Smuzhiyun 			 "wakeup-gpio not found, sleep disabled");
474*4882a593Smuzhiyun 	}
475*4882a593Smuzhiyun 
476*4882a593Smuzhiyun 	return gpio;
477*4882a593Smuzhiyun }
478*4882a593Smuzhiyun #else
mlx90614_sleep(struct mlx90614_data * data)479*4882a593Smuzhiyun static inline int mlx90614_sleep(struct mlx90614_data *data)
480*4882a593Smuzhiyun {
481*4882a593Smuzhiyun 	return -ENOSYS;
482*4882a593Smuzhiyun }
mlx90614_wakeup(struct mlx90614_data * data)483*4882a593Smuzhiyun static inline int mlx90614_wakeup(struct mlx90614_data *data)
484*4882a593Smuzhiyun {
485*4882a593Smuzhiyun 	return -ENOSYS;
486*4882a593Smuzhiyun }
mlx90614_probe_wakeup(struct i2c_client * client)487*4882a593Smuzhiyun static inline struct gpio_desc *mlx90614_probe_wakeup(struct i2c_client *client)
488*4882a593Smuzhiyun {
489*4882a593Smuzhiyun 	return NULL;
490*4882a593Smuzhiyun }
491*4882a593Smuzhiyun #endif
492*4882a593Smuzhiyun 
493*4882a593Smuzhiyun /* Return 0 for single sensor, 1 for dual sensor, <0 on error. */
mlx90614_probe_num_ir_sensors(struct i2c_client * client)494*4882a593Smuzhiyun static int mlx90614_probe_num_ir_sensors(struct i2c_client *client)
495*4882a593Smuzhiyun {
496*4882a593Smuzhiyun 	s32 ret;
497*4882a593Smuzhiyun 
498*4882a593Smuzhiyun 	ret = i2c_smbus_read_word_data(client, MLX90614_CONFIG);
499*4882a593Smuzhiyun 
500*4882a593Smuzhiyun 	if (ret < 0)
501*4882a593Smuzhiyun 		return ret;
502*4882a593Smuzhiyun 
503*4882a593Smuzhiyun 	return (ret & MLX90614_CONFIG_DUAL_MASK) ? 1 : 0;
504*4882a593Smuzhiyun }
505*4882a593Smuzhiyun 
mlx90614_probe(struct i2c_client * client,const struct i2c_device_id * id)506*4882a593Smuzhiyun static int mlx90614_probe(struct i2c_client *client,
507*4882a593Smuzhiyun 			 const struct i2c_device_id *id)
508*4882a593Smuzhiyun {
509*4882a593Smuzhiyun 	struct iio_dev *indio_dev;
510*4882a593Smuzhiyun 	struct mlx90614_data *data;
511*4882a593Smuzhiyun 	int ret;
512*4882a593Smuzhiyun 
513*4882a593Smuzhiyun 	if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_WORD_DATA))
514*4882a593Smuzhiyun 		return -EOPNOTSUPP;
515*4882a593Smuzhiyun 
516*4882a593Smuzhiyun 	indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*data));
517*4882a593Smuzhiyun 	if (!indio_dev)
518*4882a593Smuzhiyun 		return -ENOMEM;
519*4882a593Smuzhiyun 
520*4882a593Smuzhiyun 	data = iio_priv(indio_dev);
521*4882a593Smuzhiyun 	i2c_set_clientdata(client, indio_dev);
522*4882a593Smuzhiyun 	data->client = client;
523*4882a593Smuzhiyun 	mutex_init(&data->lock);
524*4882a593Smuzhiyun 	data->wakeup_gpio = mlx90614_probe_wakeup(client);
525*4882a593Smuzhiyun 
526*4882a593Smuzhiyun 	mlx90614_wakeup(data);
527*4882a593Smuzhiyun 
528*4882a593Smuzhiyun 	indio_dev->name = id->name;
529*4882a593Smuzhiyun 	indio_dev->modes = INDIO_DIRECT_MODE;
530*4882a593Smuzhiyun 	indio_dev->info = &mlx90614_info;
531*4882a593Smuzhiyun 
532*4882a593Smuzhiyun 	ret = mlx90614_probe_num_ir_sensors(client);
533*4882a593Smuzhiyun 	switch (ret) {
534*4882a593Smuzhiyun 	case 0:
535*4882a593Smuzhiyun 		dev_dbg(&client->dev, "Found single sensor");
536*4882a593Smuzhiyun 		indio_dev->channels = mlx90614_channels;
537*4882a593Smuzhiyun 		indio_dev->num_channels = 2;
538*4882a593Smuzhiyun 		break;
539*4882a593Smuzhiyun 	case 1:
540*4882a593Smuzhiyun 		dev_dbg(&client->dev, "Found dual sensor");
541*4882a593Smuzhiyun 		indio_dev->channels = mlx90614_channels;
542*4882a593Smuzhiyun 		indio_dev->num_channels = 3;
543*4882a593Smuzhiyun 		break;
544*4882a593Smuzhiyun 	default:
545*4882a593Smuzhiyun 		return ret;
546*4882a593Smuzhiyun 	}
547*4882a593Smuzhiyun 
548*4882a593Smuzhiyun 	if (data->wakeup_gpio) {
549*4882a593Smuzhiyun 		pm_runtime_set_autosuspend_delay(&client->dev,
550*4882a593Smuzhiyun 						 MLX90614_AUTOSLEEP_DELAY);
551*4882a593Smuzhiyun 		pm_runtime_use_autosuspend(&client->dev);
552*4882a593Smuzhiyun 		pm_runtime_set_active(&client->dev);
553*4882a593Smuzhiyun 		pm_runtime_enable(&client->dev);
554*4882a593Smuzhiyun 	}
555*4882a593Smuzhiyun 
556*4882a593Smuzhiyun 	return iio_device_register(indio_dev);
557*4882a593Smuzhiyun }
558*4882a593Smuzhiyun 
mlx90614_remove(struct i2c_client * client)559*4882a593Smuzhiyun static int mlx90614_remove(struct i2c_client *client)
560*4882a593Smuzhiyun {
561*4882a593Smuzhiyun 	struct iio_dev *indio_dev = i2c_get_clientdata(client);
562*4882a593Smuzhiyun 	struct mlx90614_data *data = iio_priv(indio_dev);
563*4882a593Smuzhiyun 
564*4882a593Smuzhiyun 	iio_device_unregister(indio_dev);
565*4882a593Smuzhiyun 
566*4882a593Smuzhiyun 	if (data->wakeup_gpio) {
567*4882a593Smuzhiyun 		pm_runtime_disable(&client->dev);
568*4882a593Smuzhiyun 		if (!pm_runtime_status_suspended(&client->dev))
569*4882a593Smuzhiyun 			mlx90614_sleep(data);
570*4882a593Smuzhiyun 		pm_runtime_set_suspended(&client->dev);
571*4882a593Smuzhiyun 	}
572*4882a593Smuzhiyun 
573*4882a593Smuzhiyun 	return 0;
574*4882a593Smuzhiyun }
575*4882a593Smuzhiyun 
576*4882a593Smuzhiyun static const struct i2c_device_id mlx90614_id[] = {
577*4882a593Smuzhiyun 	{ "mlx90614", 0 },
578*4882a593Smuzhiyun 	{ }
579*4882a593Smuzhiyun };
580*4882a593Smuzhiyun MODULE_DEVICE_TABLE(i2c, mlx90614_id);
581*4882a593Smuzhiyun 
582*4882a593Smuzhiyun static const struct of_device_id mlx90614_of_match[] = {
583*4882a593Smuzhiyun 	{ .compatible = "melexis,mlx90614" },
584*4882a593Smuzhiyun 	{ }
585*4882a593Smuzhiyun };
586*4882a593Smuzhiyun MODULE_DEVICE_TABLE(of, mlx90614_of_match);
587*4882a593Smuzhiyun 
588*4882a593Smuzhiyun #ifdef CONFIG_PM_SLEEP
mlx90614_pm_suspend(struct device * dev)589*4882a593Smuzhiyun static int mlx90614_pm_suspend(struct device *dev)
590*4882a593Smuzhiyun {
591*4882a593Smuzhiyun 	struct iio_dev *indio_dev = i2c_get_clientdata(to_i2c_client(dev));
592*4882a593Smuzhiyun 	struct mlx90614_data *data = iio_priv(indio_dev);
593*4882a593Smuzhiyun 
594*4882a593Smuzhiyun 	if (data->wakeup_gpio && pm_runtime_active(dev))
595*4882a593Smuzhiyun 		return mlx90614_sleep(data);
596*4882a593Smuzhiyun 
597*4882a593Smuzhiyun 	return 0;
598*4882a593Smuzhiyun }
599*4882a593Smuzhiyun 
mlx90614_pm_resume(struct device * dev)600*4882a593Smuzhiyun static int mlx90614_pm_resume(struct device *dev)
601*4882a593Smuzhiyun {
602*4882a593Smuzhiyun 	struct iio_dev *indio_dev = i2c_get_clientdata(to_i2c_client(dev));
603*4882a593Smuzhiyun 	struct mlx90614_data *data = iio_priv(indio_dev);
604*4882a593Smuzhiyun 	int err;
605*4882a593Smuzhiyun 
606*4882a593Smuzhiyun 	if (data->wakeup_gpio) {
607*4882a593Smuzhiyun 		err = mlx90614_wakeup(data);
608*4882a593Smuzhiyun 		if (err < 0)
609*4882a593Smuzhiyun 			return err;
610*4882a593Smuzhiyun 
611*4882a593Smuzhiyun 		pm_runtime_disable(dev);
612*4882a593Smuzhiyun 		pm_runtime_set_active(dev);
613*4882a593Smuzhiyun 		pm_runtime_enable(dev);
614*4882a593Smuzhiyun 	}
615*4882a593Smuzhiyun 
616*4882a593Smuzhiyun 	return 0;
617*4882a593Smuzhiyun }
618*4882a593Smuzhiyun #endif
619*4882a593Smuzhiyun 
620*4882a593Smuzhiyun #ifdef CONFIG_PM
mlx90614_pm_runtime_suspend(struct device * dev)621*4882a593Smuzhiyun static int mlx90614_pm_runtime_suspend(struct device *dev)
622*4882a593Smuzhiyun {
623*4882a593Smuzhiyun 	struct iio_dev *indio_dev = i2c_get_clientdata(to_i2c_client(dev));
624*4882a593Smuzhiyun 	struct mlx90614_data *data = iio_priv(indio_dev);
625*4882a593Smuzhiyun 
626*4882a593Smuzhiyun 	return mlx90614_sleep(data);
627*4882a593Smuzhiyun }
628*4882a593Smuzhiyun 
mlx90614_pm_runtime_resume(struct device * dev)629*4882a593Smuzhiyun static int mlx90614_pm_runtime_resume(struct device *dev)
630*4882a593Smuzhiyun {
631*4882a593Smuzhiyun 	struct iio_dev *indio_dev = i2c_get_clientdata(to_i2c_client(dev));
632*4882a593Smuzhiyun 	struct mlx90614_data *data = iio_priv(indio_dev);
633*4882a593Smuzhiyun 
634*4882a593Smuzhiyun 	return mlx90614_wakeup(data);
635*4882a593Smuzhiyun }
636*4882a593Smuzhiyun #endif
637*4882a593Smuzhiyun 
638*4882a593Smuzhiyun static const struct dev_pm_ops mlx90614_pm_ops = {
639*4882a593Smuzhiyun 	SET_SYSTEM_SLEEP_PM_OPS(mlx90614_pm_suspend, mlx90614_pm_resume)
640*4882a593Smuzhiyun 	SET_RUNTIME_PM_OPS(mlx90614_pm_runtime_suspend,
641*4882a593Smuzhiyun 			   mlx90614_pm_runtime_resume, NULL)
642*4882a593Smuzhiyun };
643*4882a593Smuzhiyun 
644*4882a593Smuzhiyun static struct i2c_driver mlx90614_driver = {
645*4882a593Smuzhiyun 	.driver = {
646*4882a593Smuzhiyun 		.name	= "mlx90614",
647*4882a593Smuzhiyun 		.of_match_table = mlx90614_of_match,
648*4882a593Smuzhiyun 		.pm	= &mlx90614_pm_ops,
649*4882a593Smuzhiyun 	},
650*4882a593Smuzhiyun 	.probe = mlx90614_probe,
651*4882a593Smuzhiyun 	.remove = mlx90614_remove,
652*4882a593Smuzhiyun 	.id_table = mlx90614_id,
653*4882a593Smuzhiyun };
654*4882a593Smuzhiyun module_i2c_driver(mlx90614_driver);
655*4882a593Smuzhiyun 
656*4882a593Smuzhiyun MODULE_AUTHOR("Peter Meerwald <pmeerw@pmeerw.net>");
657*4882a593Smuzhiyun MODULE_AUTHOR("Vianney le Clément de Saint-Marcq <vianney.leclement@essensium.com>");
658*4882a593Smuzhiyun MODULE_AUTHOR("Crt Mori <cmo@melexis.com>");
659*4882a593Smuzhiyun MODULE_DESCRIPTION("Melexis MLX90614 contactless IR temperature sensor driver");
660*4882a593Smuzhiyun MODULE_LICENSE("GPL");
661