1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * VCNL4035 Ambient Light and Proximity Sensor - 7-bit I2C slave address 0x60
4  *
5  * Copyright (c) 2018, DENX Software Engineering GmbH
6  * Author: Parthiban Nallathambi <pn@denx.de>
7  *
8  * TODO: Proximity
9  */
10 #include <linux/bitops.h>
11 #include <linux/bitfield.h>
12 #include <linux/i2c.h>
13 #include <linux/module.h>
14 #include <linux/pm_runtime.h>
15 #include <linux/regmap.h>
16 
17 #include <linux/iio/buffer.h>
18 #include <linux/iio/events.h>
19 #include <linux/iio/iio.h>
20 #include <linux/iio/sysfs.h>
21 #include <linux/iio/trigger.h>
22 #include <linux/iio/trigger_consumer.h>
23 #include <linux/iio/triggered_buffer.h>
24 
25 #define VCNL4035_DRV_NAME	"vcnl4035"
26 #define VCNL4035_IRQ_NAME	"vcnl4035_event"
27 #define VCNL4035_REGMAP_NAME	"vcnl4035_regmap"
28 
29 /* Device registers */
30 #define VCNL4035_ALS_CONF	0x00
31 #define VCNL4035_ALS_THDH	0x01
32 #define VCNL4035_ALS_THDL	0x02
33 #define VCNL4035_ALS_DATA	0x0B
34 #define VCNL4035_WHITE_DATA	0x0C
35 #define VCNL4035_INT_FLAG	0x0D
36 #define VCNL4035_DEV_ID		0x0E
37 
38 /* Register masks */
39 #define VCNL4035_MODE_ALS_MASK		BIT(0)
40 #define VCNL4035_MODE_ALS_WHITE_CHAN	BIT(8)
41 #define VCNL4035_MODE_ALS_INT_MASK	BIT(1)
42 #define VCNL4035_ALS_IT_MASK		GENMASK(7, 5)
43 #define VCNL4035_ALS_PERS_MASK		GENMASK(3, 2)
44 #define VCNL4035_INT_ALS_IF_H_MASK	BIT(12)
45 #define VCNL4035_INT_ALS_IF_L_MASK	BIT(13)
46 #define VCNL4035_DEV_ID_MASK		GENMASK(7, 0)
47 
48 /* Default values */
49 #define VCNL4035_MODE_ALS_ENABLE	BIT(0)
50 #define VCNL4035_MODE_ALS_DISABLE	0x00
51 #define VCNL4035_MODE_ALS_INT_ENABLE	BIT(1)
52 #define VCNL4035_MODE_ALS_INT_DISABLE	0
53 #define VCNL4035_DEV_ID_VAL		0x80
54 #define VCNL4035_ALS_IT_DEFAULT		0x01
55 #define VCNL4035_ALS_PERS_DEFAULT	0x00
56 #define VCNL4035_ALS_THDH_DEFAULT	5000
57 #define VCNL4035_ALS_THDL_DEFAULT	100
58 #define VCNL4035_SLEEP_DELAY_MS		2000
59 
60 struct vcnl4035_data {
61 	struct i2c_client *client;
62 	struct regmap *regmap;
63 	unsigned int als_it_val;
64 	unsigned int als_persistence;
65 	unsigned int als_thresh_low;
66 	unsigned int als_thresh_high;
67 	struct iio_trigger *drdy_trigger0;
68 };
69 
70 static inline bool vcnl4035_is_triggered(struct vcnl4035_data *data)
71 {
72 	int ret;
73 	int reg;
74 
75 	ret = regmap_read(data->regmap, VCNL4035_INT_FLAG, &reg);
76 	if (ret < 0)
77 		return false;
78 
79 	return !!(reg &
80 		(VCNL4035_INT_ALS_IF_H_MASK | VCNL4035_INT_ALS_IF_L_MASK));
81 }
82 
83 static irqreturn_t vcnl4035_drdy_irq_thread(int irq, void *private)
84 {
85 	struct iio_dev *indio_dev = private;
86 	struct vcnl4035_data *data = iio_priv(indio_dev);
87 
88 	if (vcnl4035_is_triggered(data)) {
89 		iio_push_event(indio_dev, IIO_UNMOD_EVENT_CODE(IIO_LIGHT,
90 							0,
91 							IIO_EV_TYPE_THRESH,
92 							IIO_EV_DIR_EITHER),
93 				iio_get_time_ns(indio_dev));
94 		iio_trigger_poll_nested(data->drdy_trigger0);
95 		return IRQ_HANDLED;
96 	}
97 
98 	return IRQ_NONE;
99 }
100 
101 /* Triggered buffer */
102 static irqreturn_t vcnl4035_trigger_consumer_handler(int irq, void *p)
103 {
104 	struct iio_poll_func *pf = p;
105 	struct iio_dev *indio_dev = pf->indio_dev;
106 	struct vcnl4035_data *data = iio_priv(indio_dev);
107 	/* Ensure naturally aligned timestamp */
108 	u8 buffer[ALIGN(sizeof(u16), sizeof(s64)) + sizeof(s64)]  __aligned(8) = { };
109 	int ret;
110 
111 	ret = regmap_read(data->regmap, VCNL4035_ALS_DATA, (int *)buffer);
112 	if (ret < 0) {
113 		dev_err(&data->client->dev,
114 			"Trigger consumer can't read from sensor.\n");
115 		goto fail_read;
116 	}
117 	iio_push_to_buffers_with_timestamp(indio_dev, buffer,
118 					iio_get_time_ns(indio_dev));
119 
120 fail_read:
121 	iio_trigger_notify_done(indio_dev->trig);
122 
123 	return IRQ_HANDLED;
124 }
125 
126 static int vcnl4035_als_drdy_set_state(struct iio_trigger *trigger,
127 					bool enable_drdy)
128 {
129 	struct iio_dev *indio_dev = iio_trigger_get_drvdata(trigger);
130 	struct vcnl4035_data *data = iio_priv(indio_dev);
131 	int val = enable_drdy ? VCNL4035_MODE_ALS_INT_ENABLE :
132 					VCNL4035_MODE_ALS_INT_DISABLE;
133 
134 	return regmap_update_bits(data->regmap, VCNL4035_ALS_CONF,
135 				 VCNL4035_MODE_ALS_INT_MASK,
136 				 val);
137 }
138 
139 static const struct iio_trigger_ops vcnl4035_trigger_ops = {
140 	.validate_device = iio_trigger_validate_own_device,
141 	.set_trigger_state = vcnl4035_als_drdy_set_state,
142 };
143 
144 static int vcnl4035_set_pm_runtime_state(struct vcnl4035_data *data, bool on)
145 {
146 	int ret;
147 	struct device *dev = &data->client->dev;
148 
149 	if (on) {
150 		ret = pm_runtime_resume_and_get(dev);
151 	} else {
152 		pm_runtime_mark_last_busy(dev);
153 		ret = pm_runtime_put_autosuspend(dev);
154 	}
155 
156 	return ret;
157 }
158 
159 static int vcnl4035_read_info_raw(struct iio_dev *indio_dev,
160 				  struct iio_chan_spec const *chan, int *val)
161 {
162 	struct vcnl4035_data *data = iio_priv(indio_dev);
163 	int ret;
164 	int raw_data;
165 	unsigned int reg;
166 
167 	if (!iio_device_claim_direct(indio_dev))
168 		return -EBUSY;
169 
170 	if (chan->channel)
171 		reg = VCNL4035_ALS_DATA;
172 	else
173 		reg = VCNL4035_WHITE_DATA;
174 	ret = regmap_read(data->regmap, reg, &raw_data);
175 	iio_device_release_direct(indio_dev);
176 	if (ret)
177 		return ret;
178 
179 	*val = raw_data;
180 
181 	return IIO_VAL_INT;
182 }
183 
184 /*
185  *	Device IT	INT Time (ms)	Scale (lux/step)
186  *	000		50		0.064
187  *	001		100		0.032
188  *	010		200		0.016
189  *	100		400		0.008
190  *	101 - 111	800		0.004
191  * Values are proportional, so ALS INT is selected for input due to
192  * simplicity reason. Integration time value and scaling is
193  * calculated based on device INT value
194  *
195  * Raw value needs to be scaled using ALS steps
196  */
197 static int vcnl4035_read_raw(struct iio_dev *indio_dev,
198 			    struct iio_chan_spec const *chan, int *val,
199 			    int *val2, long mask)
200 {
201 	struct vcnl4035_data *data = iio_priv(indio_dev);
202 	int ret;
203 
204 	switch (mask) {
205 	case IIO_CHAN_INFO_RAW:
206 		ret = vcnl4035_set_pm_runtime_state(data, true);
207 		if  (ret < 0)
208 			return ret;
209 		ret = vcnl4035_read_info_raw(indio_dev, chan, val);
210 		vcnl4035_set_pm_runtime_state(data, false);
211 		return ret;
212 	case IIO_CHAN_INFO_INT_TIME:
213 		*val = 50;
214 		if (data->als_it_val)
215 			*val = data->als_it_val * 100;
216 		return IIO_VAL_INT;
217 	case IIO_CHAN_INFO_SCALE:
218 		*val = 64;
219 		if (!data->als_it_val)
220 			*val2 = 1000;
221 		else
222 			*val2 = data->als_it_val * 2 * 1000;
223 		return IIO_VAL_FRACTIONAL;
224 	default:
225 		return -EINVAL;
226 	}
227 }
228 
229 static int vcnl4035_write_raw(struct iio_dev *indio_dev,
230 				struct iio_chan_spec const *chan,
231 				int val, int val2, long mask)
232 {
233 	int ret;
234 	struct vcnl4035_data *data = iio_priv(indio_dev);
235 
236 	switch (mask) {
237 	case IIO_CHAN_INFO_INT_TIME:
238 		if (val <= 0 || val > 800)
239 			return -EINVAL;
240 
241 		ret = vcnl4035_set_pm_runtime_state(data, true);
242 		if  (ret < 0)
243 			return ret;
244 
245 		ret = regmap_update_bits(data->regmap, VCNL4035_ALS_CONF,
246 					 VCNL4035_ALS_IT_MASK,
247 					 val / 100);
248 		if (!ret)
249 			data->als_it_val = val / 100;
250 
251 		vcnl4035_set_pm_runtime_state(data, false);
252 		return ret;
253 	default:
254 		return -EINVAL;
255 	}
256 }
257 
258 /* No direct ABI for persistence and threshold, so eventing */
259 static int vcnl4035_read_thresh(struct iio_dev *indio_dev,
260 		const struct iio_chan_spec *chan, enum iio_event_type type,
261 		enum iio_event_direction dir, enum iio_event_info info,
262 		int *val, int *val2)
263 {
264 	struct vcnl4035_data *data = iio_priv(indio_dev);
265 
266 	switch (info) {
267 	case IIO_EV_INFO_VALUE:
268 		switch (dir) {
269 		case IIO_EV_DIR_RISING:
270 			*val = data->als_thresh_high;
271 			return IIO_VAL_INT;
272 		case IIO_EV_DIR_FALLING:
273 			*val = data->als_thresh_low;
274 			return IIO_VAL_INT;
275 		default:
276 			return -EINVAL;
277 		}
278 		break;
279 	case IIO_EV_INFO_PERIOD:
280 		*val = data->als_persistence;
281 		return IIO_VAL_INT;
282 	default:
283 		return -EINVAL;
284 	}
285 
286 }
287 
288 static int vcnl4035_write_thresh(struct iio_dev *indio_dev,
289 		const struct iio_chan_spec *chan, enum iio_event_type type,
290 		enum iio_event_direction dir, enum iio_event_info info, int val,
291 		int val2)
292 {
293 	struct vcnl4035_data *data = iio_priv(indio_dev);
294 	int ret;
295 
296 	switch (info) {
297 	case IIO_EV_INFO_VALUE:
298 		/* 16 bit threshold range 0 - 65535 */
299 		if (val < 0 || val > 65535)
300 			return -EINVAL;
301 		if (dir == IIO_EV_DIR_RISING) {
302 			if (val < data->als_thresh_low)
303 				return -EINVAL;
304 			ret = regmap_write(data->regmap, VCNL4035_ALS_THDH,
305 					   val);
306 			if (ret)
307 				return ret;
308 			data->als_thresh_high = val;
309 		} else {
310 			if (val > data->als_thresh_high)
311 				return -EINVAL;
312 			ret = regmap_write(data->regmap, VCNL4035_ALS_THDL,
313 					   val);
314 			if (ret)
315 				return ret;
316 			data->als_thresh_low = val;
317 		}
318 		return ret;
319 	case IIO_EV_INFO_PERIOD:
320 		/* allow only 1 2 4 8 as persistence value */
321 		if (val < 0 || val > 8 || hweight8(val) != 1)
322 			return -EINVAL;
323 		ret = regmap_update_bits(data->regmap, VCNL4035_ALS_CONF,
324 					 VCNL4035_ALS_PERS_MASK, val);
325 		if (!ret)
326 			data->als_persistence = val;
327 		return ret;
328 	default:
329 		return -EINVAL;
330 	}
331 }
332 
333 static IIO_CONST_ATTR_INT_TIME_AVAIL("50 100 200 400 800");
334 
335 static struct attribute *vcnl4035_attributes[] = {
336 	&iio_const_attr_integration_time_available.dev_attr.attr,
337 	NULL,
338 };
339 
340 static const struct attribute_group vcnl4035_attribute_group = {
341 	.attrs = vcnl4035_attributes,
342 };
343 
344 static const struct iio_info vcnl4035_info = {
345 	.read_raw		= vcnl4035_read_raw,
346 	.write_raw		= vcnl4035_write_raw,
347 	.read_event_value	= vcnl4035_read_thresh,
348 	.write_event_value	= vcnl4035_write_thresh,
349 	.attrs			= &vcnl4035_attribute_group,
350 };
351 
352 static const struct iio_event_spec vcnl4035_event_spec[] = {
353 	{
354 		.type = IIO_EV_TYPE_THRESH,
355 		.dir = IIO_EV_DIR_RISING,
356 		.mask_separate = BIT(IIO_EV_INFO_VALUE),
357 	}, {
358 		.type = IIO_EV_TYPE_THRESH,
359 		.dir = IIO_EV_DIR_FALLING,
360 		.mask_separate = BIT(IIO_EV_INFO_VALUE),
361 	}, {
362 		.type = IIO_EV_TYPE_THRESH,
363 		.dir = IIO_EV_DIR_EITHER,
364 		.mask_separate = BIT(IIO_EV_INFO_PERIOD),
365 	},
366 };
367 
368 enum vcnl4035_scan_index_order {
369 	VCNL4035_CHAN_INDEX_LIGHT,
370 	VCNL4035_CHAN_INDEX_WHITE_LED,
371 };
372 
373 static const struct iio_buffer_setup_ops iio_triggered_buffer_setup_ops = {
374 	.validate_scan_mask = &iio_validate_scan_mask_onehot,
375 };
376 
377 static const struct iio_chan_spec vcnl4035_channels[] = {
378 	{
379 		.type = IIO_LIGHT,
380 		.channel = 0,
381 		.info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
382 				BIT(IIO_CHAN_INFO_INT_TIME) |
383 				BIT(IIO_CHAN_INFO_SCALE),
384 		.event_spec = vcnl4035_event_spec,
385 		.num_event_specs = ARRAY_SIZE(vcnl4035_event_spec),
386 		.scan_index = VCNL4035_CHAN_INDEX_LIGHT,
387 		.scan_type = {
388 			.sign = 'u',
389 			.realbits = 16,
390 			.storagebits = 16,
391 			.endianness = IIO_LE,
392 		},
393 	},
394 	{
395 		.type = IIO_INTENSITY,
396 		.channel = 1,
397 		.modified = 1,
398 		.channel2 = IIO_MOD_LIGHT_BOTH,
399 		.info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
400 		.scan_index = VCNL4035_CHAN_INDEX_WHITE_LED,
401 		.scan_type = {
402 			.sign = 'u',
403 			.realbits = 16,
404 			.storagebits = 16,
405 			.endianness = IIO_LE,
406 		},
407 	},
408 };
409 
410 static int vcnl4035_set_als_power_state(struct vcnl4035_data *data, u8 status)
411 {
412 	return regmap_update_bits(data->regmap, VCNL4035_ALS_CONF,
413 					VCNL4035_MODE_ALS_MASK,
414 					status);
415 }
416 
417 static int vcnl4035_init(struct vcnl4035_data *data)
418 {
419 	int ret;
420 	int id;
421 
422 	ret = regmap_read(data->regmap, VCNL4035_DEV_ID, &id);
423 	if (ret < 0) {
424 		dev_err(&data->client->dev, "Failed to read DEV_ID register\n");
425 		return ret;
426 	}
427 
428 	id = FIELD_GET(VCNL4035_DEV_ID_MASK, id);
429 	if (id != VCNL4035_DEV_ID_VAL) {
430 		dev_err(&data->client->dev, "Wrong id, got %x, expected %x\n",
431 			id, VCNL4035_DEV_ID_VAL);
432 		return -ENODEV;
433 	}
434 
435 	ret = vcnl4035_set_als_power_state(data, VCNL4035_MODE_ALS_ENABLE);
436 	if (ret < 0)
437 		return ret;
438 
439 	/* ALS white channel enable */
440 	ret = regmap_update_bits(data->regmap, VCNL4035_ALS_CONF,
441 				 VCNL4035_MODE_ALS_WHITE_CHAN,
442 				 1);
443 	if (ret) {
444 		dev_err(&data->client->dev, "set white channel enable %d\n",
445 			ret);
446 		return ret;
447 	}
448 
449 	/* set default integration time - 100 ms for ALS */
450 	ret = regmap_update_bits(data->regmap, VCNL4035_ALS_CONF,
451 				 VCNL4035_ALS_IT_MASK,
452 				 VCNL4035_ALS_IT_DEFAULT);
453 	if (ret) {
454 		dev_err(&data->client->dev, "set default ALS IT returned %d\n",
455 			ret);
456 		return ret;
457 	}
458 	data->als_it_val = VCNL4035_ALS_IT_DEFAULT;
459 
460 	/* set default persistence time - 1 for ALS */
461 	ret = regmap_update_bits(data->regmap, VCNL4035_ALS_CONF,
462 				 VCNL4035_ALS_PERS_MASK,
463 				 VCNL4035_ALS_PERS_DEFAULT);
464 	if (ret) {
465 		dev_err(&data->client->dev, "set default PERS returned %d\n",
466 			ret);
467 		return ret;
468 	}
469 	data->als_persistence = VCNL4035_ALS_PERS_DEFAULT;
470 
471 	/* set default HIGH threshold for ALS */
472 	ret = regmap_write(data->regmap, VCNL4035_ALS_THDH,
473 				VCNL4035_ALS_THDH_DEFAULT);
474 	if (ret) {
475 		dev_err(&data->client->dev, "set default THDH returned %d\n",
476 			ret);
477 		return ret;
478 	}
479 	data->als_thresh_high = VCNL4035_ALS_THDH_DEFAULT;
480 
481 	/* set default LOW threshold for ALS */
482 	ret = regmap_write(data->regmap, VCNL4035_ALS_THDL,
483 				VCNL4035_ALS_THDL_DEFAULT);
484 	if (ret) {
485 		dev_err(&data->client->dev, "set default THDL returned %d\n",
486 			ret);
487 		return ret;
488 	}
489 	data->als_thresh_low = VCNL4035_ALS_THDL_DEFAULT;
490 
491 	return 0;
492 }
493 
494 static bool vcnl4035_is_volatile_reg(struct device *dev, unsigned int reg)
495 {
496 	switch (reg) {
497 	case VCNL4035_ALS_CONF:
498 	case VCNL4035_DEV_ID:
499 		return false;
500 	default:
501 		return true;
502 	}
503 }
504 
505 static const struct regmap_config vcnl4035_regmap_config = {
506 	.name		= VCNL4035_REGMAP_NAME,
507 	.reg_bits	= 8,
508 	.val_bits	= 16,
509 	.max_register	= VCNL4035_DEV_ID,
510 	.cache_type	= REGCACHE_RBTREE,
511 	.volatile_reg	= vcnl4035_is_volatile_reg,
512 	.val_format_endian = REGMAP_ENDIAN_LITTLE,
513 };
514 
515 static int vcnl4035_probe_trigger(struct iio_dev *indio_dev)
516 {
517 	int ret;
518 	struct vcnl4035_data *data = iio_priv(indio_dev);
519 
520 	data->drdy_trigger0 = devm_iio_trigger_alloc(
521 			indio_dev->dev.parent,
522 			"%s-dev%d", indio_dev->name, iio_device_id(indio_dev));
523 	if (!data->drdy_trigger0)
524 		return -ENOMEM;
525 
526 	data->drdy_trigger0->ops = &vcnl4035_trigger_ops;
527 	iio_trigger_set_drvdata(data->drdy_trigger0, indio_dev);
528 	ret = devm_iio_trigger_register(indio_dev->dev.parent,
529 					data->drdy_trigger0);
530 	if (ret) {
531 		dev_err(&data->client->dev, "iio trigger register failed\n");
532 		return ret;
533 	}
534 
535 	/* Trigger setup */
536 	ret = devm_iio_triggered_buffer_setup(indio_dev->dev.parent, indio_dev,
537 					NULL, vcnl4035_trigger_consumer_handler,
538 					&iio_triggered_buffer_setup_ops);
539 	if (ret < 0) {
540 		dev_err(&data->client->dev, "iio triggered buffer setup failed\n");
541 		return ret;
542 	}
543 
544 	/* IRQ to trigger mapping */
545 	ret = devm_request_threaded_irq(&data->client->dev, data->client->irq,
546 			NULL, vcnl4035_drdy_irq_thread,
547 			IRQF_TRIGGER_LOW | IRQF_ONESHOT,
548 			VCNL4035_IRQ_NAME, indio_dev);
549 	if (ret < 0)
550 		dev_err(&data->client->dev, "request irq %d for trigger0 failed\n",
551 				data->client->irq);
552 	return ret;
553 }
554 
555 static int vcnl4035_probe(struct i2c_client *client)
556 {
557 	struct vcnl4035_data *data;
558 	struct iio_dev *indio_dev;
559 	struct regmap *regmap;
560 	int ret;
561 
562 	indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*data));
563 	if (!indio_dev)
564 		return -ENOMEM;
565 
566 	regmap = devm_regmap_init_i2c(client, &vcnl4035_regmap_config);
567 	if (IS_ERR(regmap)) {
568 		dev_err(&client->dev, "regmap_init failed!\n");
569 		return PTR_ERR(regmap);
570 	}
571 
572 	data = iio_priv(indio_dev);
573 	i2c_set_clientdata(client, indio_dev);
574 	data->client = client;
575 	data->regmap = regmap;
576 
577 	indio_dev->info = &vcnl4035_info;
578 	indio_dev->name = VCNL4035_DRV_NAME;
579 	indio_dev->channels = vcnl4035_channels;
580 	indio_dev->num_channels = ARRAY_SIZE(vcnl4035_channels);
581 	indio_dev->modes = INDIO_DIRECT_MODE;
582 
583 	ret = vcnl4035_init(data);
584 	if (ret < 0) {
585 		dev_err(&client->dev, "vcnl4035 chip init failed\n");
586 		return ret;
587 	}
588 
589 	if (client->irq > 0) {
590 		ret = vcnl4035_probe_trigger(indio_dev);
591 		if (ret < 0) {
592 			dev_err(&client->dev, "vcnl4035 unable init trigger\n");
593 			goto fail_poweroff;
594 		}
595 	}
596 
597 	ret = pm_runtime_set_active(&client->dev);
598 	if (ret < 0)
599 		goto fail_poweroff;
600 
601 	ret = iio_device_register(indio_dev);
602 	if (ret < 0)
603 		goto fail_poweroff;
604 
605 	pm_runtime_enable(&client->dev);
606 	pm_runtime_set_autosuspend_delay(&client->dev, VCNL4035_SLEEP_DELAY_MS);
607 	pm_runtime_use_autosuspend(&client->dev);
608 
609 	return 0;
610 
611 fail_poweroff:
612 	vcnl4035_set_als_power_state(data, VCNL4035_MODE_ALS_DISABLE);
613 	return ret;
614 }
615 
616 static void vcnl4035_remove(struct i2c_client *client)
617 {
618 	struct iio_dev *indio_dev = i2c_get_clientdata(client);
619 	int ret;
620 
621 	pm_runtime_dont_use_autosuspend(&client->dev);
622 	pm_runtime_disable(&client->dev);
623 	iio_device_unregister(indio_dev);
624 	pm_runtime_set_suspended(&client->dev);
625 
626 	ret = vcnl4035_set_als_power_state(iio_priv(indio_dev),
627 					   VCNL4035_MODE_ALS_DISABLE);
628 	if (ret)
629 		dev_warn(&client->dev, "Failed to put device into standby (%pe)\n",
630 			 ERR_PTR(ret));
631 }
632 
633 static int vcnl4035_runtime_suspend(struct device *dev)
634 {
635 	struct iio_dev *indio_dev = i2c_get_clientdata(to_i2c_client(dev));
636 	struct vcnl4035_data *data = iio_priv(indio_dev);
637 	int ret;
638 
639 	ret = vcnl4035_set_als_power_state(data, VCNL4035_MODE_ALS_DISABLE);
640 	regcache_mark_dirty(data->regmap);
641 
642 	return ret;
643 }
644 
645 static int vcnl4035_runtime_resume(struct device *dev)
646 {
647 	struct iio_dev *indio_dev = i2c_get_clientdata(to_i2c_client(dev));
648 	struct vcnl4035_data *data = iio_priv(indio_dev);
649 	int ret;
650 
651 	regcache_sync(data->regmap);
652 	ret = vcnl4035_set_als_power_state(data, VCNL4035_MODE_ALS_ENABLE);
653 	if (ret < 0)
654 		return ret;
655 
656 	/* wait for 1 ALS integration cycle */
657 	msleep(data->als_it_val * 100);
658 
659 	return 0;
660 }
661 
662 static DEFINE_RUNTIME_DEV_PM_OPS(vcnl4035_pm_ops, vcnl4035_runtime_suspend,
663 				 vcnl4035_runtime_resume, NULL);
664 
665 static const struct i2c_device_id vcnl4035_id[] = {
666 	{ "vcnl4035" },
667 	{ }
668 };
669 MODULE_DEVICE_TABLE(i2c, vcnl4035_id);
670 
671 static const struct of_device_id vcnl4035_of_match[] = {
672 	{ .compatible = "vishay,vcnl4035", },
673 	{ }
674 };
675 MODULE_DEVICE_TABLE(of, vcnl4035_of_match);
676 
677 static struct i2c_driver vcnl4035_driver = {
678 	.driver = {
679 		.name   = VCNL4035_DRV_NAME,
680 		.pm	= pm_ptr(&vcnl4035_pm_ops),
681 		.of_match_table = vcnl4035_of_match,
682 	},
683 	.probe = vcnl4035_probe,
684 	.remove	= vcnl4035_remove,
685 	.id_table = vcnl4035_id,
686 };
687 
688 module_i2c_driver(vcnl4035_driver);
689 
690 MODULE_AUTHOR("Parthiban Nallathambi <pn@denx.de>");
691 MODULE_DESCRIPTION("VCNL4035 Ambient Light Sensor driver");
692 MODULE_LICENSE("GPL v2");
693