1 // SPDX-License-Identifier: GPL-2.0-only
3 * vcnl4000.c - Support for Vishay VCNL4000/4010/4020/4040/4200 combined ambient
4 * light and proximity sensor
6 * Copyright 2012 Peter Meerwald <pmeerw@pmeerw.net>
7 * Copyright 2019 Pursim SPC
8 * Copyright 2020 Mathieu Othacehe <m.othacehe@gmail.com>
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)
16 * allow to adjust IR current
17 * interrupts (VCNL4040, VCNL4200)
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 #include <linux/units.h>
29 #include <linux/iio/buffer.h>
30 #include <linux/iio/events.h>
31 #include <linux/iio/iio.h>
32 #include <linux/iio/sysfs.h>
33 #include <linux/iio/trigger.h>
34 #include <linux/iio/trigger_consumer.h>
35 #include <linux/iio/triggered_buffer.h>
37 #define VCNL4000_DRV_NAME "vcnl4000"
38 #define VCNL4000_PROD_ID 0x01
39 #define VCNL4010_PROD_ID 0x02 /* for VCNL4020, VCNL4010 */
40 #define VCNL4040_PROD_ID 0x86
41 #define VCNL4200_PROD_ID 0x58
43 #define VCNL4000_COMMAND 0x80 /* Command register */
44 #define VCNL4000_PROD_REV 0x81 /* Product ID and Revision ID */
45 #define VCNL4010_PROX_RATE 0x82 /* Proximity rate */
46 #define VCNL4000_LED_CURRENT 0x83 /* IR LED current for proximity mode */
47 #define VCNL4000_AL_PARAM 0x84 /* Ambient light parameter register */
48 #define VCNL4010_ALS_PARAM 0x84 /* ALS rate */
49 #define VCNL4000_AL_RESULT_HI 0x85 /* Ambient light result register, MSB */
50 #define VCNL4000_AL_RESULT_LO 0x86 /* Ambient light result register, LSB */
51 #define VCNL4000_PS_RESULT_HI 0x87 /* Proximity result register, MSB */
52 #define VCNL4000_PS_RESULT_LO 0x88 /* Proximity result register, LSB */
53 #define VCNL4000_PS_MEAS_FREQ 0x89 /* Proximity test signal frequency */
54 #define VCNL4010_INT_CTRL 0x89 /* Interrupt control */
55 #define VCNL4000_PS_MOD_ADJ 0x8a /* Proximity modulator timing adjustment */
56 #define VCNL4010_LOW_THR_HI 0x8a /* Low threshold, MSB */
57 #define VCNL4010_LOW_THR_LO 0x8b /* Low threshold, LSB */
58 #define VCNL4010_HIGH_THR_HI 0x8c /* High threshold, MSB */
59 #define VCNL4010_HIGH_THR_LO 0x8d /* High threshold, LSB */
60 #define VCNL4010_ISR 0x8e /* Interrupt status */
62 #define VCNL4200_AL_CONF 0x00 /* Ambient light configuration */
63 #define VCNL4200_PS_CONF1 0x03 /* Proximity configuration */
64 #define VCNL4200_PS_CONF3 0x04 /* Proximity configuration */
65 #define VCNL4040_PS_THDL_LM 0x06 /* Proximity threshold low */
66 #define VCNL4040_PS_THDH_LM 0x07 /* Proximity threshold high */
67 #define VCNL4040_ALS_THDL_LM 0x02 /* Ambient light threshold low */
68 #define VCNL4040_ALS_THDH_LM 0x01 /* Ambient light threshold high */
69 #define VCNL4200_PS_DATA 0x08 /* Proximity data */
70 #define VCNL4200_AL_DATA 0x09 /* Ambient light data */
71 #define VCNL4040_INT_FLAGS 0x0b /* Interrupt register */
72 #define VCNL4200_INT_FLAGS 0x0d /* Interrupt register */
73 #define VCNL4200_DEV_ID 0x0e /* Device ID, slave address and version */
75 #define VCNL4040_DEV_ID 0x0c /* Device ID and version */
77 /* Bit masks for COMMAND register */
78 #define VCNL4000_AL_RDY BIT(6) /* ALS data ready? */
79 #define VCNL4000_PS_RDY BIT(5) /* proximity data ready? */
80 #define VCNL4000_AL_OD BIT(4) /* start on-demand ALS measurement */
81 #define VCNL4000_PS_OD BIT(3) /* start on-demand proximity measurement */
82 #define VCNL4000_ALS_EN BIT(2) /* start ALS measurement */
83 #define VCNL4000_PROX_EN BIT(1) /* start proximity measurement */
84 #define VCNL4000_SELF_TIMED_EN BIT(0) /* start self-timed measurement */
86 #define VCNL4040_ALS_CONF_ALS_SHUTDOWN BIT(0)
87 #define VCNL4040_ALS_CONF_IT GENMASK(7, 6) /* Ambient integration time */
88 #define VCNL4040_ALS_CONF_INT_EN BIT(1) /* Ambient light Interrupt enable */
89 #define VCNL4040_ALS_CONF_PERS GENMASK(3, 2) /* Ambient interrupt persistence setting */
90 #define VCNL4040_PS_CONF1_PS_SHUTDOWN BIT(0)
91 #define VCNL4040_PS_CONF2_PS_IT GENMASK(3, 1) /* Proximity integration time */
92 #define VCNL4040_CONF1_PS_PERS GENMASK(5, 4) /* Proximity interrupt persistence setting */
93 #define VCNL4040_PS_CONF2_PS_HD BIT(11) /* Proximity high definition */
94 #define VCNL4040_PS_CONF2_PS_INT GENMASK(9, 8) /* Proximity interrupt mode */
95 #define VCNL4040_PS_CONF3_MPS GENMASK(6, 5) /* Proximity multi pulse number */
96 #define VCNL4040_PS_MS_LED_I GENMASK(10, 8) /* Proximity current */
97 #define VCNL4040_PS_IF_AWAY BIT(8) /* Proximity event cross low threshold */
98 #define VCNL4040_PS_IF_CLOSE BIT(9) /* Proximity event cross high threshold */
99 #define VCNL4040_ALS_RISING BIT(12) /* Ambient Light cross high threshold */
100 #define VCNL4040_ALS_FALLING BIT(13) /* Ambient Light cross low threshold */
102 /* Bit masks for interrupt registers. */
103 #define VCNL4010_INT_THR_SEL BIT(0) /* Select threshold interrupt source */
104 #define VCNL4010_INT_THR_EN BIT(1) /* Threshold interrupt type */
105 #define VCNL4010_INT_ALS_EN BIT(2) /* Enable on ALS data ready */
106 #define VCNL4010_INT_PROX_EN BIT(3) /* Enable on proximity data ready */
108 #define VCNL4010_INT_THR_HIGH 0 /* High threshold exceeded */
109 #define VCNL4010_INT_THR_LOW 1 /* Low threshold exceeded */
110 #define VCNL4010_INT_ALS 2 /* ALS data ready */
111 #define VCNL4010_INT_PROXIMITY 3 /* Proximity data ready */
113 #define VCNL4010_INT_THR \
114 (BIT(VCNL4010_INT_THR_LOW) | BIT(VCNL4010_INT_THR_HIGH))
115 #define VCNL4010_INT_DRDY \
116 (BIT(VCNL4010_INT_PROXIMITY) | BIT(VCNL4010_INT_ALS))
118 #define VCNL4040_CONF3_PS_MPS_16BITS 3 /* 8 multi pulses */
119 #define VCNL4040_CONF3_PS_LED_I_16BITS 3 /* 120 mA */
121 #define VCNL4040_CONF3_PS_SAMPLE_16BITS \
122 (FIELD_PREP(VCNL4040_PS_CONF3_MPS, VCNL4040_CONF3_PS_MPS_16BITS) | \
123 FIELD_PREP(VCNL4040_PS_MS_LED_I, VCNL4040_CONF3_PS_LED_I_16BITS))
125 static const int vcnl4010_prox_sampling_frequency[][2] = {
136 static const int vcnl4040_ps_it_times[][2] = {
147 static const int vcnl4200_ps_it_times[][2] = {
156 static const int vcnl4040_als_it_times[][2] = {
163 static const int vcnl4200_als_it_times[][2] = {
170 static const int vcnl4040_ps_calibbias_ua[][2] = {
181 static const int vcnl4040_als_persistence[] = {1, 2, 4, 8};
182 static const int vcnl4040_ps_persistence[] = {1, 2, 3, 4};
183 static const int vcnl4040_ps_oversampling_ratio[] = {1, 2, 4, 8};
185 #define VCNL4000_SLEEP_DELAY_MS 2000 /* before we enter pm_runtime_suspend */
187 enum vcnl4000_device_ids {
194 struct vcnl4200_channel {
196 ktime_t last_measurement;
197 ktime_t sampling_rate;
201 struct vcnl4000_data {
202 struct i2c_client *client;
203 enum vcnl4000_device_ids id;
207 u8 ps_int; /* proximity interrupt mode */
208 u8 als_int; /* ambient light interrupt mode*/
209 const struct vcnl4000_chip_spec *chip_spec;
210 struct mutex vcnl4000_lock;
211 struct vcnl4200_channel vcnl4200_al;
212 struct vcnl4200_channel vcnl4200_ps;
216 struct vcnl4000_chip_spec {
218 struct iio_chan_spec const *channels;
219 const int num_channels;
220 const struct iio_info *info;
221 const struct iio_buffer_setup_ops *buffer_setup_ops;
222 int (*init)(struct vcnl4000_data *data);
223 int (*measure_light)(struct vcnl4000_data *data, int *val);
224 int (*measure_proximity)(struct vcnl4000_data *data, int *val);
225 int (*set_power_state)(struct vcnl4000_data *data, bool on);
226 irqreturn_t (*irq_thread)(int irq, void *priv);
227 irqreturn_t (*trig_buffer_func)(int irq, void *priv);
230 const int(*ps_it_times)[][2];
231 const int num_ps_it_times;
232 const int(*als_it_times)[][2];
233 const int num_als_it_times;
234 const unsigned int ulux_step;
237 static const struct i2c_device_id vcnl4000_id[] = {
238 { "vcnl4000", VCNL4000 },
239 { "vcnl4010", VCNL4010 },
240 { "vcnl4020", VCNL4010 },
241 { "vcnl4040", VCNL4040 },
242 { "vcnl4200", VCNL4200 },
245 MODULE_DEVICE_TABLE(i2c, vcnl4000_id);
247 static int vcnl4000_set_power_state(struct vcnl4000_data *data, bool on)
253 static int vcnl4000_init(struct vcnl4000_data *data)
257 ret = i2c_smbus_read_byte_data(data->client, VCNL4000_PROD_REV);
263 case VCNL4000_PROD_ID:
264 if (data->id != VCNL4000)
265 dev_warn(&data->client->dev,
266 "wrong device id, use vcnl4000");
268 case VCNL4010_PROD_ID:
269 if (data->id != VCNL4010)
270 dev_warn(&data->client->dev,
271 "wrong device id, use vcnl4010/4020");
277 data->rev = ret & 0xf;
278 data->al_scale = 250000;
280 return data->chip_spec->set_power_state(data, true);
283 static ssize_t vcnl4000_write_als_enable(struct vcnl4000_data *data, bool en)
287 mutex_lock(&data->vcnl4000_lock);
289 ret = i2c_smbus_read_word_data(data->client, VCNL4200_AL_CONF);
294 ret &= ~VCNL4040_ALS_CONF_ALS_SHUTDOWN;
296 ret |= VCNL4040_ALS_CONF_ALS_SHUTDOWN;
298 ret = i2c_smbus_write_word_data(data->client, VCNL4200_AL_CONF, ret);
301 mutex_unlock(&data->vcnl4000_lock);
306 static ssize_t vcnl4000_write_ps_enable(struct vcnl4000_data *data, bool en)
310 mutex_lock(&data->vcnl4000_lock);
312 ret = i2c_smbus_read_word_data(data->client, VCNL4200_PS_CONF1);
317 ret &= ~VCNL4040_PS_CONF1_PS_SHUTDOWN;
319 ret |= VCNL4040_PS_CONF1_PS_SHUTDOWN;
321 ret = i2c_smbus_write_word_data(data->client, VCNL4200_PS_CONF1, ret);
324 mutex_unlock(&data->vcnl4000_lock);
329 static int vcnl4200_set_power_state(struct vcnl4000_data *data, bool on)
333 /* Do not power down if interrupts are enabled */
334 if (!on && (data->ps_int || data->als_int))
337 ret = vcnl4000_write_als_enable(data, on);
341 ret = vcnl4000_write_ps_enable(data, on);
346 /* Wait at least one integration cycle before fetching data */
347 data->vcnl4200_al.last_measurement = ktime_get();
348 data->vcnl4200_ps.last_measurement = ktime_get();
354 static int vcnl4200_init(struct vcnl4000_data *data)
359 ret = i2c_smbus_read_word_data(data->client, VCNL4200_DEV_ID);
365 if (id != VCNL4200_PROD_ID) {
366 ret = i2c_smbus_read_word_data(data->client, VCNL4040_DEV_ID);
372 if (id != VCNL4040_PROD_ID)
376 dev_dbg(&data->client->dev, "device id 0x%x", id);
378 data->rev = (ret >> 8) & 0xf;
382 data->vcnl4200_al.reg = VCNL4200_AL_DATA;
383 data->vcnl4200_ps.reg = VCNL4200_PS_DATA;
385 case VCNL4200_PROD_ID:
386 /* Default wait time is 50ms, add 20% tolerance. */
387 data->vcnl4200_al.sampling_rate = ktime_set(0, 60000 * 1000);
388 /* Default wait time is 4.8ms, add 20% tolerance. */
389 data->vcnl4200_ps.sampling_rate = ktime_set(0, 5760 * 1000);
391 case VCNL4040_PROD_ID:
392 /* Default wait time is 80ms, add 20% tolerance. */
393 data->vcnl4200_al.sampling_rate = ktime_set(0, 96000 * 1000);
394 /* Default wait time is 5ms, add 20% tolerance. */
395 data->vcnl4200_ps.sampling_rate = ktime_set(0, 6000 * 1000);
398 data->al_scale = data->chip_spec->ulux_step;
400 mutex_init(&data->vcnl4200_al.lock);
401 mutex_init(&data->vcnl4200_ps.lock);
403 /* Use 16 bits proximity sensor readings */
404 ret = i2c_smbus_read_word_data(data->client, VCNL4200_PS_CONF1);
408 regval = ret | VCNL4040_PS_CONF2_PS_HD;
409 ret = i2c_smbus_write_word_data(data->client, VCNL4200_PS_CONF1,
414 /* Align proximity sensor sample rate to 16 bits data width */
415 ret = i2c_smbus_read_word_data(data->client, VCNL4200_PS_CONF3);
419 regval = ret | VCNL4040_CONF3_PS_SAMPLE_16BITS;
420 ret = i2c_smbus_write_word_data(data->client, VCNL4200_PS_CONF3,
425 ret = data->chip_spec->set_power_state(data, true);
432 static int vcnl4000_read_data(struct vcnl4000_data *data, u8 data_reg, int *val)
436 ret = i2c_smbus_read_word_swapped(data->client, data_reg);
444 static int vcnl4000_write_data(struct vcnl4000_data *data, u8 data_reg, int val)
449 return i2c_smbus_write_word_swapped(data->client, data_reg, val);
453 static int vcnl4000_measure(struct vcnl4000_data *data, u8 req_mask,
454 u8 rdy_mask, u8 data_reg, int *val)
459 mutex_lock(&data->vcnl4000_lock);
461 ret = i2c_smbus_write_byte_data(data->client, VCNL4000_COMMAND,
466 /* wait for data to become ready */
468 ret = i2c_smbus_read_byte_data(data->client, VCNL4000_COMMAND);
473 msleep(20); /* measurement takes up to 100 ms */
477 dev_err(&data->client->dev,
478 "vcnl4000_measure() failed, data not ready\n");
483 ret = vcnl4000_read_data(data, data_reg, val);
487 mutex_unlock(&data->vcnl4000_lock);
492 mutex_unlock(&data->vcnl4000_lock);
496 static int vcnl4200_measure(struct vcnl4000_data *data,
497 struct vcnl4200_channel *chan, int *val)
501 ktime_t next_measurement;
503 mutex_lock(&chan->lock);
505 next_measurement = ktime_add(chan->last_measurement,
506 chan->sampling_rate);
507 delta = ktime_us_delta(next_measurement, ktime_get());
509 usleep_range(delta, delta + 500);
510 chan->last_measurement = ktime_get();
512 mutex_unlock(&chan->lock);
514 ret = i2c_smbus_read_word_data(data->client, chan->reg);
523 static int vcnl4000_measure_light(struct vcnl4000_data *data, int *val)
525 return vcnl4000_measure(data,
526 VCNL4000_AL_OD, VCNL4000_AL_RDY,
527 VCNL4000_AL_RESULT_HI, val);
530 static int vcnl4200_measure_light(struct vcnl4000_data *data, int *val)
532 return vcnl4200_measure(data, &data->vcnl4200_al, val);
535 static int vcnl4000_measure_proximity(struct vcnl4000_data *data, int *val)
537 return vcnl4000_measure(data,
538 VCNL4000_PS_OD, VCNL4000_PS_RDY,
539 VCNL4000_PS_RESULT_HI, val);
542 static int vcnl4200_measure_proximity(struct vcnl4000_data *data, int *val)
544 return vcnl4200_measure(data, &data->vcnl4200_ps, val);
547 static int vcnl4010_read_proxy_samp_freq(struct vcnl4000_data *data, int *val,
552 ret = i2c_smbus_read_byte_data(data->client, VCNL4010_PROX_RATE);
556 if (ret >= ARRAY_SIZE(vcnl4010_prox_sampling_frequency))
559 *val = vcnl4010_prox_sampling_frequency[ret][0];
560 *val2 = vcnl4010_prox_sampling_frequency[ret][1];
565 static bool vcnl4010_is_in_periodic_mode(struct vcnl4000_data *data)
569 ret = i2c_smbus_read_byte_data(data->client, VCNL4000_COMMAND);
573 return !!(ret & VCNL4000_SELF_TIMED_EN);
576 static int vcnl4000_set_pm_runtime_state(struct vcnl4000_data *data, bool on)
578 struct device *dev = &data->client->dev;
582 ret = pm_runtime_resume_and_get(dev);
584 pm_runtime_mark_last_busy(dev);
585 ret = pm_runtime_put_autosuspend(dev);
591 static int vcnl4040_read_als_it(struct vcnl4000_data *data, int *val, int *val2)
595 ret = i2c_smbus_read_word_data(data->client, VCNL4200_AL_CONF);
599 ret = FIELD_GET(VCNL4040_ALS_CONF_IT, ret);
600 if (ret >= data->chip_spec->num_als_it_times)
603 *val = (*data->chip_spec->als_it_times)[ret][0];
604 *val2 = (*data->chip_spec->als_it_times)[ret][1];
609 static ssize_t vcnl4040_write_als_it(struct vcnl4000_data *data, int val)
615 for (i = 0; i < data->chip_spec->num_als_it_times; i++) {
616 if (val == (*data->chip_spec->als_it_times)[i][1])
620 if (i == data->chip_spec->num_als_it_times)
623 data->vcnl4200_al.sampling_rate = ktime_set(0, val * 1200);
624 data->al_scale = div_u64(mul_u32_u32(data->chip_spec->ulux_step,
625 (*data->chip_spec->als_it_times)[0][1]),
628 mutex_lock(&data->vcnl4000_lock);
630 ret = i2c_smbus_read_word_data(data->client, VCNL4200_AL_CONF);
634 regval = FIELD_PREP(VCNL4040_ALS_CONF_IT, i);
635 regval |= (ret & ~VCNL4040_ALS_CONF_IT);
636 ret = i2c_smbus_write_word_data(data->client,
641 mutex_unlock(&data->vcnl4000_lock);
645 static int vcnl4040_read_ps_it(struct vcnl4000_data *data, int *val, int *val2)
649 ret = i2c_smbus_read_word_data(data->client, VCNL4200_PS_CONF1);
653 ret = FIELD_GET(VCNL4040_PS_CONF2_PS_IT, ret);
655 if (ret >= data->chip_spec->num_ps_it_times)
658 *val = (*data->chip_spec->ps_it_times)[ret][0];
659 *val2 = (*data->chip_spec->ps_it_times)[ret][1];
664 static ssize_t vcnl4040_write_ps_it(struct vcnl4000_data *data, int val)
670 for (i = 0; i < data->chip_spec->num_ps_it_times; i++) {
671 if (val == (*data->chip_spec->ps_it_times)[i][1]) {
680 data->vcnl4200_ps.sampling_rate = ktime_set(0, val * 60 * NSEC_PER_USEC);
682 mutex_lock(&data->vcnl4000_lock);
684 ret = i2c_smbus_read_word_data(data->client, VCNL4200_PS_CONF1);
688 regval = (ret & ~VCNL4040_PS_CONF2_PS_IT) |
689 FIELD_PREP(VCNL4040_PS_CONF2_PS_IT, index);
690 ret = i2c_smbus_write_word_data(data->client, VCNL4200_PS_CONF1,
694 mutex_unlock(&data->vcnl4000_lock);
698 static ssize_t vcnl4040_read_als_period(struct vcnl4000_data *data, int *val, int *val2)
700 int ret, ret_pers, it;
703 ret = i2c_smbus_read_word_data(data->client, VCNL4200_AL_CONF);
707 ret_pers = FIELD_GET(VCNL4040_ALS_CONF_PERS, ret);
708 if (ret_pers >= ARRAY_SIZE(vcnl4040_als_persistence))
711 it = FIELD_GET(VCNL4040_ALS_CONF_IT, ret);
712 if (it >= data->chip_spec->num_als_it_times)
715 val_c = mul_u32_u32((*data->chip_spec->als_it_times)[it][1],
716 vcnl4040_als_persistence[ret_pers]);
717 *val = div_u64_rem(val_c, MICRO, val2);
719 return IIO_VAL_INT_PLUS_MICRO;
722 static ssize_t vcnl4040_write_als_period(struct vcnl4000_data *data, int val, int val2)
727 u64 val_n = mul_u32_u32(val, MICRO) + val2;
729 ret = i2c_smbus_read_word_data(data->client, VCNL4200_AL_CONF);
733 it = FIELD_GET(VCNL4040_ALS_CONF_IT, ret);
734 if (it >= data->chip_spec->num_als_it_times)
737 for (i = 0; i < ARRAY_SIZE(vcnl4040_als_persistence) - 1; i++) {
738 if (val_n < mul_u32_u32(vcnl4040_als_persistence[i],
739 (*data->chip_spec->als_it_times)[it][1]))
743 mutex_lock(&data->vcnl4000_lock);
745 ret = i2c_smbus_read_word_data(data->client, VCNL4200_AL_CONF);
749 regval = FIELD_PREP(VCNL4040_ALS_CONF_PERS, i);
750 regval |= (ret & ~VCNL4040_ALS_CONF_PERS);
751 ret = i2c_smbus_write_word_data(data->client, VCNL4200_AL_CONF,
755 mutex_unlock(&data->vcnl4000_lock);
759 static ssize_t vcnl4040_read_ps_period(struct vcnl4000_data *data, int *val, int *val2)
761 int ret, ret_pers, it;
763 ret = i2c_smbus_read_word_data(data->client, VCNL4200_PS_CONF1);
767 ret_pers = FIELD_GET(VCNL4040_CONF1_PS_PERS, ret);
768 if (ret_pers >= ARRAY_SIZE(vcnl4040_ps_persistence))
771 it = FIELD_GET(VCNL4040_PS_CONF2_PS_IT, ret);
772 if (it >= data->chip_spec->num_ps_it_times)
775 *val = (*data->chip_spec->ps_it_times)[it][0];
776 *val2 = (*data->chip_spec->ps_it_times)[it][1] *
777 vcnl4040_ps_persistence[ret_pers];
779 return IIO_VAL_INT_PLUS_MICRO;
782 static ssize_t vcnl4040_write_ps_period(struct vcnl4000_data *data, int val, int val2)
787 ret = i2c_smbus_read_word_data(data->client, VCNL4200_PS_CONF1);
791 it = FIELD_GET(VCNL4040_PS_CONF2_PS_IT, ret);
792 if (it >= data->chip_spec->num_ps_it_times)
796 i = ARRAY_SIZE(vcnl4040_ps_persistence) - 1;
798 for (i = 0; i < ARRAY_SIZE(vcnl4040_ps_persistence) - 1; i++) {
799 if (val2 <= vcnl4040_ps_persistence[i] *
800 (*data->chip_spec->ps_it_times)[it][1])
805 mutex_lock(&data->vcnl4000_lock);
807 ret = i2c_smbus_read_word_data(data->client, VCNL4200_PS_CONF1);
811 regval = FIELD_PREP(VCNL4040_CONF1_PS_PERS, i);
812 regval |= (ret & ~VCNL4040_CONF1_PS_PERS);
813 ret = i2c_smbus_write_word_data(data->client, VCNL4200_PS_CONF1,
817 mutex_unlock(&data->vcnl4000_lock);
821 static ssize_t vcnl4040_read_ps_oversampling_ratio(struct vcnl4000_data *data, int *val)
825 ret = i2c_smbus_read_word_data(data->client, VCNL4200_PS_CONF3);
829 ret = FIELD_GET(VCNL4040_PS_CONF3_MPS, ret);
830 if (ret >= ARRAY_SIZE(vcnl4040_ps_oversampling_ratio))
833 *val = vcnl4040_ps_oversampling_ratio[ret];
838 static ssize_t vcnl4040_write_ps_oversampling_ratio(struct vcnl4000_data *data, int val)
844 for (i = 0; i < ARRAY_SIZE(vcnl4040_ps_oversampling_ratio); i++) {
845 if (val == vcnl4040_ps_oversampling_ratio[i])
849 if (i >= ARRAY_SIZE(vcnl4040_ps_oversampling_ratio))
852 mutex_lock(&data->vcnl4000_lock);
854 ret = i2c_smbus_read_word_data(data->client, VCNL4200_PS_CONF3);
858 regval = FIELD_PREP(VCNL4040_PS_CONF3_MPS, i);
859 regval |= (ret & ~VCNL4040_PS_CONF3_MPS);
860 ret = i2c_smbus_write_word_data(data->client, VCNL4200_PS_CONF3,
864 mutex_unlock(&data->vcnl4000_lock);
868 static ssize_t vcnl4040_read_ps_calibbias(struct vcnl4000_data *data, int *val, int *val2)
872 ret = i2c_smbus_read_word_data(data->client, VCNL4200_PS_CONF3);
876 ret = FIELD_GET(VCNL4040_PS_MS_LED_I, ret);
877 if (ret >= ARRAY_SIZE(vcnl4040_ps_calibbias_ua))
880 *val = vcnl4040_ps_calibbias_ua[ret][0];
881 *val2 = vcnl4040_ps_calibbias_ua[ret][1];
886 static ssize_t vcnl4040_write_ps_calibbias(struct vcnl4000_data *data, int val)
892 for (i = 0; i < ARRAY_SIZE(vcnl4040_ps_calibbias_ua); i++) {
893 if (val == vcnl4040_ps_calibbias_ua[i][1])
897 if (i >= ARRAY_SIZE(vcnl4040_ps_calibbias_ua))
900 mutex_lock(&data->vcnl4000_lock);
902 ret = i2c_smbus_read_word_data(data->client, VCNL4200_PS_CONF3);
906 regval = (ret & ~VCNL4040_PS_MS_LED_I);
907 regval |= FIELD_PREP(VCNL4040_PS_MS_LED_I, i);
908 ret = i2c_smbus_write_word_data(data->client, VCNL4200_PS_CONF3,
912 mutex_unlock(&data->vcnl4000_lock);
916 static int vcnl4000_read_raw(struct iio_dev *indio_dev,
917 struct iio_chan_spec const *chan,
918 int *val, int *val2, long mask)
921 struct vcnl4000_data *data = iio_priv(indio_dev);
924 case IIO_CHAN_INFO_RAW:
925 ret = vcnl4000_set_pm_runtime_state(data, true);
929 switch (chan->type) {
931 ret = data->chip_spec->measure_light(data, val);
936 ret = data->chip_spec->measure_proximity(data, val);
937 *val2 = data->ps_scale;
939 ret = IIO_VAL_FRACTIONAL;
944 vcnl4000_set_pm_runtime_state(data, false);
946 case IIO_CHAN_INFO_SCALE:
947 if (chan->type != IIO_LIGHT)
951 *val2 = data->al_scale;
952 return IIO_VAL_INT_PLUS_MICRO;
953 case IIO_CHAN_INFO_INT_TIME:
954 switch (chan->type) {
956 ret = vcnl4040_read_als_it(data, val, val2);
959 ret = vcnl4040_read_ps_it(data, val, val2);
966 return IIO_VAL_INT_PLUS_MICRO;
967 case IIO_CHAN_INFO_OVERSAMPLING_RATIO:
968 switch (chan->type) {
970 ret = vcnl4040_read_ps_oversampling_ratio(data, val);
977 case IIO_CHAN_INFO_CALIBBIAS:
978 switch (chan->type) {
980 ret = vcnl4040_read_ps_calibbias(data, val, val2);
983 return IIO_VAL_INT_PLUS_MICRO;
992 static int vcnl4040_write_raw(struct iio_dev *indio_dev,
993 struct iio_chan_spec const *chan,
994 int val, int val2, long mask)
996 struct vcnl4000_data *data = iio_priv(indio_dev);
999 case IIO_CHAN_INFO_INT_TIME:
1002 switch (chan->type) {
1004 return vcnl4040_write_als_it(data, val2);
1006 return vcnl4040_write_ps_it(data, val2);
1010 case IIO_CHAN_INFO_OVERSAMPLING_RATIO:
1011 switch (chan->type) {
1013 return vcnl4040_write_ps_oversampling_ratio(data, val);
1017 case IIO_CHAN_INFO_CALIBBIAS:
1018 switch (chan->type) {
1020 return vcnl4040_write_ps_calibbias(data, val2);
1029 static int vcnl4040_read_avail(struct iio_dev *indio_dev,
1030 struct iio_chan_spec const *chan,
1031 const int **vals, int *type, int *length,
1034 struct vcnl4000_data *data = iio_priv(indio_dev);
1037 case IIO_CHAN_INFO_INT_TIME:
1038 switch (chan->type) {
1040 *vals = (int *)(*data->chip_spec->als_it_times);
1041 *length = 2 * data->chip_spec->num_als_it_times;
1044 *vals = (int *)(*data->chip_spec->ps_it_times);
1045 *length = 2 * data->chip_spec->num_ps_it_times;
1050 *type = IIO_VAL_INT_PLUS_MICRO;
1051 return IIO_AVAIL_LIST;
1052 case IIO_CHAN_INFO_OVERSAMPLING_RATIO:
1053 switch (chan->type) {
1055 *vals = (int *)vcnl4040_ps_oversampling_ratio;
1056 *length = ARRAY_SIZE(vcnl4040_ps_oversampling_ratio);
1057 *type = IIO_VAL_INT;
1058 return IIO_AVAIL_LIST;
1062 case IIO_CHAN_INFO_CALIBBIAS:
1063 switch (chan->type) {
1065 *vals = (int *)vcnl4040_ps_calibbias_ua;
1066 *length = 2 * ARRAY_SIZE(vcnl4040_ps_calibbias_ua);
1067 *type = IIO_VAL_INT_PLUS_MICRO;
1068 return IIO_AVAIL_LIST;
1077 static int vcnl4010_read_raw(struct iio_dev *indio_dev,
1078 struct iio_chan_spec const *chan,
1079 int *val, int *val2, long mask)
1082 struct vcnl4000_data *data = iio_priv(indio_dev);
1085 case IIO_CHAN_INFO_RAW:
1086 case IIO_CHAN_INFO_SCALE:
1087 ret = iio_device_claim_direct_mode(indio_dev);
1091 /* Protect against event capture. */
1092 if (vcnl4010_is_in_periodic_mode(data)) {
1095 ret = vcnl4000_read_raw(indio_dev, chan, val, val2,
1099 iio_device_release_direct_mode(indio_dev);
1101 case IIO_CHAN_INFO_SAMP_FREQ:
1102 switch (chan->type) {
1104 ret = vcnl4010_read_proxy_samp_freq(data, val, val2);
1107 return IIO_VAL_INT_PLUS_MICRO;
1116 static int vcnl4010_read_avail(struct iio_dev *indio_dev,
1117 struct iio_chan_spec const *chan,
1118 const int **vals, int *type, int *length,
1122 case IIO_CHAN_INFO_SAMP_FREQ:
1123 *vals = (int *)vcnl4010_prox_sampling_frequency;
1124 *type = IIO_VAL_INT_PLUS_MICRO;
1125 *length = 2 * ARRAY_SIZE(vcnl4010_prox_sampling_frequency);
1126 return IIO_AVAIL_LIST;
1132 static int vcnl4010_write_proxy_samp_freq(struct vcnl4000_data *data, int val,
1138 for (i = 0; i < ARRAY_SIZE(vcnl4010_prox_sampling_frequency); i++) {
1139 if (val == vcnl4010_prox_sampling_frequency[i][0] &&
1140 val2 == vcnl4010_prox_sampling_frequency[i][1]) {
1149 return i2c_smbus_write_byte_data(data->client, VCNL4010_PROX_RATE,
1153 static int vcnl4010_write_raw(struct iio_dev *indio_dev,
1154 struct iio_chan_spec const *chan,
1155 int val, int val2, long mask)
1158 struct vcnl4000_data *data = iio_priv(indio_dev);
1160 ret = iio_device_claim_direct_mode(indio_dev);
1164 /* Protect against event capture. */
1165 if (vcnl4010_is_in_periodic_mode(data)) {
1171 case IIO_CHAN_INFO_SAMP_FREQ:
1172 switch (chan->type) {
1174 ret = vcnl4010_write_proxy_samp_freq(data, val, val2);
1186 iio_device_release_direct_mode(indio_dev);
1190 static int vcnl4010_read_event(struct iio_dev *indio_dev,
1191 const struct iio_chan_spec *chan,
1192 enum iio_event_type type,
1193 enum iio_event_direction dir,
1194 enum iio_event_info info,
1195 int *val, int *val2)
1198 struct vcnl4000_data *data = iio_priv(indio_dev);
1201 case IIO_EV_INFO_VALUE:
1203 case IIO_EV_DIR_RISING:
1204 ret = vcnl4000_read_data(data, VCNL4010_HIGH_THR_HI,
1209 case IIO_EV_DIR_FALLING:
1210 ret = vcnl4000_read_data(data, VCNL4010_LOW_THR_HI,
1223 static int vcnl4010_write_event(struct iio_dev *indio_dev,
1224 const struct iio_chan_spec *chan,
1225 enum iio_event_type type,
1226 enum iio_event_direction dir,
1227 enum iio_event_info info,
1231 struct vcnl4000_data *data = iio_priv(indio_dev);
1234 case IIO_EV_INFO_VALUE:
1236 case IIO_EV_DIR_RISING:
1237 ret = vcnl4000_write_data(data, VCNL4010_HIGH_THR_HI,
1242 case IIO_EV_DIR_FALLING:
1243 ret = vcnl4000_write_data(data, VCNL4010_LOW_THR_HI,
1256 static int vcnl4040_read_event(struct iio_dev *indio_dev,
1257 const struct iio_chan_spec *chan,
1258 enum iio_event_type type,
1259 enum iio_event_direction dir,
1260 enum iio_event_info info,
1261 int *val, int *val2)
1264 struct vcnl4000_data *data = iio_priv(indio_dev);
1266 switch (chan->type) {
1269 case IIO_EV_INFO_PERIOD:
1270 return vcnl4040_read_als_period(data, val, val2);
1271 case IIO_EV_INFO_VALUE:
1273 case IIO_EV_DIR_RISING:
1274 ret = i2c_smbus_read_word_data(data->client,
1275 VCNL4040_ALS_THDH_LM);
1277 case IIO_EV_DIR_FALLING:
1278 ret = i2c_smbus_read_word_data(data->client,
1279 VCNL4040_ALS_THDL_LM);
1291 case IIO_EV_INFO_PERIOD:
1292 return vcnl4040_read_ps_period(data, val, val2);
1293 case IIO_EV_INFO_VALUE:
1295 case IIO_EV_DIR_RISING:
1296 ret = i2c_smbus_read_word_data(data->client,
1297 VCNL4040_PS_THDH_LM);
1299 case IIO_EV_DIR_FALLING:
1300 ret = i2c_smbus_read_word_data(data->client,
1301 VCNL4040_PS_THDL_LM);
1320 static int vcnl4040_write_event(struct iio_dev *indio_dev,
1321 const struct iio_chan_spec *chan,
1322 enum iio_event_type type,
1323 enum iio_event_direction dir,
1324 enum iio_event_info info,
1328 struct vcnl4000_data *data = iio_priv(indio_dev);
1330 switch (chan->type) {
1333 case IIO_EV_INFO_PERIOD:
1334 return vcnl4040_write_als_period(data, val, val2);
1335 case IIO_EV_INFO_VALUE:
1337 case IIO_EV_DIR_RISING:
1338 ret = i2c_smbus_write_word_data(data->client,
1339 VCNL4040_ALS_THDH_LM,
1342 case IIO_EV_DIR_FALLING:
1343 ret = i2c_smbus_write_word_data(data->client,
1344 VCNL4040_ALS_THDL_LM,
1357 case IIO_EV_INFO_PERIOD:
1358 return vcnl4040_write_ps_period(data, val, val2);
1359 case IIO_EV_INFO_VALUE:
1361 case IIO_EV_DIR_RISING:
1362 ret = i2c_smbus_write_word_data(data->client,
1363 VCNL4040_PS_THDH_LM,
1366 case IIO_EV_DIR_FALLING:
1367 ret = i2c_smbus_write_word_data(data->client,
1368 VCNL4040_PS_THDL_LM,
1387 static bool vcnl4010_is_thr_enabled(struct vcnl4000_data *data)
1391 ret = i2c_smbus_read_byte_data(data->client, VCNL4010_INT_CTRL);
1395 return !!(ret & VCNL4010_INT_THR_EN);
1398 static int vcnl4010_read_event_config(struct iio_dev *indio_dev,
1399 const struct iio_chan_spec *chan,
1400 enum iio_event_type type,
1401 enum iio_event_direction dir)
1403 struct vcnl4000_data *data = iio_priv(indio_dev);
1405 switch (chan->type) {
1407 return vcnl4010_is_thr_enabled(data);
1413 static int vcnl4010_config_threshold(struct iio_dev *indio_dev, bool state)
1415 struct vcnl4000_data *data = iio_priv(indio_dev);
1421 ret = iio_device_claim_direct_mode(indio_dev);
1425 /* Enable periodic measurement of proximity data. */
1426 command = VCNL4000_SELF_TIMED_EN | VCNL4000_PROX_EN;
1429 * Enable interrupts on threshold, for proximity data by
1432 icr = VCNL4010_INT_THR_EN;
1434 if (!vcnl4010_is_thr_enabled(data))
1441 ret = i2c_smbus_write_byte_data(data->client, VCNL4000_COMMAND,
1446 ret = i2c_smbus_write_byte_data(data->client, VCNL4010_INT_CTRL, icr);
1450 iio_device_release_direct_mode(indio_dev);
1455 static int vcnl4010_write_event_config(struct iio_dev *indio_dev,
1456 const struct iio_chan_spec *chan,
1457 enum iio_event_type type,
1458 enum iio_event_direction dir,
1461 switch (chan->type) {
1463 return vcnl4010_config_threshold(indio_dev, state);
1469 static int vcnl4040_read_event_config(struct iio_dev *indio_dev,
1470 const struct iio_chan_spec *chan,
1471 enum iio_event_type type,
1472 enum iio_event_direction dir)
1475 struct vcnl4000_data *data = iio_priv(indio_dev);
1477 switch (chan->type) {
1479 ret = i2c_smbus_read_word_data(data->client, VCNL4200_AL_CONF);
1483 data->als_int = FIELD_GET(VCNL4040_ALS_CONF_INT_EN, ret);
1485 return data->als_int;
1487 ret = i2c_smbus_read_word_data(data->client, VCNL4200_PS_CONF1);
1491 data->ps_int = FIELD_GET(VCNL4040_PS_CONF2_PS_INT, ret);
1493 return (dir == IIO_EV_DIR_RISING) ?
1494 FIELD_GET(VCNL4040_PS_IF_AWAY, ret) :
1495 FIELD_GET(VCNL4040_PS_IF_CLOSE, ret);
1501 static int vcnl4040_write_event_config(struct iio_dev *indio_dev,
1502 const struct iio_chan_spec *chan,
1503 enum iio_event_type type,
1504 enum iio_event_direction dir, int state)
1508 struct vcnl4000_data *data = iio_priv(indio_dev);
1510 mutex_lock(&data->vcnl4000_lock);
1512 switch (chan->type) {
1514 ret = i2c_smbus_read_word_data(data->client, VCNL4200_AL_CONF);
1518 mask = VCNL4040_ALS_CONF_INT_EN;
1522 val = (ret & ~mask);
1524 data->als_int = FIELD_GET(VCNL4040_ALS_CONF_INT_EN, val);
1525 ret = i2c_smbus_write_word_data(data->client, VCNL4200_AL_CONF,
1529 ret = i2c_smbus_read_word_data(data->client, VCNL4200_PS_CONF1);
1533 if (dir == IIO_EV_DIR_RISING)
1534 mask = VCNL4040_PS_IF_AWAY;
1536 mask = VCNL4040_PS_IF_CLOSE;
1538 val = state ? (ret | mask) : (ret & ~mask);
1540 data->ps_int = FIELD_GET(VCNL4040_PS_CONF2_PS_INT, val);
1541 ret = i2c_smbus_write_word_data(data->client, VCNL4200_PS_CONF1,
1549 mutex_unlock(&data->vcnl4000_lock);
1554 static irqreturn_t vcnl4040_irq_thread(int irq, void *p)
1556 struct iio_dev *indio_dev = p;
1557 struct vcnl4000_data *data = iio_priv(indio_dev);
1560 ret = i2c_smbus_read_word_data(data->client, data->chip_spec->int_reg);
1564 if (ret & VCNL4040_PS_IF_CLOSE) {
1565 iio_push_event(indio_dev,
1566 IIO_UNMOD_EVENT_CODE(IIO_PROXIMITY, 0,
1569 iio_get_time_ns(indio_dev));
1572 if (ret & VCNL4040_PS_IF_AWAY) {
1573 iio_push_event(indio_dev,
1574 IIO_UNMOD_EVENT_CODE(IIO_PROXIMITY, 0,
1576 IIO_EV_DIR_FALLING),
1577 iio_get_time_ns(indio_dev));
1580 if (ret & VCNL4040_ALS_FALLING) {
1581 iio_push_event(indio_dev,
1582 IIO_UNMOD_EVENT_CODE(IIO_LIGHT, 0,
1584 IIO_EV_DIR_FALLING),
1585 iio_get_time_ns(indio_dev));
1588 if (ret & VCNL4040_ALS_RISING) {
1589 iio_push_event(indio_dev,
1590 IIO_UNMOD_EVENT_CODE(IIO_LIGHT, 0,
1593 iio_get_time_ns(indio_dev));
1599 static ssize_t vcnl4000_read_near_level(struct iio_dev *indio_dev,
1601 const struct iio_chan_spec *chan,
1604 struct vcnl4000_data *data = iio_priv(indio_dev);
1606 return sprintf(buf, "%u\n", data->near_level);
1609 static irqreturn_t vcnl4010_irq_thread(int irq, void *p)
1611 struct iio_dev *indio_dev = p;
1612 struct vcnl4000_data *data = iio_priv(indio_dev);
1616 ret = i2c_smbus_read_byte_data(data->client, VCNL4010_ISR);
1622 if (isr & VCNL4010_INT_THR) {
1623 if (test_bit(VCNL4010_INT_THR_LOW, &isr)) {
1624 iio_push_event(indio_dev,
1625 IIO_UNMOD_EVENT_CODE(
1629 IIO_EV_DIR_FALLING),
1630 iio_get_time_ns(indio_dev));
1633 if (test_bit(VCNL4010_INT_THR_HIGH, &isr)) {
1634 iio_push_event(indio_dev,
1635 IIO_UNMOD_EVENT_CODE(
1640 iio_get_time_ns(indio_dev));
1643 i2c_smbus_write_byte_data(data->client, VCNL4010_ISR,
1644 isr & VCNL4010_INT_THR);
1647 if (isr & VCNL4010_INT_DRDY && iio_buffer_enabled(indio_dev))
1648 iio_trigger_poll_nested(indio_dev->trig);
1654 static irqreturn_t vcnl4010_trigger_handler(int irq, void *p)
1656 struct iio_poll_func *pf = p;
1657 struct iio_dev *indio_dev = pf->indio_dev;
1658 struct vcnl4000_data *data = iio_priv(indio_dev);
1659 const unsigned long *active_scan_mask = indio_dev->active_scan_mask;
1660 u16 buffer[8] __aligned(8) = {0}; /* 1x16-bit + naturally aligned ts */
1661 bool data_read = false;
1666 ret = i2c_smbus_read_byte_data(data->client, VCNL4010_ISR);
1672 if (test_bit(0, active_scan_mask)) {
1673 if (test_bit(VCNL4010_INT_PROXIMITY, &isr)) {
1674 ret = vcnl4000_read_data(data,
1675 VCNL4000_PS_RESULT_HI,
1685 ret = i2c_smbus_write_byte_data(data->client, VCNL4010_ISR,
1686 isr & VCNL4010_INT_DRDY);
1693 iio_push_to_buffers_with_timestamp(indio_dev, buffer,
1694 iio_get_time_ns(indio_dev));
1697 iio_trigger_notify_done(indio_dev->trig);
1701 static int vcnl4010_buffer_postenable(struct iio_dev *indio_dev)
1703 struct vcnl4000_data *data = iio_priv(indio_dev);
1707 /* Do not enable the buffer if we are already capturing events. */
1708 if (vcnl4010_is_in_periodic_mode(data))
1711 ret = i2c_smbus_write_byte_data(data->client, VCNL4010_INT_CTRL,
1712 VCNL4010_INT_PROX_EN);
1716 cmd = VCNL4000_SELF_TIMED_EN | VCNL4000_PROX_EN;
1717 return i2c_smbus_write_byte_data(data->client, VCNL4000_COMMAND, cmd);
1720 static int vcnl4010_buffer_predisable(struct iio_dev *indio_dev)
1722 struct vcnl4000_data *data = iio_priv(indio_dev);
1725 ret = i2c_smbus_write_byte_data(data->client, VCNL4010_INT_CTRL, 0);
1729 return i2c_smbus_write_byte_data(data->client, VCNL4000_COMMAND, 0);
1732 static const struct iio_buffer_setup_ops vcnl4010_buffer_ops = {
1733 .postenable = &vcnl4010_buffer_postenable,
1734 .predisable = &vcnl4010_buffer_predisable,
1737 static const struct iio_chan_spec_ext_info vcnl4000_ext_info[] = {
1739 .name = "nearlevel",
1740 .shared = IIO_SEPARATE,
1741 .read = vcnl4000_read_near_level,
1746 static const struct iio_event_spec vcnl4000_event_spec[] = {
1748 .type = IIO_EV_TYPE_THRESH,
1749 .dir = IIO_EV_DIR_RISING,
1750 .mask_separate = BIT(IIO_EV_INFO_VALUE),
1752 .type = IIO_EV_TYPE_THRESH,
1753 .dir = IIO_EV_DIR_FALLING,
1754 .mask_separate = BIT(IIO_EV_INFO_VALUE),
1756 .type = IIO_EV_TYPE_THRESH,
1757 .dir = IIO_EV_DIR_EITHER,
1758 .mask_separate = BIT(IIO_EV_INFO_ENABLE),
1762 static const struct iio_event_spec vcnl4040_als_event_spec[] = {
1764 .type = IIO_EV_TYPE_THRESH,
1765 .dir = IIO_EV_DIR_RISING,
1766 .mask_separate = BIT(IIO_EV_INFO_VALUE),
1768 .type = IIO_EV_TYPE_THRESH,
1769 .dir = IIO_EV_DIR_FALLING,
1770 .mask_separate = BIT(IIO_EV_INFO_VALUE),
1772 .type = IIO_EV_TYPE_THRESH,
1773 .dir = IIO_EV_DIR_EITHER,
1774 .mask_separate = BIT(IIO_EV_INFO_ENABLE) | BIT(IIO_EV_INFO_PERIOD),
1778 static const struct iio_event_spec vcnl4040_event_spec[] = {
1780 .type = IIO_EV_TYPE_THRESH,
1781 .dir = IIO_EV_DIR_RISING,
1782 .mask_separate = BIT(IIO_EV_INFO_VALUE) | BIT(IIO_EV_INFO_ENABLE),
1784 .type = IIO_EV_TYPE_THRESH,
1785 .dir = IIO_EV_DIR_FALLING,
1786 .mask_separate = BIT(IIO_EV_INFO_VALUE) | BIT(IIO_EV_INFO_ENABLE),
1788 .type = IIO_EV_TYPE_THRESH,
1789 .dir = IIO_EV_DIR_EITHER,
1790 .mask_separate = BIT(IIO_EV_INFO_PERIOD),
1794 static const struct iio_chan_spec vcnl4000_channels[] = {
1797 .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
1798 BIT(IIO_CHAN_INFO_SCALE),
1800 .type = IIO_PROXIMITY,
1801 .info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
1802 .ext_info = vcnl4000_ext_info,
1806 static const struct iio_chan_spec vcnl4010_channels[] = {
1810 .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
1811 BIT(IIO_CHAN_INFO_SCALE),
1813 .type = IIO_PROXIMITY,
1815 .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
1816 BIT(IIO_CHAN_INFO_SAMP_FREQ),
1817 .info_mask_separate_available = BIT(IIO_CHAN_INFO_SAMP_FREQ),
1818 .event_spec = vcnl4000_event_spec,
1819 .num_event_specs = ARRAY_SIZE(vcnl4000_event_spec),
1820 .ext_info = vcnl4000_ext_info,
1825 .endianness = IIO_CPU,
1828 IIO_CHAN_SOFT_TIMESTAMP(1),
1831 static const struct iio_chan_spec vcnl4040_channels[] = {
1834 .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
1835 BIT(IIO_CHAN_INFO_SCALE) |
1836 BIT(IIO_CHAN_INFO_INT_TIME),
1837 .info_mask_separate_available = BIT(IIO_CHAN_INFO_INT_TIME),
1838 .event_spec = vcnl4040_als_event_spec,
1839 .num_event_specs = ARRAY_SIZE(vcnl4040_als_event_spec),
1841 .type = IIO_PROXIMITY,
1842 .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
1843 BIT(IIO_CHAN_INFO_INT_TIME) |
1844 BIT(IIO_CHAN_INFO_OVERSAMPLING_RATIO) |
1845 BIT(IIO_CHAN_INFO_CALIBBIAS),
1846 .info_mask_separate_available = BIT(IIO_CHAN_INFO_INT_TIME) |
1847 BIT(IIO_CHAN_INFO_OVERSAMPLING_RATIO) |
1848 BIT(IIO_CHAN_INFO_CALIBBIAS),
1849 .ext_info = vcnl4000_ext_info,
1850 .event_spec = vcnl4040_event_spec,
1851 .num_event_specs = ARRAY_SIZE(vcnl4040_event_spec),
1855 static const struct iio_info vcnl4000_info = {
1856 .read_raw = vcnl4000_read_raw,
1859 static const struct iio_info vcnl4010_info = {
1860 .read_raw = vcnl4010_read_raw,
1861 .read_avail = vcnl4010_read_avail,
1862 .write_raw = vcnl4010_write_raw,
1863 .read_event_value = vcnl4010_read_event,
1864 .write_event_value = vcnl4010_write_event,
1865 .read_event_config = vcnl4010_read_event_config,
1866 .write_event_config = vcnl4010_write_event_config,
1869 static const struct iio_info vcnl4040_info = {
1870 .read_raw = vcnl4000_read_raw,
1871 .write_raw = vcnl4040_write_raw,
1872 .read_event_value = vcnl4040_read_event,
1873 .write_event_value = vcnl4040_write_event,
1874 .read_event_config = vcnl4040_read_event_config,
1875 .write_event_config = vcnl4040_write_event_config,
1876 .read_avail = vcnl4040_read_avail,
1879 static const struct vcnl4000_chip_spec vcnl4000_chip_spec_cfg[] = {
1882 .init = vcnl4000_init,
1883 .measure_light = vcnl4000_measure_light,
1884 .measure_proximity = vcnl4000_measure_proximity,
1885 .set_power_state = vcnl4000_set_power_state,
1886 .channels = vcnl4000_channels,
1887 .num_channels = ARRAY_SIZE(vcnl4000_channels),
1888 .info = &vcnl4000_info,
1891 .prod = "VCNL4010/4020",
1892 .init = vcnl4000_init,
1893 .measure_light = vcnl4000_measure_light,
1894 .measure_proximity = vcnl4000_measure_proximity,
1895 .set_power_state = vcnl4000_set_power_state,
1896 .channels = vcnl4010_channels,
1897 .num_channels = ARRAY_SIZE(vcnl4010_channels),
1898 .info = &vcnl4010_info,
1899 .irq_thread = vcnl4010_irq_thread,
1900 .trig_buffer_func = vcnl4010_trigger_handler,
1901 .buffer_setup_ops = &vcnl4010_buffer_ops,
1905 .init = vcnl4200_init,
1906 .measure_light = vcnl4200_measure_light,
1907 .measure_proximity = vcnl4200_measure_proximity,
1908 .set_power_state = vcnl4200_set_power_state,
1909 .channels = vcnl4040_channels,
1910 .num_channels = ARRAY_SIZE(vcnl4040_channels),
1911 .info = &vcnl4040_info,
1912 .irq_thread = vcnl4040_irq_thread,
1913 .int_reg = VCNL4040_INT_FLAGS,
1914 .ps_it_times = &vcnl4040_ps_it_times,
1915 .num_ps_it_times = ARRAY_SIZE(vcnl4040_ps_it_times),
1916 .als_it_times = &vcnl4040_als_it_times,
1917 .num_als_it_times = ARRAY_SIZE(vcnl4040_als_it_times),
1918 .ulux_step = 100000,
1922 .init = vcnl4200_init,
1923 .measure_light = vcnl4200_measure_light,
1924 .measure_proximity = vcnl4200_measure_proximity,
1925 .set_power_state = vcnl4200_set_power_state,
1926 .channels = vcnl4040_channels,
1927 .num_channels = ARRAY_SIZE(vcnl4000_channels),
1928 .info = &vcnl4040_info,
1929 .irq_thread = vcnl4040_irq_thread,
1930 .int_reg = VCNL4200_INT_FLAGS,
1931 .ps_it_times = &vcnl4200_ps_it_times,
1932 .num_ps_it_times = ARRAY_SIZE(vcnl4200_ps_it_times),
1933 .als_it_times = &vcnl4200_als_it_times,
1934 .num_als_it_times = ARRAY_SIZE(vcnl4200_als_it_times),
1939 static const struct iio_trigger_ops vcnl4010_trigger_ops = {
1940 .validate_device = iio_trigger_validate_own_device,
1943 static int vcnl4010_probe_trigger(struct iio_dev *indio_dev)
1945 struct vcnl4000_data *data = iio_priv(indio_dev);
1946 struct i2c_client *client = data->client;
1947 struct iio_trigger *trigger;
1949 trigger = devm_iio_trigger_alloc(&client->dev, "%s-dev%d",
1951 iio_device_id(indio_dev));
1955 trigger->ops = &vcnl4010_trigger_ops;
1956 iio_trigger_set_drvdata(trigger, indio_dev);
1958 return devm_iio_trigger_register(&client->dev, trigger);
1961 static int vcnl4000_probe(struct i2c_client *client)
1963 const struct i2c_device_id *id = i2c_client_get_device_id(client);
1964 struct vcnl4000_data *data;
1965 struct iio_dev *indio_dev;
1968 indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*data));
1972 data = iio_priv(indio_dev);
1973 i2c_set_clientdata(client, indio_dev);
1974 data->client = client;
1975 data->id = id->driver_data;
1976 data->chip_spec = &vcnl4000_chip_spec_cfg[data->id];
1978 mutex_init(&data->vcnl4000_lock);
1980 ret = data->chip_spec->init(data);
1984 dev_dbg(&client->dev, "%s Ambient light/proximity sensor, Rev: %02x\n",
1985 data->chip_spec->prod, data->rev);
1987 if (device_property_read_u32(&client->dev, "proximity-near-level",
1989 data->near_level = 0;
1991 indio_dev->info = data->chip_spec->info;
1992 indio_dev->channels = data->chip_spec->channels;
1993 indio_dev->num_channels = data->chip_spec->num_channels;
1994 indio_dev->name = VCNL4000_DRV_NAME;
1995 indio_dev->modes = INDIO_DIRECT_MODE;
1997 if (data->chip_spec->trig_buffer_func &&
1998 data->chip_spec->buffer_setup_ops) {
1999 ret = devm_iio_triggered_buffer_setup(&client->dev, indio_dev,
2001 data->chip_spec->trig_buffer_func,
2002 data->chip_spec->buffer_setup_ops);
2004 dev_err(&client->dev,
2005 "unable to setup iio triggered buffer\n");
2010 if (client->irq && data->chip_spec->irq_thread) {
2011 ret = devm_request_threaded_irq(&client->dev, client->irq,
2012 NULL, data->chip_spec->irq_thread,
2013 IRQF_TRIGGER_FALLING |
2018 dev_err(&client->dev, "irq request failed\n");
2022 ret = vcnl4010_probe_trigger(indio_dev);
2027 ret = pm_runtime_set_active(&client->dev);
2031 ret = iio_device_register(indio_dev);
2035 pm_runtime_enable(&client->dev);
2036 pm_runtime_set_autosuspend_delay(&client->dev, VCNL4000_SLEEP_DELAY_MS);
2037 pm_runtime_use_autosuspend(&client->dev);
2041 data->chip_spec->set_power_state(data, false);
2045 static const struct of_device_id vcnl_4000_of_match[] = {
2047 .compatible = "vishay,vcnl4000",
2048 .data = (void *)VCNL4000,
2051 .compatible = "vishay,vcnl4010",
2052 .data = (void *)VCNL4010,
2055 .compatible = "vishay,vcnl4020",
2056 .data = (void *)VCNL4010,
2059 .compatible = "vishay,vcnl4040",
2060 .data = (void *)VCNL4040,
2063 .compatible = "vishay,vcnl4200",
2064 .data = (void *)VCNL4200,
2068 MODULE_DEVICE_TABLE(of, vcnl_4000_of_match);
2070 static void vcnl4000_remove(struct i2c_client *client)
2072 struct iio_dev *indio_dev = i2c_get_clientdata(client);
2073 struct vcnl4000_data *data = iio_priv(indio_dev);
2076 pm_runtime_dont_use_autosuspend(&client->dev);
2077 pm_runtime_disable(&client->dev);
2078 iio_device_unregister(indio_dev);
2079 pm_runtime_set_suspended(&client->dev);
2081 ret = data->chip_spec->set_power_state(data, false);
2083 dev_warn(&client->dev, "Failed to power down (%pe)\n",
2087 static int vcnl4000_runtime_suspend(struct device *dev)
2089 struct iio_dev *indio_dev = i2c_get_clientdata(to_i2c_client(dev));
2090 struct vcnl4000_data *data = iio_priv(indio_dev);
2092 return data->chip_spec->set_power_state(data, false);
2095 static int vcnl4000_runtime_resume(struct device *dev)
2097 struct iio_dev *indio_dev = i2c_get_clientdata(to_i2c_client(dev));
2098 struct vcnl4000_data *data = iio_priv(indio_dev);
2100 return data->chip_spec->set_power_state(data, true);
2103 static DEFINE_RUNTIME_DEV_PM_OPS(vcnl4000_pm_ops, vcnl4000_runtime_suspend,
2104 vcnl4000_runtime_resume, NULL);
2106 static struct i2c_driver vcnl4000_driver = {
2108 .name = VCNL4000_DRV_NAME,
2109 .pm = pm_ptr(&vcnl4000_pm_ops),
2110 .of_match_table = vcnl_4000_of_match,
2112 .probe = vcnl4000_probe,
2113 .id_table = vcnl4000_id,
2114 .remove = vcnl4000_remove,
2117 module_i2c_driver(vcnl4000_driver);
2119 MODULE_AUTHOR("Peter Meerwald <pmeerw@pmeerw.net>");
2120 MODULE_AUTHOR("Mathieu Othacehe <m.othacehe@gmail.com>");
2121 MODULE_DESCRIPTION("Vishay VCNL4000 proximity/ambient light sensor driver");
2122 MODULE_LICENSE("GPL");