1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * isl29501.c: ISL29501 Time of Flight sensor driver.
4  *
5  * Copyright (C) 2018
6  * Author: Mathieu Othacehe <m.othacehe@gmail.com>
7  *
8  * 7-bit I2C slave address: 0x57
9  */
10 
11 #include <linux/kernel.h>
12 #include <linux/module.h>
13 #include <linux/i2c.h>
14 #include <linux/err.h>
15 #include <linux/of_device.h>
16 #include <linux/iio/iio.h>
17 #include <linux/iio/sysfs.h>
18 
19 #include <linux/iio/trigger_consumer.h>
20 #include <linux/iio/buffer.h>
21 #include <linux/iio/triggered_buffer.h>
22 
23 /* Control, setting and status registers */
24 #define ISL29501_DEVICE_ID			0x00
25 #define ISL29501_ID				0x0A
26 
27 /* Sampling control registers */
28 #define ISL29501_INTEGRATION_PERIOD		0x10
29 #define ISL29501_SAMPLE_PERIOD			0x11
30 
31 /* Closed loop calibration registers */
32 #define ISL29501_CROSSTALK_I_MSB		0x24
33 #define ISL29501_CROSSTALK_I_LSB		0x25
34 #define ISL29501_CROSSTALK_I_EXPONENT		0x26
35 #define ISL29501_CROSSTALK_Q_MSB		0x27
36 #define ISL29501_CROSSTALK_Q_LSB		0x28
37 #define ISL29501_CROSSTALK_Q_EXPONENT		0x29
38 #define ISL29501_CROSSTALK_GAIN_MSB		0x2A
39 #define ISL29501_CROSSTALK_GAIN_LSB		0x2B
40 #define ISL29501_MAGNITUDE_REF_EXP		0x2C
41 #define ISL29501_MAGNITUDE_REF_MSB		0x2D
42 #define ISL29501_MAGNITUDE_REF_LSB		0x2E
43 #define ISL29501_PHASE_OFFSET_MSB		0x2F
44 #define ISL29501_PHASE_OFFSET_LSB		0x30
45 
46 /* Analog control registers */
47 #define ISL29501_DRIVER_RANGE			0x90
48 #define ISL29501_EMITTER_DAC			0x91
49 
50 #define ISL29501_COMMAND_REGISTER		0xB0
51 
52 /* Commands */
53 #define ISL29501_EMUL_SAMPLE_START_PIN		0x49
54 #define ISL29501_RESET_ALL_REGISTERS		0xD7
55 #define ISL29501_RESET_INT_SM			0xD1
56 
57 /* Ambiant light and temperature corrections */
58 #define ISL29501_TEMP_REFERENCE			0x31
59 #define ISL29501_PHASE_EXPONENT			0x33
60 #define ISL29501_TEMP_COEFF_A			0x34
61 #define ISL29501_TEMP_COEFF_B			0x39
62 #define ISL29501_AMBIANT_COEFF_A		0x36
63 #define ISL29501_AMBIANT_COEFF_B		0x3B
64 
65 /* Data output registers */
66 #define ISL29501_DISTANCE_MSB_DATA		0xD1
67 #define ISL29501_DISTANCE_LSB_DATA		0xD2
68 #define ISL29501_PRECISION_MSB			0xD3
69 #define ISL29501_PRECISION_LSB			0xD4
70 #define ISL29501_MAGNITUDE_EXPONENT		0xD5
71 #define ISL29501_MAGNITUDE_MSB			0xD6
72 #define ISL29501_MAGNITUDE_LSB			0xD7
73 #define ISL29501_PHASE_MSB			0xD8
74 #define ISL29501_PHASE_LSB			0xD9
75 #define ISL29501_I_RAW_EXPONENT			0xDA
76 #define ISL29501_I_RAW_MSB			0xDB
77 #define ISL29501_I_RAW_LSB			0xDC
78 #define ISL29501_Q_RAW_EXPONENT			0xDD
79 #define ISL29501_Q_RAW_MSB			0xDE
80 #define ISL29501_Q_RAW_LSB			0xDF
81 #define ISL29501_DIE_TEMPERATURE		0xE2
82 #define ISL29501_AMBIENT_LIGHT			0xE3
83 #define ISL29501_GAIN_MSB			0xE6
84 #define ISL29501_GAIN_LSB			0xE7
85 
86 #define ISL29501_MAX_EXP_VAL 15
87 
88 #define ISL29501_INT_TIME_AVAILABLE \
89 	"0.00007 0.00014 0.00028 0.00057 0.00114 " \
90 	"0.00228 0.00455 0.00910 0.01820 0.03640 " \
91 	"0.07281 0.14561"
92 
93 #define ISL29501_CURRENT_SCALE_AVAILABLE \
94 	"0.0039 0.0078 0.0118 0.0157 0.0196 " \
95 	"0.0235 0.0275 0.0314 0.0352 0.0392 " \
96 	"0.0431 0.0471 0.0510 0.0549 0.0588"
97 
98 enum isl29501_correction_coeff {
99 	COEFF_TEMP_A,
100 	COEFF_TEMP_B,
101 	COEFF_LIGHT_A,
102 	COEFF_LIGHT_B,
103 	COEFF_MAX,
104 };
105 
106 struct isl29501_private {
107 	struct i2c_client *client;
108 	struct mutex lock;
109 	/* Exact representation of correction coefficients. */
110 	unsigned int shadow_coeffs[COEFF_MAX];
111 };
112 
113 enum isl29501_register_name {
114 	REG_DISTANCE,
115 	REG_PHASE,
116 	REG_TEMPERATURE,
117 	REG_AMBIENT_LIGHT,
118 	REG_GAIN,
119 	REG_GAIN_BIAS,
120 	REG_PHASE_EXP,
121 	REG_CALIB_PHASE_TEMP_A,
122 	REG_CALIB_PHASE_TEMP_B,
123 	REG_CALIB_PHASE_LIGHT_A,
124 	REG_CALIB_PHASE_LIGHT_B,
125 	REG_DISTANCE_BIAS,
126 	REG_TEMPERATURE_BIAS,
127 	REG_INT_TIME,
128 	REG_SAMPLE_TIME,
129 	REG_DRIVER_RANGE,
130 	REG_EMITTER_DAC,
131 };
132 
133 struct isl29501_register_desc {
134 	u8 msb;
135 	u8 lsb;
136 };
137 
138 static const struct isl29501_register_desc isl29501_registers[] = {
139 	[REG_DISTANCE] = {
140 		.msb = ISL29501_DISTANCE_MSB_DATA,
141 		.lsb = ISL29501_DISTANCE_LSB_DATA,
142 	},
143 	[REG_PHASE] = {
144 		.msb = ISL29501_PHASE_MSB,
145 		.lsb = ISL29501_PHASE_LSB,
146 	},
147 	[REG_TEMPERATURE] = {
148 		.lsb = ISL29501_DIE_TEMPERATURE,
149 	},
150 	[REG_AMBIENT_LIGHT] = {
151 		.lsb = ISL29501_AMBIENT_LIGHT,
152 	},
153 	[REG_GAIN] = {
154 		.msb = ISL29501_GAIN_MSB,
155 		.lsb = ISL29501_GAIN_LSB,
156 	},
157 	[REG_GAIN_BIAS] = {
158 		.msb = ISL29501_CROSSTALK_GAIN_MSB,
159 		.lsb = ISL29501_CROSSTALK_GAIN_LSB,
160 	},
161 	[REG_PHASE_EXP] = {
162 		.lsb = ISL29501_PHASE_EXPONENT,
163 	},
164 	[REG_CALIB_PHASE_TEMP_A] = {
165 		.lsb = ISL29501_TEMP_COEFF_A,
166 	},
167 	[REG_CALIB_PHASE_TEMP_B] = {
168 		.lsb = ISL29501_TEMP_COEFF_B,
169 	},
170 	[REG_CALIB_PHASE_LIGHT_A] = {
171 		.lsb = ISL29501_AMBIANT_COEFF_A,
172 	},
173 	[REG_CALIB_PHASE_LIGHT_B] = {
174 		.lsb = ISL29501_AMBIANT_COEFF_B,
175 	},
176 	[REG_DISTANCE_BIAS] = {
177 		.msb = ISL29501_PHASE_OFFSET_MSB,
178 		.lsb = ISL29501_PHASE_OFFSET_LSB,
179 	},
180 	[REG_TEMPERATURE_BIAS] = {
181 		.lsb = ISL29501_TEMP_REFERENCE,
182 	},
183 	[REG_INT_TIME] = {
184 		.lsb = ISL29501_INTEGRATION_PERIOD,
185 	},
186 	[REG_SAMPLE_TIME] = {
187 		.lsb = ISL29501_SAMPLE_PERIOD,
188 	},
189 	[REG_DRIVER_RANGE] = {
190 		.lsb = ISL29501_DRIVER_RANGE,
191 	},
192 	[REG_EMITTER_DAC] = {
193 		.lsb = ISL29501_EMITTER_DAC,
194 	},
195 };
196 
isl29501_register_read(struct isl29501_private * isl29501,enum isl29501_register_name name,u32 * val)197 static int isl29501_register_read(struct isl29501_private *isl29501,
198 				  enum isl29501_register_name name,
199 				  u32 *val)
200 {
201 	const struct isl29501_register_desc *reg = &isl29501_registers[name];
202 	u8 msb = 0, lsb = 0;
203 	s32 ret;
204 
205 	mutex_lock(&isl29501->lock);
206 	if (reg->msb) {
207 		ret = i2c_smbus_read_byte_data(isl29501->client, reg->msb);
208 		if (ret < 0)
209 			goto err;
210 		msb = ret;
211 	}
212 
213 	if (reg->lsb) {
214 		ret = i2c_smbus_read_byte_data(isl29501->client, reg->lsb);
215 		if (ret < 0)
216 			goto err;
217 		lsb = ret;
218 	}
219 	mutex_unlock(&isl29501->lock);
220 
221 	*val = (msb << 8) + lsb;
222 
223 	return 0;
224 err:
225 	mutex_unlock(&isl29501->lock);
226 
227 	return ret;
228 }
229 
isl29501_register_write(struct isl29501_private * isl29501,enum isl29501_register_name name,u32 value)230 static u32 isl29501_register_write(struct isl29501_private *isl29501,
231 				   enum isl29501_register_name name,
232 				   u32 value)
233 {
234 	const struct isl29501_register_desc *reg = &isl29501_registers[name];
235 	u8 msb, lsb;
236 	int ret;
237 
238 	if (!reg->msb && value > U8_MAX)
239 		return -ERANGE;
240 
241 	if (value > U16_MAX)
242 		return -ERANGE;
243 
244 	if (!reg->msb) {
245 		lsb = value & 0xFF;
246 	} else {
247 		msb = (value >> 8) & 0xFF;
248 		lsb = value & 0xFF;
249 	}
250 
251 	mutex_lock(&isl29501->lock);
252 	if (reg->msb) {
253 		ret = i2c_smbus_write_byte_data(isl29501->client,
254 						reg->msb, msb);
255 		if (ret < 0)
256 			goto err;
257 	}
258 
259 	ret = i2c_smbus_write_byte_data(isl29501->client, reg->lsb, lsb);
260 
261 err:
262 	mutex_unlock(&isl29501->lock);
263 	return ret;
264 }
265 
isl29501_read_ext(struct iio_dev * indio_dev,uintptr_t private,const struct iio_chan_spec * chan,char * buf)266 static ssize_t isl29501_read_ext(struct iio_dev *indio_dev,
267 				 uintptr_t private,
268 				 const struct iio_chan_spec *chan,
269 				 char *buf)
270 {
271 	struct isl29501_private *isl29501 = iio_priv(indio_dev);
272 	enum isl29501_register_name reg = private;
273 	int ret;
274 	u32 value, gain, coeff, exp;
275 
276 	switch (reg) {
277 	case REG_GAIN:
278 	case REG_GAIN_BIAS:
279 		ret = isl29501_register_read(isl29501, reg, &gain);
280 		if (ret < 0)
281 			return ret;
282 
283 		value = gain;
284 		break;
285 	case REG_CALIB_PHASE_TEMP_A:
286 	case REG_CALIB_PHASE_TEMP_B:
287 	case REG_CALIB_PHASE_LIGHT_A:
288 	case REG_CALIB_PHASE_LIGHT_B:
289 		ret = isl29501_register_read(isl29501, REG_PHASE_EXP, &exp);
290 		if (ret < 0)
291 			return ret;
292 
293 		ret = isl29501_register_read(isl29501, reg, &coeff);
294 		if (ret < 0)
295 			return ret;
296 
297 		value = coeff << exp;
298 		break;
299 	default:
300 		return -EINVAL;
301 	}
302 
303 	return sprintf(buf, "%u\n", value);
304 }
305 
isl29501_set_shadow_coeff(struct isl29501_private * isl29501,enum isl29501_register_name reg,unsigned int val)306 static int isl29501_set_shadow_coeff(struct isl29501_private *isl29501,
307 				     enum isl29501_register_name reg,
308 				     unsigned int val)
309 {
310 	enum isl29501_correction_coeff coeff;
311 
312 	switch (reg) {
313 	case REG_CALIB_PHASE_TEMP_A:
314 		coeff = COEFF_TEMP_A;
315 		break;
316 	case REG_CALIB_PHASE_TEMP_B:
317 		coeff = COEFF_TEMP_B;
318 		break;
319 	case REG_CALIB_PHASE_LIGHT_A:
320 		coeff = COEFF_LIGHT_A;
321 		break;
322 	case REG_CALIB_PHASE_LIGHT_B:
323 		coeff = COEFF_LIGHT_B;
324 		break;
325 	default:
326 		return -EINVAL;
327 	}
328 	isl29501->shadow_coeffs[coeff] = val;
329 
330 	return 0;
331 }
332 
isl29501_write_coeff(struct isl29501_private * isl29501,enum isl29501_correction_coeff coeff,int val)333 static int isl29501_write_coeff(struct isl29501_private *isl29501,
334 				enum isl29501_correction_coeff coeff,
335 				int val)
336 {
337 	enum isl29501_register_name reg;
338 
339 	switch (coeff) {
340 	case COEFF_TEMP_A:
341 		reg = REG_CALIB_PHASE_TEMP_A;
342 		break;
343 	case COEFF_TEMP_B:
344 		reg = REG_CALIB_PHASE_TEMP_B;
345 		break;
346 	case COEFF_LIGHT_A:
347 		reg = REG_CALIB_PHASE_LIGHT_A;
348 		break;
349 	case COEFF_LIGHT_B:
350 		reg = REG_CALIB_PHASE_LIGHT_B;
351 		break;
352 	default:
353 		return -EINVAL;
354 	}
355 
356 	return isl29501_register_write(isl29501, reg, val);
357 }
358 
isl29501_find_corr_exp(unsigned int val,unsigned int max_exp,unsigned int max_mantissa)359 static unsigned int isl29501_find_corr_exp(unsigned int val,
360 					   unsigned int max_exp,
361 					   unsigned int max_mantissa)
362 {
363 	unsigned int exp = 1;
364 
365 	/*
366 	 * Correction coefficients are represented under
367 	 * mantissa * 2^exponent form, where mantissa and exponent
368 	 * are stored in two separate registers of the sensor.
369 	 *
370 	 * Compute and return the lowest exponent such as:
371 	 *	     mantissa = value / 2^exponent
372 	 *
373 	 *  where mantissa < max_mantissa.
374 	 */
375 	if (val <= max_mantissa)
376 		return 0;
377 
378 	while ((val >> exp) > max_mantissa) {
379 		exp++;
380 
381 		if (exp > max_exp)
382 			return max_exp;
383 	}
384 
385 	return exp;
386 }
387 
isl29501_write_ext(struct iio_dev * indio_dev,uintptr_t private,const struct iio_chan_spec * chan,const char * buf,size_t len)388 static ssize_t isl29501_write_ext(struct iio_dev *indio_dev,
389 				  uintptr_t private,
390 				  const struct iio_chan_spec *chan,
391 				  const char *buf, size_t len)
392 {
393 	struct isl29501_private *isl29501 = iio_priv(indio_dev);
394 	enum isl29501_register_name reg = private;
395 	unsigned int val;
396 	int max_exp = 0;
397 	int ret;
398 	int i;
399 
400 	ret = kstrtouint(buf, 10, &val);
401 	if (ret)
402 		return ret;
403 
404 	switch (reg) {
405 	case REG_GAIN_BIAS:
406 		if (val > U16_MAX)
407 			return -ERANGE;
408 
409 		ret = isl29501_register_write(isl29501, reg, val);
410 		if (ret < 0)
411 			return ret;
412 
413 		break;
414 	case REG_CALIB_PHASE_TEMP_A:
415 	case REG_CALIB_PHASE_TEMP_B:
416 	case REG_CALIB_PHASE_LIGHT_A:
417 	case REG_CALIB_PHASE_LIGHT_B:
418 
419 		if (val > (U8_MAX << ISL29501_MAX_EXP_VAL))
420 			return -ERANGE;
421 
422 		/* Store the correction coefficient under its exact form. */
423 		ret = isl29501_set_shadow_coeff(isl29501, reg, val);
424 		if (ret < 0)
425 			return ret;
426 
427 		/*
428 		 * Find the highest exponent needed to represent
429 		 * correction coefficients.
430 		 */
431 		for (i = 0; i < COEFF_MAX; i++) {
432 			int corr;
433 			int corr_exp;
434 
435 			corr = isl29501->shadow_coeffs[i];
436 			corr_exp = isl29501_find_corr_exp(corr,
437 							  ISL29501_MAX_EXP_VAL,
438 							  U8_MAX / 2);
439 			dev_dbg(&isl29501->client->dev,
440 				"found exp of corr(%d) = %d\n", corr, corr_exp);
441 
442 			max_exp = max(max_exp, corr_exp);
443 		}
444 
445 		/*
446 		 * Represent every correction coefficient under
447 		 * mantissa * 2^max_exponent form and force the
448 		 * writing of those coefficients on the sensor.
449 		 */
450 		for (i = 0; i < COEFF_MAX; i++) {
451 			int corr;
452 			int mantissa;
453 
454 			corr = isl29501->shadow_coeffs[i];
455 			if (!corr)
456 				continue;
457 
458 			mantissa = corr >> max_exp;
459 
460 			ret = isl29501_write_coeff(isl29501, i, mantissa);
461 			if (ret < 0)
462 				return ret;
463 		}
464 
465 		ret = isl29501_register_write(isl29501, REG_PHASE_EXP, max_exp);
466 		if (ret < 0)
467 			return ret;
468 
469 		break;
470 	default:
471 		return -EINVAL;
472 	}
473 
474 	return len;
475 }
476 
477 #define _ISL29501_EXT_INFO(_name, _ident) { \
478 	.name = _name, \
479 	.read = isl29501_read_ext, \
480 	.write = isl29501_write_ext, \
481 	.private = _ident, \
482 	.shared = IIO_SEPARATE, \
483 }
484 
485 static const struct iio_chan_spec_ext_info isl29501_ext_info[] = {
486 	_ISL29501_EXT_INFO("agc_gain", REG_GAIN),
487 	_ISL29501_EXT_INFO("agc_gain_bias", REG_GAIN_BIAS),
488 	_ISL29501_EXT_INFO("calib_phase_temp_a", REG_CALIB_PHASE_TEMP_A),
489 	_ISL29501_EXT_INFO("calib_phase_temp_b", REG_CALIB_PHASE_TEMP_B),
490 	_ISL29501_EXT_INFO("calib_phase_light_a", REG_CALIB_PHASE_LIGHT_A),
491 	_ISL29501_EXT_INFO("calib_phase_light_b", REG_CALIB_PHASE_LIGHT_B),
492 	{ },
493 };
494 
495 #define ISL29501_DISTANCE_SCAN_INDEX 0
496 #define ISL29501_TIMESTAMP_SCAN_INDEX 1
497 
498 static const struct iio_chan_spec isl29501_channels[] = {
499 	{
500 		.type = IIO_PROXIMITY,
501 		.scan_index = ISL29501_DISTANCE_SCAN_INDEX,
502 		.info_mask_separate =
503 			BIT(IIO_CHAN_INFO_RAW)   |
504 			BIT(IIO_CHAN_INFO_SCALE) |
505 			BIT(IIO_CHAN_INFO_CALIBBIAS),
506 		.scan_type = {
507 			.sign = 'u',
508 			.realbits = 16,
509 			.storagebits = 16,
510 			.endianness = IIO_CPU,
511 		},
512 		.info_mask_shared_by_all = BIT(IIO_CHAN_INFO_INT_TIME) |
513 				BIT(IIO_CHAN_INFO_SAMP_FREQ),
514 		.ext_info = isl29501_ext_info,
515 	},
516 	{
517 		.type = IIO_PHASE,
518 		.scan_index = -1,
519 		.info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
520 				BIT(IIO_CHAN_INFO_SCALE),
521 	},
522 	{
523 		.type = IIO_CURRENT,
524 		.scan_index = -1,
525 		.output = 1,
526 		.info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
527 				BIT(IIO_CHAN_INFO_SCALE),
528 	},
529 	{
530 		.type = IIO_TEMP,
531 		.scan_index = -1,
532 		.info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
533 				BIT(IIO_CHAN_INFO_SCALE)     |
534 				BIT(IIO_CHAN_INFO_CALIBBIAS),
535 	},
536 	{
537 		.type = IIO_INTENSITY,
538 		.scan_index = -1,
539 		.modified = 1,
540 		.channel2 = IIO_MOD_LIGHT_CLEAR,
541 		.info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
542 				BIT(IIO_CHAN_INFO_SCALE),
543 	},
544 	IIO_CHAN_SOFT_TIMESTAMP(ISL29501_TIMESTAMP_SCAN_INDEX),
545 };
546 
isl29501_reset_registers(struct isl29501_private * isl29501)547 static int isl29501_reset_registers(struct isl29501_private *isl29501)
548 {
549 	int ret;
550 
551 	ret = i2c_smbus_write_byte_data(isl29501->client,
552 					ISL29501_COMMAND_REGISTER,
553 					ISL29501_RESET_ALL_REGISTERS);
554 	if (ret < 0) {
555 		dev_err(&isl29501->client->dev,
556 			"cannot reset registers %d\n", ret);
557 		return ret;
558 	}
559 
560 	ret = i2c_smbus_write_byte_data(isl29501->client,
561 					ISL29501_COMMAND_REGISTER,
562 					ISL29501_RESET_INT_SM);
563 	if (ret < 0)
564 		dev_err(&isl29501->client->dev,
565 			"cannot reset state machine %d\n", ret);
566 
567 	return ret;
568 }
569 
isl29501_begin_acquisition(struct isl29501_private * isl29501)570 static int isl29501_begin_acquisition(struct isl29501_private *isl29501)
571 {
572 	int ret;
573 
574 	ret = i2c_smbus_write_byte_data(isl29501->client,
575 					ISL29501_COMMAND_REGISTER,
576 					ISL29501_EMUL_SAMPLE_START_PIN);
577 	if (ret < 0)
578 		dev_err(&isl29501->client->dev,
579 			"cannot begin acquisition %d\n", ret);
580 
581 	return ret;
582 }
583 
584 static IIO_CONST_ATTR_INT_TIME_AVAIL(ISL29501_INT_TIME_AVAILABLE);
585 static IIO_CONST_ATTR(out_current_scale_available,
586 		      ISL29501_CURRENT_SCALE_AVAILABLE);
587 
588 static struct attribute *isl29501_attributes[] = {
589 	&iio_const_attr_integration_time_available.dev_attr.attr,
590 	&iio_const_attr_out_current_scale_available.dev_attr.attr,
591 	NULL
592 };
593 
594 static const struct attribute_group isl29501_attribute_group = {
595 	.attrs = isl29501_attributes,
596 };
597 
598 static const int isl29501_current_scale_table[][2] = {
599 	{0, 3900}, {0, 7800}, {0, 11800}, {0, 15700},
600 	{0, 19600}, {0, 23500}, {0, 27500}, {0, 31400},
601 	{0, 35200}, {0, 39200}, {0, 43100}, {0, 47100},
602 	{0, 51000}, {0, 54900}, {0, 58800},
603 };
604 
605 static const int isl29501_int_time[][2] = {
606 	{0, 70},    /* 0.07 ms */
607 	{0, 140},   /* 0.14 ms */
608 	{0, 280},   /* 0.28 ms */
609 	{0, 570},   /* 0.57 ms */
610 	{0, 1140},  /* 1.14 ms */
611 	{0, 2280},  /* 2.28 ms */
612 	{0, 4550},  /* 4.55 ms */
613 	{0, 9100},  /* 9.11 ms */
614 	{0, 18200}, /* 18.2 ms */
615 	{0, 36400}, /* 36.4 ms */
616 	{0, 72810}, /* 72.81 ms */
617 	{0, 145610} /* 145.28 ms */
618 };
619 
isl29501_get_raw(struct isl29501_private * isl29501,const struct iio_chan_spec * chan,int * raw)620 static int isl29501_get_raw(struct isl29501_private *isl29501,
621 			    const struct iio_chan_spec *chan,
622 			    int *raw)
623 {
624 	int ret;
625 
626 	switch (chan->type) {
627 	case IIO_PROXIMITY:
628 		ret = isl29501_register_read(isl29501, REG_DISTANCE, raw);
629 		if (ret < 0)
630 			return ret;
631 
632 		return IIO_VAL_INT;
633 	case IIO_INTENSITY:
634 		ret = isl29501_register_read(isl29501,
635 					     REG_AMBIENT_LIGHT,
636 					     raw);
637 		if (ret < 0)
638 			return ret;
639 
640 		return IIO_VAL_INT;
641 	case IIO_PHASE:
642 		ret = isl29501_register_read(isl29501, REG_PHASE, raw);
643 		if (ret < 0)
644 			return ret;
645 
646 		return IIO_VAL_INT;
647 	case IIO_CURRENT:
648 		ret = isl29501_register_read(isl29501, REG_EMITTER_DAC, raw);
649 		if (ret < 0)
650 			return ret;
651 
652 		return IIO_VAL_INT;
653 	case IIO_TEMP:
654 		ret = isl29501_register_read(isl29501, REG_TEMPERATURE, raw);
655 		if (ret < 0)
656 			return ret;
657 
658 		return IIO_VAL_INT;
659 	default:
660 		return -EINVAL;
661 	}
662 }
663 
isl29501_get_scale(struct isl29501_private * isl29501,const struct iio_chan_spec * chan,int * val,int * val2)664 static int isl29501_get_scale(struct isl29501_private *isl29501,
665 			      const struct iio_chan_spec *chan,
666 			      int *val, int *val2)
667 {
668 	int ret;
669 	u32 current_scale;
670 
671 	switch (chan->type) {
672 	case IIO_PROXIMITY:
673 		/* distance = raw_distance * 33.31 / 65536 (m) */
674 		*val = 3331;
675 		*val2 = 6553600;
676 
677 		return IIO_VAL_FRACTIONAL;
678 	case IIO_PHASE:
679 		/* phase = raw_phase * 2pi / 65536 (rad) */
680 		*val = 0;
681 		*val2 = 95874;
682 
683 		return IIO_VAL_INT_PLUS_NANO;
684 	case IIO_INTENSITY:
685 		/* light = raw_light * 35 / 10000 (mA) */
686 		*val = 35;
687 		*val2 = 10000;
688 
689 		return IIO_VAL_FRACTIONAL;
690 	case IIO_CURRENT:
691 		ret = isl29501_register_read(isl29501,
692 					     REG_DRIVER_RANGE,
693 					     &current_scale);
694 		if (ret < 0)
695 			return ret;
696 
697 		if (current_scale > ARRAY_SIZE(isl29501_current_scale_table))
698 			return -EINVAL;
699 
700 		if (!current_scale) {
701 			*val = 0;
702 			*val2 = 0;
703 			return IIO_VAL_INT;
704 		}
705 
706 		*val = isl29501_current_scale_table[current_scale - 1][0];
707 		*val2 = isl29501_current_scale_table[current_scale - 1][1];
708 
709 		return IIO_VAL_INT_PLUS_MICRO;
710 	case IIO_TEMP:
711 		/* temperature = raw_temperature * 125 / 100000 (milli °C) */
712 		*val = 125;
713 		*val2 = 100000;
714 
715 		return IIO_VAL_FRACTIONAL;
716 	default:
717 		return -EINVAL;
718 	}
719 }
720 
isl29501_get_calibbias(struct isl29501_private * isl29501,const struct iio_chan_spec * chan,int * bias)721 static int isl29501_get_calibbias(struct isl29501_private *isl29501,
722 				  const struct iio_chan_spec *chan,
723 				  int *bias)
724 {
725 	switch (chan->type) {
726 	case IIO_PROXIMITY:
727 		return isl29501_register_read(isl29501,
728 					      REG_DISTANCE_BIAS,
729 					      bias);
730 	case IIO_TEMP:
731 		return isl29501_register_read(isl29501,
732 					      REG_TEMPERATURE_BIAS,
733 					      bias);
734 	default:
735 		return -EINVAL;
736 	}
737 }
738 
isl29501_get_inttime(struct isl29501_private * isl29501,int * val,int * val2)739 static int isl29501_get_inttime(struct isl29501_private *isl29501,
740 				int *val, int *val2)
741 {
742 	int ret;
743 	u32 inttime;
744 
745 	ret = isl29501_register_read(isl29501, REG_INT_TIME, &inttime);
746 	if (ret < 0)
747 		return ret;
748 
749 	if (inttime >= ARRAY_SIZE(isl29501_int_time))
750 		return -EINVAL;
751 
752 	*val = isl29501_int_time[inttime][0];
753 	*val2 = isl29501_int_time[inttime][1];
754 
755 	return IIO_VAL_INT_PLUS_MICRO;
756 }
757 
isl29501_get_freq(struct isl29501_private * isl29501,int * val,int * val2)758 static int isl29501_get_freq(struct isl29501_private *isl29501,
759 			     int *val, int *val2)
760 {
761 	int ret;
762 	int sample_time;
763 	unsigned long long freq;
764 	u32 temp;
765 
766 	ret = isl29501_register_read(isl29501, REG_SAMPLE_TIME, &sample_time);
767 	if (ret < 0)
768 		return ret;
769 
770 	/* freq = 1 / (0.000450 * (sample_time + 1) * 10^-6) */
771 	freq = 1000000ULL * 1000000ULL;
772 
773 	do_div(freq, 450 * (sample_time + 1));
774 
775 	temp = do_div(freq, 1000000);
776 	*val = freq;
777 	*val2 = temp;
778 
779 	return IIO_VAL_INT_PLUS_MICRO;
780 }
781 
isl29501_read_raw(struct iio_dev * indio_dev,struct iio_chan_spec const * chan,int * val,int * val2,long mask)782 static int isl29501_read_raw(struct iio_dev *indio_dev,
783 			     struct iio_chan_spec const *chan, int *val,
784 			     int *val2, long mask)
785 {
786 	struct isl29501_private *isl29501 = iio_priv(indio_dev);
787 
788 	switch (mask) {
789 	case IIO_CHAN_INFO_RAW:
790 		return isl29501_get_raw(isl29501, chan, val);
791 	case IIO_CHAN_INFO_SCALE:
792 		return isl29501_get_scale(isl29501, chan, val, val2);
793 	case IIO_CHAN_INFO_INT_TIME:
794 		return isl29501_get_inttime(isl29501, val, val2);
795 	case IIO_CHAN_INFO_SAMP_FREQ:
796 		return isl29501_get_freq(isl29501, val, val2);
797 	case IIO_CHAN_INFO_CALIBBIAS:
798 		return isl29501_get_calibbias(isl29501, chan, val);
799 	default:
800 		return -EINVAL;
801 	}
802 }
803 
isl29501_set_raw(struct isl29501_private * isl29501,const struct iio_chan_spec * chan,int raw)804 static int isl29501_set_raw(struct isl29501_private *isl29501,
805 			    const struct iio_chan_spec *chan,
806 			    int raw)
807 {
808 	switch (chan->type) {
809 	case IIO_CURRENT:
810 		return isl29501_register_write(isl29501, REG_EMITTER_DAC, raw);
811 	default:
812 		return -EINVAL;
813 	}
814 }
815 
isl29501_set_inttime(struct isl29501_private * isl29501,int val,int val2)816 static int isl29501_set_inttime(struct isl29501_private *isl29501,
817 				int val, int val2)
818 {
819 	int i;
820 
821 	for (i = 0; i < ARRAY_SIZE(isl29501_int_time); i++) {
822 		if (isl29501_int_time[i][0] == val &&
823 		    isl29501_int_time[i][1] == val2) {
824 			return isl29501_register_write(isl29501,
825 						       REG_INT_TIME,
826 						       i);
827 		}
828 	}
829 
830 	return -EINVAL;
831 }
832 
isl29501_set_scale(struct isl29501_private * isl29501,const struct iio_chan_spec * chan,int val,int val2)833 static int isl29501_set_scale(struct isl29501_private *isl29501,
834 			      const struct iio_chan_spec *chan,
835 			      int val, int val2)
836 {
837 	int i;
838 
839 	if (chan->type != IIO_CURRENT)
840 		return -EINVAL;
841 
842 	for (i = 0; i < ARRAY_SIZE(isl29501_current_scale_table); i++) {
843 		if (isl29501_current_scale_table[i][0] == val &&
844 		    isl29501_current_scale_table[i][1] == val2) {
845 			return isl29501_register_write(isl29501,
846 						       REG_DRIVER_RANGE,
847 						       i + 1);
848 		}
849 	}
850 
851 	return -EINVAL;
852 }
853 
isl29501_set_calibbias(struct isl29501_private * isl29501,const struct iio_chan_spec * chan,int bias)854 static int isl29501_set_calibbias(struct isl29501_private *isl29501,
855 				  const struct iio_chan_spec *chan,
856 				  int bias)
857 {
858 	switch (chan->type) {
859 	case IIO_PROXIMITY:
860 		return isl29501_register_write(isl29501,
861 					      REG_DISTANCE_BIAS,
862 					      bias);
863 	case IIO_TEMP:
864 		return isl29501_register_write(isl29501,
865 					       REG_TEMPERATURE_BIAS,
866 					       bias);
867 	default:
868 		return -EINVAL;
869 	}
870 }
871 
isl29501_set_freq(struct isl29501_private * isl29501,int val,int val2)872 static int isl29501_set_freq(struct isl29501_private *isl29501,
873 			     int val, int val2)
874 {
875 	int freq;
876 	unsigned long long sample_time;
877 
878 	/* sample_freq = 1 / (0.000450 * (sample_time + 1) * 10^-6) */
879 	freq = val * 1000000 + val2 % 1000000;
880 	sample_time = 2222ULL * 1000000ULL;
881 	do_div(sample_time, freq);
882 
883 	sample_time -= 1;
884 
885 	if (sample_time > 255)
886 		return -ERANGE;
887 
888 	return isl29501_register_write(isl29501, REG_SAMPLE_TIME, sample_time);
889 }
890 
isl29501_write_raw(struct iio_dev * indio_dev,struct iio_chan_spec const * chan,int val,int val2,long mask)891 static int isl29501_write_raw(struct iio_dev *indio_dev,
892 			      struct iio_chan_spec const *chan,
893 			      int val, int val2, long mask)
894 {
895 	struct isl29501_private *isl29501 = iio_priv(indio_dev);
896 
897 	switch (mask) {
898 	case IIO_CHAN_INFO_RAW:
899 		return isl29501_set_raw(isl29501, chan, val);
900 	case IIO_CHAN_INFO_INT_TIME:
901 		return isl29501_set_inttime(isl29501, val, val2);
902 	case IIO_CHAN_INFO_SAMP_FREQ:
903 		return isl29501_set_freq(isl29501, val, val2);
904 	case IIO_CHAN_INFO_SCALE:
905 		return isl29501_set_scale(isl29501, chan, val, val2);
906 	case IIO_CHAN_INFO_CALIBBIAS:
907 		return isl29501_set_calibbias(isl29501, chan, val);
908 	default:
909 		return -EINVAL;
910 	}
911 }
912 
913 static const struct iio_info isl29501_info = {
914 	.read_raw = &isl29501_read_raw,
915 	.write_raw = &isl29501_write_raw,
916 	.attrs = &isl29501_attribute_group,
917 };
918 
isl29501_init_chip(struct isl29501_private * isl29501)919 static int isl29501_init_chip(struct isl29501_private *isl29501)
920 {
921 	int ret;
922 
923 	ret = i2c_smbus_read_byte_data(isl29501->client, ISL29501_DEVICE_ID);
924 	if (ret < 0) {
925 		dev_err(&isl29501->client->dev, "Error reading device id\n");
926 		return ret;
927 	}
928 
929 	if (ret != ISL29501_ID) {
930 		dev_err(&isl29501->client->dev,
931 			"Wrong chip id, got %x expected %x\n",
932 			ret, ISL29501_DEVICE_ID);
933 		return -ENODEV;
934 	}
935 
936 	ret = isl29501_reset_registers(isl29501);
937 	if (ret < 0)
938 		return ret;
939 
940 	return isl29501_begin_acquisition(isl29501);
941 }
942 
isl29501_trigger_handler(int irq,void * p)943 static irqreturn_t isl29501_trigger_handler(int irq, void *p)
944 {
945 	struct iio_poll_func *pf = p;
946 	struct iio_dev *indio_dev = pf->indio_dev;
947 	struct isl29501_private *isl29501 = iio_priv(indio_dev);
948 	const unsigned long *active_mask = indio_dev->active_scan_mask;
949 	u32 buffer[4] __aligned(8) = {}; /* 1x16-bit + naturally aligned ts */
950 
951 	if (test_bit(ISL29501_DISTANCE_SCAN_INDEX, active_mask))
952 		isl29501_register_read(isl29501, REG_DISTANCE, buffer);
953 
954 	iio_push_to_buffers_with_timestamp(indio_dev, buffer, pf->timestamp);
955 	iio_trigger_notify_done(indio_dev->trig);
956 
957 	return IRQ_HANDLED;
958 }
959 
isl29501_probe(struct i2c_client * client,const struct i2c_device_id * id)960 static int isl29501_probe(struct i2c_client *client,
961 			  const struct i2c_device_id *id)
962 {
963 	struct iio_dev *indio_dev;
964 	struct isl29501_private *isl29501;
965 	int ret;
966 
967 	indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*isl29501));
968 	if (!indio_dev)
969 		return -ENOMEM;
970 
971 	isl29501 = iio_priv(indio_dev);
972 
973 	i2c_set_clientdata(client, indio_dev);
974 	isl29501->client = client;
975 
976 	mutex_init(&isl29501->lock);
977 
978 	ret = isl29501_init_chip(isl29501);
979 	if (ret < 0)
980 		return ret;
981 
982 	indio_dev->modes = INDIO_DIRECT_MODE;
983 	indio_dev->dev.parent = &client->dev;
984 	indio_dev->channels = isl29501_channels;
985 	indio_dev->num_channels = ARRAY_SIZE(isl29501_channels);
986 	indio_dev->name = client->name;
987 	indio_dev->info = &isl29501_info;
988 
989 	ret = devm_iio_triggered_buffer_setup(&client->dev, indio_dev,
990 					      iio_pollfunc_store_time,
991 					      isl29501_trigger_handler,
992 					      NULL);
993 	if (ret < 0) {
994 		dev_err(&client->dev, "unable to setup iio triggered buffer\n");
995 		return ret;
996 	}
997 
998 	return devm_iio_device_register(&client->dev, indio_dev);
999 }
1000 
1001 static const struct i2c_device_id isl29501_id[] = {
1002 	{"isl29501", 0},
1003 	{}
1004 };
1005 
1006 MODULE_DEVICE_TABLE(i2c, isl29501_id);
1007 
1008 #if defined(CONFIG_OF)
1009 static const struct of_device_id isl29501_i2c_matches[] = {
1010 	{ .compatible = "renesas,isl29501" },
1011 	{ }
1012 };
1013 MODULE_DEVICE_TABLE(of, isl29501_i2c_matches);
1014 #endif
1015 
1016 static struct i2c_driver isl29501_driver = {
1017 	.driver = {
1018 		.name	= "isl29501",
1019 	},
1020 	.id_table	= isl29501_id,
1021 	.probe		= isl29501_probe,
1022 };
1023 module_i2c_driver(isl29501_driver);
1024 
1025 MODULE_AUTHOR("Mathieu Othacehe <m.othacehe@gmail.com>");
1026 MODULE_DESCRIPTION("ISL29501 Time of Flight sensor driver");
1027 MODULE_LICENSE("GPL v2");
1028