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/module.h>
21 #include <linux/i2c.h>
22 #include <linux/err.h>
23 #include <linux/delay.h>
24 #include <linux/pm_runtime.h>
25 #include <linux/interrupt.h>
27 #include <linux/iio/buffer.h>
28 #include <linux/iio/events.h>
29 #include <linux/iio/iio.h>
30 #include <linux/iio/sysfs.h>
31 #include <linux/iio/trigger.h>
32 #include <linux/iio/trigger_consumer.h>
33 #include <linux/iio/triggered_buffer.h>
35 #define VCNL4000_DRV_NAME "vcnl4000"
36 #define VCNL4000_PROD_ID 0x01
37 #define VCNL4010_PROD_ID 0x02 /* for VCNL4020, VCNL4010 */
38 #define VCNL4040_PROD_ID 0x86
39 #define VCNL4200_PROD_ID 0x58
41 #define VCNL4000_COMMAND 0x80 /* Command register */
42 #define VCNL4000_PROD_REV 0x81 /* Product ID and Revision ID */
43 #define VCNL4010_PROX_RATE 0x82 /* Proximity rate */
44 #define VCNL4000_LED_CURRENT 0x83 /* IR LED current for proximity mode */
45 #define VCNL4000_AL_PARAM 0x84 /* Ambient light parameter register */
46 #define VCNL4010_ALS_PARAM 0x84 /* ALS rate */
47 #define VCNL4000_AL_RESULT_HI 0x85 /* Ambient light result register, MSB */
48 #define VCNL4000_AL_RESULT_LO 0x86 /* Ambient light result register, LSB */
49 #define VCNL4000_PS_RESULT_HI 0x87 /* Proximity result register, MSB */
50 #define VCNL4000_PS_RESULT_LO 0x88 /* Proximity result register, LSB */
51 #define VCNL4000_PS_MEAS_FREQ 0x89 /* Proximity test signal frequency */
52 #define VCNL4010_INT_CTRL 0x89 /* Interrupt control */
53 #define VCNL4000_PS_MOD_ADJ 0x8a /* Proximity modulator timing adjustment */
54 #define VCNL4010_LOW_THR_HI 0x8a /* Low threshold, MSB */
55 #define VCNL4010_LOW_THR_LO 0x8b /* Low threshold, LSB */
56 #define VCNL4010_HIGH_THR_HI 0x8c /* High threshold, MSB */
57 #define VCNL4010_HIGH_THR_LO 0x8d /* High threshold, LSB */
58 #define VCNL4010_ISR 0x8e /* Interrupt status */
60 #define VCNL4200_AL_CONF 0x00 /* Ambient light configuration */
61 #define VCNL4200_PS_CONF1 0x03 /* Proximity configuration */
62 #define VCNL4200_PS_DATA 0x08 /* Proximity data */
63 #define VCNL4200_AL_DATA 0x09 /* Ambient light data */
64 #define VCNL4200_DEV_ID 0x0e /* Device ID, slave address and version */
66 #define VCNL4040_DEV_ID 0x0c /* Device ID and version */
68 /* Bit masks for COMMAND register */
69 #define VCNL4000_AL_RDY BIT(6) /* ALS data ready? */
70 #define VCNL4000_PS_RDY BIT(5) /* proximity data ready? */
71 #define VCNL4000_AL_OD BIT(4) /* start on-demand ALS measurement */
72 #define VCNL4000_PS_OD BIT(3) /* start on-demand proximity measurement */
73 #define VCNL4000_ALS_EN BIT(2) /* start ALS measurement */
74 #define VCNL4000_PROX_EN BIT(1) /* start proximity measurement */
75 #define VCNL4000_SELF_TIMED_EN BIT(0) /* start self-timed measurement */
77 /* Bit masks for interrupt registers. */
78 #define VCNL4010_INT_THR_SEL BIT(0) /* Select threshold interrupt source */
79 #define VCNL4010_INT_THR_EN BIT(1) /* Threshold interrupt type */
80 #define VCNL4010_INT_ALS_EN BIT(2) /* Enable on ALS data ready */
81 #define VCNL4010_INT_PROX_EN BIT(3) /* Enable on proximity data ready */
83 #define VCNL4010_INT_THR_HIGH 0 /* High threshold exceeded */
84 #define VCNL4010_INT_THR_LOW 1 /* Low threshold exceeded */
85 #define VCNL4010_INT_ALS 2 /* ALS data ready */
86 #define VCNL4010_INT_PROXIMITY 3 /* Proximity data ready */
88 #define VCNL4010_INT_THR \
89 (BIT(VCNL4010_INT_THR_LOW) | BIT(VCNL4010_INT_THR_HIGH))
90 #define VCNL4010_INT_DRDY \
91 (BIT(VCNL4010_INT_PROXIMITY) | BIT(VCNL4010_INT_ALS))
93 static const int vcnl4010_prox_sampling_frequency
[][2] = {
104 #define VCNL4000_SLEEP_DELAY_MS 2000 /* before we enter pm_runtime_suspend */
106 enum vcnl4000_device_ids
{
113 struct vcnl4200_channel
{
115 ktime_t last_measurement
;
116 ktime_t sampling_rate
;
120 struct vcnl4000_data
{
121 struct i2c_client
*client
;
122 enum vcnl4000_device_ids id
;
125 const struct vcnl4000_chip_spec
*chip_spec
;
126 struct mutex vcnl4000_lock
;
127 struct vcnl4200_channel vcnl4200_al
;
128 struct vcnl4200_channel vcnl4200_ps
;
132 struct vcnl4000_chip_spec
{
134 struct iio_chan_spec
const *channels
;
135 const int num_channels
;
136 const struct iio_info
*info
;
138 int (*init
)(struct vcnl4000_data
*data
);
139 int (*measure_light
)(struct vcnl4000_data
*data
, int *val
);
140 int (*measure_proximity
)(struct vcnl4000_data
*data
, int *val
);
141 int (*set_power_state
)(struct vcnl4000_data
*data
, bool on
);
144 static const struct i2c_device_id vcnl4000_id
[] = {
145 { "vcnl4000", VCNL4000
},
146 { "vcnl4010", VCNL4010
},
147 { "vcnl4020", VCNL4010
},
148 { "vcnl4040", VCNL4040
},
149 { "vcnl4200", VCNL4200
},
152 MODULE_DEVICE_TABLE(i2c
, vcnl4000_id
);
154 static int vcnl4000_set_power_state(struct vcnl4000_data
*data
, bool on
)
160 static int vcnl4000_init(struct vcnl4000_data
*data
)
164 ret
= i2c_smbus_read_byte_data(data
->client
, VCNL4000_PROD_REV
);
170 case VCNL4000_PROD_ID
:
171 if (data
->id
!= VCNL4000
)
172 dev_warn(&data
->client
->dev
,
173 "wrong device id, use vcnl4000");
175 case VCNL4010_PROD_ID
:
176 if (data
->id
!= VCNL4010
)
177 dev_warn(&data
->client
->dev
,
178 "wrong device id, use vcnl4010/4020");
184 data
->rev
= ret
& 0xf;
185 data
->al_scale
= 250000;
186 mutex_init(&data
->vcnl4000_lock
);
188 return data
->chip_spec
->set_power_state(data
, true);
191 static int vcnl4200_set_power_state(struct vcnl4000_data
*data
, bool on
)
193 u16 val
= on
? 0 /* power on */ : 1 /* shut down */;
196 ret
= i2c_smbus_write_word_data(data
->client
, VCNL4200_AL_CONF
, val
);
200 ret
= i2c_smbus_write_word_data(data
->client
, VCNL4200_PS_CONF1
, val
);
205 /* Wait at least one integration cycle before fetching data */
206 data
->vcnl4200_al
.last_measurement
= ktime_get();
207 data
->vcnl4200_ps
.last_measurement
= ktime_get();
213 static int vcnl4200_init(struct vcnl4000_data
*data
)
217 ret
= i2c_smbus_read_word_data(data
->client
, VCNL4200_DEV_ID
);
223 if (id
!= VCNL4200_PROD_ID
) {
224 ret
= i2c_smbus_read_word_data(data
->client
, VCNL4040_DEV_ID
);
230 if (id
!= VCNL4040_PROD_ID
)
234 dev_dbg(&data
->client
->dev
, "device id 0x%x", id
);
236 data
->rev
= (ret
>> 8) & 0xf;
238 data
->vcnl4200_al
.reg
= VCNL4200_AL_DATA
;
239 data
->vcnl4200_ps
.reg
= VCNL4200_PS_DATA
;
241 case VCNL4200_PROD_ID
:
242 /* Default wait time is 50ms, add 20% tolerance. */
243 data
->vcnl4200_al
.sampling_rate
= ktime_set(0, 60000 * 1000);
244 /* Default wait time is 4.8ms, add 20% tolerance. */
245 data
->vcnl4200_ps
.sampling_rate
= ktime_set(0, 5760 * 1000);
246 data
->al_scale
= 24000;
248 case VCNL4040_PROD_ID
:
249 /* Default wait time is 80ms, add 20% tolerance. */
250 data
->vcnl4200_al
.sampling_rate
= ktime_set(0, 96000 * 1000);
251 /* Default wait time is 5ms, add 20% tolerance. */
252 data
->vcnl4200_ps
.sampling_rate
= ktime_set(0, 6000 * 1000);
253 data
->al_scale
= 120000;
256 mutex_init(&data
->vcnl4200_al
.lock
);
257 mutex_init(&data
->vcnl4200_ps
.lock
);
259 ret
= data
->chip_spec
->set_power_state(data
, true);
266 static int vcnl4000_read_data(struct vcnl4000_data
*data
, u8 data_reg
, int *val
)
270 ret
= i2c_smbus_read_word_swapped(data
->client
, data_reg
);
278 static int vcnl4000_write_data(struct vcnl4000_data
*data
, u8 data_reg
, int val
)
283 return i2c_smbus_write_word_swapped(data
->client
, data_reg
, val
);
287 static int vcnl4000_measure(struct vcnl4000_data
*data
, u8 req_mask
,
288 u8 rdy_mask
, u8 data_reg
, int *val
)
293 mutex_lock(&data
->vcnl4000_lock
);
295 ret
= i2c_smbus_write_byte_data(data
->client
, VCNL4000_COMMAND
,
300 /* wait for data to become ready */
302 ret
= i2c_smbus_read_byte_data(data
->client
, VCNL4000_COMMAND
);
307 msleep(20); /* measurement takes up to 100 ms */
311 dev_err(&data
->client
->dev
,
312 "vcnl4000_measure() failed, data not ready\n");
317 ret
= vcnl4000_read_data(data
, data_reg
, val
);
321 mutex_unlock(&data
->vcnl4000_lock
);
326 mutex_unlock(&data
->vcnl4000_lock
);
330 static int vcnl4200_measure(struct vcnl4000_data
*data
,
331 struct vcnl4200_channel
*chan
, int *val
)
335 ktime_t next_measurement
;
337 mutex_lock(&chan
->lock
);
339 next_measurement
= ktime_add(chan
->last_measurement
,
340 chan
->sampling_rate
);
341 delta
= ktime_us_delta(next_measurement
, ktime_get());
343 usleep_range(delta
, delta
+ 500);
344 chan
->last_measurement
= ktime_get();
346 mutex_unlock(&chan
->lock
);
348 ret
= i2c_smbus_read_word_data(data
->client
, chan
->reg
);
357 static int vcnl4000_measure_light(struct vcnl4000_data
*data
, int *val
)
359 return vcnl4000_measure(data
,
360 VCNL4000_AL_OD
, VCNL4000_AL_RDY
,
361 VCNL4000_AL_RESULT_HI
, val
);
364 static int vcnl4200_measure_light(struct vcnl4000_data
*data
, int *val
)
366 return vcnl4200_measure(data
, &data
->vcnl4200_al
, val
);
369 static int vcnl4000_measure_proximity(struct vcnl4000_data
*data
, int *val
)
371 return vcnl4000_measure(data
,
372 VCNL4000_PS_OD
, VCNL4000_PS_RDY
,
373 VCNL4000_PS_RESULT_HI
, val
);
376 static int vcnl4200_measure_proximity(struct vcnl4000_data
*data
, int *val
)
378 return vcnl4200_measure(data
, &data
->vcnl4200_ps
, val
);
381 static int vcnl4010_read_proxy_samp_freq(struct vcnl4000_data
*data
, int *val
,
386 ret
= i2c_smbus_read_byte_data(data
->client
, VCNL4010_PROX_RATE
);
390 if (ret
>= ARRAY_SIZE(vcnl4010_prox_sampling_frequency
))
393 *val
= vcnl4010_prox_sampling_frequency
[ret
][0];
394 *val2
= vcnl4010_prox_sampling_frequency
[ret
][1];
399 static bool vcnl4010_is_in_periodic_mode(struct vcnl4000_data
*data
)
403 ret
= i2c_smbus_read_byte_data(data
->client
, VCNL4000_COMMAND
);
407 return !!(ret
& VCNL4000_SELF_TIMED_EN
);
410 static int vcnl4000_set_pm_runtime_state(struct vcnl4000_data
*data
, bool on
)
412 struct device
*dev
= &data
->client
->dev
;
416 ret
= pm_runtime_get_sync(dev
);
418 pm_runtime_put_noidle(dev
);
420 pm_runtime_mark_last_busy(dev
);
421 ret
= pm_runtime_put_autosuspend(dev
);
427 static int vcnl4000_read_raw(struct iio_dev
*indio_dev
,
428 struct iio_chan_spec
const *chan
,
429 int *val
, int *val2
, long mask
)
432 struct vcnl4000_data
*data
= iio_priv(indio_dev
);
435 case IIO_CHAN_INFO_RAW
:
436 ret
= vcnl4000_set_pm_runtime_state(data
, true);
440 switch (chan
->type
) {
442 ret
= data
->chip_spec
->measure_light(data
, val
);
447 ret
= data
->chip_spec
->measure_proximity(data
, val
);
454 vcnl4000_set_pm_runtime_state(data
, false);
456 case IIO_CHAN_INFO_SCALE
:
457 if (chan
->type
!= IIO_LIGHT
)
461 *val2
= data
->al_scale
;
462 return IIO_VAL_INT_PLUS_MICRO
;
468 static int vcnl4010_read_raw(struct iio_dev
*indio_dev
,
469 struct iio_chan_spec
const *chan
,
470 int *val
, int *val2
, long mask
)
473 struct vcnl4000_data
*data
= iio_priv(indio_dev
);
476 case IIO_CHAN_INFO_RAW
:
477 case IIO_CHAN_INFO_SCALE
:
478 ret
= iio_device_claim_direct_mode(indio_dev
);
482 /* Protect against event capture. */
483 if (vcnl4010_is_in_periodic_mode(data
)) {
486 ret
= vcnl4000_read_raw(indio_dev
, chan
, val
, val2
,
490 iio_device_release_direct_mode(indio_dev
);
492 case IIO_CHAN_INFO_SAMP_FREQ
:
493 switch (chan
->type
) {
495 ret
= vcnl4010_read_proxy_samp_freq(data
, val
, val2
);
498 return IIO_VAL_INT_PLUS_MICRO
;
507 static int vcnl4010_read_avail(struct iio_dev
*indio_dev
,
508 struct iio_chan_spec
const *chan
,
509 const int **vals
, int *type
, int *length
,
513 case IIO_CHAN_INFO_SAMP_FREQ
:
514 *vals
= (int *)vcnl4010_prox_sampling_frequency
;
515 *type
= IIO_VAL_INT_PLUS_MICRO
;
516 *length
= 2 * ARRAY_SIZE(vcnl4010_prox_sampling_frequency
);
517 return IIO_AVAIL_LIST
;
523 static int vcnl4010_write_proxy_samp_freq(struct vcnl4000_data
*data
, int val
,
529 for (i
= 0; i
< ARRAY_SIZE(vcnl4010_prox_sampling_frequency
); i
++) {
530 if (val
== vcnl4010_prox_sampling_frequency
[i
][0] &&
531 val2
== vcnl4010_prox_sampling_frequency
[i
][1]) {
540 return i2c_smbus_write_byte_data(data
->client
, VCNL4010_PROX_RATE
,
544 static int vcnl4010_write_raw(struct iio_dev
*indio_dev
,
545 struct iio_chan_spec
const *chan
,
546 int val
, int val2
, long mask
)
549 struct vcnl4000_data
*data
= iio_priv(indio_dev
);
551 ret
= iio_device_claim_direct_mode(indio_dev
);
555 /* Protect against event capture. */
556 if (vcnl4010_is_in_periodic_mode(data
)) {
562 case IIO_CHAN_INFO_SAMP_FREQ
:
563 switch (chan
->type
) {
565 ret
= vcnl4010_write_proxy_samp_freq(data
, val
, val2
);
577 iio_device_release_direct_mode(indio_dev
);
581 static int vcnl4010_read_event(struct iio_dev
*indio_dev
,
582 const struct iio_chan_spec
*chan
,
583 enum iio_event_type type
,
584 enum iio_event_direction dir
,
585 enum iio_event_info info
,
589 struct vcnl4000_data
*data
= iio_priv(indio_dev
);
592 case IIO_EV_INFO_VALUE
:
594 case IIO_EV_DIR_RISING
:
595 ret
= vcnl4000_read_data(data
, VCNL4010_HIGH_THR_HI
,
600 case IIO_EV_DIR_FALLING
:
601 ret
= vcnl4000_read_data(data
, VCNL4010_LOW_THR_HI
,
614 static int vcnl4010_write_event(struct iio_dev
*indio_dev
,
615 const struct iio_chan_spec
*chan
,
616 enum iio_event_type type
,
617 enum iio_event_direction dir
,
618 enum iio_event_info info
,
622 struct vcnl4000_data
*data
= iio_priv(indio_dev
);
625 case IIO_EV_INFO_VALUE
:
627 case IIO_EV_DIR_RISING
:
628 ret
= vcnl4000_write_data(data
, VCNL4010_HIGH_THR_HI
,
633 case IIO_EV_DIR_FALLING
:
634 ret
= vcnl4000_write_data(data
, VCNL4010_LOW_THR_HI
,
647 static bool vcnl4010_is_thr_enabled(struct vcnl4000_data
*data
)
651 ret
= i2c_smbus_read_byte_data(data
->client
, VCNL4010_INT_CTRL
);
655 return !!(ret
& VCNL4010_INT_THR_EN
);
658 static int vcnl4010_read_event_config(struct iio_dev
*indio_dev
,
659 const struct iio_chan_spec
*chan
,
660 enum iio_event_type type
,
661 enum iio_event_direction dir
)
663 struct vcnl4000_data
*data
= iio_priv(indio_dev
);
665 switch (chan
->type
) {
667 return vcnl4010_is_thr_enabled(data
);
673 static int vcnl4010_config_threshold(struct iio_dev
*indio_dev
, bool state
)
675 struct vcnl4000_data
*data
= iio_priv(indio_dev
);
681 ret
= iio_device_claim_direct_mode(indio_dev
);
685 /* Enable periodic measurement of proximity data. */
686 command
= VCNL4000_SELF_TIMED_EN
| VCNL4000_PROX_EN
;
689 * Enable interrupts on threshold, for proximity data by
692 icr
= VCNL4010_INT_THR_EN
;
694 if (!vcnl4010_is_thr_enabled(data
))
701 ret
= i2c_smbus_write_byte_data(data
->client
, VCNL4000_COMMAND
,
706 ret
= i2c_smbus_write_byte_data(data
->client
, VCNL4010_INT_CTRL
, icr
);
710 iio_device_release_direct_mode(indio_dev
);
715 static int vcnl4010_write_event_config(struct iio_dev
*indio_dev
,
716 const struct iio_chan_spec
*chan
,
717 enum iio_event_type type
,
718 enum iio_event_direction dir
,
721 switch (chan
->type
) {
723 return vcnl4010_config_threshold(indio_dev
, state
);
729 static ssize_t
vcnl4000_read_near_level(struct iio_dev
*indio_dev
,
731 const struct iio_chan_spec
*chan
,
734 struct vcnl4000_data
*data
= iio_priv(indio_dev
);
736 return sprintf(buf
, "%u\n", data
->near_level
);
739 static const struct iio_chan_spec_ext_info vcnl4000_ext_info
[] = {
742 .shared
= IIO_SEPARATE
,
743 .read
= vcnl4000_read_near_level
,
748 static const struct iio_event_spec vcnl4000_event_spec
[] = {
750 .type
= IIO_EV_TYPE_THRESH
,
751 .dir
= IIO_EV_DIR_RISING
,
752 .mask_separate
= BIT(IIO_EV_INFO_VALUE
),
754 .type
= IIO_EV_TYPE_THRESH
,
755 .dir
= IIO_EV_DIR_FALLING
,
756 .mask_separate
= BIT(IIO_EV_INFO_VALUE
),
758 .type
= IIO_EV_TYPE_THRESH
,
759 .dir
= IIO_EV_DIR_EITHER
,
760 .mask_separate
= BIT(IIO_EV_INFO_ENABLE
),
764 static const struct iio_chan_spec vcnl4000_channels
[] = {
767 .info_mask_separate
= BIT(IIO_CHAN_INFO_RAW
) |
768 BIT(IIO_CHAN_INFO_SCALE
),
770 .type
= IIO_PROXIMITY
,
771 .info_mask_separate
= BIT(IIO_CHAN_INFO_RAW
),
772 .ext_info
= vcnl4000_ext_info
,
776 static const struct iio_chan_spec vcnl4010_channels
[] = {
780 .info_mask_separate
= BIT(IIO_CHAN_INFO_RAW
) |
781 BIT(IIO_CHAN_INFO_SCALE
),
783 .type
= IIO_PROXIMITY
,
785 .info_mask_separate
= BIT(IIO_CHAN_INFO_RAW
) |
786 BIT(IIO_CHAN_INFO_SAMP_FREQ
),
787 .info_mask_separate_available
= BIT(IIO_CHAN_INFO_SAMP_FREQ
),
788 .event_spec
= vcnl4000_event_spec
,
789 .num_event_specs
= ARRAY_SIZE(vcnl4000_event_spec
),
790 .ext_info
= vcnl4000_ext_info
,
795 .endianness
= IIO_CPU
,
798 IIO_CHAN_SOFT_TIMESTAMP(1),
801 static const struct iio_info vcnl4000_info
= {
802 .read_raw
= vcnl4000_read_raw
,
805 static const struct iio_info vcnl4010_info
= {
806 .read_raw
= vcnl4010_read_raw
,
807 .read_avail
= vcnl4010_read_avail
,
808 .write_raw
= vcnl4010_write_raw
,
809 .read_event_value
= vcnl4010_read_event
,
810 .write_event_value
= vcnl4010_write_event
,
811 .read_event_config
= vcnl4010_read_event_config
,
812 .write_event_config
= vcnl4010_write_event_config
,
815 static const struct vcnl4000_chip_spec vcnl4000_chip_spec_cfg
[] = {
818 .init
= vcnl4000_init
,
819 .measure_light
= vcnl4000_measure_light
,
820 .measure_proximity
= vcnl4000_measure_proximity
,
821 .set_power_state
= vcnl4000_set_power_state
,
822 .channels
= vcnl4000_channels
,
823 .num_channels
= ARRAY_SIZE(vcnl4000_channels
),
824 .info
= &vcnl4000_info
,
825 .irq_support
= false,
828 .prod
= "VCNL4010/4020",
829 .init
= vcnl4000_init
,
830 .measure_light
= vcnl4000_measure_light
,
831 .measure_proximity
= vcnl4000_measure_proximity
,
832 .set_power_state
= vcnl4000_set_power_state
,
833 .channels
= vcnl4010_channels
,
834 .num_channels
= ARRAY_SIZE(vcnl4010_channels
),
835 .info
= &vcnl4010_info
,
840 .init
= vcnl4200_init
,
841 .measure_light
= vcnl4200_measure_light
,
842 .measure_proximity
= vcnl4200_measure_proximity
,
843 .set_power_state
= vcnl4200_set_power_state
,
844 .channels
= vcnl4000_channels
,
845 .num_channels
= ARRAY_SIZE(vcnl4000_channels
),
846 .info
= &vcnl4000_info
,
847 .irq_support
= false,
851 .init
= vcnl4200_init
,
852 .measure_light
= vcnl4200_measure_light
,
853 .measure_proximity
= vcnl4200_measure_proximity
,
854 .set_power_state
= vcnl4200_set_power_state
,
855 .channels
= vcnl4000_channels
,
856 .num_channels
= ARRAY_SIZE(vcnl4000_channels
),
857 .info
= &vcnl4000_info
,
858 .irq_support
= false,
862 static irqreturn_t
vcnl4010_irq_thread(int irq
, void *p
)
864 struct iio_dev
*indio_dev
= p
;
865 struct vcnl4000_data
*data
= iio_priv(indio_dev
);
869 ret
= i2c_smbus_read_byte_data(data
->client
, VCNL4010_ISR
);
875 if (isr
& VCNL4010_INT_THR
) {
876 if (test_bit(VCNL4010_INT_THR_LOW
, &isr
)) {
877 iio_push_event(indio_dev
,
878 IIO_UNMOD_EVENT_CODE(
883 iio_get_time_ns(indio_dev
));
886 if (test_bit(VCNL4010_INT_THR_HIGH
, &isr
)) {
887 iio_push_event(indio_dev
,
888 IIO_UNMOD_EVENT_CODE(
893 iio_get_time_ns(indio_dev
));
896 i2c_smbus_write_byte_data(data
->client
, VCNL4010_ISR
,
897 isr
& VCNL4010_INT_THR
);
900 if (isr
& VCNL4010_INT_DRDY
&& iio_buffer_enabled(indio_dev
))
901 iio_trigger_poll_chained(indio_dev
->trig
);
907 static irqreturn_t
vcnl4010_trigger_handler(int irq
, void *p
)
909 struct iio_poll_func
*pf
= p
;
910 struct iio_dev
*indio_dev
= pf
->indio_dev
;
911 struct vcnl4000_data
*data
= iio_priv(indio_dev
);
912 const unsigned long *active_scan_mask
= indio_dev
->active_scan_mask
;
913 u16 buffer
[8] = {0}; /* 1x16-bit + ts */
914 bool data_read
= false;
919 ret
= i2c_smbus_read_byte_data(data
->client
, VCNL4010_ISR
);
925 if (test_bit(0, active_scan_mask
)) {
926 if (test_bit(VCNL4010_INT_PROXIMITY
, &isr
)) {
927 ret
= vcnl4000_read_data(data
,
928 VCNL4000_PS_RESULT_HI
,
938 ret
= i2c_smbus_write_byte_data(data
->client
, VCNL4010_ISR
,
939 isr
& VCNL4010_INT_DRDY
);
946 iio_push_to_buffers_with_timestamp(indio_dev
, buffer
,
947 iio_get_time_ns(indio_dev
));
950 iio_trigger_notify_done(indio_dev
->trig
);
954 static int vcnl4010_buffer_postenable(struct iio_dev
*indio_dev
)
956 struct vcnl4000_data
*data
= iio_priv(indio_dev
);
960 /* Do not enable the buffer if we are already capturing events. */
961 if (vcnl4010_is_in_periodic_mode(data
))
964 ret
= i2c_smbus_write_byte_data(data
->client
, VCNL4010_INT_CTRL
,
965 VCNL4010_INT_PROX_EN
);
969 cmd
= VCNL4000_SELF_TIMED_EN
| VCNL4000_PROX_EN
;
970 return i2c_smbus_write_byte_data(data
->client
, VCNL4000_COMMAND
, cmd
);
973 static int vcnl4010_buffer_predisable(struct iio_dev
*indio_dev
)
975 struct vcnl4000_data
*data
= iio_priv(indio_dev
);
978 ret
= i2c_smbus_write_byte_data(data
->client
, VCNL4010_INT_CTRL
, 0);
982 return i2c_smbus_write_byte_data(data
->client
, VCNL4000_COMMAND
, 0);
985 static const struct iio_buffer_setup_ops vcnl4010_buffer_ops
= {
986 .postenable
= &vcnl4010_buffer_postenable
,
987 .predisable
= &vcnl4010_buffer_predisable
,
990 static const struct iio_trigger_ops vcnl4010_trigger_ops
= {
991 .validate_device
= iio_trigger_validate_own_device
,
994 static int vcnl4010_probe_trigger(struct iio_dev
*indio_dev
)
996 struct vcnl4000_data
*data
= iio_priv(indio_dev
);
997 struct i2c_client
*client
= data
->client
;
998 struct iio_trigger
*trigger
;
1000 trigger
= devm_iio_trigger_alloc(&client
->dev
, "%s-dev%d",
1001 indio_dev
->name
, indio_dev
->id
);
1005 trigger
->dev
.parent
= &client
->dev
;
1006 trigger
->ops
= &vcnl4010_trigger_ops
;
1007 iio_trigger_set_drvdata(trigger
, indio_dev
);
1009 return devm_iio_trigger_register(&client
->dev
, trigger
);
1012 static int vcnl4000_probe(struct i2c_client
*client
,
1013 const struct i2c_device_id
*id
)
1015 struct vcnl4000_data
*data
;
1016 struct iio_dev
*indio_dev
;
1019 indio_dev
= devm_iio_device_alloc(&client
->dev
, sizeof(*data
));
1023 data
= iio_priv(indio_dev
);
1024 i2c_set_clientdata(client
, indio_dev
);
1025 data
->client
= client
;
1026 data
->id
= id
->driver_data
;
1027 data
->chip_spec
= &vcnl4000_chip_spec_cfg
[data
->id
];
1029 ret
= data
->chip_spec
->init(data
);
1033 dev_dbg(&client
->dev
, "%s Ambient light/proximity sensor, Rev: %02x\n",
1034 data
->chip_spec
->prod
, data
->rev
);
1036 if (device_property_read_u32(&client
->dev
, "proximity-near-level",
1038 data
->near_level
= 0;
1040 indio_dev
->info
= data
->chip_spec
->info
;
1041 indio_dev
->channels
= data
->chip_spec
->channels
;
1042 indio_dev
->num_channels
= data
->chip_spec
->num_channels
;
1043 indio_dev
->name
= VCNL4000_DRV_NAME
;
1044 indio_dev
->modes
= INDIO_DIRECT_MODE
;
1046 if (client
->irq
&& data
->chip_spec
->irq_support
) {
1047 ret
= devm_iio_triggered_buffer_setup(&client
->dev
, indio_dev
,
1049 vcnl4010_trigger_handler
,
1050 &vcnl4010_buffer_ops
);
1052 dev_err(&client
->dev
,
1053 "unable to setup iio triggered buffer\n");
1057 ret
= devm_request_threaded_irq(&client
->dev
, client
->irq
,
1058 NULL
, vcnl4010_irq_thread
,
1059 IRQF_TRIGGER_FALLING
|
1064 dev_err(&client
->dev
, "irq request failed\n");
1068 ret
= vcnl4010_probe_trigger(indio_dev
);
1073 ret
= pm_runtime_set_active(&client
->dev
);
1077 ret
= iio_device_register(indio_dev
);
1081 pm_runtime_enable(&client
->dev
);
1082 pm_runtime_set_autosuspend_delay(&client
->dev
, VCNL4000_SLEEP_DELAY_MS
);
1083 pm_runtime_use_autosuspend(&client
->dev
);
1087 data
->chip_spec
->set_power_state(data
, false);
1091 static const struct of_device_id vcnl_4000_of_match
[] = {
1093 .compatible
= "vishay,vcnl4000",
1094 .data
= (void *)VCNL4000
,
1097 .compatible
= "vishay,vcnl4010",
1098 .data
= (void *)VCNL4010
,
1101 .compatible
= "vishay,vcnl4020",
1102 .data
= (void *)VCNL4010
,
1105 .compatible
= "vishay,vcnl4040",
1106 .data
= (void *)VCNL4040
,
1109 .compatible
= "vishay,vcnl4200",
1110 .data
= (void *)VCNL4200
,
1114 MODULE_DEVICE_TABLE(of
, vcnl_4000_of_match
);
1116 static int vcnl4000_remove(struct i2c_client
*client
)
1118 struct iio_dev
*indio_dev
= i2c_get_clientdata(client
);
1119 struct vcnl4000_data
*data
= iio_priv(indio_dev
);
1121 pm_runtime_dont_use_autosuspend(&client
->dev
);
1122 pm_runtime_disable(&client
->dev
);
1123 iio_device_unregister(indio_dev
);
1124 pm_runtime_set_suspended(&client
->dev
);
1126 return data
->chip_spec
->set_power_state(data
, false);
1129 static int __maybe_unused
vcnl4000_runtime_suspend(struct device
*dev
)
1131 struct iio_dev
*indio_dev
= i2c_get_clientdata(to_i2c_client(dev
));
1132 struct vcnl4000_data
*data
= iio_priv(indio_dev
);
1134 return data
->chip_spec
->set_power_state(data
, false);
1137 static int __maybe_unused
vcnl4000_runtime_resume(struct device
*dev
)
1139 struct iio_dev
*indio_dev
= i2c_get_clientdata(to_i2c_client(dev
));
1140 struct vcnl4000_data
*data
= iio_priv(indio_dev
);
1142 return data
->chip_spec
->set_power_state(data
, true);
1145 static const struct dev_pm_ops vcnl4000_pm_ops
= {
1146 SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend
,
1147 pm_runtime_force_resume
)
1148 SET_RUNTIME_PM_OPS(vcnl4000_runtime_suspend
,
1149 vcnl4000_runtime_resume
, NULL
)
1152 static struct i2c_driver vcnl4000_driver
= {
1154 .name
= VCNL4000_DRV_NAME
,
1155 .pm
= &vcnl4000_pm_ops
,
1156 .of_match_table
= vcnl_4000_of_match
,
1158 .probe
= vcnl4000_probe
,
1159 .id_table
= vcnl4000_id
,
1160 .remove
= vcnl4000_remove
,
1163 module_i2c_driver(vcnl4000_driver
);
1165 MODULE_AUTHOR("Peter Meerwald <pmeerw@pmeerw.net>");
1166 MODULE_AUTHOR("Mathieu Othacehe <m.othacehe@gmail.com>");
1167 MODULE_DESCRIPTION("Vishay VCNL4000 proximity/ambient light sensor driver");
1168 MODULE_LICENSE("GPL");