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