]> Git Repo - J-linux.git/blob - drivers/iio/light/vcnl4000.c
Merge tag 'amd-drm-next-6.5-2023-06-09' of https://gitlab.freedesktop.org/agd5f/linux...
[J-linux.git] / drivers / iio / light / vcnl4000.c
1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3  * vcnl4000.c - Support for Vishay VCNL4000/4010/4020/4040/4200 combined ambient
4  * light and proximity sensor
5  *
6  * Copyright 2012 Peter Meerwald <[email protected]>
7  * Copyright 2019 Pursim SPC
8  * Copyright 2020 Mathieu Othacehe <[email protected]>
9  *
10  * IIO driver for:
11  *   VCNL4000/10/20 (7-bit I2C slave address 0x13)
12  *   VCNL4040 (7-bit I2C slave address 0x60)
13  *   VCNL4200 (7-bit I2C slave address 0x51)
14  *
15  * TODO:
16  *   allow to adjust IR current
17  *   interrupts (VCNL4040, VCNL4200)
18  */
19
20 #include <linux/bitfield.h>
21 #include <linux/module.h>
22 #include <linux/i2c.h>
23 #include <linux/err.h>
24 #include <linux/delay.h>
25 #include <linux/pm_runtime.h>
26 #include <linux/interrupt.h>
27
28 #include <linux/iio/buffer.h>
29 #include <linux/iio/events.h>
30 #include <linux/iio/iio.h>
31 #include <linux/iio/sysfs.h>
32 #include <linux/iio/trigger.h>
33 #include <linux/iio/trigger_consumer.h>
34 #include <linux/iio/triggered_buffer.h>
35
36 #define VCNL4000_DRV_NAME "vcnl4000"
37 #define VCNL4000_PROD_ID        0x01
38 #define VCNL4010_PROD_ID        0x02 /* for VCNL4020, VCNL4010 */
39 #define VCNL4040_PROD_ID        0x86
40 #define VCNL4200_PROD_ID        0x58
41
42 #define VCNL4000_COMMAND        0x80 /* Command register */
43 #define VCNL4000_PROD_REV       0x81 /* Product ID and Revision ID */
44 #define VCNL4010_PROX_RATE      0x82 /* Proximity rate */
45 #define VCNL4000_LED_CURRENT    0x83 /* IR LED current for proximity mode */
46 #define VCNL4000_AL_PARAM       0x84 /* Ambient light parameter register */
47 #define VCNL4010_ALS_PARAM      0x84 /* ALS rate */
48 #define VCNL4000_AL_RESULT_HI   0x85 /* Ambient light result register, MSB */
49 #define VCNL4000_AL_RESULT_LO   0x86 /* Ambient light result register, LSB */
50 #define VCNL4000_PS_RESULT_HI   0x87 /* Proximity result register, MSB */
51 #define VCNL4000_PS_RESULT_LO   0x88 /* Proximity result register, LSB */
52 #define VCNL4000_PS_MEAS_FREQ   0x89 /* Proximity test signal frequency */
53 #define VCNL4010_INT_CTRL       0x89 /* Interrupt control */
54 #define VCNL4000_PS_MOD_ADJ     0x8a /* Proximity modulator timing adjustment */
55 #define VCNL4010_LOW_THR_HI     0x8a /* Low threshold, MSB */
56 #define VCNL4010_LOW_THR_LO     0x8b /* Low threshold, LSB */
57 #define VCNL4010_HIGH_THR_HI    0x8c /* High threshold, MSB */
58 #define VCNL4010_HIGH_THR_LO    0x8d /* High threshold, LSB */
59 #define VCNL4010_ISR            0x8e /* Interrupt status */
60
61 #define VCNL4200_AL_CONF        0x00 /* Ambient light configuration */
62 #define VCNL4200_PS_CONF1       0x03 /* Proximity configuration */
63 #define VCNL4040_PS_THDL_LM     0x06 /* Proximity threshold low */
64 #define VCNL4040_PS_THDH_LM     0x07 /* Proximity threshold high */
65 #define VCNL4200_PS_DATA        0x08 /* Proximity data */
66 #define VCNL4200_AL_DATA        0x09 /* Ambient light data */
67 #define VCNL4040_INT_FLAGS      0x0b /* Interrupt register */
68 #define VCNL4200_DEV_ID         0x0e /* Device ID, slave address and version */
69
70 #define VCNL4040_DEV_ID         0x0c /* Device ID and version */
71
72 /* Bit masks for COMMAND register */
73 #define VCNL4000_AL_RDY         BIT(6) /* ALS data ready? */
74 #define VCNL4000_PS_RDY         BIT(5) /* proximity data ready? */
75 #define VCNL4000_AL_OD          BIT(4) /* start on-demand ALS measurement */
76 #define VCNL4000_PS_OD          BIT(3) /* start on-demand proximity measurement */
77 #define VCNL4000_ALS_EN         BIT(2) /* start ALS measurement */
78 #define VCNL4000_PROX_EN        BIT(1) /* start proximity measurement */
79 #define VCNL4000_SELF_TIMED_EN  BIT(0) /* start self-timed measurement */
80
81 #define VCNL4040_ALS_CONF_ALS_SHUTDOWN  BIT(0)
82 #define VCNL4040_PS_CONF1_PS_SHUTDOWN   BIT(0)
83 #define VCNL4040_PS_CONF2_PS_IT GENMASK(3, 1) /* Proximity integration time */
84 #define VCNL4040_PS_CONF2_PS_INT        GENMASK(9, 8) /* Proximity interrupt mode */
85 #define VCNL4040_PS_IF_AWAY             BIT(8) /* Proximity event cross low threshold */
86 #define VCNL4040_PS_IF_CLOSE            BIT(9) /* Proximity event cross high threshold */
87
88 /* Bit masks for interrupt registers. */
89 #define VCNL4010_INT_THR_SEL    BIT(0) /* Select threshold interrupt source */
90 #define VCNL4010_INT_THR_EN     BIT(1) /* Threshold interrupt type */
91 #define VCNL4010_INT_ALS_EN     BIT(2) /* Enable on ALS data ready */
92 #define VCNL4010_INT_PROX_EN    BIT(3) /* Enable on proximity data ready */
93
94 #define VCNL4010_INT_THR_HIGH   0 /* High threshold exceeded */
95 #define VCNL4010_INT_THR_LOW    1 /* Low threshold exceeded */
96 #define VCNL4010_INT_ALS        2 /* ALS data ready */
97 #define VCNL4010_INT_PROXIMITY  3 /* Proximity data ready */
98
99 #define VCNL4010_INT_THR \
100         (BIT(VCNL4010_INT_THR_LOW) | BIT(VCNL4010_INT_THR_HIGH))
101 #define VCNL4010_INT_DRDY \
102         (BIT(VCNL4010_INT_PROXIMITY) | BIT(VCNL4010_INT_ALS))
103
104 static const int vcnl4010_prox_sampling_frequency[][2] = {
105         {1, 950000},
106         {3, 906250},
107         {7, 812500},
108         {16, 625000},
109         {31, 250000},
110         {62, 500000},
111         {125, 0},
112         {250, 0},
113 };
114
115 static const int vcnl4040_ps_it_times[][2] = {
116         {0, 100},
117         {0, 150},
118         {0, 200},
119         {0, 250},
120         {0, 300},
121         {0, 350},
122         {0, 400},
123         {0, 800},
124 };
125
126 #define VCNL4000_SLEEP_DELAY_MS 2000 /* before we enter pm_runtime_suspend */
127
128 enum vcnl4000_device_ids {
129         VCNL4000,
130         VCNL4010,
131         VCNL4040,
132         VCNL4200,
133 };
134
135 struct vcnl4200_channel {
136         u8 reg;
137         ktime_t last_measurement;
138         ktime_t sampling_rate;
139         struct mutex lock;
140 };
141
142 struct vcnl4000_data {
143         struct i2c_client *client;
144         enum vcnl4000_device_ids id;
145         int rev;
146         int al_scale;
147         u8 ps_int;              /* proximity interrupt mode */
148         const struct vcnl4000_chip_spec *chip_spec;
149         struct mutex vcnl4000_lock;
150         struct vcnl4200_channel vcnl4200_al;
151         struct vcnl4200_channel vcnl4200_ps;
152         uint32_t near_level;
153 };
154
155 struct vcnl4000_chip_spec {
156         const char *prod;
157         struct iio_chan_spec const *channels;
158         const int num_channels;
159         const struct iio_info *info;
160         const struct iio_buffer_setup_ops *buffer_setup_ops;
161         int (*init)(struct vcnl4000_data *data);
162         int (*measure_light)(struct vcnl4000_data *data, int *val);
163         int (*measure_proximity)(struct vcnl4000_data *data, int *val);
164         int (*set_power_state)(struct vcnl4000_data *data, bool on);
165         irqreturn_t (*irq_thread)(int irq, void *priv);
166         irqreturn_t (*trig_buffer_func)(int irq, void *priv);
167 };
168
169 static const struct i2c_device_id vcnl4000_id[] = {
170         { "vcnl4000", VCNL4000 },
171         { "vcnl4010", VCNL4010 },
172         { "vcnl4020", VCNL4010 },
173         { "vcnl4040", VCNL4040 },
174         { "vcnl4200", VCNL4200 },
175         { }
176 };
177 MODULE_DEVICE_TABLE(i2c, vcnl4000_id);
178
179 static int vcnl4000_set_power_state(struct vcnl4000_data *data, bool on)
180 {
181         /* no suspend op */
182         return 0;
183 }
184
185 static int vcnl4000_init(struct vcnl4000_data *data)
186 {
187         int ret, prod_id;
188
189         ret = i2c_smbus_read_byte_data(data->client, VCNL4000_PROD_REV);
190         if (ret < 0)
191                 return ret;
192
193         prod_id = ret >> 4;
194         switch (prod_id) {
195         case VCNL4000_PROD_ID:
196                 if (data->id != VCNL4000)
197                         dev_warn(&data->client->dev,
198                                         "wrong device id, use vcnl4000");
199                 break;
200         case VCNL4010_PROD_ID:
201                 if (data->id != VCNL4010)
202                         dev_warn(&data->client->dev,
203                                         "wrong device id, use vcnl4010/4020");
204                 break;
205         default:
206                 return -ENODEV;
207         }
208
209         data->rev = ret & 0xf;
210         data->al_scale = 250000;
211
212         return data->chip_spec->set_power_state(data, true);
213 };
214
215 static ssize_t vcnl4000_write_als_enable(struct vcnl4000_data *data, bool en)
216 {
217         int ret;
218
219         mutex_lock(&data->vcnl4000_lock);
220
221         ret = i2c_smbus_read_word_data(data->client, VCNL4200_AL_CONF);
222         if (ret < 0)
223                 goto out;
224
225         if (en)
226                 ret &= ~VCNL4040_ALS_CONF_ALS_SHUTDOWN;
227         else
228                 ret |= VCNL4040_ALS_CONF_ALS_SHUTDOWN;
229
230         ret = i2c_smbus_write_word_data(data->client, VCNL4200_AL_CONF, ret);
231
232 out:
233         mutex_unlock(&data->vcnl4000_lock);
234
235         return ret;
236 }
237
238 static ssize_t vcnl4000_write_ps_enable(struct vcnl4000_data *data, bool en)
239 {
240         int ret;
241
242         mutex_lock(&data->vcnl4000_lock);
243
244         ret = i2c_smbus_read_word_data(data->client, VCNL4200_PS_CONF1);
245         if (ret < 0)
246                 goto out;
247
248         if (en)
249                 ret &= ~VCNL4040_PS_CONF1_PS_SHUTDOWN;
250         else
251                 ret |= VCNL4040_PS_CONF1_PS_SHUTDOWN;
252
253         ret = i2c_smbus_write_word_data(data->client, VCNL4200_PS_CONF1, ret);
254
255 out:
256         mutex_unlock(&data->vcnl4000_lock);
257
258         return ret;
259 }
260
261 static int vcnl4200_set_power_state(struct vcnl4000_data *data, bool on)
262 {
263         int ret;
264
265         /* Do not power down if interrupts are enabled */
266         if (!on && data->ps_int)
267                 return 0;
268
269         ret = vcnl4000_write_als_enable(data, on);
270         if (ret < 0)
271                 return ret;
272
273         ret = vcnl4000_write_ps_enable(data, on);
274         if (ret < 0)
275                 return ret;
276
277         if (on) {
278                 /* Wait at least one integration cycle before fetching data */
279                 data->vcnl4200_al.last_measurement = ktime_get();
280                 data->vcnl4200_ps.last_measurement = ktime_get();
281         }
282
283         return 0;
284 }
285
286 static int vcnl4200_init(struct vcnl4000_data *data)
287 {
288         int ret, id;
289
290         ret = i2c_smbus_read_word_data(data->client, VCNL4200_DEV_ID);
291         if (ret < 0)
292                 return ret;
293
294         id = ret & 0xff;
295
296         if (id != VCNL4200_PROD_ID) {
297                 ret = i2c_smbus_read_word_data(data->client, VCNL4040_DEV_ID);
298                 if (ret < 0)
299                         return ret;
300
301                 id = ret & 0xff;
302
303                 if (id != VCNL4040_PROD_ID)
304                         return -ENODEV;
305         }
306
307         dev_dbg(&data->client->dev, "device id 0x%x", id);
308
309         data->rev = (ret >> 8) & 0xf;
310         data->ps_int = 0;
311
312         data->vcnl4200_al.reg = VCNL4200_AL_DATA;
313         data->vcnl4200_ps.reg = VCNL4200_PS_DATA;
314         switch (id) {
315         case VCNL4200_PROD_ID:
316                 /* Default wait time is 50ms, add 20% tolerance. */
317                 data->vcnl4200_al.sampling_rate = ktime_set(0, 60000 * 1000);
318                 /* Default wait time is 4.8ms, add 20% tolerance. */
319                 data->vcnl4200_ps.sampling_rate = ktime_set(0, 5760 * 1000);
320                 data->al_scale = 24000;
321                 break;
322         case VCNL4040_PROD_ID:
323                 /* Default wait time is 80ms, add 20% tolerance. */
324                 data->vcnl4200_al.sampling_rate = ktime_set(0, 96000 * 1000);
325                 /* Default wait time is 5ms, add 20% tolerance. */
326                 data->vcnl4200_ps.sampling_rate = ktime_set(0, 6000 * 1000);
327                 data->al_scale = 120000;
328                 break;
329         }
330         mutex_init(&data->vcnl4200_al.lock);
331         mutex_init(&data->vcnl4200_ps.lock);
332
333         ret = data->chip_spec->set_power_state(data, true);
334         if (ret < 0)
335                 return ret;
336
337         return 0;
338 };
339
340 static int vcnl4000_read_data(struct vcnl4000_data *data, u8 data_reg, int *val)
341 {
342         s32 ret;
343
344         ret = i2c_smbus_read_word_swapped(data->client, data_reg);
345         if (ret < 0)
346                 return ret;
347
348         *val = ret;
349         return 0;
350 }
351
352 static int vcnl4000_write_data(struct vcnl4000_data *data, u8 data_reg, int val)
353 {
354         if (val > U16_MAX)
355                 return -ERANGE;
356
357         return i2c_smbus_write_word_swapped(data->client, data_reg, val);
358 }
359
360
361 static int vcnl4000_measure(struct vcnl4000_data *data, u8 req_mask,
362                                 u8 rdy_mask, u8 data_reg, int *val)
363 {
364         int tries = 20;
365         int ret;
366
367         mutex_lock(&data->vcnl4000_lock);
368
369         ret = i2c_smbus_write_byte_data(data->client, VCNL4000_COMMAND,
370                                         req_mask);
371         if (ret < 0)
372                 goto fail;
373
374         /* wait for data to become ready */
375         while (tries--) {
376                 ret = i2c_smbus_read_byte_data(data->client, VCNL4000_COMMAND);
377                 if (ret < 0)
378                         goto fail;
379                 if (ret & rdy_mask)
380                         break;
381                 msleep(20); /* measurement takes up to 100 ms */
382         }
383
384         if (tries < 0) {
385                 dev_err(&data->client->dev,
386                         "vcnl4000_measure() failed, data not ready\n");
387                 ret = -EIO;
388                 goto fail;
389         }
390
391         ret = vcnl4000_read_data(data, data_reg, val);
392         if (ret < 0)
393                 goto fail;
394
395         mutex_unlock(&data->vcnl4000_lock);
396
397         return 0;
398
399 fail:
400         mutex_unlock(&data->vcnl4000_lock);
401         return ret;
402 }
403
404 static int vcnl4200_measure(struct vcnl4000_data *data,
405                 struct vcnl4200_channel *chan, int *val)
406 {
407         int ret;
408         s64 delta;
409         ktime_t next_measurement;
410
411         mutex_lock(&chan->lock);
412
413         next_measurement = ktime_add(chan->last_measurement,
414                         chan->sampling_rate);
415         delta = ktime_us_delta(next_measurement, ktime_get());
416         if (delta > 0)
417                 usleep_range(delta, delta + 500);
418         chan->last_measurement = ktime_get();
419
420         mutex_unlock(&chan->lock);
421
422         ret = i2c_smbus_read_word_data(data->client, chan->reg);
423         if (ret < 0)
424                 return ret;
425
426         *val = ret;
427
428         return 0;
429 }
430
431 static int vcnl4000_measure_light(struct vcnl4000_data *data, int *val)
432 {
433         return vcnl4000_measure(data,
434                         VCNL4000_AL_OD, VCNL4000_AL_RDY,
435                         VCNL4000_AL_RESULT_HI, val);
436 }
437
438 static int vcnl4200_measure_light(struct vcnl4000_data *data, int *val)
439 {
440         return vcnl4200_measure(data, &data->vcnl4200_al, val);
441 }
442
443 static int vcnl4000_measure_proximity(struct vcnl4000_data *data, int *val)
444 {
445         return vcnl4000_measure(data,
446                         VCNL4000_PS_OD, VCNL4000_PS_RDY,
447                         VCNL4000_PS_RESULT_HI, val);
448 }
449
450 static int vcnl4200_measure_proximity(struct vcnl4000_data *data, int *val)
451 {
452         return vcnl4200_measure(data, &data->vcnl4200_ps, val);
453 }
454
455 static int vcnl4010_read_proxy_samp_freq(struct vcnl4000_data *data, int *val,
456                                          int *val2)
457 {
458         int ret;
459
460         ret = i2c_smbus_read_byte_data(data->client, VCNL4010_PROX_RATE);
461         if (ret < 0)
462                 return ret;
463
464         if (ret >= ARRAY_SIZE(vcnl4010_prox_sampling_frequency))
465                 return -EINVAL;
466
467         *val = vcnl4010_prox_sampling_frequency[ret][0];
468         *val2 = vcnl4010_prox_sampling_frequency[ret][1];
469
470         return 0;
471 }
472
473 static bool vcnl4010_is_in_periodic_mode(struct vcnl4000_data *data)
474 {
475         int ret;
476
477         ret = i2c_smbus_read_byte_data(data->client, VCNL4000_COMMAND);
478         if (ret < 0)
479                 return false;
480
481         return !!(ret & VCNL4000_SELF_TIMED_EN);
482 }
483
484 static int vcnl4000_set_pm_runtime_state(struct vcnl4000_data *data, bool on)
485 {
486         struct device *dev = &data->client->dev;
487         int ret;
488
489         if (on) {
490                 ret = pm_runtime_resume_and_get(dev);
491         } else {
492                 pm_runtime_mark_last_busy(dev);
493                 ret = pm_runtime_put_autosuspend(dev);
494         }
495
496         return ret;
497 }
498
499 static int vcnl4040_read_ps_it(struct vcnl4000_data *data, int *val, int *val2)
500 {
501         int ret;
502
503         ret = i2c_smbus_read_word_data(data->client, VCNL4200_PS_CONF1);
504         if (ret < 0)
505                 return ret;
506
507         ret = FIELD_GET(VCNL4040_PS_CONF2_PS_IT, ret);
508
509         if (ret >= ARRAY_SIZE(vcnl4040_ps_it_times))
510                 return -EINVAL;
511
512         *val = vcnl4040_ps_it_times[ret][0];
513         *val2 = vcnl4040_ps_it_times[ret][1];
514
515         return 0;
516 }
517
518 static ssize_t vcnl4040_write_ps_it(struct vcnl4000_data *data, int val)
519 {
520         unsigned int i;
521         int ret, index = -1;
522         u16 regval;
523
524         for (i = 0; i < ARRAY_SIZE(vcnl4040_ps_it_times); i++) {
525                 if (val == vcnl4040_ps_it_times[i][1]) {
526                         index = i;
527                         break;
528                 }
529         }
530
531         if (index < 0)
532                 return -EINVAL;
533
534         mutex_lock(&data->vcnl4000_lock);
535
536         ret = i2c_smbus_read_word_data(data->client, VCNL4200_PS_CONF1);
537         if (ret < 0)
538                 goto out;
539
540         regval = (ret & ~VCNL4040_PS_CONF2_PS_IT) |
541             FIELD_PREP(VCNL4040_PS_CONF2_PS_IT, index);
542         ret = i2c_smbus_write_word_data(data->client, VCNL4200_PS_CONF1,
543                                         regval);
544
545 out:
546         mutex_unlock(&data->vcnl4000_lock);
547         return ret;
548 }
549
550 static int vcnl4000_read_raw(struct iio_dev *indio_dev,
551                                 struct iio_chan_spec const *chan,
552                                 int *val, int *val2, long mask)
553 {
554         int ret;
555         struct vcnl4000_data *data = iio_priv(indio_dev);
556
557         switch (mask) {
558         case IIO_CHAN_INFO_RAW:
559                 ret = vcnl4000_set_pm_runtime_state(data, true);
560                 if  (ret < 0)
561                         return ret;
562
563                 switch (chan->type) {
564                 case IIO_LIGHT:
565                         ret = data->chip_spec->measure_light(data, val);
566                         if (!ret)
567                                 ret = IIO_VAL_INT;
568                         break;
569                 case IIO_PROXIMITY:
570                         ret = data->chip_spec->measure_proximity(data, val);
571                         if (!ret)
572                                 ret = IIO_VAL_INT;
573                         break;
574                 default:
575                         ret = -EINVAL;
576                 }
577                 vcnl4000_set_pm_runtime_state(data, false);
578                 return ret;
579         case IIO_CHAN_INFO_SCALE:
580                 if (chan->type != IIO_LIGHT)
581                         return -EINVAL;
582
583                 *val = 0;
584                 *val2 = data->al_scale;
585                 return IIO_VAL_INT_PLUS_MICRO;
586         case IIO_CHAN_INFO_INT_TIME:
587                 if (chan->type != IIO_PROXIMITY)
588                         return -EINVAL;
589                 ret = vcnl4040_read_ps_it(data, val, val2);
590                 if (ret < 0)
591                         return ret;
592                 return IIO_VAL_INT_PLUS_MICRO;
593         default:
594                 return -EINVAL;
595         }
596 }
597
598 static int vcnl4040_write_raw(struct iio_dev *indio_dev,
599                               struct iio_chan_spec const *chan,
600                               int val, int val2, long mask)
601 {
602         struct vcnl4000_data *data = iio_priv(indio_dev);
603
604         switch (mask) {
605         case IIO_CHAN_INFO_INT_TIME:
606                 if (val != 0)
607                         return -EINVAL;
608                 if (chan->type != IIO_PROXIMITY)
609                         return -EINVAL;
610                 return vcnl4040_write_ps_it(data, val2);
611         default:
612                 return -EINVAL;
613         }
614 }
615
616 static int vcnl4040_read_avail(struct iio_dev *indio_dev,
617                                struct iio_chan_spec const *chan,
618                                const int **vals, int *type, int *length,
619                                long mask)
620 {
621         switch (mask) {
622         case IIO_CHAN_INFO_INT_TIME:
623                 *vals = (int *)vcnl4040_ps_it_times;
624                 *type = IIO_VAL_INT_PLUS_MICRO;
625                 *length = 2 * ARRAY_SIZE(vcnl4040_ps_it_times);
626                 return IIO_AVAIL_LIST;
627         default:
628                 return -EINVAL;
629         }
630 }
631
632 static int vcnl4010_read_raw(struct iio_dev *indio_dev,
633                              struct iio_chan_spec const *chan,
634                              int *val, int *val2, long mask)
635 {
636         int ret;
637         struct vcnl4000_data *data = iio_priv(indio_dev);
638
639         switch (mask) {
640         case IIO_CHAN_INFO_RAW:
641         case IIO_CHAN_INFO_SCALE:
642                 ret = iio_device_claim_direct_mode(indio_dev);
643                 if (ret)
644                         return ret;
645
646                 /* Protect against event capture. */
647                 if (vcnl4010_is_in_periodic_mode(data)) {
648                         ret = -EBUSY;
649                 } else {
650                         ret = vcnl4000_read_raw(indio_dev, chan, val, val2,
651                                                 mask);
652                 }
653
654                 iio_device_release_direct_mode(indio_dev);
655                 return ret;
656         case IIO_CHAN_INFO_SAMP_FREQ:
657                 switch (chan->type) {
658                 case IIO_PROXIMITY:
659                         ret = vcnl4010_read_proxy_samp_freq(data, val, val2);
660                         if (ret < 0)
661                                 return ret;
662                         return IIO_VAL_INT_PLUS_MICRO;
663                 default:
664                         return -EINVAL;
665                 }
666         default:
667                 return -EINVAL;
668         }
669 }
670
671 static int vcnl4010_read_avail(struct iio_dev *indio_dev,
672                                struct iio_chan_spec const *chan,
673                                const int **vals, int *type, int *length,
674                                long mask)
675 {
676         switch (mask) {
677         case IIO_CHAN_INFO_SAMP_FREQ:
678                 *vals = (int *)vcnl4010_prox_sampling_frequency;
679                 *type = IIO_VAL_INT_PLUS_MICRO;
680                 *length = 2 * ARRAY_SIZE(vcnl4010_prox_sampling_frequency);
681                 return IIO_AVAIL_LIST;
682         default:
683                 return -EINVAL;
684         }
685 }
686
687 static int vcnl4010_write_proxy_samp_freq(struct vcnl4000_data *data, int val,
688                                           int val2)
689 {
690         unsigned int i;
691         int index = -1;
692
693         for (i = 0; i < ARRAY_SIZE(vcnl4010_prox_sampling_frequency); i++) {
694                 if (val == vcnl4010_prox_sampling_frequency[i][0] &&
695                     val2 == vcnl4010_prox_sampling_frequency[i][1]) {
696                         index = i;
697                         break;
698                 }
699         }
700
701         if (index < 0)
702                 return -EINVAL;
703
704         return i2c_smbus_write_byte_data(data->client, VCNL4010_PROX_RATE,
705                                          index);
706 }
707
708 static int vcnl4010_write_raw(struct iio_dev *indio_dev,
709                               struct iio_chan_spec const *chan,
710                               int val, int val2, long mask)
711 {
712         int ret;
713         struct vcnl4000_data *data = iio_priv(indio_dev);
714
715         ret = iio_device_claim_direct_mode(indio_dev);
716         if (ret)
717                 return ret;
718
719         /* Protect against event capture. */
720         if (vcnl4010_is_in_periodic_mode(data)) {
721                 ret = -EBUSY;
722                 goto end;
723         }
724
725         switch (mask) {
726         case IIO_CHAN_INFO_SAMP_FREQ:
727                 switch (chan->type) {
728                 case IIO_PROXIMITY:
729                         ret = vcnl4010_write_proxy_samp_freq(data, val, val2);
730                         goto end;
731                 default:
732                         ret = -EINVAL;
733                         goto end;
734                 }
735         default:
736                 ret = -EINVAL;
737                 goto end;
738         }
739
740 end:
741         iio_device_release_direct_mode(indio_dev);
742         return ret;
743 }
744
745 static int vcnl4010_read_event(struct iio_dev *indio_dev,
746                                const struct iio_chan_spec *chan,
747                                enum iio_event_type type,
748                                enum iio_event_direction dir,
749                                enum iio_event_info info,
750                                int *val, int *val2)
751 {
752         int ret;
753         struct vcnl4000_data *data = iio_priv(indio_dev);
754
755         switch (info) {
756         case IIO_EV_INFO_VALUE:
757                 switch (dir) {
758                 case IIO_EV_DIR_RISING:
759                         ret = vcnl4000_read_data(data, VCNL4010_HIGH_THR_HI,
760                                                  val);
761                         if (ret < 0)
762                                 return ret;
763                         return IIO_VAL_INT;
764                 case IIO_EV_DIR_FALLING:
765                         ret = vcnl4000_read_data(data, VCNL4010_LOW_THR_HI,
766                                                  val);
767                         if (ret < 0)
768                                 return ret;
769                         return IIO_VAL_INT;
770                 default:
771                         return -EINVAL;
772                 }
773         default:
774                 return -EINVAL;
775         }
776 }
777
778 static int vcnl4010_write_event(struct iio_dev *indio_dev,
779                                 const struct iio_chan_spec *chan,
780                                 enum iio_event_type type,
781                                 enum iio_event_direction dir,
782                                 enum iio_event_info info,
783                                 int val, int val2)
784 {
785         int ret;
786         struct vcnl4000_data *data = iio_priv(indio_dev);
787
788         switch (info) {
789         case IIO_EV_INFO_VALUE:
790                 switch (dir) {
791                 case IIO_EV_DIR_RISING:
792                         ret = vcnl4000_write_data(data, VCNL4010_HIGH_THR_HI,
793                                                   val);
794                         if (ret < 0)
795                                 return ret;
796                         return IIO_VAL_INT;
797                 case IIO_EV_DIR_FALLING:
798                         ret = vcnl4000_write_data(data, VCNL4010_LOW_THR_HI,
799                                                   val);
800                         if (ret < 0)
801                                 return ret;
802                         return IIO_VAL_INT;
803                 default:
804                         return -EINVAL;
805                 }
806         default:
807                 return -EINVAL;
808         }
809 }
810
811 static int vcnl4040_read_event(struct iio_dev *indio_dev,
812                                const struct iio_chan_spec *chan,
813                                enum iio_event_type type,
814                                enum iio_event_direction dir,
815                                enum iio_event_info info,
816                                int *val, int *val2)
817 {
818         int ret;
819         struct vcnl4000_data *data = iio_priv(indio_dev);
820
821         switch (dir) {
822         case IIO_EV_DIR_RISING:
823                 ret = i2c_smbus_read_word_data(data->client,
824                                                VCNL4040_PS_THDH_LM);
825                 if (ret < 0)
826                         return ret;
827                 *val = ret;
828                 return IIO_VAL_INT;
829         case IIO_EV_DIR_FALLING:
830                 ret = i2c_smbus_read_word_data(data->client,
831                                                VCNL4040_PS_THDL_LM);
832                 if (ret < 0)
833                         return ret;
834                 *val = ret;
835                 return IIO_VAL_INT;
836         default:
837                 return -EINVAL;
838         }
839 }
840
841 static int vcnl4040_write_event(struct iio_dev *indio_dev,
842                                 const struct iio_chan_spec *chan,
843                                 enum iio_event_type type,
844                                 enum iio_event_direction dir,
845                                 enum iio_event_info info,
846                                 int val, int val2)
847 {
848         int ret;
849         struct vcnl4000_data *data = iio_priv(indio_dev);
850
851         switch (dir) {
852         case IIO_EV_DIR_RISING:
853                 ret = i2c_smbus_write_word_data(data->client,
854                                                 VCNL4040_PS_THDH_LM, val);
855                 if (ret < 0)
856                         return ret;
857                 return IIO_VAL_INT;
858         case IIO_EV_DIR_FALLING:
859                 ret = i2c_smbus_write_word_data(data->client,
860                                                 VCNL4040_PS_THDL_LM, val);
861                 if (ret < 0)
862                         return ret;
863                 return IIO_VAL_INT;
864         default:
865                 return -EINVAL;
866         }
867 }
868
869 static bool vcnl4010_is_thr_enabled(struct vcnl4000_data *data)
870 {
871         int ret;
872
873         ret = i2c_smbus_read_byte_data(data->client, VCNL4010_INT_CTRL);
874         if (ret < 0)
875                 return false;
876
877         return !!(ret & VCNL4010_INT_THR_EN);
878 }
879
880 static int vcnl4010_read_event_config(struct iio_dev *indio_dev,
881                                       const struct iio_chan_spec *chan,
882                                       enum iio_event_type type,
883                                       enum iio_event_direction dir)
884 {
885         struct vcnl4000_data *data = iio_priv(indio_dev);
886
887         switch (chan->type) {
888         case IIO_PROXIMITY:
889                 return vcnl4010_is_thr_enabled(data);
890         default:
891                 return -EINVAL;
892         }
893 }
894
895 static int vcnl4010_config_threshold(struct iio_dev *indio_dev, bool state)
896 {
897         struct vcnl4000_data *data = iio_priv(indio_dev);
898         int ret;
899         int icr;
900         int command;
901
902         if (state) {
903                 ret = iio_device_claim_direct_mode(indio_dev);
904                 if (ret)
905                         return ret;
906
907                 /* Enable periodic measurement of proximity data. */
908                 command = VCNL4000_SELF_TIMED_EN | VCNL4000_PROX_EN;
909
910                 /*
911                  * Enable interrupts on threshold, for proximity data by
912                  * default.
913                  */
914                 icr = VCNL4010_INT_THR_EN;
915         } else {
916                 if (!vcnl4010_is_thr_enabled(data))
917                         return 0;
918
919                 command = 0;
920                 icr = 0;
921         }
922
923         ret = i2c_smbus_write_byte_data(data->client, VCNL4000_COMMAND,
924                                         command);
925         if (ret < 0)
926                 goto end;
927
928         ret = i2c_smbus_write_byte_data(data->client, VCNL4010_INT_CTRL, icr);
929
930 end:
931         if (state)
932                 iio_device_release_direct_mode(indio_dev);
933
934         return ret;
935 }
936
937 static int vcnl4010_write_event_config(struct iio_dev *indio_dev,
938                                        const struct iio_chan_spec *chan,
939                                        enum iio_event_type type,
940                                        enum iio_event_direction dir,
941                                        int state)
942 {
943         switch (chan->type) {
944         case IIO_PROXIMITY:
945                 return vcnl4010_config_threshold(indio_dev, state);
946         default:
947                 return -EINVAL;
948         }
949 }
950
951 static int vcnl4040_read_event_config(struct iio_dev *indio_dev,
952                                       const struct iio_chan_spec *chan,
953                                       enum iio_event_type type,
954                                       enum iio_event_direction dir)
955 {
956         int ret;
957         struct vcnl4000_data *data = iio_priv(indio_dev);
958
959         ret = i2c_smbus_read_word_data(data->client, VCNL4200_PS_CONF1);
960         if (ret < 0)
961                 return ret;
962
963         data->ps_int = FIELD_GET(VCNL4040_PS_CONF2_PS_INT, ret);
964
965         return (dir == IIO_EV_DIR_RISING) ?
966                 FIELD_GET(VCNL4040_PS_IF_AWAY, ret) :
967                 FIELD_GET(VCNL4040_PS_IF_CLOSE, ret);
968 }
969
970 static int vcnl4040_write_event_config(struct iio_dev *indio_dev,
971                                        const struct iio_chan_spec *chan,
972                                        enum iio_event_type type,
973                                        enum iio_event_direction dir, int state)
974 {
975         int ret;
976         u16 val, mask;
977         struct vcnl4000_data *data = iio_priv(indio_dev);
978
979         mutex_lock(&data->vcnl4000_lock);
980
981         ret = i2c_smbus_read_word_data(data->client, VCNL4200_PS_CONF1);
982         if (ret < 0)
983                 goto out;
984
985         if (dir == IIO_EV_DIR_RISING)
986                 mask = VCNL4040_PS_IF_AWAY;
987         else
988                 mask = VCNL4040_PS_IF_CLOSE;
989
990         val = state ? (ret | mask) : (ret & ~mask);
991
992         data->ps_int = FIELD_GET(VCNL4040_PS_CONF2_PS_INT, val);
993         ret = i2c_smbus_write_word_data(data->client, VCNL4200_PS_CONF1, val);
994
995 out:
996         mutex_unlock(&data->vcnl4000_lock);
997         data->chip_spec->set_power_state(data, data->ps_int != 0);
998
999         return ret;
1000 }
1001
1002 static irqreturn_t vcnl4040_irq_thread(int irq, void *p)
1003 {
1004         struct iio_dev *indio_dev = p;
1005         struct vcnl4000_data *data = iio_priv(indio_dev);
1006         int ret;
1007
1008         ret = i2c_smbus_read_word_data(data->client, VCNL4040_INT_FLAGS);
1009         if (ret < 0)
1010                 return IRQ_HANDLED;
1011
1012         if (ret & VCNL4040_PS_IF_CLOSE) {
1013                 iio_push_event(indio_dev,
1014                                IIO_UNMOD_EVENT_CODE(IIO_PROXIMITY, 0,
1015                                                     IIO_EV_TYPE_THRESH,
1016                                                     IIO_EV_DIR_RISING),
1017                                iio_get_time_ns(indio_dev));
1018         }
1019
1020         if (ret & VCNL4040_PS_IF_AWAY) {
1021                 iio_push_event(indio_dev,
1022                                IIO_UNMOD_EVENT_CODE(IIO_PROXIMITY, 0,
1023                                                     IIO_EV_TYPE_THRESH,
1024                                                     IIO_EV_DIR_FALLING),
1025                                iio_get_time_ns(indio_dev));
1026         }
1027
1028         return IRQ_HANDLED;
1029 }
1030
1031 static ssize_t vcnl4000_read_near_level(struct iio_dev *indio_dev,
1032                                         uintptr_t priv,
1033                                         const struct iio_chan_spec *chan,
1034                                         char *buf)
1035 {
1036         struct vcnl4000_data *data = iio_priv(indio_dev);
1037
1038         return sprintf(buf, "%u\n", data->near_level);
1039 }
1040
1041 static irqreturn_t vcnl4010_irq_thread(int irq, void *p)
1042 {
1043         struct iio_dev *indio_dev = p;
1044         struct vcnl4000_data *data = iio_priv(indio_dev);
1045         unsigned long isr;
1046         int ret;
1047
1048         ret = i2c_smbus_read_byte_data(data->client, VCNL4010_ISR);
1049         if (ret < 0)
1050                 goto end;
1051
1052         isr = ret;
1053
1054         if (isr & VCNL4010_INT_THR) {
1055                 if (test_bit(VCNL4010_INT_THR_LOW, &isr)) {
1056                         iio_push_event(indio_dev,
1057                                        IIO_UNMOD_EVENT_CODE(
1058                                                IIO_PROXIMITY,
1059                                                1,
1060                                                IIO_EV_TYPE_THRESH,
1061                                                IIO_EV_DIR_FALLING),
1062                                        iio_get_time_ns(indio_dev));
1063                 }
1064
1065                 if (test_bit(VCNL4010_INT_THR_HIGH, &isr)) {
1066                         iio_push_event(indio_dev,
1067                                        IIO_UNMOD_EVENT_CODE(
1068                                                IIO_PROXIMITY,
1069                                                1,
1070                                                IIO_EV_TYPE_THRESH,
1071                                                IIO_EV_DIR_RISING),
1072                                        iio_get_time_ns(indio_dev));
1073                 }
1074
1075                 i2c_smbus_write_byte_data(data->client, VCNL4010_ISR,
1076                                           isr & VCNL4010_INT_THR);
1077         }
1078
1079         if (isr & VCNL4010_INT_DRDY && iio_buffer_enabled(indio_dev))
1080                 iio_trigger_poll_nested(indio_dev->trig);
1081
1082 end:
1083         return IRQ_HANDLED;
1084 }
1085
1086 static irqreturn_t vcnl4010_trigger_handler(int irq, void *p)
1087 {
1088         struct iio_poll_func *pf = p;
1089         struct iio_dev *indio_dev = pf->indio_dev;
1090         struct vcnl4000_data *data = iio_priv(indio_dev);
1091         const unsigned long *active_scan_mask = indio_dev->active_scan_mask;
1092         u16 buffer[8] __aligned(8) = {0}; /* 1x16-bit + naturally aligned ts */
1093         bool data_read = false;
1094         unsigned long isr;
1095         int val = 0;
1096         int ret;
1097
1098         ret = i2c_smbus_read_byte_data(data->client, VCNL4010_ISR);
1099         if (ret < 0)
1100                 goto end;
1101
1102         isr = ret;
1103
1104         if (test_bit(0, active_scan_mask)) {
1105                 if (test_bit(VCNL4010_INT_PROXIMITY, &isr)) {
1106                         ret = vcnl4000_read_data(data,
1107                                                  VCNL4000_PS_RESULT_HI,
1108                                                  &val);
1109                         if (ret < 0)
1110                                 goto end;
1111
1112                         buffer[0] = val;
1113                         data_read = true;
1114                 }
1115         }
1116
1117         ret = i2c_smbus_write_byte_data(data->client, VCNL4010_ISR,
1118                                         isr & VCNL4010_INT_DRDY);
1119         if (ret < 0)
1120                 goto end;
1121
1122         if (!data_read)
1123                 goto end;
1124
1125         iio_push_to_buffers_with_timestamp(indio_dev, buffer,
1126                                            iio_get_time_ns(indio_dev));
1127
1128 end:
1129         iio_trigger_notify_done(indio_dev->trig);
1130         return IRQ_HANDLED;
1131 }
1132
1133 static int vcnl4010_buffer_postenable(struct iio_dev *indio_dev)
1134 {
1135         struct vcnl4000_data *data = iio_priv(indio_dev);
1136         int ret;
1137         int cmd;
1138
1139         /* Do not enable the buffer if we are already capturing events. */
1140         if (vcnl4010_is_in_periodic_mode(data))
1141                 return -EBUSY;
1142
1143         ret = i2c_smbus_write_byte_data(data->client, VCNL4010_INT_CTRL,
1144                                         VCNL4010_INT_PROX_EN);
1145         if (ret < 0)
1146                 return ret;
1147
1148         cmd = VCNL4000_SELF_TIMED_EN | VCNL4000_PROX_EN;
1149         return i2c_smbus_write_byte_data(data->client, VCNL4000_COMMAND, cmd);
1150 }
1151
1152 static int vcnl4010_buffer_predisable(struct iio_dev *indio_dev)
1153 {
1154         struct vcnl4000_data *data = iio_priv(indio_dev);
1155         int ret;
1156
1157         ret = i2c_smbus_write_byte_data(data->client, VCNL4010_INT_CTRL, 0);
1158         if (ret < 0)
1159                 return ret;
1160
1161         return i2c_smbus_write_byte_data(data->client, VCNL4000_COMMAND, 0);
1162 }
1163
1164 static const struct iio_buffer_setup_ops vcnl4010_buffer_ops = {
1165         .postenable = &vcnl4010_buffer_postenable,
1166         .predisable = &vcnl4010_buffer_predisable,
1167 };
1168
1169 static const struct iio_chan_spec_ext_info vcnl4000_ext_info[] = {
1170         {
1171                 .name = "nearlevel",
1172                 .shared = IIO_SEPARATE,
1173                 .read = vcnl4000_read_near_level,
1174         },
1175         { /* sentinel */ }
1176 };
1177
1178 static const struct iio_event_spec vcnl4000_event_spec[] = {
1179         {
1180                 .type = IIO_EV_TYPE_THRESH,
1181                 .dir = IIO_EV_DIR_RISING,
1182                 .mask_separate = BIT(IIO_EV_INFO_VALUE),
1183         }, {
1184                 .type = IIO_EV_TYPE_THRESH,
1185                 .dir = IIO_EV_DIR_FALLING,
1186                 .mask_separate = BIT(IIO_EV_INFO_VALUE),
1187         }, {
1188                 .type = IIO_EV_TYPE_THRESH,
1189                 .dir = IIO_EV_DIR_EITHER,
1190                 .mask_separate = BIT(IIO_EV_INFO_ENABLE),
1191         }
1192 };
1193
1194 static const struct iio_event_spec vcnl4040_event_spec[] = {
1195         {
1196                 .type = IIO_EV_TYPE_THRESH,
1197                 .dir = IIO_EV_DIR_RISING,
1198                 .mask_separate = BIT(IIO_EV_INFO_VALUE) | BIT(IIO_EV_INFO_ENABLE),
1199         }, {
1200                 .type = IIO_EV_TYPE_THRESH,
1201                 .dir = IIO_EV_DIR_FALLING,
1202                 .mask_separate = BIT(IIO_EV_INFO_VALUE) | BIT(IIO_EV_INFO_ENABLE),
1203         },
1204 };
1205
1206 static const struct iio_chan_spec vcnl4000_channels[] = {
1207         {
1208                 .type = IIO_LIGHT,
1209                 .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
1210                         BIT(IIO_CHAN_INFO_SCALE),
1211         }, {
1212                 .type = IIO_PROXIMITY,
1213                 .info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
1214                 .ext_info = vcnl4000_ext_info,
1215         }
1216 };
1217
1218 static const struct iio_chan_spec vcnl4010_channels[] = {
1219         {
1220                 .type = IIO_LIGHT,
1221                 .scan_index = -1,
1222                 .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
1223                         BIT(IIO_CHAN_INFO_SCALE),
1224         }, {
1225                 .type = IIO_PROXIMITY,
1226                 .scan_index = 0,
1227                 .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
1228                         BIT(IIO_CHAN_INFO_SAMP_FREQ),
1229                 .info_mask_separate_available = BIT(IIO_CHAN_INFO_SAMP_FREQ),
1230                 .event_spec = vcnl4000_event_spec,
1231                 .num_event_specs = ARRAY_SIZE(vcnl4000_event_spec),
1232                 .ext_info = vcnl4000_ext_info,
1233                 .scan_type = {
1234                         .sign = 'u',
1235                         .realbits = 16,
1236                         .storagebits = 16,
1237                         .endianness = IIO_CPU,
1238                 },
1239         },
1240         IIO_CHAN_SOFT_TIMESTAMP(1),
1241 };
1242
1243 static const struct iio_chan_spec vcnl4040_channels[] = {
1244         {
1245                 .type = IIO_LIGHT,
1246                 .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
1247                         BIT(IIO_CHAN_INFO_SCALE),
1248         }, {
1249                 .type = IIO_PROXIMITY,
1250                 .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
1251                         BIT(IIO_CHAN_INFO_INT_TIME),
1252                 .info_mask_separate_available = BIT(IIO_CHAN_INFO_INT_TIME),
1253                 .ext_info = vcnl4000_ext_info,
1254                 .event_spec = vcnl4040_event_spec,
1255                 .num_event_specs = ARRAY_SIZE(vcnl4040_event_spec),
1256         }
1257 };
1258
1259 static const struct iio_info vcnl4000_info = {
1260         .read_raw = vcnl4000_read_raw,
1261 };
1262
1263 static const struct iio_info vcnl4010_info = {
1264         .read_raw = vcnl4010_read_raw,
1265         .read_avail = vcnl4010_read_avail,
1266         .write_raw = vcnl4010_write_raw,
1267         .read_event_value = vcnl4010_read_event,
1268         .write_event_value = vcnl4010_write_event,
1269         .read_event_config = vcnl4010_read_event_config,
1270         .write_event_config = vcnl4010_write_event_config,
1271 };
1272
1273 static const struct iio_info vcnl4040_info = {
1274         .read_raw = vcnl4000_read_raw,
1275         .write_raw = vcnl4040_write_raw,
1276         .read_event_value = vcnl4040_read_event,
1277         .write_event_value = vcnl4040_write_event,
1278         .read_event_config = vcnl4040_read_event_config,
1279         .write_event_config = vcnl4040_write_event_config,
1280         .read_avail = vcnl4040_read_avail,
1281 };
1282
1283 static const struct vcnl4000_chip_spec vcnl4000_chip_spec_cfg[] = {
1284         [VCNL4000] = {
1285                 .prod = "VCNL4000",
1286                 .init = vcnl4000_init,
1287                 .measure_light = vcnl4000_measure_light,
1288                 .measure_proximity = vcnl4000_measure_proximity,
1289                 .set_power_state = vcnl4000_set_power_state,
1290                 .channels = vcnl4000_channels,
1291                 .num_channels = ARRAY_SIZE(vcnl4000_channels),
1292                 .info = &vcnl4000_info,
1293         },
1294         [VCNL4010] = {
1295                 .prod = "VCNL4010/4020",
1296                 .init = vcnl4000_init,
1297                 .measure_light = vcnl4000_measure_light,
1298                 .measure_proximity = vcnl4000_measure_proximity,
1299                 .set_power_state = vcnl4000_set_power_state,
1300                 .channels = vcnl4010_channels,
1301                 .num_channels = ARRAY_SIZE(vcnl4010_channels),
1302                 .info = &vcnl4010_info,
1303                 .irq_thread = vcnl4010_irq_thread,
1304                 .trig_buffer_func = vcnl4010_trigger_handler,
1305                 .buffer_setup_ops = &vcnl4010_buffer_ops,
1306         },
1307         [VCNL4040] = {
1308                 .prod = "VCNL4040",
1309                 .init = vcnl4200_init,
1310                 .measure_light = vcnl4200_measure_light,
1311                 .measure_proximity = vcnl4200_measure_proximity,
1312                 .set_power_state = vcnl4200_set_power_state,
1313                 .channels = vcnl4040_channels,
1314                 .num_channels = ARRAY_SIZE(vcnl4040_channels),
1315                 .info = &vcnl4040_info,
1316                 .irq_thread = vcnl4040_irq_thread,
1317         },
1318         [VCNL4200] = {
1319                 .prod = "VCNL4200",
1320                 .init = vcnl4200_init,
1321                 .measure_light = vcnl4200_measure_light,
1322                 .measure_proximity = vcnl4200_measure_proximity,
1323                 .set_power_state = vcnl4200_set_power_state,
1324                 .channels = vcnl4000_channels,
1325                 .num_channels = ARRAY_SIZE(vcnl4000_channels),
1326                 .info = &vcnl4000_info,
1327         },
1328 };
1329
1330 static const struct iio_trigger_ops vcnl4010_trigger_ops = {
1331         .validate_device = iio_trigger_validate_own_device,
1332 };
1333
1334 static int vcnl4010_probe_trigger(struct iio_dev *indio_dev)
1335 {
1336         struct vcnl4000_data *data = iio_priv(indio_dev);
1337         struct i2c_client *client = data->client;
1338         struct iio_trigger *trigger;
1339
1340         trigger = devm_iio_trigger_alloc(&client->dev, "%s-dev%d",
1341                                          indio_dev->name,
1342                                          iio_device_id(indio_dev));
1343         if (!trigger)
1344                 return -ENOMEM;
1345
1346         trigger->ops = &vcnl4010_trigger_ops;
1347         iio_trigger_set_drvdata(trigger, indio_dev);
1348
1349         return devm_iio_trigger_register(&client->dev, trigger);
1350 }
1351
1352 static int vcnl4000_probe(struct i2c_client *client)
1353 {
1354         const struct i2c_device_id *id = i2c_client_get_device_id(client);
1355         struct vcnl4000_data *data;
1356         struct iio_dev *indio_dev;
1357         int ret;
1358
1359         indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*data));
1360         if (!indio_dev)
1361                 return -ENOMEM;
1362
1363         data = iio_priv(indio_dev);
1364         i2c_set_clientdata(client, indio_dev);
1365         data->client = client;
1366         data->id = id->driver_data;
1367         data->chip_spec = &vcnl4000_chip_spec_cfg[data->id];
1368
1369         mutex_init(&data->vcnl4000_lock);
1370
1371         ret = data->chip_spec->init(data);
1372         if (ret < 0)
1373                 return ret;
1374
1375         dev_dbg(&client->dev, "%s Ambient light/proximity sensor, Rev: %02x\n",
1376                 data->chip_spec->prod, data->rev);
1377
1378         if (device_property_read_u32(&client->dev, "proximity-near-level",
1379                                      &data->near_level))
1380                 data->near_level = 0;
1381
1382         indio_dev->info = data->chip_spec->info;
1383         indio_dev->channels = data->chip_spec->channels;
1384         indio_dev->num_channels = data->chip_spec->num_channels;
1385         indio_dev->name = VCNL4000_DRV_NAME;
1386         indio_dev->modes = INDIO_DIRECT_MODE;
1387
1388         if (data->chip_spec->trig_buffer_func &&
1389             data->chip_spec->buffer_setup_ops) {
1390                 ret = devm_iio_triggered_buffer_setup(&client->dev, indio_dev,
1391                                                       NULL,
1392                                                       data->chip_spec->trig_buffer_func,
1393                                                       data->chip_spec->buffer_setup_ops);
1394                 if (ret < 0) {
1395                         dev_err(&client->dev,
1396                                 "unable to setup iio triggered buffer\n");
1397                         return ret;
1398                 }
1399         }
1400
1401         if (client->irq && data->chip_spec->irq_thread) {
1402                 ret = devm_request_threaded_irq(&client->dev, client->irq,
1403                                                 NULL, data->chip_spec->irq_thread,
1404                                                 IRQF_TRIGGER_FALLING |
1405                                                 IRQF_ONESHOT,
1406                                                 "vcnl4000_irq",
1407                                                 indio_dev);
1408                 if (ret < 0) {
1409                         dev_err(&client->dev, "irq request failed\n");
1410                         return ret;
1411                 }
1412
1413                 ret = vcnl4010_probe_trigger(indio_dev);
1414                 if (ret < 0)
1415                         return ret;
1416         }
1417
1418         ret = pm_runtime_set_active(&client->dev);
1419         if (ret < 0)
1420                 goto fail_poweroff;
1421
1422         ret = iio_device_register(indio_dev);
1423         if (ret < 0)
1424                 goto fail_poweroff;
1425
1426         pm_runtime_enable(&client->dev);
1427         pm_runtime_set_autosuspend_delay(&client->dev, VCNL4000_SLEEP_DELAY_MS);
1428         pm_runtime_use_autosuspend(&client->dev);
1429
1430         return 0;
1431 fail_poweroff:
1432         data->chip_spec->set_power_state(data, false);
1433         return ret;
1434 }
1435
1436 static const struct of_device_id vcnl_4000_of_match[] = {
1437         {
1438                 .compatible = "vishay,vcnl4000",
1439                 .data = (void *)VCNL4000,
1440         },
1441         {
1442                 .compatible = "vishay,vcnl4010",
1443                 .data = (void *)VCNL4010,
1444         },
1445         {
1446                 .compatible = "vishay,vcnl4020",
1447                 .data = (void *)VCNL4010,
1448         },
1449         {
1450                 .compatible = "vishay,vcnl4040",
1451                 .data = (void *)VCNL4040,
1452         },
1453         {
1454                 .compatible = "vishay,vcnl4200",
1455                 .data = (void *)VCNL4200,
1456         },
1457         {},
1458 };
1459 MODULE_DEVICE_TABLE(of, vcnl_4000_of_match);
1460
1461 static void vcnl4000_remove(struct i2c_client *client)
1462 {
1463         struct iio_dev *indio_dev = i2c_get_clientdata(client);
1464         struct vcnl4000_data *data = iio_priv(indio_dev);
1465         int ret;
1466
1467         pm_runtime_dont_use_autosuspend(&client->dev);
1468         pm_runtime_disable(&client->dev);
1469         iio_device_unregister(indio_dev);
1470         pm_runtime_set_suspended(&client->dev);
1471
1472         ret = data->chip_spec->set_power_state(data, false);
1473         if (ret)
1474                 dev_warn(&client->dev, "Failed to power down (%pe)\n",
1475                          ERR_PTR(ret));
1476 }
1477
1478 static int vcnl4000_runtime_suspend(struct device *dev)
1479 {
1480         struct iio_dev *indio_dev = i2c_get_clientdata(to_i2c_client(dev));
1481         struct vcnl4000_data *data = iio_priv(indio_dev);
1482
1483         return data->chip_spec->set_power_state(data, false);
1484 }
1485
1486 static int vcnl4000_runtime_resume(struct device *dev)
1487 {
1488         struct iio_dev *indio_dev = i2c_get_clientdata(to_i2c_client(dev));
1489         struct vcnl4000_data *data = iio_priv(indio_dev);
1490
1491         return data->chip_spec->set_power_state(data, true);
1492 }
1493
1494 static DEFINE_RUNTIME_DEV_PM_OPS(vcnl4000_pm_ops, vcnl4000_runtime_suspend,
1495                                  vcnl4000_runtime_resume, NULL);
1496
1497 static struct i2c_driver vcnl4000_driver = {
1498         .driver = {
1499                 .name   = VCNL4000_DRV_NAME,
1500                 .pm     = pm_ptr(&vcnl4000_pm_ops),
1501                 .of_match_table = vcnl_4000_of_match,
1502         },
1503         .probe_new = vcnl4000_probe,
1504         .id_table = vcnl4000_id,
1505         .remove = vcnl4000_remove,
1506 };
1507
1508 module_i2c_driver(vcnl4000_driver);
1509
1510 MODULE_AUTHOR("Peter Meerwald <[email protected]>");
1511 MODULE_AUTHOR("Mathieu Othacehe <[email protected]>");
1512 MODULE_DESCRIPTION("Vishay VCNL4000 proximity/ambient light sensor driver");
1513 MODULE_LICENSE("GPL");
This page took 0.118322 seconds and 4 git commands to generate.