xref: /linux/drivers/iio/light/vcnl4000.c (revision 3a2c4d55e32ad65efebdb6de44eef3bfa08bb49d)
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 <pmeerw@pmeerw.net>
7  * Copyright 2019 Pursim SPC
8  * Copyright 2020 Mathieu Othacehe <m.othacehe@gmail.com>
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/cleanup.h>
22 #include <linux/delay.h>
23 #include <linux/err.h>
24 #include <linux/i2c.h>
25 #include <linux/interrupt.h>
26 #include <linux/module.h>
27 #include <linux/pm_runtime.h>
28 #include <linux/regulator/consumer.h>
29 #include <linux/units.h>
30 
31 #include <linux/iio/buffer.h>
32 #include <linux/iio/events.h>
33 #include <linux/iio/iio.h>
34 #include <linux/iio/sysfs.h>
35 #include <linux/iio/trigger.h>
36 #include <linux/iio/trigger_consumer.h>
37 #include <linux/iio/triggered_buffer.h>
38 
39 #define VCNL4000_DRV_NAME "vcnl4000"
40 #define VCNL4000_PROD_ID	0x01
41 #define VCNL4010_PROD_ID	0x02 /* for VCNL4020, VCNL4010 */
42 #define VCNL4040_PROD_ID	0x86
43 #define VCNL4200_PROD_ID	0x58
44 
45 #define VCNL4000_COMMAND	0x80 /* Command register */
46 #define VCNL4000_PROD_REV	0x81 /* Product ID and Revision ID */
47 #define VCNL4010_PROX_RATE      0x82 /* Proximity rate */
48 #define VCNL4000_LED_CURRENT	0x83 /* IR LED current for proximity mode */
49 #define VCNL4000_AL_PARAM	0x84 /* Ambient light parameter register */
50 #define VCNL4010_ALS_PARAM      0x84 /* ALS rate */
51 #define VCNL4000_AL_RESULT_HI	0x85 /* Ambient light result register, MSB */
52 #define VCNL4000_AL_RESULT_LO	0x86 /* Ambient light result register, LSB */
53 #define VCNL4000_PS_RESULT_HI	0x87 /* Proximity result register, MSB */
54 #define VCNL4000_PS_RESULT_LO	0x88 /* Proximity result register, LSB */
55 #define VCNL4000_PS_MEAS_FREQ	0x89 /* Proximity test signal frequency */
56 #define VCNL4010_INT_CTRL	0x89 /* Interrupt control */
57 #define VCNL4000_PS_MOD_ADJ	0x8a /* Proximity modulator timing adjustment */
58 #define VCNL4010_LOW_THR_HI     0x8a /* Low threshold, MSB */
59 #define VCNL4010_LOW_THR_LO     0x8b /* Low threshold, LSB */
60 #define VCNL4010_HIGH_THR_HI    0x8c /* High threshold, MSB */
61 #define VCNL4010_HIGH_THR_LO    0x8d /* High threshold, LSB */
62 #define VCNL4010_ISR		0x8e /* Interrupt status */
63 
64 #define VCNL4200_AL_CONF	0x00 /* Ambient light configuration */
65 #define VCNL4200_PS_CONF1	0x03 /* Proximity configuration */
66 #define VCNL4200_PS_CONF3	0x04 /* Proximity configuration */
67 #define VCNL4040_PS_THDL_LM	0x06 /* Proximity threshold low */
68 #define VCNL4040_PS_THDH_LM	0x07 /* Proximity threshold high */
69 #define VCNL4040_ALS_THDL_LM	0x02 /* Ambient light threshold low */
70 #define VCNL4040_ALS_THDH_LM	0x01 /* Ambient light threshold high */
71 #define VCNL4200_PS_DATA	0x08 /* Proximity data */
72 #define VCNL4200_AL_DATA	0x09 /* Ambient light data */
73 #define VCNL4040_INT_FLAGS	0x0b /* Interrupt register */
74 #define VCNL4200_INT_FLAGS	0x0d /* Interrupt register */
75 #define VCNL4200_DEV_ID		0x0e /* Device ID, slave address and version */
76 
77 #define VCNL4040_DEV_ID		0x0c /* Device ID and version */
78 
79 /* Bit masks for COMMAND register */
80 #define VCNL4000_AL_RDY		BIT(6) /* ALS data ready? */
81 #define VCNL4000_PS_RDY		BIT(5) /* proximity data ready? */
82 #define VCNL4000_AL_OD		BIT(4) /* start on-demand ALS measurement */
83 #define VCNL4000_PS_OD		BIT(3) /* start on-demand proximity measurement */
84 #define VCNL4000_ALS_EN		BIT(2) /* start ALS measurement */
85 #define VCNL4000_PROX_EN	BIT(1) /* start proximity measurement */
86 #define VCNL4000_SELF_TIMED_EN	BIT(0) /* start self-timed measurement */
87 
88 #define VCNL4040_ALS_CONF_ALS_SHUTDOWN	BIT(0)
89 #define VCNL4040_ALS_CONF_IT		GENMASK(7, 6) /* Ambient integration time */
90 #define VCNL4040_ALS_CONF_INT_EN	BIT(1) /* Ambient light Interrupt enable */
91 #define VCNL4040_ALS_CONF_PERS	GENMASK(3, 2) /* Ambient interrupt persistence setting */
92 #define VCNL4040_PS_CONF1_PS_SHUTDOWN	BIT(0)
93 #define VCNL4040_PS_CONF2_PS_IT	GENMASK(3, 1) /* Proximity integration time */
94 #define VCNL4040_CONF1_PS_PERS	GENMASK(5, 4) /* Proximity interrupt persistence setting */
95 #define VCNL4040_PS_CONF2_PS_HD		BIT(11)	/* Proximity high definition */
96 #define VCNL4040_PS_CONF2_PS_INT	GENMASK(9, 8) /* Proximity interrupt mode */
97 #define VCNL4040_PS_CONF3_MPS		GENMASK(6, 5) /* Proximity multi pulse number */
98 #define VCNL4040_PS_MS_LED_I		GENMASK(10, 8) /* Proximity current */
99 #define VCNL4040_PS_IF_AWAY		BIT(8) /* Proximity event cross low threshold */
100 #define VCNL4040_PS_IF_CLOSE		BIT(9) /* Proximity event cross high threshold */
101 #define VCNL4040_ALS_RISING		BIT(12) /* Ambient Light cross high threshold */
102 #define VCNL4040_ALS_FALLING		BIT(13) /* Ambient Light cross low threshold */
103 
104 /* Bit masks for interrupt registers. */
105 #define VCNL4010_INT_THR_SEL	BIT(0) /* Select threshold interrupt source */
106 #define VCNL4010_INT_THR_EN	BIT(1) /* Threshold interrupt type */
107 #define VCNL4010_INT_ALS_EN	BIT(2) /* Enable on ALS data ready */
108 #define VCNL4010_INT_PROX_EN	BIT(3) /* Enable on proximity data ready */
109 
110 #define VCNL4010_INT_THR_HIGH	0 /* High threshold exceeded */
111 #define VCNL4010_INT_THR_LOW	1 /* Low threshold exceeded */
112 #define VCNL4010_INT_ALS	2 /* ALS data ready */
113 #define VCNL4010_INT_PROXIMITY	3 /* Proximity data ready */
114 
115 #define VCNL4010_INT_THR \
116 	(BIT(VCNL4010_INT_THR_LOW) | BIT(VCNL4010_INT_THR_HIGH))
117 #define VCNL4010_INT_DRDY \
118 	(BIT(VCNL4010_INT_PROXIMITY) | BIT(VCNL4010_INT_ALS))
119 
120 #define VCNL4040_CONF3_PS_MPS_16BITS	3	/* 8 multi pulses */
121 #define VCNL4040_CONF3_PS_LED_I_16BITS	3	/* 120 mA */
122 
123 #define VCNL4040_CONF3_PS_SAMPLE_16BITS \
124 	(FIELD_PREP(VCNL4040_PS_CONF3_MPS, VCNL4040_CONF3_PS_MPS_16BITS) | \
125 	 FIELD_PREP(VCNL4040_PS_MS_LED_I, VCNL4040_CONF3_PS_LED_I_16BITS))
126 
127 static const int vcnl4010_prox_sampling_frequency[][2] = {
128 	{1, 950000},
129 	{3, 906250},
130 	{7, 812500},
131 	{16, 625000},
132 	{31, 250000},
133 	{62, 500000},
134 	{125, 0},
135 	{250, 0},
136 };
137 
138 static const int vcnl4040_ps_it_times[][2] = {
139 	{0, 100},
140 	{0, 150},
141 	{0, 200},
142 	{0, 250},
143 	{0, 300},
144 	{0, 350},
145 	{0, 400},
146 	{0, 800},
147 };
148 
149 static const int vcnl4200_ps_it_times[][2] = {
150 	{0, 96},
151 	{0, 144},
152 	{0, 192},
153 	{0, 384},
154 	{0, 768},
155 	{0, 864},
156 };
157 
158 static const int vcnl4040_als_it_times[][2] = {
159 	{0, 80000},
160 	{0, 160000},
161 	{0, 320000},
162 	{0, 640000},
163 };
164 
165 static const int vcnl4200_als_it_times[][2] = {
166 	{0, 50000},
167 	{0, 100000},
168 	{0, 200000},
169 	{0, 400000},
170 };
171 
172 static const int vcnl4040_ps_calibbias_ua[][2] = {
173 	{0, 50000},
174 	{0, 75000},
175 	{0, 100000},
176 	{0, 120000},
177 	{0, 140000},
178 	{0, 160000},
179 	{0, 180000},
180 	{0, 200000},
181 };
182 
183 static const int vcnl4040_als_persistence[] = {1, 2, 4, 8};
184 static const int vcnl4040_ps_persistence[] = {1, 2, 3, 4};
185 static const int vcnl4040_ps_oversampling_ratio[] = {1, 2, 4, 8};
186 
187 #define VCNL4000_SLEEP_DELAY_MS	2000 /* before we enter pm_runtime_suspend */
188 
189 struct vcnl4200_channel {
190 	u8 reg;
191 	ktime_t last_measurement;
192 	ktime_t sampling_rate;
193 	struct mutex lock;
194 };
195 
196 struct vcnl4000_data {
197 	struct i2c_client *client;
198 	int rev;
199 	int al_scale;
200 	int ps_scale;
201 	u8 ps_int;		/* proximity interrupt mode */
202 	u8 als_int;		/* ambient light interrupt mode*/
203 	const struct vcnl4000_chip_spec *chip_spec;
204 	struct mutex vcnl4000_lock;
205 	struct vcnl4200_channel vcnl4200_al;
206 	struct vcnl4200_channel vcnl4200_ps;
207 	uint32_t near_level;
208 };
209 
210 struct vcnl4000_chip_spec {
211 	const char *prod;
212 	struct iio_chan_spec const *channels;
213 	const int num_channels;
214 	const struct iio_info *info;
215 	const struct iio_buffer_setup_ops *buffer_setup_ops;
216 	int (*init)(struct vcnl4000_data *data);
217 	int (*measure_light)(struct vcnl4000_data *data, int *val);
218 	int (*measure_proximity)(struct vcnl4000_data *data, int *val);
219 	int (*set_power_state)(struct vcnl4000_data *data, bool on);
220 	irqreturn_t (*irq_thread)(int irq, void *priv);
221 	irqreturn_t (*trig_buffer_func)(int irq, void *priv);
222 
223 	u8 int_reg;
224 	const int(*ps_it_times)[][2];
225 	const int num_ps_it_times;
226 	const int(*als_it_times)[][2];
227 	const int num_als_it_times;
228 	const unsigned int ulux_step;
229 	const int prod_id;
230 };
231 
232 static int vcnl4000_set_power_state(struct vcnl4000_data *data, bool on)
233 {
234 	/* no suspend op */
235 	return 0;
236 }
237 
238 static int vcnl4000_init(struct vcnl4000_data *data)
239 {
240 	int ret, prod_id;
241 
242 	ret = i2c_smbus_read_byte_data(data->client, VCNL4000_PROD_REV);
243 	if (ret < 0)
244 		return ret;
245 
246 	prod_id = ret >> 4;
247 	switch (prod_id) {
248 	case VCNL4000_PROD_ID:
249 		if (data->chip_spec->prod_id != VCNL4000_PROD_ID)
250 			dev_warn(&data->client->dev,
251 					"wrong device id, use vcnl4000");
252 		break;
253 	case VCNL4010_PROD_ID:
254 		if (data->chip_spec->prod_id != VCNL4010_PROD_ID)
255 			dev_warn(&data->client->dev,
256 					"wrong device id, use vcnl4010/4020");
257 		break;
258 	default:
259 		return -ENODEV;
260 	}
261 
262 	data->rev = ret & 0xf;
263 	data->al_scale = 250000;
264 
265 	return 0;
266 };
267 
268 static ssize_t vcnl4000_write_als_enable(struct vcnl4000_data *data, bool en)
269 {
270 	int ret;
271 
272 	guard(mutex)(&data->vcnl4000_lock);
273 
274 	ret = i2c_smbus_read_word_data(data->client, VCNL4200_AL_CONF);
275 	if (ret < 0)
276 		return ret;
277 
278 	if (en)
279 		ret &= ~VCNL4040_ALS_CONF_ALS_SHUTDOWN;
280 	else
281 		ret |= VCNL4040_ALS_CONF_ALS_SHUTDOWN;
282 
283 	return i2c_smbus_write_word_data(data->client, VCNL4200_AL_CONF, ret);
284 }
285 
286 static ssize_t vcnl4000_write_ps_enable(struct vcnl4000_data *data, bool en)
287 {
288 	int ret;
289 
290 	guard(mutex)(&data->vcnl4000_lock);
291 
292 	ret = i2c_smbus_read_word_data(data->client, VCNL4200_PS_CONF1);
293 	if (ret < 0)
294 		return ret;
295 
296 	if (en)
297 		ret &= ~VCNL4040_PS_CONF1_PS_SHUTDOWN;
298 	else
299 		ret |= VCNL4040_PS_CONF1_PS_SHUTDOWN;
300 
301 	return i2c_smbus_write_word_data(data->client, VCNL4200_PS_CONF1, ret);
302 }
303 
304 static int vcnl4200_set_power_state(struct vcnl4000_data *data, bool on)
305 {
306 	int ret;
307 
308 	/* Do not power down if interrupts are enabled */
309 	if (!on && (data->ps_int || data->als_int))
310 		return 0;
311 
312 	ret = vcnl4000_write_als_enable(data, on);
313 	if (ret < 0)
314 		return ret;
315 
316 	ret = vcnl4000_write_ps_enable(data, on);
317 	if (ret < 0)
318 		return ret;
319 
320 	if (on) {
321 		/* Wait at least one integration cycle before fetching data */
322 		data->vcnl4200_al.last_measurement = ktime_get();
323 		data->vcnl4200_ps.last_measurement = ktime_get();
324 	}
325 
326 	return 0;
327 }
328 
329 static int vcnl4200_init(struct vcnl4000_data *data)
330 {
331 	struct i2c_client *client = data->client;
332 	struct device *dev = &client->dev;
333 	int ret, id;
334 	u16 regval;
335 
336 	ret = i2c_smbus_read_word_data(client, VCNL4200_DEV_ID);
337 	if (ret < 0)
338 		return ret;
339 
340 	id = ret & 0xff;
341 
342 	if (id != VCNL4200_PROD_ID) {
343 		ret = i2c_smbus_read_word_data(client, VCNL4040_DEV_ID);
344 		if (ret < 0)
345 			return ret;
346 
347 		id = ret & 0xff;
348 
349 		if (id != VCNL4040_PROD_ID)
350 			return -ENODEV;
351 	}
352 
353 	dev_dbg(dev, "device id 0x%x", id);
354 
355 	data->rev = (ret >> 8) & 0xf;
356 	data->ps_int = 0;
357 	data->als_int = 0;
358 
359 	data->vcnl4200_al.reg = VCNL4200_AL_DATA;
360 	data->vcnl4200_ps.reg = VCNL4200_PS_DATA;
361 	switch (id) {
362 	case VCNL4200_PROD_ID:
363 		/* Default wait time is 50ms, add 20% tolerance. */
364 		data->vcnl4200_al.sampling_rate = ktime_set(0, 60000 * 1000);
365 		/* Default wait time is 4.8ms, add 20% tolerance. */
366 		data->vcnl4200_ps.sampling_rate = ktime_set(0, 5760 * 1000);
367 		break;
368 	case VCNL4040_PROD_ID:
369 		/* Default wait time is 80ms, add 20% tolerance. */
370 		data->vcnl4200_al.sampling_rate = ktime_set(0, 96000 * 1000);
371 		/* Default wait time is 5ms, add 20% tolerance. */
372 		data->vcnl4200_ps.sampling_rate = ktime_set(0, 6000 * 1000);
373 		break;
374 	}
375 	data->al_scale = data->chip_spec->ulux_step;
376 	data->ps_scale = 16;
377 
378 	ret = devm_mutex_init(dev, &data->vcnl4200_al.lock);
379 	if (ret)
380 		return ret;
381 
382 	ret = devm_mutex_init(dev, &data->vcnl4200_ps.lock);
383 	if (ret)
384 		return ret;
385 
386 	/* Use 16 bits proximity sensor readings */
387 	ret = i2c_smbus_read_word_data(client, VCNL4200_PS_CONF1);
388 	if (ret < 0)
389 		return ret;
390 
391 	regval = ret | VCNL4040_PS_CONF2_PS_HD;
392 	ret = i2c_smbus_write_word_data(client, VCNL4200_PS_CONF1, regval);
393 	if (ret < 0)
394 		return ret;
395 
396 	/* Align proximity sensor sample rate to 16 bits data width */
397 	ret = i2c_smbus_read_word_data(client, VCNL4200_PS_CONF3);
398 	if (ret < 0)
399 		return ret;
400 
401 	regval = ret | VCNL4040_CONF3_PS_SAMPLE_16BITS;
402 	ret = i2c_smbus_write_word_data(client, VCNL4200_PS_CONF3, regval);
403 	if (ret < 0)
404 		return ret;
405 
406 	return 0;
407 };
408 
409 static int vcnl4000_read_data(struct vcnl4000_data *data, u8 data_reg, int *val)
410 {
411 	s32 ret;
412 
413 	ret = i2c_smbus_read_word_swapped(data->client, data_reg);
414 	if (ret < 0)
415 		return ret;
416 
417 	*val = ret;
418 	return 0;
419 }
420 
421 static int vcnl4000_write_data(struct vcnl4000_data *data, u8 data_reg, int val)
422 {
423 	if (val > U16_MAX)
424 		return -ERANGE;
425 
426 	return i2c_smbus_write_word_swapped(data->client, data_reg, val);
427 }
428 
429 
430 static int vcnl4000_measure(struct vcnl4000_data *data, u8 req_mask,
431 				u8 rdy_mask, u8 data_reg, int *val)
432 {
433 	int tries = 20;
434 	int ret;
435 
436 	guard(mutex)(&data->vcnl4000_lock);
437 
438 	ret = i2c_smbus_write_byte_data(data->client, VCNL4000_COMMAND,
439 					req_mask);
440 	if (ret < 0)
441 		return ret;
442 
443 	/* wait for data to become ready */
444 	while (tries--) {
445 		ret = i2c_smbus_read_byte_data(data->client, VCNL4000_COMMAND);
446 		if (ret < 0)
447 			return ret;
448 		if (ret & rdy_mask)
449 			break;
450 		msleep(20); /* measurement takes up to 100 ms */
451 	}
452 
453 	if (tries < 0) {
454 		dev_err(&data->client->dev,
455 			"vcnl4000_measure() failed, data not ready\n");
456 		return -EIO;
457 	}
458 
459 	return vcnl4000_read_data(data, data_reg, val);
460 }
461 
462 static int vcnl4200_measure(struct vcnl4000_data *data,
463 		struct vcnl4200_channel *chan, int *val)
464 {
465 	int ret;
466 	s64 delta;
467 	ktime_t next_measurement;
468 
469 	scoped_guard(mutex, &chan->lock) {
470 		next_measurement = ktime_add(chan->last_measurement,
471 				chan->sampling_rate);
472 		delta = ktime_us_delta(next_measurement, ktime_get());
473 		if (delta > 0)
474 			usleep_range(delta, delta + 500);
475 		chan->last_measurement = ktime_get();
476 	}
477 
478 	ret = i2c_smbus_read_word_data(data->client, chan->reg);
479 	if (ret < 0)
480 		return ret;
481 
482 	*val = ret;
483 
484 	return 0;
485 }
486 
487 static int vcnl4000_measure_light(struct vcnl4000_data *data, int *val)
488 {
489 	return vcnl4000_measure(data,
490 			VCNL4000_AL_OD, VCNL4000_AL_RDY,
491 			VCNL4000_AL_RESULT_HI, val);
492 }
493 
494 static int vcnl4200_measure_light(struct vcnl4000_data *data, int *val)
495 {
496 	return vcnl4200_measure(data, &data->vcnl4200_al, val);
497 }
498 
499 static int vcnl4000_measure_proximity(struct vcnl4000_data *data, int *val)
500 {
501 	return vcnl4000_measure(data,
502 			VCNL4000_PS_OD, VCNL4000_PS_RDY,
503 			VCNL4000_PS_RESULT_HI, val);
504 }
505 
506 static int vcnl4200_measure_proximity(struct vcnl4000_data *data, int *val)
507 {
508 	return vcnl4200_measure(data, &data->vcnl4200_ps, val);
509 }
510 
511 static int vcnl4010_read_proxy_samp_freq(struct vcnl4000_data *data, int *val,
512 					 int *val2)
513 {
514 	int ret;
515 
516 	ret = i2c_smbus_read_byte_data(data->client, VCNL4010_PROX_RATE);
517 	if (ret < 0)
518 		return ret;
519 
520 	if (ret >= ARRAY_SIZE(vcnl4010_prox_sampling_frequency))
521 		return -EINVAL;
522 
523 	*val = vcnl4010_prox_sampling_frequency[ret][0];
524 	*val2 = vcnl4010_prox_sampling_frequency[ret][1];
525 
526 	return 0;
527 }
528 
529 static bool vcnl4010_is_in_periodic_mode(struct vcnl4000_data *data)
530 {
531 	int ret;
532 
533 	ret = i2c_smbus_read_byte_data(data->client, VCNL4000_COMMAND);
534 	if (ret < 0)
535 		return false;
536 
537 	return !!(ret & VCNL4000_SELF_TIMED_EN);
538 }
539 
540 static int vcnl4040_read_als_it(struct vcnl4000_data *data, int *val, int *val2)
541 {
542 	int ret;
543 
544 	ret = i2c_smbus_read_word_data(data->client, VCNL4200_AL_CONF);
545 	if (ret < 0)
546 		return ret;
547 
548 	ret = FIELD_GET(VCNL4040_ALS_CONF_IT, ret);
549 	if (ret >= data->chip_spec->num_als_it_times)
550 		return -EINVAL;
551 
552 	*val = (*data->chip_spec->als_it_times)[ret][0];
553 	*val2 = (*data->chip_spec->als_it_times)[ret][1];
554 
555 	return 0;
556 }
557 
558 static ssize_t vcnl4040_write_als_it(struct vcnl4000_data *data, int val)
559 {
560 	unsigned int i;
561 	int ret;
562 	u16 regval;
563 
564 	for (i = 0; i < data->chip_spec->num_als_it_times; i++) {
565 		if (val == (*data->chip_spec->als_it_times)[i][1])
566 			break;
567 	}
568 
569 	if (i == data->chip_spec->num_als_it_times)
570 		return -EINVAL;
571 
572 	data->vcnl4200_al.sampling_rate = ktime_set(0, val * 1200);
573 	data->al_scale = div_u64(mul_u32_u32(data->chip_spec->ulux_step,
574 			 (*data->chip_spec->als_it_times)[0][1]),
575 			 val);
576 
577 	guard(mutex)(&data->vcnl4000_lock);
578 
579 	ret = i2c_smbus_read_word_data(data->client, VCNL4200_AL_CONF);
580 	if (ret < 0)
581 		return ret;
582 
583 	regval = FIELD_PREP(VCNL4040_ALS_CONF_IT, i);
584 	regval |= (ret & ~VCNL4040_ALS_CONF_IT);
585 	return i2c_smbus_write_word_data(data->client, VCNL4200_AL_CONF, regval);
586 }
587 
588 static int vcnl4040_read_ps_it(struct vcnl4000_data *data, int *val, int *val2)
589 {
590 	int ret;
591 
592 	ret = i2c_smbus_read_word_data(data->client, VCNL4200_PS_CONF1);
593 	if (ret < 0)
594 		return ret;
595 
596 	ret = FIELD_GET(VCNL4040_PS_CONF2_PS_IT, ret);
597 
598 	if (ret >= data->chip_spec->num_ps_it_times)
599 		return -EINVAL;
600 
601 	*val = (*data->chip_spec->ps_it_times)[ret][0];
602 	*val2 = (*data->chip_spec->ps_it_times)[ret][1];
603 
604 	return 0;
605 }
606 
607 static ssize_t vcnl4040_write_ps_it(struct vcnl4000_data *data, int val)
608 {
609 	unsigned int i;
610 	int ret, index = -1;
611 	u16 regval;
612 
613 	for (i = 0; i < data->chip_spec->num_ps_it_times; i++) {
614 		if (val == (*data->chip_spec->ps_it_times)[i][1]) {
615 			index = i;
616 			break;
617 		}
618 	}
619 
620 	if (index < 0)
621 		return -EINVAL;
622 
623 	data->vcnl4200_ps.sampling_rate = ktime_set(0, val * 60 * NSEC_PER_USEC);
624 
625 	guard(mutex)(&data->vcnl4000_lock);
626 
627 	ret = i2c_smbus_read_word_data(data->client, VCNL4200_PS_CONF1);
628 	if (ret < 0)
629 		return ret;
630 
631 	regval = (ret & ~VCNL4040_PS_CONF2_PS_IT) |
632 	    FIELD_PREP(VCNL4040_PS_CONF2_PS_IT, index);
633 	return i2c_smbus_write_word_data(data->client, VCNL4200_PS_CONF1, regval);
634 }
635 
636 static ssize_t vcnl4040_read_als_period(struct vcnl4000_data *data, int *val, int *val2)
637 {
638 	int ret, ret_pers, it;
639 	int64_t val_c;
640 
641 	ret = i2c_smbus_read_word_data(data->client, VCNL4200_AL_CONF);
642 	if (ret < 0)
643 		return ret;
644 
645 	ret_pers = FIELD_GET(VCNL4040_ALS_CONF_PERS, ret);
646 	if (ret_pers >= ARRAY_SIZE(vcnl4040_als_persistence))
647 		return -EINVAL;
648 
649 	it = FIELD_GET(VCNL4040_ALS_CONF_IT, ret);
650 	if (it >= data->chip_spec->num_als_it_times)
651 		return -EINVAL;
652 
653 	val_c = mul_u32_u32((*data->chip_spec->als_it_times)[it][1],
654 			    vcnl4040_als_persistence[ret_pers]);
655 	*val = div_u64_rem(val_c, MICRO, val2);
656 
657 	return IIO_VAL_INT_PLUS_MICRO;
658 }
659 
660 static ssize_t vcnl4040_write_als_period(struct vcnl4000_data *data, int val, int val2)
661 {
662 	unsigned int i;
663 	int ret, it;
664 	u16 regval;
665 	u64 val_n = mul_u32_u32(val, MICRO) + val2;
666 
667 	ret = i2c_smbus_read_word_data(data->client, VCNL4200_AL_CONF);
668 	if (ret < 0)
669 		return ret;
670 
671 	it = FIELD_GET(VCNL4040_ALS_CONF_IT, ret);
672 	if (it >= data->chip_spec->num_als_it_times)
673 		return -EINVAL;
674 
675 	for (i = 0; i < ARRAY_SIZE(vcnl4040_als_persistence) - 1; i++) {
676 		if (val_n < mul_u32_u32(vcnl4040_als_persistence[i],
677 					(*data->chip_spec->als_it_times)[it][1]))
678 			break;
679 	}
680 
681 	guard(mutex)(&data->vcnl4000_lock);
682 
683 	ret = i2c_smbus_read_word_data(data->client, VCNL4200_AL_CONF);
684 	if (ret < 0)
685 		return ret;
686 
687 	regval = FIELD_PREP(VCNL4040_ALS_CONF_PERS, i);
688 	regval |= (ret & ~VCNL4040_ALS_CONF_PERS);
689 	return i2c_smbus_write_word_data(data->client, VCNL4200_AL_CONF, regval);
690 }
691 
692 static ssize_t vcnl4040_read_ps_period(struct vcnl4000_data *data, int *val, int *val2)
693 {
694 	int ret, ret_pers, it;
695 
696 	ret = i2c_smbus_read_word_data(data->client, VCNL4200_PS_CONF1);
697 	if (ret < 0)
698 		return ret;
699 
700 	ret_pers = FIELD_GET(VCNL4040_CONF1_PS_PERS, ret);
701 	if (ret_pers >= ARRAY_SIZE(vcnl4040_ps_persistence))
702 		return -EINVAL;
703 
704 	it = FIELD_GET(VCNL4040_PS_CONF2_PS_IT, ret);
705 	if (it >= data->chip_spec->num_ps_it_times)
706 		return -EINVAL;
707 
708 	*val = (*data->chip_spec->ps_it_times)[it][0];
709 	*val2 = (*data->chip_spec->ps_it_times)[it][1] *
710 		vcnl4040_ps_persistence[ret_pers];
711 
712 	return IIO_VAL_INT_PLUS_MICRO;
713 }
714 
715 static ssize_t vcnl4040_write_ps_period(struct vcnl4000_data *data, int val, int val2)
716 {
717 	int ret, it, i;
718 	u16 regval;
719 
720 	ret = i2c_smbus_read_word_data(data->client, VCNL4200_PS_CONF1);
721 	if (ret < 0)
722 		return ret;
723 
724 	it = FIELD_GET(VCNL4040_PS_CONF2_PS_IT, ret);
725 	if (it >= data->chip_spec->num_ps_it_times)
726 		return -EINVAL;
727 
728 	if (val > 0)
729 		i = ARRAY_SIZE(vcnl4040_ps_persistence) - 1;
730 	else {
731 		for (i = 0; i < ARRAY_SIZE(vcnl4040_ps_persistence) - 1; i++) {
732 			if (val2 <= vcnl4040_ps_persistence[i] *
733 					(*data->chip_spec->ps_it_times)[it][1])
734 				break;
735 		}
736 	}
737 
738 	guard(mutex)(&data->vcnl4000_lock);
739 
740 	ret = i2c_smbus_read_word_data(data->client, VCNL4200_PS_CONF1);
741 	if (ret < 0)
742 		return ret;
743 
744 	regval = FIELD_PREP(VCNL4040_CONF1_PS_PERS, i);
745 	regval |= (ret & ~VCNL4040_CONF1_PS_PERS);
746 	return i2c_smbus_write_word_data(data->client, VCNL4200_PS_CONF1, regval);
747 }
748 
749 static ssize_t vcnl4040_read_ps_oversampling_ratio(struct vcnl4000_data *data, int *val)
750 {
751 	int ret;
752 
753 	ret = i2c_smbus_read_word_data(data->client, VCNL4200_PS_CONF3);
754 	if (ret < 0)
755 		return ret;
756 
757 	ret = FIELD_GET(VCNL4040_PS_CONF3_MPS, ret);
758 	if (ret >= ARRAY_SIZE(vcnl4040_ps_oversampling_ratio))
759 		return -EINVAL;
760 
761 	*val = vcnl4040_ps_oversampling_ratio[ret];
762 
763 	return ret;
764 }
765 
766 static ssize_t vcnl4040_write_ps_oversampling_ratio(struct vcnl4000_data *data, int val)
767 {
768 	unsigned int i;
769 	int ret;
770 	u16 regval;
771 
772 	for (i = 0; i < ARRAY_SIZE(vcnl4040_ps_oversampling_ratio); i++) {
773 		if (val == vcnl4040_ps_oversampling_ratio[i])
774 			break;
775 	}
776 
777 	if (i >= ARRAY_SIZE(vcnl4040_ps_oversampling_ratio))
778 		return -EINVAL;
779 
780 	guard(mutex)(&data->vcnl4000_lock);
781 
782 	ret = i2c_smbus_read_word_data(data->client, VCNL4200_PS_CONF3);
783 	if (ret < 0)
784 		return ret;
785 
786 	regval = FIELD_PREP(VCNL4040_PS_CONF3_MPS, i);
787 	regval |= (ret & ~VCNL4040_PS_CONF3_MPS);
788 	return i2c_smbus_write_word_data(data->client, VCNL4200_PS_CONF3, regval);
789 }
790 
791 static ssize_t vcnl4040_read_ps_calibbias(struct vcnl4000_data *data, int *val, int *val2)
792 {
793 	int ret;
794 
795 	ret = i2c_smbus_read_word_data(data->client, VCNL4200_PS_CONF3);
796 	if (ret < 0)
797 		return ret;
798 
799 	ret = FIELD_GET(VCNL4040_PS_MS_LED_I, ret);
800 	if (ret >= ARRAY_SIZE(vcnl4040_ps_calibbias_ua))
801 		return -EINVAL;
802 
803 	*val = vcnl4040_ps_calibbias_ua[ret][0];
804 	*val2 = vcnl4040_ps_calibbias_ua[ret][1];
805 
806 	return ret;
807 }
808 
809 static ssize_t vcnl4040_write_ps_calibbias(struct vcnl4000_data *data, int val)
810 {
811 	unsigned int i;
812 	int ret;
813 	u16 regval;
814 
815 	for (i = 0; i < ARRAY_SIZE(vcnl4040_ps_calibbias_ua); i++) {
816 		if (val == vcnl4040_ps_calibbias_ua[i][1])
817 			break;
818 	}
819 
820 	if (i >= ARRAY_SIZE(vcnl4040_ps_calibbias_ua))
821 		return -EINVAL;
822 
823 	guard(mutex)(&data->vcnl4000_lock);
824 
825 	ret = i2c_smbus_read_word_data(data->client, VCNL4200_PS_CONF3);
826 	if (ret < 0)
827 		return ret;
828 
829 	regval = (ret & ~VCNL4040_PS_MS_LED_I);
830 	regval |= FIELD_PREP(VCNL4040_PS_MS_LED_I, i);
831 	return i2c_smbus_write_word_data(data->client, VCNL4200_PS_CONF3, regval);
832 }
833 
834 static int vcnl4000_read_raw(struct iio_dev *indio_dev,
835 				struct iio_chan_spec const *chan,
836 				int *val, int *val2, long mask)
837 {
838 	int ret;
839 	struct vcnl4000_data *data = iio_priv(indio_dev);
840 
841 	switch (mask) {
842 	case IIO_CHAN_INFO_RAW:
843 		ret = pm_runtime_resume_and_get(&data->client->dev);
844 		if  (ret < 0)
845 			return ret;
846 
847 		switch (chan->type) {
848 		case IIO_LIGHT:
849 			ret = data->chip_spec->measure_light(data, val);
850 			if (!ret)
851 				ret = IIO_VAL_INT;
852 			break;
853 		case IIO_PROXIMITY:
854 			ret = data->chip_spec->measure_proximity(data, val);
855 			*val2 = data->ps_scale;
856 			if (!ret)
857 				ret = IIO_VAL_FRACTIONAL;
858 			break;
859 		default:
860 			ret = -EINVAL;
861 		}
862 		pm_runtime_put_autosuspend(&data->client->dev);
863 		return ret;
864 	case IIO_CHAN_INFO_SCALE:
865 		if (chan->type != IIO_LIGHT)
866 			return -EINVAL;
867 
868 		*val = 0;
869 		*val2 = data->al_scale;
870 		return IIO_VAL_INT_PLUS_MICRO;
871 	case IIO_CHAN_INFO_INT_TIME:
872 		switch (chan->type) {
873 		case IIO_LIGHT:
874 			ret = vcnl4040_read_als_it(data, val, val2);
875 			break;
876 		case IIO_PROXIMITY:
877 			ret = vcnl4040_read_ps_it(data, val, val2);
878 			break;
879 		default:
880 			return -EINVAL;
881 		}
882 		if (ret < 0)
883 			return ret;
884 		return IIO_VAL_INT_PLUS_MICRO;
885 	case IIO_CHAN_INFO_OVERSAMPLING_RATIO:
886 		switch (chan->type) {
887 		case IIO_PROXIMITY:
888 			ret = vcnl4040_read_ps_oversampling_ratio(data, val);
889 			if (ret < 0)
890 				return ret;
891 			return IIO_VAL_INT;
892 		default:
893 			return -EINVAL;
894 		}
895 	case IIO_CHAN_INFO_CALIBBIAS:
896 		switch (chan->type) {
897 		case IIO_PROXIMITY:
898 			ret = vcnl4040_read_ps_calibbias(data, val, val2);
899 			if (ret < 0)
900 				return ret;
901 			return IIO_VAL_INT_PLUS_MICRO;
902 		default:
903 			return -EINVAL;
904 		}
905 	default:
906 		return -EINVAL;
907 	}
908 }
909 
910 static int vcnl4040_write_raw(struct iio_dev *indio_dev,
911 			      struct iio_chan_spec const *chan,
912 			      int val, int val2, long mask)
913 {
914 	struct vcnl4000_data *data = iio_priv(indio_dev);
915 
916 	switch (mask) {
917 	case IIO_CHAN_INFO_INT_TIME:
918 		if (val != 0)
919 			return -EINVAL;
920 		switch (chan->type) {
921 		case IIO_LIGHT:
922 			return vcnl4040_write_als_it(data, val2);
923 		case IIO_PROXIMITY:
924 			return vcnl4040_write_ps_it(data, val2);
925 		default:
926 			return -EINVAL;
927 		}
928 	case IIO_CHAN_INFO_OVERSAMPLING_RATIO:
929 		switch (chan->type) {
930 		case IIO_PROXIMITY:
931 			return vcnl4040_write_ps_oversampling_ratio(data, val);
932 		default:
933 			return -EINVAL;
934 		}
935 	case IIO_CHAN_INFO_CALIBBIAS:
936 		switch (chan->type) {
937 		case IIO_PROXIMITY:
938 			return vcnl4040_write_ps_calibbias(data, val2);
939 		default:
940 			return -EINVAL;
941 		}
942 	default:
943 		return -EINVAL;
944 	}
945 }
946 
947 static int vcnl4040_read_avail(struct iio_dev *indio_dev,
948 			       struct iio_chan_spec const *chan,
949 			       const int **vals, int *type, int *length,
950 			       long mask)
951 {
952 	struct vcnl4000_data *data = iio_priv(indio_dev);
953 
954 	switch (mask) {
955 	case IIO_CHAN_INFO_INT_TIME:
956 		switch (chan->type) {
957 		case IIO_LIGHT:
958 			*vals = (int *)(*data->chip_spec->als_it_times);
959 			*length = 2 * data->chip_spec->num_als_it_times;
960 			break;
961 		case IIO_PROXIMITY:
962 			*vals = (int *)(*data->chip_spec->ps_it_times);
963 			*length = 2 * data->chip_spec->num_ps_it_times;
964 			break;
965 		default:
966 			return -EINVAL;
967 		}
968 		*type = IIO_VAL_INT_PLUS_MICRO;
969 		return IIO_AVAIL_LIST;
970 	case IIO_CHAN_INFO_OVERSAMPLING_RATIO:
971 		switch (chan->type) {
972 		case IIO_PROXIMITY:
973 			*vals = (int *)vcnl4040_ps_oversampling_ratio;
974 			*length = ARRAY_SIZE(vcnl4040_ps_oversampling_ratio);
975 			*type = IIO_VAL_INT;
976 			return IIO_AVAIL_LIST;
977 		default:
978 			return -EINVAL;
979 		}
980 	case IIO_CHAN_INFO_CALIBBIAS:
981 		switch (chan->type) {
982 		case IIO_PROXIMITY:
983 			*vals = (int *)vcnl4040_ps_calibbias_ua;
984 			*length = 2 * ARRAY_SIZE(vcnl4040_ps_calibbias_ua);
985 			*type = IIO_VAL_INT_PLUS_MICRO;
986 			return IIO_AVAIL_LIST;
987 		default:
988 			return -EINVAL;
989 		}
990 	default:
991 		return -EINVAL;
992 	}
993 }
994 
995 static int vcnl4010_read_raw(struct iio_dev *indio_dev,
996 			     struct iio_chan_spec const *chan,
997 			     int *val, int *val2, long mask)
998 {
999 	int ret;
1000 	struct vcnl4000_data *data = iio_priv(indio_dev);
1001 
1002 	switch (mask) {
1003 	case IIO_CHAN_INFO_RAW:
1004 	case IIO_CHAN_INFO_SCALE: {
1005 		IIO_DEV_ACQUIRE_DIRECT_MODE(indio_dev, claim);
1006 		if (IIO_DEV_ACQUIRE_FAILED(claim))
1007 			return -EBUSY;
1008 
1009 		/* Protect against event capture. */
1010 		if (vcnl4010_is_in_periodic_mode(data))
1011 			return -EBUSY;
1012 
1013 		return vcnl4000_read_raw(indio_dev, chan, val, val2, mask);
1014 	}
1015 	case IIO_CHAN_INFO_SAMP_FREQ:
1016 		switch (chan->type) {
1017 		case IIO_PROXIMITY:
1018 			ret = vcnl4010_read_proxy_samp_freq(data, val, val2);
1019 			if (ret < 0)
1020 				return ret;
1021 			return IIO_VAL_INT_PLUS_MICRO;
1022 		default:
1023 			return -EINVAL;
1024 		}
1025 	default:
1026 		return -EINVAL;
1027 	}
1028 }
1029 
1030 static int vcnl4010_read_avail(struct iio_dev *indio_dev,
1031 			       struct iio_chan_spec const *chan,
1032 			       const int **vals, int *type, int *length,
1033 			       long mask)
1034 {
1035 	switch (mask) {
1036 	case IIO_CHAN_INFO_SAMP_FREQ:
1037 		*vals = (int *)vcnl4010_prox_sampling_frequency;
1038 		*type = IIO_VAL_INT_PLUS_MICRO;
1039 		*length = 2 * ARRAY_SIZE(vcnl4010_prox_sampling_frequency);
1040 		return IIO_AVAIL_LIST;
1041 	default:
1042 		return -EINVAL;
1043 	}
1044 }
1045 
1046 static int vcnl4010_write_proxy_samp_freq(struct vcnl4000_data *data, int val,
1047 					  int val2)
1048 {
1049 	unsigned int i;
1050 	int index = -1;
1051 
1052 	for (i = 0; i < ARRAY_SIZE(vcnl4010_prox_sampling_frequency); i++) {
1053 		if (val == vcnl4010_prox_sampling_frequency[i][0] &&
1054 		    val2 == vcnl4010_prox_sampling_frequency[i][1]) {
1055 			index = i;
1056 			break;
1057 		}
1058 	}
1059 
1060 	if (index < 0)
1061 		return -EINVAL;
1062 
1063 	return i2c_smbus_write_byte_data(data->client, VCNL4010_PROX_RATE,
1064 					 index);
1065 }
1066 
1067 static int vcnl4010_write_raw(struct iio_dev *indio_dev,
1068 			      struct iio_chan_spec const *chan,
1069 			      int val, int val2, long mask)
1070 {
1071 	struct vcnl4000_data *data = iio_priv(indio_dev);
1072 
1073 	IIO_DEV_ACQUIRE_DIRECT_MODE(indio_dev, claim);
1074 	if (IIO_DEV_ACQUIRE_FAILED(claim))
1075 		return -EBUSY;
1076 
1077 	/* Protect against event capture. */
1078 	if (vcnl4010_is_in_periodic_mode(data))
1079 		return -EBUSY;
1080 
1081 	switch (mask) {
1082 	case IIO_CHAN_INFO_SAMP_FREQ:
1083 		switch (chan->type) {
1084 		case IIO_PROXIMITY:
1085 			return vcnl4010_write_proxy_samp_freq(data, val, val2);
1086 		default:
1087 			return -EINVAL;
1088 		}
1089 	default:
1090 		return -EINVAL;
1091 	}
1092 }
1093 
1094 static int vcnl4010_read_event(struct iio_dev *indio_dev,
1095 			       const struct iio_chan_spec *chan,
1096 			       enum iio_event_type type,
1097 			       enum iio_event_direction dir,
1098 			       enum iio_event_info info,
1099 			       int *val, int *val2)
1100 {
1101 	int ret;
1102 	struct vcnl4000_data *data = iio_priv(indio_dev);
1103 
1104 	switch (info) {
1105 	case IIO_EV_INFO_VALUE:
1106 		switch (dir) {
1107 		case IIO_EV_DIR_RISING:
1108 			ret = vcnl4000_read_data(data, VCNL4010_HIGH_THR_HI,
1109 						 val);
1110 			if (ret < 0)
1111 				return ret;
1112 			return IIO_VAL_INT;
1113 		case IIO_EV_DIR_FALLING:
1114 			ret = vcnl4000_read_data(data, VCNL4010_LOW_THR_HI,
1115 						 val);
1116 			if (ret < 0)
1117 				return ret;
1118 			return IIO_VAL_INT;
1119 		default:
1120 			return -EINVAL;
1121 		}
1122 	default:
1123 		return -EINVAL;
1124 	}
1125 }
1126 
1127 static int vcnl4010_write_event(struct iio_dev *indio_dev,
1128 				const struct iio_chan_spec *chan,
1129 				enum iio_event_type type,
1130 				enum iio_event_direction dir,
1131 				enum iio_event_info info,
1132 				int val, int val2)
1133 {
1134 	int ret;
1135 	struct vcnl4000_data *data = iio_priv(indio_dev);
1136 
1137 	switch (info) {
1138 	case IIO_EV_INFO_VALUE:
1139 		switch (dir) {
1140 		case IIO_EV_DIR_RISING:
1141 			ret = vcnl4000_write_data(data, VCNL4010_HIGH_THR_HI,
1142 						  val);
1143 			if (ret < 0)
1144 				return ret;
1145 			return IIO_VAL_INT;
1146 		case IIO_EV_DIR_FALLING:
1147 			ret = vcnl4000_write_data(data, VCNL4010_LOW_THR_HI,
1148 						  val);
1149 			if (ret < 0)
1150 				return ret;
1151 			return IIO_VAL_INT;
1152 		default:
1153 			return -EINVAL;
1154 		}
1155 	default:
1156 		return -EINVAL;
1157 	}
1158 }
1159 
1160 static int vcnl4040_read_event(struct iio_dev *indio_dev,
1161 			       const struct iio_chan_spec *chan,
1162 			       enum iio_event_type type,
1163 			       enum iio_event_direction dir,
1164 			       enum iio_event_info info,
1165 			       int *val, int *val2)
1166 {
1167 	int ret;
1168 	struct vcnl4000_data *data = iio_priv(indio_dev);
1169 
1170 	switch (chan->type) {
1171 	case IIO_LIGHT:
1172 		switch (info) {
1173 		case IIO_EV_INFO_PERIOD:
1174 			return vcnl4040_read_als_period(data, val, val2);
1175 		case IIO_EV_INFO_VALUE:
1176 			switch (dir) {
1177 			case IIO_EV_DIR_RISING:
1178 				ret = i2c_smbus_read_word_data(data->client,
1179 							       VCNL4040_ALS_THDH_LM);
1180 				break;
1181 			case IIO_EV_DIR_FALLING:
1182 				ret = i2c_smbus_read_word_data(data->client,
1183 							       VCNL4040_ALS_THDL_LM);
1184 				break;
1185 			default:
1186 				return -EINVAL;
1187 			}
1188 			break;
1189 		default:
1190 			return -EINVAL;
1191 		}
1192 		break;
1193 	case IIO_PROXIMITY:
1194 		switch (info) {
1195 		case IIO_EV_INFO_PERIOD:
1196 			return vcnl4040_read_ps_period(data, val, val2);
1197 		case IIO_EV_INFO_VALUE:
1198 			switch (dir) {
1199 			case IIO_EV_DIR_RISING:
1200 				ret = i2c_smbus_read_word_data(data->client,
1201 							       VCNL4040_PS_THDH_LM);
1202 				break;
1203 			case IIO_EV_DIR_FALLING:
1204 				ret = i2c_smbus_read_word_data(data->client,
1205 							       VCNL4040_PS_THDL_LM);
1206 				break;
1207 			default:
1208 				return -EINVAL;
1209 			}
1210 			break;
1211 		default:
1212 			return -EINVAL;
1213 		}
1214 		break;
1215 	default:
1216 		return -EINVAL;
1217 	}
1218 	if (ret < 0)
1219 		return ret;
1220 	*val = ret;
1221 	return IIO_VAL_INT;
1222 }
1223 
1224 static int vcnl4040_write_event(struct iio_dev *indio_dev,
1225 				const struct iio_chan_spec *chan,
1226 				enum iio_event_type type,
1227 				enum iio_event_direction dir,
1228 				enum iio_event_info info,
1229 				int val, int val2)
1230 {
1231 	int ret;
1232 	struct vcnl4000_data *data = iio_priv(indio_dev);
1233 
1234 	switch (chan->type) {
1235 	case IIO_LIGHT:
1236 		switch (info) {
1237 		case IIO_EV_INFO_PERIOD:
1238 			return vcnl4040_write_als_period(data, val, val2);
1239 		case IIO_EV_INFO_VALUE:
1240 			switch (dir) {
1241 			case IIO_EV_DIR_RISING:
1242 				ret = i2c_smbus_write_word_data(data->client,
1243 								VCNL4040_ALS_THDH_LM,
1244 								val);
1245 				break;
1246 			case IIO_EV_DIR_FALLING:
1247 				ret = i2c_smbus_write_word_data(data->client,
1248 								VCNL4040_ALS_THDL_LM,
1249 								val);
1250 				break;
1251 			default:
1252 				return -EINVAL;
1253 			}
1254 			break;
1255 		default:
1256 			return -EINVAL;
1257 		}
1258 		break;
1259 	case IIO_PROXIMITY:
1260 		switch (info) {
1261 		case IIO_EV_INFO_PERIOD:
1262 			return vcnl4040_write_ps_period(data, val, val2);
1263 		case IIO_EV_INFO_VALUE:
1264 			switch (dir) {
1265 			case IIO_EV_DIR_RISING:
1266 				ret = i2c_smbus_write_word_data(data->client,
1267 								VCNL4040_PS_THDH_LM,
1268 								val);
1269 				break;
1270 			case IIO_EV_DIR_FALLING:
1271 				ret = i2c_smbus_write_word_data(data->client,
1272 								VCNL4040_PS_THDL_LM,
1273 								val);
1274 				break;
1275 			default:
1276 				return -EINVAL;
1277 			}
1278 			break;
1279 		default:
1280 			return -EINVAL;
1281 		}
1282 		break;
1283 	default:
1284 		return -EINVAL;
1285 	}
1286 	if (ret < 0)
1287 		return ret;
1288 	return IIO_VAL_INT;
1289 }
1290 
1291 static bool vcnl4010_is_thr_enabled(struct vcnl4000_data *data)
1292 {
1293 	int ret;
1294 
1295 	ret = i2c_smbus_read_byte_data(data->client, VCNL4010_INT_CTRL);
1296 	if (ret < 0)
1297 		return false;
1298 
1299 	return !!(ret & VCNL4010_INT_THR_EN);
1300 }
1301 
1302 static int vcnl4010_read_event_config(struct iio_dev *indio_dev,
1303 				      const struct iio_chan_spec *chan,
1304 				      enum iio_event_type type,
1305 				      enum iio_event_direction dir)
1306 {
1307 	struct vcnl4000_data *data = iio_priv(indio_dev);
1308 
1309 	switch (chan->type) {
1310 	case IIO_PROXIMITY:
1311 		return vcnl4010_is_thr_enabled(data);
1312 	default:
1313 		return -EINVAL;
1314 	}
1315 }
1316 
1317 static int vcnl4010_config_threshold_enable(struct vcnl4000_data *data)
1318 {
1319 	int ret;
1320 
1321 	/* Enable periodic measurement of proximity data. */
1322 	ret = i2c_smbus_write_byte_data(data->client, VCNL4000_COMMAND,
1323 					VCNL4000_SELF_TIMED_EN | VCNL4000_PROX_EN);
1324 	if (ret < 0)
1325 		return ret;
1326 
1327 	/*
1328 	 * Enable interrupts on threshold, for proximity data by
1329 	 * default.
1330 	 */
1331 	return i2c_smbus_write_byte_data(data->client, VCNL4010_INT_CTRL,
1332 					 VCNL4010_INT_THR_EN);
1333 }
1334 
1335 static int vcnl4010_config_threshold_disable(struct vcnl4000_data *data)
1336 {
1337 	int ret;
1338 
1339 	if (!vcnl4010_is_thr_enabled(data))
1340 		return 0;
1341 
1342 	ret = i2c_smbus_write_byte_data(data->client, VCNL4000_COMMAND, 0);
1343 	if (ret < 0)
1344 		return ret;
1345 
1346 	return i2c_smbus_write_byte_data(data->client, VCNL4010_INT_CTRL, 0);
1347 }
1348 
1349 static int vcnl4010_config_threshold(struct iio_dev *indio_dev, bool state)
1350 {
1351 	struct vcnl4000_data *data = iio_priv(indio_dev);
1352 
1353 	if (state) {
1354 		IIO_DEV_ACQUIRE_DIRECT_MODE(indio_dev, claim);
1355 		if (IIO_DEV_ACQUIRE_FAILED(claim))
1356 			return -EBUSY;
1357 
1358 		return vcnl4010_config_threshold_enable(data);
1359 	} else {
1360 		return vcnl4010_config_threshold_disable(data);
1361 	}
1362 }
1363 
1364 static int vcnl4010_write_event_config(struct iio_dev *indio_dev,
1365 				       const struct iio_chan_spec *chan,
1366 				       enum iio_event_type type,
1367 				       enum iio_event_direction dir,
1368 				       bool state)
1369 {
1370 	switch (chan->type) {
1371 	case IIO_PROXIMITY:
1372 		return vcnl4010_config_threshold(indio_dev, state);
1373 	default:
1374 		return -EINVAL;
1375 	}
1376 }
1377 
1378 static int vcnl4040_read_event_config(struct iio_dev *indio_dev,
1379 				      const struct iio_chan_spec *chan,
1380 				      enum iio_event_type type,
1381 				      enum iio_event_direction dir)
1382 {
1383 	int ret;
1384 	struct vcnl4000_data *data = iio_priv(indio_dev);
1385 
1386 	switch (chan->type) {
1387 	case IIO_LIGHT:
1388 		ret = i2c_smbus_read_word_data(data->client, VCNL4200_AL_CONF);
1389 		if (ret < 0)
1390 			return ret;
1391 
1392 		data->als_int = FIELD_GET(VCNL4040_ALS_CONF_INT_EN, ret);
1393 
1394 		return data->als_int;
1395 	case IIO_PROXIMITY:
1396 		ret = i2c_smbus_read_word_data(data->client, VCNL4200_PS_CONF1);
1397 		if (ret < 0)
1398 			return ret;
1399 
1400 		data->ps_int = FIELD_GET(VCNL4040_PS_CONF2_PS_INT, ret);
1401 
1402 		return (dir == IIO_EV_DIR_RISING) ?
1403 			FIELD_GET(VCNL4040_PS_IF_AWAY, ret) :
1404 			FIELD_GET(VCNL4040_PS_IF_CLOSE, ret);
1405 	default:
1406 		return -EINVAL;
1407 	}
1408 }
1409 
1410 static int vcnl4040_write_event_config(struct iio_dev *indio_dev,
1411 				       const struct iio_chan_spec *chan,
1412 				       enum iio_event_type type,
1413 				       enum iio_event_direction dir,
1414 				       bool state)
1415 {
1416 	int ret;
1417 	u16 val, mask;
1418 	struct vcnl4000_data *data = iio_priv(indio_dev);
1419 
1420 	guard(mutex)(&data->vcnl4000_lock);
1421 
1422 	switch (chan->type) {
1423 	case IIO_LIGHT:
1424 		ret = i2c_smbus_read_word_data(data->client, VCNL4200_AL_CONF);
1425 		if (ret < 0)
1426 			return ret;
1427 
1428 		mask = VCNL4040_ALS_CONF_INT_EN;
1429 		if (state)
1430 			val = (ret | mask);
1431 		else
1432 			val = (ret & ~mask);
1433 
1434 		data->als_int = FIELD_GET(VCNL4040_ALS_CONF_INT_EN, val);
1435 		return i2c_smbus_write_word_data(data->client, VCNL4200_AL_CONF, val);
1436 	case IIO_PROXIMITY:
1437 		ret = i2c_smbus_read_word_data(data->client, VCNL4200_PS_CONF1);
1438 		if (ret < 0)
1439 			return ret;
1440 
1441 		if (dir == IIO_EV_DIR_RISING)
1442 			mask = VCNL4040_PS_IF_AWAY;
1443 		else
1444 			mask = VCNL4040_PS_IF_CLOSE;
1445 
1446 		val = state ? (ret | mask) : (ret & ~mask);
1447 
1448 		data->ps_int = FIELD_GET(VCNL4040_PS_CONF2_PS_INT, val);
1449 		return i2c_smbus_write_word_data(data->client, VCNL4200_PS_CONF1, val);
1450 	default:
1451 		return -EINVAL;
1452 	}
1453 }
1454 
1455 static irqreturn_t vcnl4040_irq_thread(int irq, void *p)
1456 {
1457 	struct iio_dev *indio_dev = p;
1458 	struct vcnl4000_data *data = iio_priv(indio_dev);
1459 	int ret;
1460 
1461 	ret = i2c_smbus_read_word_data(data->client, data->chip_spec->int_reg);
1462 	if (ret < 0)
1463 		return IRQ_HANDLED;
1464 
1465 	if (ret & VCNL4040_PS_IF_CLOSE) {
1466 		iio_push_event(indio_dev,
1467 			       IIO_UNMOD_EVENT_CODE(IIO_PROXIMITY, 0,
1468 						    IIO_EV_TYPE_THRESH,
1469 						    IIO_EV_DIR_RISING),
1470 			       iio_get_time_ns(indio_dev));
1471 	}
1472 
1473 	if (ret & VCNL4040_PS_IF_AWAY) {
1474 		iio_push_event(indio_dev,
1475 			       IIO_UNMOD_EVENT_CODE(IIO_PROXIMITY, 0,
1476 						    IIO_EV_TYPE_THRESH,
1477 						    IIO_EV_DIR_FALLING),
1478 			       iio_get_time_ns(indio_dev));
1479 	}
1480 
1481 	if (ret & VCNL4040_ALS_FALLING) {
1482 		iio_push_event(indio_dev,
1483 			       IIO_UNMOD_EVENT_CODE(IIO_LIGHT, 0,
1484 						    IIO_EV_TYPE_THRESH,
1485 						    IIO_EV_DIR_FALLING),
1486 			       iio_get_time_ns(indio_dev));
1487 	}
1488 
1489 	if (ret & VCNL4040_ALS_RISING) {
1490 		iio_push_event(indio_dev,
1491 			       IIO_UNMOD_EVENT_CODE(IIO_LIGHT, 0,
1492 						    IIO_EV_TYPE_THRESH,
1493 						    IIO_EV_DIR_RISING),
1494 			       iio_get_time_ns(indio_dev));
1495 	}
1496 
1497 	return IRQ_HANDLED;
1498 }
1499 
1500 static ssize_t vcnl4000_read_near_level(struct iio_dev *indio_dev,
1501 					uintptr_t priv,
1502 					const struct iio_chan_spec *chan,
1503 					char *buf)
1504 {
1505 	struct vcnl4000_data *data = iio_priv(indio_dev);
1506 
1507 	return sprintf(buf, "%u\n", data->near_level);
1508 }
1509 
1510 static irqreturn_t vcnl4010_irq_thread(int irq, void *p)
1511 {
1512 	struct iio_dev *indio_dev = p;
1513 	struct vcnl4000_data *data = iio_priv(indio_dev);
1514 	unsigned long isr;
1515 	int ret;
1516 
1517 	ret = i2c_smbus_read_byte_data(data->client, VCNL4010_ISR);
1518 	if (ret < 0)
1519 		goto end;
1520 
1521 	isr = ret;
1522 
1523 	if (isr & VCNL4010_INT_THR) {
1524 		if (test_bit(VCNL4010_INT_THR_LOW, &isr)) {
1525 			iio_push_event(indio_dev,
1526 				       IIO_UNMOD_EVENT_CODE(
1527 					       IIO_PROXIMITY,
1528 					       1,
1529 					       IIO_EV_TYPE_THRESH,
1530 					       IIO_EV_DIR_FALLING),
1531 				       iio_get_time_ns(indio_dev));
1532 		}
1533 
1534 		if (test_bit(VCNL4010_INT_THR_HIGH, &isr)) {
1535 			iio_push_event(indio_dev,
1536 				       IIO_UNMOD_EVENT_CODE(
1537 					       IIO_PROXIMITY,
1538 					       1,
1539 					       IIO_EV_TYPE_THRESH,
1540 					       IIO_EV_DIR_RISING),
1541 				       iio_get_time_ns(indio_dev));
1542 		}
1543 
1544 		i2c_smbus_write_byte_data(data->client, VCNL4010_ISR,
1545 					  isr & VCNL4010_INT_THR);
1546 	}
1547 
1548 	if (isr & VCNL4010_INT_DRDY && iio_buffer_enabled(indio_dev))
1549 		iio_trigger_poll_nested(indio_dev->trig);
1550 
1551 end:
1552 	return IRQ_HANDLED;
1553 }
1554 
1555 static irqreturn_t vcnl4010_trigger_handler(int irq, void *p)
1556 {
1557 	struct iio_poll_func *pf = p;
1558 	struct iio_dev *indio_dev = pf->indio_dev;
1559 	struct vcnl4000_data *data = iio_priv(indio_dev);
1560 	const unsigned long *active_scan_mask = indio_dev->active_scan_mask;
1561 	struct {
1562 		u16 chan;
1563 		aligned_s64 ts;
1564 	} scan = { };
1565 	bool data_read = false;
1566 	unsigned long isr;
1567 	int val = 0;
1568 	int ret;
1569 
1570 	ret = i2c_smbus_read_byte_data(data->client, VCNL4010_ISR);
1571 	if (ret < 0)
1572 		goto end;
1573 
1574 	isr = ret;
1575 
1576 	if (test_bit(0, active_scan_mask)) {
1577 		if (test_bit(VCNL4010_INT_PROXIMITY, &isr)) {
1578 			ret = vcnl4000_read_data(data,
1579 						 VCNL4000_PS_RESULT_HI,
1580 						 &val);
1581 			if (ret < 0)
1582 				goto end;
1583 
1584 			scan.chan = val;
1585 			data_read = true;
1586 		}
1587 	}
1588 
1589 	ret = i2c_smbus_write_byte_data(data->client, VCNL4010_ISR,
1590 					isr & VCNL4010_INT_DRDY);
1591 	if (ret < 0)
1592 		goto end;
1593 
1594 	if (!data_read)
1595 		goto end;
1596 
1597 	iio_push_to_buffers_with_ts(indio_dev, &scan, sizeof(scan),
1598 				    iio_get_time_ns(indio_dev));
1599 
1600 end:
1601 	iio_trigger_notify_done(indio_dev->trig);
1602 	return IRQ_HANDLED;
1603 }
1604 
1605 static int vcnl4010_buffer_postenable(struct iio_dev *indio_dev)
1606 {
1607 	struct vcnl4000_data *data = iio_priv(indio_dev);
1608 	int ret;
1609 	int cmd;
1610 
1611 	/* Do not enable the buffer if we are already capturing events. */
1612 	if (vcnl4010_is_in_periodic_mode(data))
1613 		return -EBUSY;
1614 
1615 	ret = i2c_smbus_write_byte_data(data->client, VCNL4010_INT_CTRL,
1616 					VCNL4010_INT_PROX_EN);
1617 	if (ret < 0)
1618 		return ret;
1619 
1620 	cmd = VCNL4000_SELF_TIMED_EN | VCNL4000_PROX_EN;
1621 	return i2c_smbus_write_byte_data(data->client, VCNL4000_COMMAND, cmd);
1622 }
1623 
1624 static int vcnl4010_buffer_predisable(struct iio_dev *indio_dev)
1625 {
1626 	struct vcnl4000_data *data = iio_priv(indio_dev);
1627 	int ret;
1628 
1629 	ret = i2c_smbus_write_byte_data(data->client, VCNL4010_INT_CTRL, 0);
1630 	if (ret < 0)
1631 		return ret;
1632 
1633 	return i2c_smbus_write_byte_data(data->client, VCNL4000_COMMAND, 0);
1634 }
1635 
1636 static const struct iio_buffer_setup_ops vcnl4010_buffer_ops = {
1637 	.postenable = &vcnl4010_buffer_postenable,
1638 	.predisable = &vcnl4010_buffer_predisable,
1639 };
1640 
1641 static const struct iio_chan_spec_ext_info vcnl4000_ext_info[] = {
1642 	{
1643 		.name = "nearlevel",
1644 		.shared = IIO_SEPARATE,
1645 		.read = vcnl4000_read_near_level,
1646 	},
1647 	{ }
1648 };
1649 
1650 static const struct iio_event_spec vcnl4000_event_spec[] = {
1651 	{
1652 		.type = IIO_EV_TYPE_THRESH,
1653 		.dir = IIO_EV_DIR_RISING,
1654 		.mask_separate = BIT(IIO_EV_INFO_VALUE),
1655 	}, {
1656 		.type = IIO_EV_TYPE_THRESH,
1657 		.dir = IIO_EV_DIR_FALLING,
1658 		.mask_separate = BIT(IIO_EV_INFO_VALUE),
1659 	}, {
1660 		.type = IIO_EV_TYPE_THRESH,
1661 		.dir = IIO_EV_DIR_EITHER,
1662 		.mask_separate = BIT(IIO_EV_INFO_ENABLE),
1663 	}
1664 };
1665 
1666 static const struct iio_event_spec vcnl4040_als_event_spec[] = {
1667 	{
1668 		.type = IIO_EV_TYPE_THRESH,
1669 		.dir = IIO_EV_DIR_RISING,
1670 		.mask_separate = BIT(IIO_EV_INFO_VALUE),
1671 	}, {
1672 		.type = IIO_EV_TYPE_THRESH,
1673 		.dir = IIO_EV_DIR_FALLING,
1674 		.mask_separate = BIT(IIO_EV_INFO_VALUE),
1675 	}, {
1676 		.type = IIO_EV_TYPE_THRESH,
1677 		.dir = IIO_EV_DIR_EITHER,
1678 		.mask_separate = BIT(IIO_EV_INFO_ENABLE) | BIT(IIO_EV_INFO_PERIOD),
1679 	},
1680 };
1681 
1682 static const struct iio_event_spec vcnl4040_event_spec[] = {
1683 	{
1684 		.type = IIO_EV_TYPE_THRESH,
1685 		.dir = IIO_EV_DIR_RISING,
1686 		.mask_separate = BIT(IIO_EV_INFO_VALUE) | BIT(IIO_EV_INFO_ENABLE),
1687 	}, {
1688 		.type = IIO_EV_TYPE_THRESH,
1689 		.dir = IIO_EV_DIR_FALLING,
1690 		.mask_separate = BIT(IIO_EV_INFO_VALUE) | BIT(IIO_EV_INFO_ENABLE),
1691 	}, {
1692 		.type = IIO_EV_TYPE_THRESH,
1693 		.dir = IIO_EV_DIR_EITHER,
1694 		.mask_separate = BIT(IIO_EV_INFO_PERIOD),
1695 	},
1696 };
1697 
1698 static const struct iio_chan_spec vcnl4000_channels[] = {
1699 	{
1700 		.type = IIO_LIGHT,
1701 		.info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
1702 			BIT(IIO_CHAN_INFO_SCALE),
1703 	}, {
1704 		.type = IIO_PROXIMITY,
1705 		.info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
1706 		.ext_info = vcnl4000_ext_info,
1707 	}
1708 };
1709 
1710 static const struct iio_chan_spec vcnl4010_channels[] = {
1711 	{
1712 		.type = IIO_LIGHT,
1713 		.scan_index = -1,
1714 		.info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
1715 			BIT(IIO_CHAN_INFO_SCALE),
1716 	}, {
1717 		.type = IIO_PROXIMITY,
1718 		.scan_index = 0,
1719 		.info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
1720 			BIT(IIO_CHAN_INFO_SAMP_FREQ),
1721 		.info_mask_separate_available = BIT(IIO_CHAN_INFO_SAMP_FREQ),
1722 		.event_spec = vcnl4000_event_spec,
1723 		.num_event_specs = ARRAY_SIZE(vcnl4000_event_spec),
1724 		.ext_info = vcnl4000_ext_info,
1725 		.scan_type = {
1726 			.sign = 'u',
1727 			.realbits = 16,
1728 			.storagebits = 16,
1729 			.endianness = IIO_CPU,
1730 		},
1731 	},
1732 	IIO_CHAN_SOFT_TIMESTAMP(1),
1733 };
1734 
1735 static const struct iio_chan_spec vcnl4040_channels[] = {
1736 	{
1737 		.type = IIO_LIGHT,
1738 		.info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
1739 			BIT(IIO_CHAN_INFO_SCALE) |
1740 			BIT(IIO_CHAN_INFO_INT_TIME),
1741 		.info_mask_separate_available = BIT(IIO_CHAN_INFO_INT_TIME),
1742 		.event_spec = vcnl4040_als_event_spec,
1743 		.num_event_specs = ARRAY_SIZE(vcnl4040_als_event_spec),
1744 	}, {
1745 		.type = IIO_PROXIMITY,
1746 		.info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
1747 			BIT(IIO_CHAN_INFO_INT_TIME) |
1748 			BIT(IIO_CHAN_INFO_OVERSAMPLING_RATIO) |
1749 			BIT(IIO_CHAN_INFO_CALIBBIAS),
1750 		.info_mask_separate_available = BIT(IIO_CHAN_INFO_INT_TIME) |
1751 			BIT(IIO_CHAN_INFO_OVERSAMPLING_RATIO) |
1752 			BIT(IIO_CHAN_INFO_CALIBBIAS),
1753 		.ext_info = vcnl4000_ext_info,
1754 		.event_spec = vcnl4040_event_spec,
1755 		.num_event_specs = ARRAY_SIZE(vcnl4040_event_spec),
1756 	}
1757 };
1758 
1759 static const struct iio_chan_spec cm36672p_channels[] = {
1760 	{
1761 		.type = IIO_PROXIMITY,
1762 		.info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
1763 			BIT(IIO_CHAN_INFO_INT_TIME) |
1764 			BIT(IIO_CHAN_INFO_OVERSAMPLING_RATIO) |
1765 			BIT(IIO_CHAN_INFO_CALIBBIAS),
1766 		.info_mask_separate_available = BIT(IIO_CHAN_INFO_INT_TIME) |
1767 			BIT(IIO_CHAN_INFO_OVERSAMPLING_RATIO) |
1768 			BIT(IIO_CHAN_INFO_CALIBBIAS),
1769 		.ext_info = vcnl4000_ext_info,
1770 		.event_spec = vcnl4040_event_spec,
1771 		.num_event_specs = ARRAY_SIZE(vcnl4040_event_spec),
1772 	},
1773 };
1774 
1775 static const struct iio_info vcnl4000_info = {
1776 	.read_raw = vcnl4000_read_raw,
1777 };
1778 
1779 static const struct iio_info vcnl4010_info = {
1780 	.read_raw = vcnl4010_read_raw,
1781 	.read_avail = vcnl4010_read_avail,
1782 	.write_raw = vcnl4010_write_raw,
1783 	.read_event_value = vcnl4010_read_event,
1784 	.write_event_value = vcnl4010_write_event,
1785 	.read_event_config = vcnl4010_read_event_config,
1786 	.write_event_config = vcnl4010_write_event_config,
1787 };
1788 
1789 static const struct iio_info vcnl4040_info = {
1790 	.read_raw = vcnl4000_read_raw,
1791 	.write_raw = vcnl4040_write_raw,
1792 	.read_event_value = vcnl4040_read_event,
1793 	.write_event_value = vcnl4040_write_event,
1794 	.read_event_config = vcnl4040_read_event_config,
1795 	.write_event_config = vcnl4040_write_event_config,
1796 	.read_avail = vcnl4040_read_avail,
1797 };
1798 
1799 static const struct vcnl4000_chip_spec cm36672p_spec = {
1800 	.prod = "CM36672P",
1801 	.init = vcnl4200_init,
1802 	.measure_proximity = vcnl4200_measure_proximity,
1803 	.set_power_state = vcnl4200_set_power_state,
1804 	.channels = cm36672p_channels,
1805 	.num_channels = ARRAY_SIZE(cm36672p_channels),
1806 	.info = &vcnl4040_info,
1807 	.irq_thread = vcnl4040_irq_thread,
1808 	.int_reg = VCNL4040_INT_FLAGS,
1809 	.ps_it_times = &vcnl4040_ps_it_times,
1810 	.num_ps_it_times = ARRAY_SIZE(vcnl4040_ps_it_times),
1811 	.prod_id = VCNL4040_PROD_ID,
1812 };
1813 
1814 static const struct vcnl4000_chip_spec vcnl4000_spec = {
1815 	.prod = "VCNL4000",
1816 	.init = vcnl4000_init,
1817 	.measure_light = vcnl4000_measure_light,
1818 	.measure_proximity = vcnl4000_measure_proximity,
1819 	.set_power_state = vcnl4000_set_power_state,
1820 	.channels = vcnl4000_channels,
1821 	.num_channels = ARRAY_SIZE(vcnl4000_channels),
1822 	.info = &vcnl4000_info,
1823 	.prod_id = VCNL4000_PROD_ID,
1824 };
1825 
1826 static const struct vcnl4000_chip_spec vcnl4010_spec = {
1827 	.prod = "VCNL4010/4020",
1828 	.init = vcnl4000_init,
1829 	.measure_light = vcnl4000_measure_light,
1830 	.measure_proximity = vcnl4000_measure_proximity,
1831 	.set_power_state = vcnl4000_set_power_state,
1832 	.channels = vcnl4010_channels,
1833 	.num_channels = ARRAY_SIZE(vcnl4010_channels),
1834 	.info = &vcnl4010_info,
1835 	.irq_thread = vcnl4010_irq_thread,
1836 	.trig_buffer_func = vcnl4010_trigger_handler,
1837 	.buffer_setup_ops = &vcnl4010_buffer_ops,
1838 	.prod_id = VCNL4010_PROD_ID,
1839 };
1840 
1841 static const struct vcnl4000_chip_spec vcnl4040_spec = {
1842 	.prod = "VCNL4040",
1843 	.init = vcnl4200_init,
1844 	.measure_light = vcnl4200_measure_light,
1845 	.measure_proximity = vcnl4200_measure_proximity,
1846 	.set_power_state = vcnl4200_set_power_state,
1847 	.channels = vcnl4040_channels,
1848 	.num_channels = ARRAY_SIZE(vcnl4040_channels),
1849 	.info = &vcnl4040_info,
1850 	.irq_thread = vcnl4040_irq_thread,
1851 	.int_reg = VCNL4040_INT_FLAGS,
1852 	.ps_it_times = &vcnl4040_ps_it_times,
1853 	.num_ps_it_times = ARRAY_SIZE(vcnl4040_ps_it_times),
1854 	.als_it_times = &vcnl4040_als_it_times,
1855 	.num_als_it_times = ARRAY_SIZE(vcnl4040_als_it_times),
1856 	.ulux_step = 100000,
1857 	.prod_id = VCNL4040_PROD_ID,
1858 };
1859 
1860 static const struct vcnl4000_chip_spec vcnl4200_spec = {
1861 	.prod = "VCNL4200",
1862 	.init = vcnl4200_init,
1863 	.measure_light = vcnl4200_measure_light,
1864 	.measure_proximity = vcnl4200_measure_proximity,
1865 	.set_power_state = vcnl4200_set_power_state,
1866 	.channels = vcnl4040_channels,
1867 	.num_channels = ARRAY_SIZE(vcnl4000_channels),
1868 	.info = &vcnl4040_info,
1869 	.irq_thread = vcnl4040_irq_thread,
1870 	.int_reg = VCNL4200_INT_FLAGS,
1871 	.ps_it_times = &vcnl4200_ps_it_times,
1872 	.num_ps_it_times = ARRAY_SIZE(vcnl4200_ps_it_times),
1873 	.als_it_times = &vcnl4200_als_it_times,
1874 	.num_als_it_times = ARRAY_SIZE(vcnl4200_als_it_times),
1875 	.ulux_step = 24000,
1876 	.prod_id = VCNL4200_PROD_ID,
1877 };
1878 
1879 static const struct iio_trigger_ops vcnl4010_trigger_ops = {
1880 	.validate_device = iio_trigger_validate_own_device,
1881 };
1882 
1883 static int vcnl4010_probe_trigger(struct iio_dev *indio_dev)
1884 {
1885 	struct vcnl4000_data *data = iio_priv(indio_dev);
1886 	struct i2c_client *client = data->client;
1887 	struct iio_trigger *trigger;
1888 
1889 	trigger = devm_iio_trigger_alloc(&client->dev, "%s-dev%d",
1890 					 indio_dev->name,
1891 					 iio_device_id(indio_dev));
1892 	if (!trigger)
1893 		return -ENOMEM;
1894 
1895 	trigger->ops = &vcnl4010_trigger_ops;
1896 	iio_trigger_set_drvdata(trigger, indio_dev);
1897 
1898 	return devm_iio_trigger_register(&client->dev, trigger);
1899 }
1900 
1901 static void vcnl4000_cleanup(void *data)
1902 {
1903 	struct iio_dev *indio_dev = data;
1904 	struct vcnl4000_data *chip = iio_priv(indio_dev);
1905 	struct device *dev = &chip->client->dev;
1906 	int ret;
1907 
1908 	ret = chip->chip_spec->set_power_state(chip, false);
1909 	if (ret)
1910 		dev_warn(dev, "Failed to power down (%pe)", ERR_PTR(ret));
1911 }
1912 
1913 static int vcnl4000_probe(struct i2c_client *client)
1914 {
1915 	static const char * const regulator_names[] = { "vdd", "vio", "vled" };
1916 	struct device *dev = &client->dev;
1917 	struct vcnl4000_data *data;
1918 	struct iio_dev *indio_dev;
1919 	int ret;
1920 
1921 	indio_dev = devm_iio_device_alloc(dev, sizeof(*data));
1922 	if (!indio_dev)
1923 		return -ENOMEM;
1924 
1925 	data = iio_priv(indio_dev);
1926 	i2c_set_clientdata(client, indio_dev);
1927 	data->client = client;
1928 	data->chip_spec = i2c_get_match_data(client);
1929 
1930 	ret = devm_regulator_bulk_get_enable(dev, ARRAY_SIZE(regulator_names),
1931 					     regulator_names);
1932 	if (ret)
1933 		return ret;
1934 
1935 	ret = devm_mutex_init(dev, &data->vcnl4000_lock);
1936 	if (ret)
1937 		return ret;
1938 
1939 	ret = data->chip_spec->init(data);
1940 	if (ret < 0)
1941 		return ret;
1942 
1943 	ret = data->chip_spec->set_power_state(data, true);
1944 	if (ret)
1945 		return ret;
1946 
1947 	ret = devm_add_action_or_reset(dev, vcnl4000_cleanup, indio_dev);
1948 	if (ret)
1949 		return ret;
1950 
1951 	dev_dbg(dev, "%s Ambient light/proximity sensor, Rev: %02x\n",
1952 		data->chip_spec->prod, data->rev);
1953 
1954 	device_property_read_u32(dev, "proximity-near-level", &data->near_level);
1955 
1956 	indio_dev->info = data->chip_spec->info;
1957 	indio_dev->channels = data->chip_spec->channels;
1958 	indio_dev->num_channels = data->chip_spec->num_channels;
1959 	indio_dev->name = VCNL4000_DRV_NAME;
1960 	indio_dev->modes = INDIO_DIRECT_MODE;
1961 
1962 	if (data->chip_spec->trig_buffer_func &&
1963 	    data->chip_spec->buffer_setup_ops) {
1964 		ret = devm_iio_triggered_buffer_setup(dev, indio_dev, NULL,
1965 						      data->chip_spec->trig_buffer_func,
1966 						      data->chip_spec->buffer_setup_ops);
1967 		if (ret < 0)
1968 			return ret;
1969 	}
1970 
1971 	if (client->irq && data->chip_spec->irq_thread) {
1972 		ret = devm_request_threaded_irq(dev, client->irq, NULL,
1973 						data->chip_spec->irq_thread,
1974 						IRQF_TRIGGER_FALLING |
1975 						IRQF_ONESHOT,
1976 						"vcnl4000_irq",
1977 						indio_dev);
1978 		if (ret < 0)
1979 			return ret;
1980 
1981 		ret = vcnl4010_probe_trigger(indio_dev);
1982 		if (ret < 0)
1983 			return ret;
1984 	}
1985 
1986 	ret = devm_pm_runtime_set_active_enabled(dev);
1987 	if (ret)
1988 		return ret;
1989 
1990 	ret = devm_iio_device_register(dev, indio_dev);
1991 	if (ret)
1992 		return ret;
1993 
1994 	pm_runtime_set_autosuspend_delay(dev, VCNL4000_SLEEP_DELAY_MS);
1995 	pm_runtime_use_autosuspend(dev);
1996 
1997 	return 0;
1998 }
1999 
2000 static const struct of_device_id vcnl_4000_of_match[] = {
2001 	{ .compatible = "capella,cm36672p", .data = &cm36672p_spec },
2002 	/* Capella CM36686 is fully compatible with Vishay VCNL4040 */
2003 	{ .compatible = "capella,cm36686", .data = &vcnl4040_spec },
2004 	{ .compatible = "vishay,vcnl4000", .data = &vcnl4000_spec },
2005 	{ .compatible = "vishay,vcnl4010", .data = &vcnl4010_spec },
2006 	{ .compatible = "vishay,vcnl4020", .data = &vcnl4010_spec },
2007 	{ .compatible = "vishay,vcnl4040", .data = &vcnl4040_spec },
2008 	{ .compatible = "vishay,vcnl4200", .data = &vcnl4200_spec },
2009 	{ }
2010 };
2011 MODULE_DEVICE_TABLE(of, vcnl_4000_of_match);
2012 
2013 static int vcnl4000_runtime_suspend(struct device *dev)
2014 {
2015 	struct iio_dev *indio_dev = i2c_get_clientdata(to_i2c_client(dev));
2016 	struct vcnl4000_data *data = iio_priv(indio_dev);
2017 
2018 	return data->chip_spec->set_power_state(data, false);
2019 }
2020 
2021 static int vcnl4000_runtime_resume(struct device *dev)
2022 {
2023 	struct iio_dev *indio_dev = i2c_get_clientdata(to_i2c_client(dev));
2024 	struct vcnl4000_data *data = iio_priv(indio_dev);
2025 
2026 	return data->chip_spec->set_power_state(data, true);
2027 }
2028 
2029 static DEFINE_RUNTIME_DEV_PM_OPS(vcnl4000_pm_ops, vcnl4000_runtime_suspend,
2030 				 vcnl4000_runtime_resume, NULL);
2031 
2032 static const struct i2c_device_id vcnl4000_id[] = {
2033 	{ .name = "cm36672p", .driver_data = (kernel_ulong_t)&cm36672p_spec },
2034 	{ .name = "cm36686", .driver_data = (kernel_ulong_t)&vcnl4040_spec },
2035 	{ .name = "vcnl4000", .driver_data = (kernel_ulong_t)&vcnl4000_spec },
2036 	{ .name = "vcnl4010", .driver_data = (kernel_ulong_t)&vcnl4010_spec },
2037 	{ .name = "vcnl4020", .driver_data = (kernel_ulong_t)&vcnl4010_spec },
2038 	{ .name = "vcnl4040", .driver_data = (kernel_ulong_t)&vcnl4040_spec },
2039 	{ .name = "vcnl4200", .driver_data = (kernel_ulong_t)&vcnl4200_spec },
2040 	{ }
2041 };
2042 MODULE_DEVICE_TABLE(i2c, vcnl4000_id);
2043 
2044 static struct i2c_driver vcnl4000_driver = {
2045 	.driver = {
2046 		.name   = VCNL4000_DRV_NAME,
2047 		.pm	= pm_ptr(&vcnl4000_pm_ops),
2048 		.of_match_table = vcnl_4000_of_match,
2049 	},
2050 	.probe = vcnl4000_probe,
2051 	.id_table = vcnl4000_id,
2052 };
2053 
2054 module_i2c_driver(vcnl4000_driver);
2055 
2056 MODULE_AUTHOR("Peter Meerwald <pmeerw@pmeerw.net>");
2057 MODULE_AUTHOR("Mathieu Othacehe <m.othacehe@gmail.com>");
2058 MODULE_DESCRIPTION("Vishay VCNL4000 proximity/ambient light sensor driver");
2059 MODULE_LICENSE("GPL");
2060