GNU Linux-libre 5.16.19-gnu
[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         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
253 err:
254         mutex_unlock(&isl29501->lock);
255         return ret;
256 }
257
258 static 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
298 static 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
325 static 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
351 static 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
380 static 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
477 static 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
490 static 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
539 static 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
562 static 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
576 static IIO_CONST_ATTR_INT_TIME_AVAIL(ISL29501_INT_TIME_AVAILABLE);
577 static IIO_CONST_ATTR(out_current_scale_available,
578                       ISL29501_CURRENT_SCALE_AVAILABLE);
579
580 static 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
586 static const struct attribute_group isl29501_attribute_group = {
587         .attrs = isl29501_attributes,
588 };
589
590 static 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
597 static 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
612 static 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
656 static 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
713 static 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
731 static 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
750 static 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
774 static 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
796 static 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
808 static 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
825 static 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
846 static 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
864 static 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
883 static 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
905 static 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
911 static 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
935 static 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
952 static int isl29501_probe(struct i2c_client *client,
953                           const struct i2c_device_id *id)
954 {
955         struct iio_dev *indio_dev;
956         struct isl29501_private *isl29501;
957         int ret;
958
959         indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*isl29501));
960         if (!indio_dev)
961                 return -ENOMEM;
962
963         isl29501 = iio_priv(indio_dev);
964
965         i2c_set_clientdata(client, indio_dev);
966         isl29501->client = client;
967
968         mutex_init(&isl29501->lock);
969
970         ret = isl29501_init_chip(isl29501);
971         if (ret < 0)
972                 return ret;
973
974         indio_dev->modes = INDIO_DIRECT_MODE;
975         indio_dev->channels = isl29501_channels;
976         indio_dev->num_channels = ARRAY_SIZE(isl29501_channels);
977         indio_dev->name = client->name;
978         indio_dev->info = &isl29501_info;
979
980         ret = devm_iio_triggered_buffer_setup(&client->dev, indio_dev,
981                                               iio_pollfunc_store_time,
982                                               isl29501_trigger_handler,
983                                               NULL);
984         if (ret < 0) {
985                 dev_err(&client->dev, "unable to setup iio triggered buffer\n");
986                 return ret;
987         }
988
989         return devm_iio_device_register(&client->dev, indio_dev);
990 }
991
992 static const struct i2c_device_id isl29501_id[] = {
993         {"isl29501", 0},
994         {}
995 };
996
997 MODULE_DEVICE_TABLE(i2c, isl29501_id);
998
999 #if defined(CONFIG_OF)
1000 static const struct of_device_id isl29501_i2c_matches[] = {
1001         { .compatible = "renesas,isl29501" },
1002         { }
1003 };
1004 MODULE_DEVICE_TABLE(of, isl29501_i2c_matches);
1005 #endif
1006
1007 static struct i2c_driver isl29501_driver = {
1008         .driver = {
1009                 .name   = "isl29501",
1010         },
1011         .id_table       = isl29501_id,
1012         .probe          = isl29501_probe,
1013 };
1014 module_i2c_driver(isl29501_driver);
1015
1016 MODULE_AUTHOR("Mathieu Othacehe <m.othacehe@gmail.com>");
1017 MODULE_DESCRIPTION("ISL29501 Time of Flight sensor driver");
1018 MODULE_LICENSE("GPL v2");