1 // SPDX-License-Identifier: GPL-2.0-only
3 * vl6180.c - Support for STMicroelectronics VL6180 ALS, range and proximity
6 * Copyright 2017 Peter Meerwald-Stadler <pmeerw@pmeerw.net>
7 * Copyright 2017 Manivannan Sadhasivam <manivannanece23@gmail.com>
9 * IIO driver for VL6180 (7-bit I2C slave address 0x29)
12 * ALS: < 1 Lux up to 100 kLux
15 * TODO: irq, threshold events, continuous mode, hardware buffer
18 #include <linux/module.h>
19 #include <linux/mod_devicetable.h>
20 #include <linux/i2c.h>
21 #include <linux/mutex.h>
22 #include <linux/err.h>
23 #include <linux/delay.h>
24 #include <linux/util_macros.h>
26 #include <linux/iio/iio.h>
27 #include <linux/iio/sysfs.h>
28 #include <linux/iio/buffer.h>
29 #include <linux/iio/trigger.h>
30 #include <linux/iio/trigger_consumer.h>
31 #include <linux/iio/triggered_buffer.h>
33 #define VL6180_DRV_NAME "vl6180"
35 /* Device identification register and value */
36 #define VL6180_MODEL_ID 0x000
37 #define VL6180_MODEL_ID_VAL 0xb4
39 /* Configuration registers */
40 #define VL6180_INTR_CONFIG 0x014
41 #define VL6180_INTR_CLEAR 0x015
42 #define VL6180_OUT_OF_RESET 0x016
43 #define VL6180_HOLD 0x017
44 #define VL6180_RANGE_START 0x018
45 #define VL6180_RANGE_INTER_MEAS_TIME 0x01b
46 #define VL6180_ALS_START 0x038
47 #define VL6180_ALS_INTER_MEAS_TIME 0x03e
48 #define VL6180_ALS_GAIN 0x03f
49 #define VL6180_ALS_IT 0x040
51 /* Status registers */
52 #define VL6180_RANGE_STATUS 0x04d
53 #define VL6180_ALS_STATUS 0x04e
54 #define VL6180_INTR_STATUS 0x04f
56 /* Result value registers */
57 #define VL6180_ALS_VALUE 0x050
58 #define VL6180_RANGE_VALUE 0x062
59 #define VL6180_RANGE_RATE 0x066
61 /* bits of the RANGE_START and ALS_START register */
62 #define VL6180_MODE_CONT BIT(1) /* continuous mode */
63 #define VL6180_STARTSTOP BIT(0) /* start measurement, auto-reset */
65 /* bits of the INTR_STATUS and INTR_CONFIG register */
66 #define VL6180_ALS_READY BIT(5)
67 #define VL6180_RANGE_READY BIT(2)
69 /* bits of the INTR_CLEAR register */
70 #define VL6180_CLEAR_ERROR BIT(2)
71 #define VL6180_CLEAR_ALS BIT(1)
72 #define VL6180_CLEAR_RANGE BIT(0)
74 /* bits of the HOLD register */
75 #define VL6180_HOLD_ON BIT(0)
77 /* default value for the ALS_IT register */
78 #define VL6180_ALS_IT_100 0x63 /* 100 ms */
80 /* values for the ALS_GAIN register */
81 #define VL6180_ALS_GAIN_1 0x46
82 #define VL6180_ALS_GAIN_1_25 0x45
83 #define VL6180_ALS_GAIN_1_67 0x44
84 #define VL6180_ALS_GAIN_2_5 0x43
85 #define VL6180_ALS_GAIN_5 0x42
86 #define VL6180_ALS_GAIN_10 0x41
87 #define VL6180_ALS_GAIN_20 0x40
88 #define VL6180_ALS_GAIN_40 0x47
91 struct i2c_client
*client
;
93 struct completion completion
;
94 struct iio_trigger
*trig
;
95 unsigned int als_gain_milli
;
96 unsigned int als_it_ms
;
97 unsigned int als_meas_rate
;
98 unsigned int range_meas_rate
;
102 aligned_s64 timestamp
;
106 enum { VL6180_ALS
, VL6180_RANGE
, VL6180_PROX
};
109 * struct vl6180_chan_regs - Registers for accessing channels
110 * @drdy_mask: Data ready bit in status register
111 * @start_reg: Conversion start register
112 * @value_reg: Result value register
113 * @word: Register word length
115 struct vl6180_chan_regs
{
117 u16 start_reg
, value_reg
;
121 static const struct vl6180_chan_regs vl6180_chan_regs_table
[] = {
123 .drdy_mask
= VL6180_ALS_READY
,
124 .start_reg
= VL6180_ALS_START
,
125 .value_reg
= VL6180_ALS_VALUE
,
129 .drdy_mask
= VL6180_RANGE_READY
,
130 .start_reg
= VL6180_RANGE_START
,
131 .value_reg
= VL6180_RANGE_VALUE
,
135 .drdy_mask
= VL6180_RANGE_READY
,
136 .start_reg
= VL6180_RANGE_START
,
137 .value_reg
= VL6180_RANGE_RATE
,
142 static int vl6180_read(struct i2c_client
*client
, u16 cmd
, void *databuf
,
145 __be16 cmdbuf
= cpu_to_be16(cmd
);
146 struct i2c_msg msgs
[2] = {
147 { .addr
= client
->addr
, .len
= sizeof(cmdbuf
), .buf
= (u8
*) &cmdbuf
},
148 { .addr
= client
->addr
, .len
= len
, .buf
= databuf
,
149 .flags
= I2C_M_RD
} };
152 ret
= i2c_transfer(client
->adapter
, msgs
, ARRAY_SIZE(msgs
));
154 dev_err(&client
->dev
, "failed reading register 0x%04x\n", cmd
);
159 static int vl6180_read_byte(struct i2c_client
*client
, u16 cmd
)
164 ret
= vl6180_read(client
, cmd
, &data
, sizeof(data
));
171 static int vl6180_read_word(struct i2c_client
*client
, u16 cmd
)
176 ret
= vl6180_read(client
, cmd
, &data
, sizeof(data
));
180 return be16_to_cpu(data
);
183 static int vl6180_write_byte(struct i2c_client
*client
, u16 cmd
, u8 val
)
186 struct i2c_msg msgs
[1] = {
187 { .addr
= client
->addr
, .len
= sizeof(buf
), .buf
= (u8
*) &buf
} };
194 ret
= i2c_transfer(client
->adapter
, msgs
, ARRAY_SIZE(msgs
));
196 dev_err(&client
->dev
, "failed writing register 0x%04x\n", cmd
);
203 static int vl6180_write_word(struct i2c_client
*client
, u16 cmd
, u16 val
)
206 struct i2c_msg msgs
[1] = {
207 { .addr
= client
->addr
, .len
= sizeof(buf
), .buf
= (u8
*) &buf
} };
210 buf
[0] = cpu_to_be16(cmd
);
211 buf
[1] = cpu_to_be16(val
);
213 ret
= i2c_transfer(client
->adapter
, msgs
, ARRAY_SIZE(msgs
));
215 dev_err(&client
->dev
, "failed writing register 0x%04x\n", cmd
);
222 static int vl6180_measure(struct vl6180_data
*data
, int addr
)
224 struct i2c_client
*client
= data
->client
;
225 unsigned long time_left
;
229 mutex_lock(&data
->lock
);
230 reinit_completion(&data
->completion
);
232 /* Start single shot measurement */
233 ret
= vl6180_write_byte(client
,
234 vl6180_chan_regs_table
[addr
].start_reg
, VL6180_STARTSTOP
);
239 time_left
= wait_for_completion_timeout(&data
->completion
, HZ
/ 10);
240 if (time_left
== 0) {
246 ret
= vl6180_read_byte(client
, VL6180_INTR_STATUS
);
250 if (ret
& vl6180_chan_regs_table
[addr
].drdy_mask
)
261 /* Read result value from appropriate registers */
262 ret
= vl6180_chan_regs_table
[addr
].word
?
263 vl6180_read_word(client
, vl6180_chan_regs_table
[addr
].value_reg
) :
264 vl6180_read_byte(client
, vl6180_chan_regs_table
[addr
].value_reg
);
269 /* Clear the interrupt flag after data read */
270 ret
= vl6180_write_byte(client
, VL6180_INTR_CLEAR
,
271 VL6180_CLEAR_ERROR
| VL6180_CLEAR_ALS
| VL6180_CLEAR_RANGE
);
278 mutex_unlock(&data
->lock
);
283 static const struct iio_chan_spec vl6180_channels
[] = {
286 .address
= VL6180_ALS
,
287 .scan_index
= VL6180_ALS
,
293 .info_mask_separate
= BIT(IIO_CHAN_INFO_RAW
) |
294 BIT(IIO_CHAN_INFO_INT_TIME
) |
295 BIT(IIO_CHAN_INFO_SCALE
) |
296 BIT(IIO_CHAN_INFO_HARDWAREGAIN
) |
297 BIT(IIO_CHAN_INFO_SAMP_FREQ
),
299 .type
= IIO_DISTANCE
,
300 .address
= VL6180_RANGE
,
301 .scan_index
= VL6180_RANGE
,
307 .info_mask_separate
= BIT(IIO_CHAN_INFO_RAW
) |
308 BIT(IIO_CHAN_INFO_SCALE
) |
309 BIT(IIO_CHAN_INFO_SAMP_FREQ
),
311 .type
= IIO_PROXIMITY
,
312 .address
= VL6180_PROX
,
313 .scan_index
= VL6180_PROX
,
319 .info_mask_separate
= BIT(IIO_CHAN_INFO_RAW
),
321 IIO_CHAN_SOFT_TIMESTAMP(3),
325 * Available Ambient Light Sensor gain settings, 1/1000th, and
326 * corresponding setting for the VL6180_ALS_GAIN register
328 static const int vl6180_als_gain_tab
[8] = {
329 1000, 1250, 1670, 2500, 5000, 10000, 20000, 40000
331 static const u8 vl6180_als_gain_tab_bits
[8] = {
332 VL6180_ALS_GAIN_1
, VL6180_ALS_GAIN_1_25
,
333 VL6180_ALS_GAIN_1_67
, VL6180_ALS_GAIN_2_5
,
334 VL6180_ALS_GAIN_5
, VL6180_ALS_GAIN_10
,
335 VL6180_ALS_GAIN_20
, VL6180_ALS_GAIN_40
338 static int vl6180_read_raw(struct iio_dev
*indio_dev
,
339 struct iio_chan_spec
const *chan
,
340 int *val
, int *val2
, long mask
)
342 struct vl6180_data
*data
= iio_priv(indio_dev
);
346 case IIO_CHAN_INFO_RAW
:
347 ret
= vl6180_measure(data
, chan
->address
);
353 case IIO_CHAN_INFO_INT_TIME
:
354 *val
= data
->als_it_ms
;
357 return IIO_VAL_FRACTIONAL
;
359 case IIO_CHAN_INFO_SCALE
:
360 switch (chan
->type
) {
362 /* one ALS count is 0.32 Lux @ gain 1, IT 100 ms */
363 *val
= 32000; /* 0.32 * 1000 * 100 */
364 *val2
= data
->als_gain_milli
* data
->als_it_ms
;
366 return IIO_VAL_FRACTIONAL
;
369 *val
= 0; /* sensor reports mm, scale to meter */
376 return IIO_VAL_INT_PLUS_MICRO
;
377 case IIO_CHAN_INFO_HARDWAREGAIN
:
378 *val
= data
->als_gain_milli
;
381 return IIO_VAL_FRACTIONAL
;
383 case IIO_CHAN_INFO_SAMP_FREQ
:
384 switch (chan
->type
) {
386 *val
= data
->range_meas_rate
;
389 *val
= data
->als_meas_rate
;
400 static IIO_CONST_ATTR(als_gain_available
, "1 1.25 1.67 2.5 5 10 20 40");
402 static struct attribute
*vl6180_attributes
[] = {
403 &iio_const_attr_als_gain_available
.dev_attr
.attr
,
407 static const struct attribute_group vl6180_attribute_group
= {
408 .attrs
= vl6180_attributes
,
411 /* HOLD is needed before updating any config registers */
412 static int vl6180_hold(struct vl6180_data
*data
, bool hold
)
414 return vl6180_write_byte(data
->client
, VL6180_HOLD
,
415 hold
? VL6180_HOLD_ON
: 0);
418 static int vl6180_set_als_gain(struct vl6180_data
*data
, int val
, int val2
)
422 if (val
< 1 || val
> 40)
425 gain
= (val
* 1000000 + val2
) / 1000;
426 if (gain
< 1 || gain
> 40000)
429 i
= find_closest(gain
, vl6180_als_gain_tab
,
430 ARRAY_SIZE(vl6180_als_gain_tab
));
432 mutex_lock(&data
->lock
);
433 ret
= vl6180_hold(data
, true);
437 ret
= vl6180_write_byte(data
->client
, VL6180_ALS_GAIN
,
438 vl6180_als_gain_tab_bits
[i
]);
441 data
->als_gain_milli
= vl6180_als_gain_tab
[i
];
444 vl6180_hold(data
, false);
445 mutex_unlock(&data
->lock
);
449 static int vl6180_set_it(struct vl6180_data
*data
, int val
, int val2
)
453 it_ms
= DIV_ROUND_CLOSEST(val2
, 1000); /* round to ms */
454 if (val
!= 0 || it_ms
< 1 || it_ms
> 512)
457 mutex_lock(&data
->lock
);
458 ret
= vl6180_hold(data
, true);
462 ret
= vl6180_write_word(data
->client
, VL6180_ALS_IT
, it_ms
- 1);
465 data
->als_it_ms
= it_ms
;
468 vl6180_hold(data
, false);
469 mutex_unlock(&data
->lock
);
474 static int vl6180_meas_reg_val_from_mhz(unsigned int mhz
)
476 unsigned int period
= DIV_ROUND_CLOSEST(1000 * 1000, mhz
);
477 unsigned int reg_val
= 0;
480 reg_val
= period
< 2550 ? (DIV_ROUND_CLOSEST(period
, 10) - 1) : 254;
485 static int vl6180_write_raw(struct iio_dev
*indio_dev
,
486 struct iio_chan_spec
const *chan
,
487 int val
, int val2
, long mask
)
489 struct vl6180_data
*data
= iio_priv(indio_dev
);
490 unsigned int reg_val
;
493 case IIO_CHAN_INFO_INT_TIME
:
494 return vl6180_set_it(data
, val
, val2
);
496 case IIO_CHAN_INFO_HARDWAREGAIN
:
497 if (chan
->type
!= IIO_LIGHT
)
500 return vl6180_set_als_gain(data
, val
, val2
);
502 case IIO_CHAN_INFO_SAMP_FREQ
:
504 guard(mutex
)(&data
->lock
);
505 switch (chan
->type
) {
507 data
->range_meas_rate
= val
;
508 reg_val
= vl6180_meas_reg_val_from_mhz(val
);
509 return vl6180_write_byte(data
->client
,
510 VL6180_RANGE_INTER_MEAS_TIME
, reg_val
);
513 data
->als_meas_rate
= val
;
514 reg_val
= vl6180_meas_reg_val_from_mhz(val
);
515 return vl6180_write_byte(data
->client
,
516 VL6180_ALS_INTER_MEAS_TIME
, reg_val
);
528 static irqreturn_t
vl6180_threaded_irq(int irq
, void *priv
)
530 struct iio_dev
*indio_dev
= priv
;
531 struct vl6180_data
*data
= iio_priv(indio_dev
);
533 if (iio_buffer_enabled(indio_dev
))
534 iio_trigger_poll_nested(indio_dev
->trig
);
536 complete(&data
->completion
);
541 static irqreturn_t
vl6180_trigger_handler(int irq
, void *priv
)
543 struct iio_poll_func
*pf
= priv
;
544 struct iio_dev
*indio_dev
= pf
->indio_dev
;
545 struct vl6180_data
*data
= iio_priv(indio_dev
);
546 s64 time_ns
= iio_get_time_ns(indio_dev
);
549 iio_for_each_active_channel(indio_dev
, bit
) {
550 if (vl6180_chan_regs_table
[bit
].word
)
551 ret
= vl6180_read_word(data
->client
,
552 vl6180_chan_regs_table
[bit
].value_reg
);
554 ret
= vl6180_read_byte(data
->client
,
555 vl6180_chan_regs_table
[bit
].value_reg
);
558 dev_err(&data
->client
->dev
,
559 "failed to read from value regs: %d\n", ret
);
563 data
->scan
.chan
[i
++] = ret
;
566 iio_push_to_buffers_with_timestamp(indio_dev
, &data
->scan
, time_ns
);
567 iio_trigger_notify_done(indio_dev
->trig
);
569 /* Clear the interrupt flag after data read */
570 ret
= vl6180_write_byte(data
->client
, VL6180_INTR_CLEAR
,
571 VL6180_CLEAR_ERROR
| VL6180_CLEAR_ALS
| VL6180_CLEAR_RANGE
);
573 dev_err(&data
->client
->dev
, "failed to clear irq: %d\n", ret
);
578 static const struct iio_info vl6180_info
= {
579 .read_raw
= vl6180_read_raw
,
580 .write_raw
= vl6180_write_raw
,
581 .attrs
= &vl6180_attribute_group
,
582 .validate_trigger
= iio_validate_own_trigger
,
585 static int vl6180_buffer_postenable(struct iio_dev
*indio_dev
)
587 struct vl6180_data
*data
= iio_priv(indio_dev
);
590 iio_for_each_active_channel(indio_dev
, bit
)
591 return vl6180_write_byte(data
->client
,
592 vl6180_chan_regs_table
[bit
].start_reg
,
593 VL6180_MODE_CONT
| VL6180_STARTSTOP
);
598 static int vl6180_buffer_postdisable(struct iio_dev
*indio_dev
)
600 struct vl6180_data
*data
= iio_priv(indio_dev
);
603 iio_for_each_active_channel(indio_dev
, bit
)
604 return vl6180_write_byte(data
->client
,
605 vl6180_chan_regs_table
[bit
].start_reg
,
611 static const struct iio_buffer_setup_ops iio_triggered_buffer_setup_ops
= {
612 .postenable
= &vl6180_buffer_postenable
,
613 .postdisable
= &vl6180_buffer_postdisable
,
616 static const struct iio_trigger_ops vl6180_trigger_ops
= {
617 .validate_device
= iio_trigger_validate_own_device
,
620 static int vl6180_init(struct vl6180_data
*data
, struct iio_dev
*indio_dev
)
622 struct i2c_client
*client
= data
->client
;
625 ret
= vl6180_read_byte(client
, VL6180_MODEL_ID
);
629 if (ret
!= VL6180_MODEL_ID_VAL
) {
630 dev_err(&client
->dev
, "invalid model ID %02x\n", ret
);
634 ret
= vl6180_hold(data
, true);
638 ret
= vl6180_read_byte(client
, VL6180_OUT_OF_RESET
);
643 * Detect false reset condition here. This bit is always set when the
644 * system comes out of reset.
647 dev_info(&client
->dev
, "device is not fresh out of reset\n");
649 /* Enable ALS and Range ready interrupts */
650 ret
= vl6180_write_byte(client
, VL6180_INTR_CONFIG
,
651 VL6180_ALS_READY
| VL6180_RANGE_READY
);
655 ret
= devm_iio_triggered_buffer_setup(&client
->dev
, indio_dev
, NULL
,
656 &vl6180_trigger_handler
,
657 &iio_triggered_buffer_setup_ops
);
661 /* Default Range inter-measurement time: 50ms or 20000 mHz */
662 ret
= vl6180_write_byte(client
, VL6180_RANGE_INTER_MEAS_TIME
,
663 vl6180_meas_reg_val_from_mhz(20000));
666 data
->range_meas_rate
= 20000;
668 /* Default ALS inter-measurement time: 10ms or 100000 mHz */
669 ret
= vl6180_write_byte(client
, VL6180_ALS_INTER_MEAS_TIME
,
670 vl6180_meas_reg_val_from_mhz(100000));
673 data
->als_meas_rate
= 100000;
675 /* ALS integration time: 100ms */
676 data
->als_it_ms
= 100;
677 ret
= vl6180_write_word(client
, VL6180_ALS_IT
, VL6180_ALS_IT_100
);
682 data
->als_gain_milli
= 1000;
683 ret
= vl6180_write_byte(client
, VL6180_ALS_GAIN
, VL6180_ALS_GAIN_1
);
687 ret
= vl6180_write_byte(client
, VL6180_OUT_OF_RESET
, 0x00);
691 return vl6180_hold(data
, false);
694 static int vl6180_probe(struct i2c_client
*client
)
696 struct vl6180_data
*data
;
697 struct iio_dev
*indio_dev
;
700 indio_dev
= devm_iio_device_alloc(&client
->dev
, sizeof(*data
));
704 data
= iio_priv(indio_dev
);
705 i2c_set_clientdata(client
, indio_dev
);
706 data
->client
= client
;
707 mutex_init(&data
->lock
);
709 indio_dev
->info
= &vl6180_info
;
710 indio_dev
->channels
= vl6180_channels
;
711 indio_dev
->num_channels
= ARRAY_SIZE(vl6180_channels
);
712 indio_dev
->name
= VL6180_DRV_NAME
;
713 indio_dev
->modes
= INDIO_DIRECT_MODE
;
715 ret
= vl6180_init(data
, indio_dev
);
720 ret
= devm_request_threaded_irq(&client
->dev
, client
->irq
,
721 NULL
, vl6180_threaded_irq
,
723 indio_dev
->name
, indio_dev
);
725 return dev_err_probe(&client
->dev
, ret
, "devm_request_irq error \n");
727 init_completion(&data
->completion
);
729 data
->trig
= devm_iio_trigger_alloc(&client
->dev
, "%s-dev%d",
730 indio_dev
->name
, iio_device_id(indio_dev
));
734 data
->trig
->ops
= &vl6180_trigger_ops
;
735 iio_trigger_set_drvdata(data
->trig
, indio_dev
);
736 ret
= devm_iio_trigger_register(&client
->dev
, data
->trig
);
740 indio_dev
->trig
= iio_trigger_get(data
->trig
);
743 return devm_iio_device_register(&client
->dev
, indio_dev
);
746 static const struct of_device_id vl6180_of_match
[] = {
747 { .compatible
= "st,vl6180", },
750 MODULE_DEVICE_TABLE(of
, vl6180_of_match
);
752 static const struct i2c_device_id vl6180_id
[] = {
756 MODULE_DEVICE_TABLE(i2c
, vl6180_id
);
758 static struct i2c_driver vl6180_driver
= {
760 .name
= VL6180_DRV_NAME
,
761 .of_match_table
= vl6180_of_match
,
763 .probe
= vl6180_probe
,
764 .id_table
= vl6180_id
,
767 module_i2c_driver(vl6180_driver
);
769 MODULE_AUTHOR("Peter Meerwald-Stadler <pmeerw@pmeerw.net>");
770 MODULE_AUTHOR("Manivannan Sadhasivam <manivannanece23@gmail.com>");
771 MODULE_DESCRIPTION("STMicro VL6180 ALS, range and proximity sensor driver");
772 MODULE_LICENSE("GPL");