GNU Linux-libre 4.19.242-gnu1
[releases.git] / drivers / iio / proximity / isl29501.c
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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");