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/mod_devicetable.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
98enum isl29501_correction_coeff {
99	COEFF_TEMP_A,
100	COEFF_TEMP_B,
101	COEFF_LIGHT_A,
102	COEFF_LIGHT_B,
103	COEFF_MAX,
104};
105
106struct 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
113enum 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
133struct isl29501_register_desc {
134	u8 msb;
135	u8 lsb;
136};
137
138static 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
197static 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;
224err:
225	mutex_unlock(&isl29501->lock);
226
227	return ret;
228}
229
230static 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	int ret;
236
237	if (!reg->msb && value > U8_MAX)
238		return -ERANGE;
239
240	if (value > U16_MAX)
241		return -ERANGE;
242
243	mutex_lock(&isl29501->lock);
244	if (reg->msb) {
245		ret = i2c_smbus_write_byte_data(isl29501->client,
246						reg->msb, value >> 8);
247		if (ret < 0)
248			goto err;
249	}
250
251	ret = i2c_smbus_write_byte_data(isl29501->client, reg->lsb, value);
252
253err:
254	mutex_unlock(&isl29501->lock);
255	return ret;
256}
257
258static ssize_t isl29501_read_ext(struct iio_dev *indio_dev,
259				 uintptr_t private,
260				 const struct iio_chan_spec *chan,
261				 char *buf)
262{
263	struct isl29501_private *isl29501 = iio_priv(indio_dev);
264	enum isl29501_register_name reg = private;
265	int ret;
266	u32 value, gain, coeff, exp;
267
268	switch (reg) {
269	case REG_GAIN:
270	case REG_GAIN_BIAS:
271		ret = isl29501_register_read(isl29501, reg, &gain);
272		if (ret < 0)
273			return ret;
274
275		value = gain;
276		break;
277	case REG_CALIB_PHASE_TEMP_A:
278	case REG_CALIB_PHASE_TEMP_B:
279	case REG_CALIB_PHASE_LIGHT_A:
280	case REG_CALIB_PHASE_LIGHT_B:
281		ret = isl29501_register_read(isl29501, REG_PHASE_EXP, &exp);
282		if (ret < 0)
283			return ret;
284
285		ret = isl29501_register_read(isl29501, reg, &coeff);
286		if (ret < 0)
287			return ret;
288
289		value = coeff << exp;
290		break;
291	default:
292		return -EINVAL;
293	}
294
295	return sprintf(buf, "%u\n", value);
296}
297
298static int isl29501_set_shadow_coeff(struct isl29501_private *isl29501,
299				     enum isl29501_register_name reg,
300				     unsigned int val)
301{
302	enum isl29501_correction_coeff coeff;
303
304	switch (reg) {
305	case REG_CALIB_PHASE_TEMP_A:
306		coeff = COEFF_TEMP_A;
307		break;
308	case REG_CALIB_PHASE_TEMP_B:
309		coeff = COEFF_TEMP_B;
310		break;
311	case REG_CALIB_PHASE_LIGHT_A:
312		coeff = COEFF_LIGHT_A;
313		break;
314	case REG_CALIB_PHASE_LIGHT_B:
315		coeff = COEFF_LIGHT_B;
316		break;
317	default:
318		return -EINVAL;
319	}
320	isl29501->shadow_coeffs[coeff] = val;
321
322	return 0;
323}
324
325static int isl29501_write_coeff(struct isl29501_private *isl29501,
326				enum isl29501_correction_coeff coeff,
327				int val)
328{
329	enum isl29501_register_name reg;
330
331	switch (coeff) {
332	case COEFF_TEMP_A:
333		reg = REG_CALIB_PHASE_TEMP_A;
334		break;
335	case COEFF_TEMP_B:
336		reg = REG_CALIB_PHASE_TEMP_B;
337		break;
338	case COEFF_LIGHT_A:
339		reg = REG_CALIB_PHASE_LIGHT_A;
340		break;
341	case COEFF_LIGHT_B:
342		reg = REG_CALIB_PHASE_LIGHT_B;
343		break;
344	default:
345		return -EINVAL;
346	}
347
348	return isl29501_register_write(isl29501, reg, val);
349}
350
351static unsigned int isl29501_find_corr_exp(unsigned int val,
352					   unsigned int max_exp,
353					   unsigned int max_mantissa)
354{
355	unsigned int exp = 1;
356
357	/*
358	 * Correction coefficients are represented under
359	 * mantissa * 2^exponent form, where mantissa and exponent
360	 * are stored in two separate registers of the sensor.
361	 *
362	 * Compute and return the lowest exponent such as:
363	 *	     mantissa = value / 2^exponent
364	 *
365	 *  where mantissa < max_mantissa.
366	 */
367	if (val <= max_mantissa)
368		return 0;
369
370	while ((val >> exp) > max_mantissa) {
371		exp++;
372
373		if (exp > max_exp)
374			return max_exp;
375	}
376
377	return exp;
378}
379
380static ssize_t isl29501_write_ext(struct iio_dev *indio_dev,
381				  uintptr_t private,
382				  const struct iio_chan_spec *chan,
383				  const char *buf, size_t len)
384{
385	struct isl29501_private *isl29501 = iio_priv(indio_dev);
386	enum isl29501_register_name reg = private;
387	unsigned int val;
388	int max_exp = 0;
389	int ret;
390	int i;
391
392	ret = kstrtouint(buf, 10, &val);
393	if (ret)
394		return ret;
395
396	switch (reg) {
397	case REG_GAIN_BIAS:
398		if (val > U16_MAX)
399			return -ERANGE;
400
401		ret = isl29501_register_write(isl29501, reg, val);
402		if (ret < 0)
403			return ret;
404
405		break;
406	case REG_CALIB_PHASE_TEMP_A:
407	case REG_CALIB_PHASE_TEMP_B:
408	case REG_CALIB_PHASE_LIGHT_A:
409	case REG_CALIB_PHASE_LIGHT_B:
410
411		if (val > (U8_MAX << ISL29501_MAX_EXP_VAL))
412			return -ERANGE;
413
414		/* Store the correction coefficient under its exact form. */
415		ret = isl29501_set_shadow_coeff(isl29501, reg, val);
416		if (ret < 0)
417			return ret;
418
419		/*
420		 * Find the highest exponent needed to represent
421		 * correction coefficients.
422		 */
423		for (i = 0; i < COEFF_MAX; i++) {
424			int corr;
425			int corr_exp;
426
427			corr = isl29501->shadow_coeffs[i];
428			corr_exp = isl29501_find_corr_exp(corr,
429							  ISL29501_MAX_EXP_VAL,
430							  U8_MAX / 2);
431			dev_dbg(&isl29501->client->dev,
432				"found exp of corr(%d) = %d\n", corr, corr_exp);
433
434			max_exp = max(max_exp, corr_exp);
435		}
436
437		/*
438		 * Represent every correction coefficient under
439		 * mantissa * 2^max_exponent form and force the
440		 * writing of those coefficients on the sensor.
441		 */
442		for (i = 0; i < COEFF_MAX; i++) {
443			int corr;
444			int mantissa;
445
446			corr = isl29501->shadow_coeffs[i];
447			if (!corr)
448				continue;
449
450			mantissa = corr >> max_exp;
451
452			ret = isl29501_write_coeff(isl29501, i, mantissa);
453			if (ret < 0)
454				return ret;
455		}
456
457		ret = isl29501_register_write(isl29501, REG_PHASE_EXP, max_exp);
458		if (ret < 0)
459			return ret;
460
461		break;
462	default:
463		return -EINVAL;
464	}
465
466	return len;
467}
468
469#define _ISL29501_EXT_INFO(_name, _ident) { \
470	.name = _name, \
471	.read = isl29501_read_ext, \
472	.write = isl29501_write_ext, \
473	.private = _ident, \
474	.shared = IIO_SEPARATE, \
475}
476
477static const struct iio_chan_spec_ext_info isl29501_ext_info[] = {
478	_ISL29501_EXT_INFO("agc_gain", REG_GAIN),
479	_ISL29501_EXT_INFO("agc_gain_bias", REG_GAIN_BIAS),
480	_ISL29501_EXT_INFO("calib_phase_temp_a", REG_CALIB_PHASE_TEMP_A),
481	_ISL29501_EXT_INFO("calib_phase_temp_b", REG_CALIB_PHASE_TEMP_B),
482	_ISL29501_EXT_INFO("calib_phase_light_a", REG_CALIB_PHASE_LIGHT_A),
483	_ISL29501_EXT_INFO("calib_phase_light_b", REG_CALIB_PHASE_LIGHT_B),
484	{ },
485};
486
487#define ISL29501_DISTANCE_SCAN_INDEX 0
488#define ISL29501_TIMESTAMP_SCAN_INDEX 1
489
490static const struct iio_chan_spec isl29501_channels[] = {
491	{
492		.type = IIO_PROXIMITY,
493		.scan_index = ISL29501_DISTANCE_SCAN_INDEX,
494		.info_mask_separate =
495			BIT(IIO_CHAN_INFO_RAW)   |
496			BIT(IIO_CHAN_INFO_SCALE) |
497			BIT(IIO_CHAN_INFO_CALIBBIAS),
498		.scan_type = {
499			.sign = 'u',
500			.realbits = 16,
501			.storagebits = 16,
502			.endianness = IIO_CPU,
503		},
504		.info_mask_shared_by_all = BIT(IIO_CHAN_INFO_INT_TIME) |
505				BIT(IIO_CHAN_INFO_SAMP_FREQ),
506		.ext_info = isl29501_ext_info,
507	},
508	{
509		.type = IIO_PHASE,
510		.scan_index = -1,
511		.info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
512				BIT(IIO_CHAN_INFO_SCALE),
513	},
514	{
515		.type = IIO_CURRENT,
516		.scan_index = -1,
517		.output = 1,
518		.info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
519				BIT(IIO_CHAN_INFO_SCALE),
520	},
521	{
522		.type = IIO_TEMP,
523		.scan_index = -1,
524		.info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
525				BIT(IIO_CHAN_INFO_SCALE)     |
526				BIT(IIO_CHAN_INFO_CALIBBIAS),
527	},
528	{
529		.type = IIO_INTENSITY,
530		.scan_index = -1,
531		.modified = 1,
532		.channel2 = IIO_MOD_LIGHT_CLEAR,
533		.info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
534				BIT(IIO_CHAN_INFO_SCALE),
535	},
536	IIO_CHAN_SOFT_TIMESTAMP(ISL29501_TIMESTAMP_SCAN_INDEX),
537};
538
539static int isl29501_reset_registers(struct isl29501_private *isl29501)
540{
541	int ret;
542
543	ret = i2c_smbus_write_byte_data(isl29501->client,
544					ISL29501_COMMAND_REGISTER,
545					ISL29501_RESET_ALL_REGISTERS);
546	if (ret < 0) {
547		dev_err(&isl29501->client->dev,
548			"cannot reset registers %d\n", ret);
549		return ret;
550	}
551
552	ret = i2c_smbus_write_byte_data(isl29501->client,
553					ISL29501_COMMAND_REGISTER,
554					ISL29501_RESET_INT_SM);
555	if (ret < 0)
556		dev_err(&isl29501->client->dev,
557			"cannot reset state machine %d\n", ret);
558
559	return ret;
560}
561
562static int isl29501_begin_acquisition(struct isl29501_private *isl29501)
563{
564	int ret;
565
566	ret = i2c_smbus_write_byte_data(isl29501->client,
567					ISL29501_COMMAND_REGISTER,
568					ISL29501_EMUL_SAMPLE_START_PIN);
569	if (ret < 0)
570		dev_err(&isl29501->client->dev,
571			"cannot begin acquisition %d\n", ret);
572
573	return ret;
574}
575
576static IIO_CONST_ATTR_INT_TIME_AVAIL(ISL29501_INT_TIME_AVAILABLE);
577static IIO_CONST_ATTR(out_current_scale_available,
578		      ISL29501_CURRENT_SCALE_AVAILABLE);
579
580static struct attribute *isl29501_attributes[] = {
581	&iio_const_attr_integration_time_available.dev_attr.attr,
582	&iio_const_attr_out_current_scale_available.dev_attr.attr,
583	NULL
584};
585
586static const struct attribute_group isl29501_attribute_group = {
587	.attrs = isl29501_attributes,
588};
589
590static const int isl29501_current_scale_table[][2] = {
591	{0, 3900}, {0, 7800}, {0, 11800}, {0, 15700},
592	{0, 19600}, {0, 23500}, {0, 27500}, {0, 31400},
593	{0, 35200}, {0, 39200}, {0, 43100}, {0, 47100},
594	{0, 51000}, {0, 54900}, {0, 58800},
595};
596
597static const int isl29501_int_time[][2] = {
598	{0, 70},    /* 0.07 ms */
599	{0, 140},   /* 0.14 ms */
600	{0, 280},   /* 0.28 ms */
601	{0, 570},   /* 0.57 ms */
602	{0, 1140},  /* 1.14 ms */
603	{0, 2280},  /* 2.28 ms */
604	{0, 4550},  /* 4.55 ms */
605	{0, 9100},  /* 9.11 ms */
606	{0, 18200}, /* 18.2 ms */
607	{0, 36400}, /* 36.4 ms */
608	{0, 72810}, /* 72.81 ms */
609	{0, 145610} /* 145.28 ms */
610};
611
612static int isl29501_get_raw(struct isl29501_private *isl29501,
613			    const struct iio_chan_spec *chan,
614			    int *raw)
615{
616	int ret;
617
618	switch (chan->type) {
619	case IIO_PROXIMITY:
620		ret = isl29501_register_read(isl29501, REG_DISTANCE, raw);
621		if (ret < 0)
622			return ret;
623
624		return IIO_VAL_INT;
625	case IIO_INTENSITY:
626		ret = isl29501_register_read(isl29501,
627					     REG_AMBIENT_LIGHT,
628					     raw);
629		if (ret < 0)
630			return ret;
631
632		return IIO_VAL_INT;
633	case IIO_PHASE:
634		ret = isl29501_register_read(isl29501, REG_PHASE, raw);
635		if (ret < 0)
636			return ret;
637
638		return IIO_VAL_INT;
639	case IIO_CURRENT:
640		ret = isl29501_register_read(isl29501, REG_EMITTER_DAC, raw);
641		if (ret < 0)
642			return ret;
643
644		return IIO_VAL_INT;
645	case IIO_TEMP:
646		ret = isl29501_register_read(isl29501, REG_TEMPERATURE, raw);
647		if (ret < 0)
648			return ret;
649
650		return IIO_VAL_INT;
651	default:
652		return -EINVAL;
653	}
654}
655
656static int isl29501_get_scale(struct isl29501_private *isl29501,
657			      const struct iio_chan_spec *chan,
658			      int *val, int *val2)
659{
660	int ret;
661	u32 current_scale;
662
663	switch (chan->type) {
664	case IIO_PROXIMITY:
665		/* distance = raw_distance * 33.31 / 65536 (m) */
666		*val = 3331;
667		*val2 = 6553600;
668
669		return IIO_VAL_FRACTIONAL;
670	case IIO_PHASE:
671		/* phase = raw_phase * 2pi / 65536 (rad) */
672		*val = 0;
673		*val2 = 95874;
674
675		return IIO_VAL_INT_PLUS_NANO;
676	case IIO_INTENSITY:
677		/* light = raw_light * 35 / 10000 (mA) */
678		*val = 35;
679		*val2 = 10000;
680
681		return IIO_VAL_FRACTIONAL;
682	case IIO_CURRENT:
683		ret = isl29501_register_read(isl29501,
684					     REG_DRIVER_RANGE,
685					     &current_scale);
686		if (ret < 0)
687			return ret;
688
689		if (current_scale > ARRAY_SIZE(isl29501_current_scale_table))
690			return -EINVAL;
691
692		if (!current_scale) {
693			*val = 0;
694			*val2 = 0;
695			return IIO_VAL_INT;
696		}
697
698		*val = isl29501_current_scale_table[current_scale - 1][0];
699		*val2 = isl29501_current_scale_table[current_scale - 1][1];
700
701		return IIO_VAL_INT_PLUS_MICRO;
702	case IIO_TEMP:
703		/* temperature = raw_temperature * 125 / 100000 (milli ��C) */
704		*val = 125;
705		*val2 = 100000;
706
707		return IIO_VAL_FRACTIONAL;
708	default:
709		return -EINVAL;
710	}
711}
712
713static int isl29501_get_calibbias(struct isl29501_private *isl29501,
714				  const struct iio_chan_spec *chan,
715				  int *bias)
716{
717	switch (chan->type) {
718	case IIO_PROXIMITY:
719		return isl29501_register_read(isl29501,
720					      REG_DISTANCE_BIAS,
721					      bias);
722	case IIO_TEMP:
723		return isl29501_register_read(isl29501,
724					      REG_TEMPERATURE_BIAS,
725					      bias);
726	default:
727		return -EINVAL;
728	}
729}
730
731static int isl29501_get_inttime(struct isl29501_private *isl29501,
732				int *val, int *val2)
733{
734	int ret;
735	u32 inttime;
736
737	ret = isl29501_register_read(isl29501, REG_INT_TIME, &inttime);
738	if (ret < 0)
739		return ret;
740
741	if (inttime >= ARRAY_SIZE(isl29501_int_time))
742		return -EINVAL;
743
744	*val = isl29501_int_time[inttime][0];
745	*val2 = isl29501_int_time[inttime][1];
746
747	return IIO_VAL_INT_PLUS_MICRO;
748}
749
750static int isl29501_get_freq(struct isl29501_private *isl29501,
751			     int *val, int *val2)
752{
753	int ret;
754	int sample_time;
755	unsigned long long freq;
756	u32 temp;
757
758	ret = isl29501_register_read(isl29501, REG_SAMPLE_TIME, &sample_time);
759	if (ret < 0)
760		return ret;
761
762	/* freq = 1 / (0.000450 * (sample_time + 1) * 10^-6) */
763	freq = 1000000ULL * 1000000ULL;
764
765	do_div(freq, 450 * (sample_time + 1));
766
767	temp = do_div(freq, 1000000);
768	*val = freq;
769	*val2 = temp;
770
771	return IIO_VAL_INT_PLUS_MICRO;
772}
773
774static int isl29501_read_raw(struct iio_dev *indio_dev,
775			     struct iio_chan_spec const *chan, int *val,
776			     int *val2, long mask)
777{
778	struct isl29501_private *isl29501 = iio_priv(indio_dev);
779
780	switch (mask) {
781	case IIO_CHAN_INFO_RAW:
782		return isl29501_get_raw(isl29501, chan, val);
783	case IIO_CHAN_INFO_SCALE:
784		return isl29501_get_scale(isl29501, chan, val, val2);
785	case IIO_CHAN_INFO_INT_TIME:
786		return isl29501_get_inttime(isl29501, val, val2);
787	case IIO_CHAN_INFO_SAMP_FREQ:
788		return isl29501_get_freq(isl29501, val, val2);
789	case IIO_CHAN_INFO_CALIBBIAS:
790		return isl29501_get_calibbias(isl29501, chan, val);
791	default:
792		return -EINVAL;
793	}
794}
795
796static int isl29501_set_raw(struct isl29501_private *isl29501,
797			    const struct iio_chan_spec *chan,
798			    int raw)
799{
800	switch (chan->type) {
801	case IIO_CURRENT:
802		return isl29501_register_write(isl29501, REG_EMITTER_DAC, raw);
803	default:
804		return -EINVAL;
805	}
806}
807
808static int isl29501_set_inttime(struct isl29501_private *isl29501,
809				int val, int val2)
810{
811	int i;
812
813	for (i = 0; i < ARRAY_SIZE(isl29501_int_time); i++) {
814		if (isl29501_int_time[i][0] == val &&
815		    isl29501_int_time[i][1] == val2) {
816			return isl29501_register_write(isl29501,
817						       REG_INT_TIME,
818						       i);
819		}
820	}
821
822	return -EINVAL;
823}
824
825static int isl29501_set_scale(struct isl29501_private *isl29501,
826			      const struct iio_chan_spec *chan,
827			      int val, int val2)
828{
829	int i;
830
831	if (chan->type != IIO_CURRENT)
832		return -EINVAL;
833
834	for (i = 0; i < ARRAY_SIZE(isl29501_current_scale_table); i++) {
835		if (isl29501_current_scale_table[i][0] == val &&
836		    isl29501_current_scale_table[i][1] == val2) {
837			return isl29501_register_write(isl29501,
838						       REG_DRIVER_RANGE,
839						       i + 1);
840		}
841	}
842
843	return -EINVAL;
844}
845
846static int isl29501_set_calibbias(struct isl29501_private *isl29501,
847				  const struct iio_chan_spec *chan,
848				  int bias)
849{
850	switch (chan->type) {
851	case IIO_PROXIMITY:
852		return isl29501_register_write(isl29501,
853					      REG_DISTANCE_BIAS,
854					      bias);
855	case IIO_TEMP:
856		return isl29501_register_write(isl29501,
857					       REG_TEMPERATURE_BIAS,
858					       bias);
859	default:
860		return -EINVAL;
861	}
862}
863
864static int isl29501_set_freq(struct isl29501_private *isl29501,
865			     int val, int val2)
866{
867	int freq;
868	unsigned long long sample_time;
869
870	/* sample_freq = 1 / (0.000450 * (sample_time + 1) * 10^-6) */
871	freq = val * 1000000 + val2 % 1000000;
872	sample_time = 2222ULL * 1000000ULL;
873	do_div(sample_time, freq);
874
875	sample_time -= 1;
876
877	if (sample_time > 255)
878		return -ERANGE;
879
880	return isl29501_register_write(isl29501, REG_SAMPLE_TIME, sample_time);
881}
882
883static int isl29501_write_raw(struct iio_dev *indio_dev,
884			      struct iio_chan_spec const *chan,
885			      int val, int val2, long mask)
886{
887	struct isl29501_private *isl29501 = iio_priv(indio_dev);
888
889	switch (mask) {
890	case IIO_CHAN_INFO_RAW:
891		return isl29501_set_raw(isl29501, chan, val);
892	case IIO_CHAN_INFO_INT_TIME:
893		return isl29501_set_inttime(isl29501, val, val2);
894	case IIO_CHAN_INFO_SAMP_FREQ:
895		return isl29501_set_freq(isl29501, val, val2);
896	case IIO_CHAN_INFO_SCALE:
897		return isl29501_set_scale(isl29501, chan, val, val2);
898	case IIO_CHAN_INFO_CALIBBIAS:
899		return isl29501_set_calibbias(isl29501, chan, val);
900	default:
901		return -EINVAL;
902	}
903}
904
905static const struct iio_info isl29501_info = {
906	.read_raw = &isl29501_read_raw,
907	.write_raw = &isl29501_write_raw,
908	.attrs = &isl29501_attribute_group,
909};
910
911static int isl29501_init_chip(struct isl29501_private *isl29501)
912{
913	int ret;
914
915	ret = i2c_smbus_read_byte_data(isl29501->client, ISL29501_DEVICE_ID);
916	if (ret < 0) {
917		dev_err(&isl29501->client->dev, "Error reading device id\n");
918		return ret;
919	}
920
921	if (ret != ISL29501_ID) {
922		dev_err(&isl29501->client->dev,
923			"Wrong chip id, got %x expected %x\n",
924			ret, ISL29501_DEVICE_ID);
925		return -ENODEV;
926	}
927
928	ret = isl29501_reset_registers(isl29501);
929	if (ret < 0)
930		return ret;
931
932	return isl29501_begin_acquisition(isl29501);
933}
934
935static irqreturn_t isl29501_trigger_handler(int irq, void *p)
936{
937	struct iio_poll_func *pf = p;
938	struct iio_dev *indio_dev = pf->indio_dev;
939	struct isl29501_private *isl29501 = iio_priv(indio_dev);
940	const unsigned long *active_mask = indio_dev->active_scan_mask;
941	u32 buffer[4] __aligned(8) = {}; /* 1x16-bit + naturally aligned ts */
942
943	if (test_bit(ISL29501_DISTANCE_SCAN_INDEX, active_mask))
944		isl29501_register_read(isl29501, REG_DISTANCE, buffer);
945
946	iio_push_to_buffers_with_timestamp(indio_dev, buffer, pf->timestamp);
947	iio_trigger_notify_done(indio_dev->trig);
948
949	return IRQ_HANDLED;
950}
951
952static int isl29501_probe(struct i2c_client *client)
953{
954	struct iio_dev *indio_dev;
955	struct isl29501_private *isl29501;
956	int ret;
957
958	indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*isl29501));
959	if (!indio_dev)
960		return -ENOMEM;
961
962	isl29501 = iio_priv(indio_dev);
963
964	i2c_set_clientdata(client, indio_dev);
965	isl29501->client = client;
966
967	mutex_init(&isl29501->lock);
968
969	ret = isl29501_init_chip(isl29501);
970	if (ret < 0)
971		return ret;
972
973	indio_dev->modes = INDIO_DIRECT_MODE;
974	indio_dev->channels = isl29501_channels;
975	indio_dev->num_channels = ARRAY_SIZE(isl29501_channels);
976	indio_dev->name = client->name;
977	indio_dev->info = &isl29501_info;
978
979	ret = devm_iio_triggered_buffer_setup(&client->dev, indio_dev,
980					      iio_pollfunc_store_time,
981					      isl29501_trigger_handler,
982					      NULL);
983	if (ret < 0) {
984		dev_err(&client->dev, "unable to setup iio triggered buffer\n");
985		return ret;
986	}
987
988	return devm_iio_device_register(&client->dev, indio_dev);
989}
990
991static const struct i2c_device_id isl29501_id[] = {
992	{"isl29501", 0},
993	{}
994};
995
996MODULE_DEVICE_TABLE(i2c, isl29501_id);
997
998static const struct of_device_id isl29501_i2c_matches[] = {
999	{ .compatible = "renesas,isl29501" },
1000	{ }
1001};
1002MODULE_DEVICE_TABLE(of, isl29501_i2c_matches);
1003
1004static struct i2c_driver isl29501_driver = {
1005	.driver = {
1006		.name	= "isl29501",
1007		.of_match_table = isl29501_i2c_matches,
1008	},
1009	.id_table	= isl29501_id,
1010	.probe		= isl29501_probe,
1011};
1012module_i2c_driver(isl29501_driver);
1013
1014MODULE_AUTHOR("Mathieu Othacehe <m.othacehe@gmail.com>");
1015MODULE_DESCRIPTION("ISL29501 Time of Flight sensor driver");
1016MODULE_LICENSE("GPL v2");
1017