1
1
/*
2
- * vcnl4000.c - Support for Vishay VCNL4000/4010/4020/4200 combined ambient
2
+ * vcnl4000.c - Support for Vishay VCNL4000/4010/4020/4040/ 4200 combined ambient
3
3
* light and proximity sensor
4
4
*
5
5
* Copyright 2012 Peter Meerwald <[email protected] >
6
+ * Copyright 2019 Pursim SPC
6
7
*
7
8
* This file is subject to the terms and conditions of version 2 of
8
9
* the GNU General Public License. See the file COPYING in the main
9
10
* directory of this archive for more details.
10
11
*
11
12
* IIO driver for:
12
13
* VCNL4000/10/20 (7-bit I2C slave address 0x13)
14
+ * VCNL4040 (7-bit I2C slave address 0x60)
13
15
* VCNL4200 (7-bit I2C slave address 0x51)
14
16
*
15
17
* TODO:
16
18
* allow to adjust IR current
17
19
* proximity threshold and event handling
18
20
* periodic ALS/proximity measurement (VCNL4010/20)
19
- * interrupts (VCNL4010/20, VCNL4200)
21
+ * interrupts (VCNL4010/20/40 , VCNL4200)
20
22
*/
21
23
22
24
#include <linux/module.h>
30
32
#define VCNL4000_DRV_NAME "vcnl4000"
31
33
#define VCNL4000_PROD_ID 0x01
32
34
#define VCNL4010_PROD_ID 0x02 /* for VCNL4020, VCNL4010 */
35
+ #define VCNL4040_PROD_ID 0x86
33
36
#define VCNL4200_PROD_ID 0x58
34
37
35
38
#define VCNL4000_COMMAND 0x80 /* Command register */
49
52
#define VCNL4200_AL_DATA 0x09 /* Ambient light data */
50
53
#define VCNL4200_DEV_ID 0x0e /* Device ID, slave address and version */
51
54
55
+ #define VCNL4040_DEV_ID 0x0c /* Device ID and version */
56
+
52
57
/* Bit masks for COMMAND register */
53
58
#define VCNL4000_AL_RDY BIT(6) /* ALS data ready? */
54
59
#define VCNL4000_PS_RDY BIT(5) /* proximity data ready? */
58
63
enum vcnl4000_device_ids {
59
64
VCNL4000 ,
60
65
VCNL4010 ,
66
+ VCNL4040 ,
61
67
VCNL4200 ,
62
68
};
63
69
@@ -90,6 +96,7 @@ static const struct i2c_device_id vcnl4000_id[] = {
90
96
{ "vcnl4000" , VCNL4000 },
91
97
{ "vcnl4010" , VCNL4010 },
92
98
{ "vcnl4020" , VCNL4010 },
99
+ { "vcnl4040" , VCNL4040 },
93
100
{ "vcnl4200" , VCNL4200 },
94
101
{ }
95
102
};
@@ -128,14 +135,26 @@ static int vcnl4000_init(struct vcnl4000_data *data)
128
135
129
136
static int vcnl4200_init (struct vcnl4000_data * data )
130
137
{
131
- int ret ;
138
+ int ret , id ;
132
139
133
140
ret = i2c_smbus_read_word_data (data -> client , VCNL4200_DEV_ID );
134
141
if (ret < 0 )
135
142
return ret ;
136
143
137
- if ((ret & 0xff ) != VCNL4200_PROD_ID )
138
- return - ENODEV ;
144
+ id = ret & 0xff ;
145
+
146
+ if (id != VCNL4200_PROD_ID ) {
147
+ ret = i2c_smbus_read_word_data (data -> client , VCNL4040_DEV_ID );
148
+ if (ret < 0 )
149
+ return ret ;
150
+
151
+ id = ret & 0xff ;
152
+
153
+ if (id != VCNL4040_PROD_ID )
154
+ return - ENODEV ;
155
+ }
156
+
157
+ dev_dbg (& data -> client -> dev , "device id 0x%x" , id );
139
158
140
159
data -> rev = (ret >> 8 ) & 0xf ;
141
160
@@ -150,9 +169,19 @@ static int vcnl4200_init(struct vcnl4000_data *data)
150
169
data -> al_scale = 24000 ;
151
170
data -> vcnl4200_al .reg = VCNL4200_AL_DATA ;
152
171
data -> vcnl4200_ps .reg = VCNL4200_PS_DATA ;
153
- /* Integration time is 50ms, but the experiments show 54ms in total. */
154
- data -> vcnl4200_al .sampling_rate = ktime_set (0 , 54000 * 1000 );
155
- data -> vcnl4200_ps .sampling_rate = ktime_set (0 , 4200 * 1000 );
172
+ switch (id ) {
173
+ case VCNL4200_PROD_ID :
174
+ /* Integration time is 50ms, but the experiments */
175
+ /* show 54ms in total. */
176
+ data -> vcnl4200_al .sampling_rate = ktime_set (0 , 54000 * 1000 );
177
+ data -> vcnl4200_ps .sampling_rate = ktime_set (0 , 4200 * 1000 );
178
+ break ;
179
+ case VCNL4040_PROD_ID :
180
+ /* Integration time is 80ms, add 10ms. */
181
+ data -> vcnl4200_al .sampling_rate = ktime_set (0 , 100000 * 1000 );
182
+ data -> vcnl4200_ps .sampling_rate = ktime_set (0 , 100000 * 1000 );
183
+ break ;
184
+ }
156
185
data -> vcnl4200_al .last_measurement = ktime_set (0 , 0 );
157
186
data -> vcnl4200_ps .last_measurement = ktime_set (0 , 0 );
158
187
mutex_init (& data -> vcnl4200_al .lock );
@@ -271,6 +300,12 @@ static const struct vcnl4000_chip_spec vcnl4000_chip_spec_cfg[] = {
271
300
.measure_light = vcnl4000_measure_light ,
272
301
.measure_proximity = vcnl4000_measure_proximity ,
273
302
},
303
+ [VCNL4040 ] = {
304
+ .prod = "VCNL4040" ,
305
+ .init = vcnl4200_init ,
306
+ .measure_light = vcnl4200_measure_light ,
307
+ .measure_proximity = vcnl4200_measure_proximity ,
308
+ },
274
309
[VCNL4200 ] = {
275
310
.prod = "VCNL4200" ,
276
311
.init = vcnl4200_init ,
0 commit comments