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