xref: /openbmc/linux/drivers/iio/light/us5182d.c (revision 03638e62)
1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3  * Copyright (c) 2015 Intel Corporation
4  *
5  * Driver for UPISEMI us5182d Proximity and Ambient Light Sensor.
6  *
7  * To do: Interrupt support.
8  */
9 
10 #include <linux/kernel.h>
11 #include <linux/module.h>
12 #include <linux/acpi.h>
13 #include <linux/delay.h>
14 #include <linux/i2c.h>
15 #include <linux/iio/events.h>
16 #include <linux/iio/iio.h>
17 #include <linux/interrupt.h>
18 #include <linux/irq.h>
19 #include <linux/iio/sysfs.h>
20 #include <linux/mutex.h>
21 #include <linux/pm.h>
22 #include <linux/pm_runtime.h>
23 
24 #define US5182D_REG_CFG0				0x00
25 #define US5182D_CFG0_ONESHOT_EN				BIT(6)
26 #define US5182D_CFG0_SHUTDOWN_EN			BIT(7)
27 #define US5182D_CFG0_WORD_ENABLE			BIT(0)
28 #define US5182D_CFG0_PROX				BIT(3)
29 #define US5182D_CFG0_PX_IRQ				BIT(2)
30 
31 #define US5182D_REG_CFG1				0x01
32 #define US5182D_CFG1_ALS_RES16				BIT(4)
33 #define US5182D_CFG1_AGAIN_DEFAULT			0x00
34 
35 #define US5182D_REG_CFG2				0x02
36 #define US5182D_CFG2_PX_RES16				BIT(4)
37 #define US5182D_CFG2_PXGAIN_DEFAULT			BIT(2)
38 
39 #define US5182D_REG_CFG3				0x03
40 #define US5182D_CFG3_LED_CURRENT100			(BIT(4) | BIT(5))
41 #define US5182D_CFG3_INT_SOURCE_PX			BIT(3)
42 
43 #define US5182D_REG_CFG4				0x10
44 
45 /*
46  * Registers for tuning the auto dark current cancelling feature.
47  * DARK_TH(reg 0x27,0x28) - threshold (counts) for auto dark cancelling.
48  * when ALS  > DARK_TH --> ALS_Code = ALS - Upper(0x2A) * Dark
49  * when ALS < DARK_TH --> ALS_Code = ALS - Lower(0x29) * Dark
50  */
51 #define US5182D_REG_UDARK_TH			0x27
52 #define US5182D_REG_DARK_AUTO_EN		0x2b
53 #define US5182D_REG_AUTO_LDARK_GAIN		0x29
54 #define US5182D_REG_AUTO_HDARK_GAIN		0x2a
55 
56 /* Thresholds for events: px low (0x08-l, 0x09-h), px high (0x0a-l 0x0b-h) */
57 #define US5182D_REG_PXL_TH			0x08
58 #define US5182D_REG_PXH_TH			0x0a
59 
60 #define US5182D_REG_PXL_TH_DEFAULT		1000
61 #define US5182D_REG_PXH_TH_DEFAULT		30000
62 
63 #define US5182D_OPMODE_ALS			0x01
64 #define US5182D_OPMODE_PX			0x02
65 #define US5182D_OPMODE_SHIFT			4
66 
67 #define US5182D_REG_DARK_AUTO_EN_DEFAULT	0x80
68 #define US5182D_REG_AUTO_LDARK_GAIN_DEFAULT	0x16
69 #define US5182D_REG_AUTO_HDARK_GAIN_DEFAULT	0x00
70 
71 #define US5182D_REG_ADL				0x0c
72 #define US5182D_REG_PDL				0x0e
73 
74 #define US5182D_REG_MODE_STORE			0x21
75 #define US5182D_STORE_MODE			0x01
76 
77 #define US5182D_REG_CHIPID			0xb2
78 
79 #define US5182D_OPMODE_MASK			GENMASK(5, 4)
80 #define US5182D_AGAIN_MASK			0x07
81 #define US5182D_RESET_CHIP			0x01
82 
83 #define US5182D_CHIPID				0x26
84 #define US5182D_DRV_NAME			"us5182d"
85 
86 #define US5182D_GA_RESOLUTION			1000
87 
88 #define US5182D_READ_BYTE			1
89 #define US5182D_READ_WORD			2
90 #define US5182D_OPSTORE_SLEEP_TIME		20 /* ms */
91 #define US5182D_SLEEP_MS			3000 /* ms */
92 #define US5182D_PXH_TH_DISABLE			0xffff
93 #define US5182D_PXL_TH_DISABLE			0x0000
94 
95 /* Available ranges: [12354, 7065, 3998, 2202, 1285, 498, 256, 138] lux */
96 static const int us5182d_scales[] = {188500, 107800, 61000, 33600, 19600, 7600,
97 				     3900, 2100};
98 
99 /*
100  * Experimental thresholds that work with US5182D sensor on evaluation board
101  * roughly between 12-32 lux
102  */
103 static u16 us5182d_dark_ths_vals[] = {170, 200, 512, 512, 800, 2000, 4000,
104 				      8000};
105 
106 enum mode {
107 	US5182D_ALS_PX,
108 	US5182D_ALS_ONLY,
109 	US5182D_PX_ONLY
110 };
111 
112 enum pmode {
113 	US5182D_CONTINUOUS,
114 	US5182D_ONESHOT
115 };
116 
117 struct us5182d_data {
118 	struct i2c_client *client;
119 	struct mutex lock;
120 
121 	/* Glass attenuation factor */
122 	u32 ga;
123 
124 	/* Dark gain tuning */
125 	u8 lower_dark_gain;
126 	u8 upper_dark_gain;
127 	u16 *us5182d_dark_ths;
128 
129 	u16 px_low_th;
130 	u16 px_high_th;
131 
132 	int rising_en;
133 	int falling_en;
134 
135 	u8 opmode;
136 	u8 power_mode;
137 
138 	bool als_enabled;
139 	bool px_enabled;
140 
141 	bool default_continuous;
142 };
143 
144 static IIO_CONST_ATTR(in_illuminance_scale_available,
145 		      "0.0021 0.0039 0.0076 0.0196 0.0336 0.061 0.1078 0.1885");
146 
147 static struct attribute *us5182d_attrs[] = {
148 	&iio_const_attr_in_illuminance_scale_available.dev_attr.attr,
149 	NULL
150 };
151 
152 static const struct attribute_group us5182d_attr_group = {
153 	.attrs = us5182d_attrs,
154 };
155 
156 static const struct {
157 	u8 reg;
158 	u8 val;
159 } us5182d_regvals[] = {
160 	{US5182D_REG_CFG0, US5182D_CFG0_WORD_ENABLE},
161 	{US5182D_REG_CFG1, US5182D_CFG1_ALS_RES16},
162 	{US5182D_REG_CFG2, (US5182D_CFG2_PX_RES16 |
163 			    US5182D_CFG2_PXGAIN_DEFAULT)},
164 	{US5182D_REG_CFG3, US5182D_CFG3_LED_CURRENT100 |
165 			   US5182D_CFG3_INT_SOURCE_PX},
166 	{US5182D_REG_CFG4, 0x00},
167 };
168 
169 static const struct iio_event_spec us5182d_events[] = {
170 	{
171 		.type = IIO_EV_TYPE_THRESH,
172 		.dir = IIO_EV_DIR_RISING,
173 		.mask_separate = BIT(IIO_EV_INFO_VALUE) |
174 				BIT(IIO_EV_INFO_ENABLE),
175 	},
176 	{
177 		.type = IIO_EV_TYPE_THRESH,
178 		.dir = IIO_EV_DIR_FALLING,
179 		.mask_separate = BIT(IIO_EV_INFO_VALUE) |
180 				BIT(IIO_EV_INFO_ENABLE),
181 	},
182 };
183 
184 static const struct iio_chan_spec us5182d_channels[] = {
185 	{
186 		.type = IIO_LIGHT,
187 		.info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
188 				      BIT(IIO_CHAN_INFO_SCALE),
189 	},
190 	{
191 		.type = IIO_PROXIMITY,
192 		.info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
193 		.event_spec = us5182d_events,
194 		.num_event_specs = ARRAY_SIZE(us5182d_events),
195 	}
196 };
197 
198 static int us5182d_oneshot_en(struct us5182d_data *data)
199 {
200 	int ret;
201 
202 	ret = i2c_smbus_read_byte_data(data->client, US5182D_REG_CFG0);
203 	if (ret < 0)
204 		return ret;
205 
206 	/*
207 	 * In oneshot mode the chip will power itself down after taking the
208 	 * required measurement.
209 	 */
210 	ret = ret | US5182D_CFG0_ONESHOT_EN;
211 
212 	return i2c_smbus_write_byte_data(data->client, US5182D_REG_CFG0, ret);
213 }
214 
215 static int us5182d_set_opmode(struct us5182d_data *data, u8 mode)
216 {
217 	int ret;
218 
219 	if (mode == data->opmode)
220 		return 0;
221 
222 	ret = i2c_smbus_read_byte_data(data->client, US5182D_REG_CFG0);
223 	if (ret < 0)
224 		return ret;
225 
226 	/* update mode */
227 	ret = ret & ~US5182D_OPMODE_MASK;
228 	ret = ret | (mode << US5182D_OPMODE_SHIFT);
229 
230 	/*
231 	 * After updating the operating mode, the chip requires that
232 	 * the operation is stored, by writing 1 in the STORE_MODE
233 	 * register (auto-clearing).
234 	 */
235 	ret = i2c_smbus_write_byte_data(data->client, US5182D_REG_CFG0, ret);
236 	if (ret < 0)
237 		return ret;
238 
239 	ret = i2c_smbus_write_byte_data(data->client, US5182D_REG_MODE_STORE,
240 					US5182D_STORE_MODE);
241 	if (ret < 0)
242 		return ret;
243 
244 	data->opmode = mode;
245 	msleep(US5182D_OPSTORE_SLEEP_TIME);
246 
247 	return 0;
248 }
249 
250 static int us5182d_als_enable(struct us5182d_data *data)
251 {
252 	int ret;
253 	u8 mode;
254 
255 	if (data->power_mode == US5182D_ONESHOT) {
256 		ret = us5182d_set_opmode(data, US5182D_ALS_ONLY);
257 		if (ret < 0)
258 			return ret;
259 		data->px_enabled = false;
260 	}
261 
262 	if (data->als_enabled)
263 		return 0;
264 
265 	mode = data->px_enabled ? US5182D_ALS_PX : US5182D_ALS_ONLY;
266 
267 	ret = us5182d_set_opmode(data, mode);
268 	if (ret < 0)
269 		return ret;
270 
271 	data->als_enabled = true;
272 
273 	return 0;
274 }
275 
276 static int us5182d_px_enable(struct us5182d_data *data)
277 {
278 	int ret;
279 	u8 mode;
280 
281 	if (data->power_mode == US5182D_ONESHOT) {
282 		ret = us5182d_set_opmode(data, US5182D_PX_ONLY);
283 		if (ret < 0)
284 			return ret;
285 		data->als_enabled = false;
286 	}
287 
288 	if (data->px_enabled)
289 		return 0;
290 
291 	mode = data->als_enabled ? US5182D_ALS_PX : US5182D_PX_ONLY;
292 
293 	ret = us5182d_set_opmode(data, mode);
294 	if (ret < 0)
295 		return ret;
296 
297 	data->px_enabled = true;
298 
299 	return 0;
300 }
301 
302 static int us5182d_get_als(struct us5182d_data *data)
303 {
304 	int ret;
305 	unsigned long result;
306 
307 	ret = us5182d_als_enable(data);
308 	if (ret < 0)
309 		return ret;
310 
311 	ret = i2c_smbus_read_word_data(data->client,
312 				       US5182D_REG_ADL);
313 	if (ret < 0)
314 		return ret;
315 
316 	result = ret * data->ga / US5182D_GA_RESOLUTION;
317 	if (result > 0xffff)
318 		result = 0xffff;
319 
320 	return result;
321 }
322 
323 static int us5182d_get_px(struct us5182d_data *data)
324 {
325 	int ret;
326 
327 	ret = us5182d_px_enable(data);
328 	if (ret < 0)
329 		return ret;
330 
331 	return i2c_smbus_read_word_data(data->client,
332 					US5182D_REG_PDL);
333 }
334 
335 static int us5182d_shutdown_en(struct us5182d_data *data, u8 state)
336 {
337 	int ret;
338 
339 	if (data->power_mode == US5182D_ONESHOT)
340 		return 0;
341 
342 	ret = i2c_smbus_read_byte_data(data->client, US5182D_REG_CFG0);
343 	if (ret < 0)
344 		return ret;
345 
346 	ret = ret & ~US5182D_CFG0_SHUTDOWN_EN;
347 	ret = ret | state;
348 
349 	ret = i2c_smbus_write_byte_data(data->client, US5182D_REG_CFG0, ret);
350 	if (ret < 0)
351 		return ret;
352 
353 	if (state & US5182D_CFG0_SHUTDOWN_EN) {
354 		data->als_enabled = false;
355 		data->px_enabled = false;
356 	}
357 
358 	return ret;
359 }
360 
361 
362 static int us5182d_set_power_state(struct us5182d_data *data, bool on)
363 {
364 	int ret;
365 
366 	if (data->power_mode == US5182D_ONESHOT)
367 		return 0;
368 
369 	if (on) {
370 		ret = pm_runtime_get_sync(&data->client->dev);
371 		if (ret < 0)
372 			pm_runtime_put_noidle(&data->client->dev);
373 	} else {
374 		pm_runtime_mark_last_busy(&data->client->dev);
375 		ret = pm_runtime_put_autosuspend(&data->client->dev);
376 	}
377 
378 	return ret;
379 }
380 
381 static int us5182d_read_value(struct us5182d_data *data,
382 			      struct iio_chan_spec const *chan)
383 {
384 	int ret, value;
385 
386 	mutex_lock(&data->lock);
387 
388 	if (data->power_mode == US5182D_ONESHOT) {
389 		ret = us5182d_oneshot_en(data);
390 		if (ret < 0)
391 			goto out_err;
392 	}
393 
394 	ret = us5182d_set_power_state(data, true);
395 	if (ret < 0)
396 		goto out_err;
397 
398 	if (chan->type == IIO_LIGHT)
399 		ret = us5182d_get_als(data);
400 	else
401 		ret = us5182d_get_px(data);
402 	if (ret < 0)
403 		goto out_poweroff;
404 
405 	value = ret;
406 
407 	ret = us5182d_set_power_state(data, false);
408 	if (ret < 0)
409 		goto out_err;
410 
411 	mutex_unlock(&data->lock);
412 	return value;
413 
414 out_poweroff:
415 	us5182d_set_power_state(data, false);
416 out_err:
417 	mutex_unlock(&data->lock);
418 	return ret;
419 }
420 
421 static int us5182d_read_raw(struct iio_dev *indio_dev,
422 			    struct iio_chan_spec const *chan, int *val,
423 			    int *val2, long mask)
424 {
425 	struct us5182d_data *data = iio_priv(indio_dev);
426 	int ret;
427 
428 	switch (mask) {
429 	case IIO_CHAN_INFO_RAW:
430 		ret = us5182d_read_value(data, chan);
431 		if (ret < 0)
432 			return ret;
433 		*val = ret;
434 		return IIO_VAL_INT;
435 	case IIO_CHAN_INFO_SCALE:
436 		ret = i2c_smbus_read_byte_data(data->client, US5182D_REG_CFG1);
437 		if (ret < 0)
438 			return ret;
439 		*val = 0;
440 		*val2 = us5182d_scales[ret & US5182D_AGAIN_MASK];
441 		return IIO_VAL_INT_PLUS_MICRO;
442 	default:
443 		return -EINVAL;
444 	}
445 }
446 
447 /**
448  * us5182d_update_dark_th - update Darh_Th registers
449  * @data	us5182d_data structure
450  * @index	index in us5182d_dark_ths array to use for the updated value
451  *
452  * Function needs to be called with a lock held because it needs two i2c write
453  * byte operations as these registers (0x27 0x28) don't work in word mode
454  * accessing.
455  */
456 static int us5182d_update_dark_th(struct us5182d_data *data, int index)
457 {
458 	__be16 dark_th = cpu_to_be16(data->us5182d_dark_ths[index]);
459 	int ret;
460 
461 	ret = i2c_smbus_write_byte_data(data->client, US5182D_REG_UDARK_TH,
462 					((u8 *)&dark_th)[0]);
463 	if (ret < 0)
464 		return ret;
465 
466 	return i2c_smbus_write_byte_data(data->client, US5182D_REG_UDARK_TH + 1,
467 					((u8 *)&dark_th)[1]);
468 }
469 
470 /**
471  * us5182d_apply_scale - update the ALS scale
472  * @data	us5182d_data structure
473  * @index	index in us5182d_scales array to use for the updated value
474  *
475  * Function needs to be called with a lock held as we're having more than one
476  * i2c operation.
477  */
478 static int us5182d_apply_scale(struct us5182d_data *data, int index)
479 {
480 	int ret;
481 
482 	ret = i2c_smbus_read_byte_data(data->client, US5182D_REG_CFG1);
483 	if (ret < 0)
484 		return ret;
485 
486 	ret = ret & (~US5182D_AGAIN_MASK);
487 	ret |= index;
488 
489 	ret = i2c_smbus_write_byte_data(data->client, US5182D_REG_CFG1, ret);
490 	if (ret < 0)
491 		return ret;
492 
493 	return us5182d_update_dark_th(data, index);
494 }
495 
496 static int us5182d_write_raw(struct iio_dev *indio_dev,
497 			     struct iio_chan_spec const *chan, int val,
498 			     int val2, long mask)
499 {
500 	struct us5182d_data *data = iio_priv(indio_dev);
501 	int ret, i;
502 
503 	switch (mask) {
504 	case IIO_CHAN_INFO_SCALE:
505 		if (val != 0)
506 			return -EINVAL;
507 		for (i = 0; i < ARRAY_SIZE(us5182d_scales); i++)
508 			if (val2 == us5182d_scales[i]) {
509 				mutex_lock(&data->lock);
510 				ret = us5182d_apply_scale(data, i);
511 				mutex_unlock(&data->lock);
512 				return ret;
513 			}
514 		break;
515 	default:
516 		return -EINVAL;
517 	}
518 
519 	return -EINVAL;
520 }
521 
522 static int us5182d_setup_prox(struct iio_dev *indio_dev,
523 			      enum iio_event_direction dir, u16 val)
524 {
525 	struct us5182d_data *data = iio_priv(indio_dev);
526 
527 	if (dir == IIO_EV_DIR_FALLING)
528 		return i2c_smbus_write_word_data(data->client,
529 						 US5182D_REG_PXL_TH, val);
530 	else if (dir == IIO_EV_DIR_RISING)
531 		return i2c_smbus_write_word_data(data->client,
532 						 US5182D_REG_PXH_TH, val);
533 
534 	return 0;
535 }
536 
537 static int us5182d_read_thresh(struct iio_dev *indio_dev,
538 	const struct iio_chan_spec *chan, enum iio_event_type type,
539 	enum iio_event_direction dir, enum iio_event_info info, int *val,
540 	int *val2)
541 {
542 	struct us5182d_data *data = iio_priv(indio_dev);
543 
544 	switch (dir) {
545 	case IIO_EV_DIR_RISING:
546 		mutex_lock(&data->lock);
547 		*val = data->px_high_th;
548 		mutex_unlock(&data->lock);
549 		break;
550 	case IIO_EV_DIR_FALLING:
551 		mutex_lock(&data->lock);
552 		*val = data->px_low_th;
553 		mutex_unlock(&data->lock);
554 		break;
555 	default:
556 		return -EINVAL;
557 	}
558 
559 	return IIO_VAL_INT;
560 }
561 
562 static int us5182d_write_thresh(struct iio_dev *indio_dev,
563 	const struct iio_chan_spec *chan, enum iio_event_type type,
564 	enum iio_event_direction dir, enum iio_event_info info, int val,
565 	int val2)
566 {
567 	struct us5182d_data *data = iio_priv(indio_dev);
568 	int ret;
569 
570 	if (val < 0 || val > USHRT_MAX || val2 != 0)
571 		return -EINVAL;
572 
573 	switch (dir) {
574 	case IIO_EV_DIR_RISING:
575 		mutex_lock(&data->lock);
576 		if (data->rising_en) {
577 			ret = us5182d_setup_prox(indio_dev, dir, val);
578 			if (ret < 0)
579 				goto err;
580 		}
581 		data->px_high_th = val;
582 		mutex_unlock(&data->lock);
583 		break;
584 	case IIO_EV_DIR_FALLING:
585 		mutex_lock(&data->lock);
586 		if (data->falling_en) {
587 			ret = us5182d_setup_prox(indio_dev, dir, val);
588 			if (ret < 0)
589 				goto err;
590 		}
591 		data->px_low_th = val;
592 		mutex_unlock(&data->lock);
593 		break;
594 	default:
595 		return -EINVAL;
596 	}
597 
598 	return 0;
599 err:
600 	mutex_unlock(&data->lock);
601 	return ret;
602 }
603 
604 static int us5182d_read_event_config(struct iio_dev *indio_dev,
605 	const struct iio_chan_spec *chan, enum iio_event_type type,
606 	enum iio_event_direction dir)
607 {
608 	struct us5182d_data *data = iio_priv(indio_dev);
609 	int ret;
610 
611 	switch (dir) {
612 	case IIO_EV_DIR_RISING:
613 		mutex_lock(&data->lock);
614 		ret = data->rising_en;
615 		mutex_unlock(&data->lock);
616 		break;
617 	case IIO_EV_DIR_FALLING:
618 		mutex_lock(&data->lock);
619 		ret = data->falling_en;
620 		mutex_unlock(&data->lock);
621 		break;
622 	default:
623 		ret = -EINVAL;
624 		break;
625 	}
626 
627 	return ret;
628 }
629 
630 static int us5182d_write_event_config(struct iio_dev *indio_dev,
631 	const struct iio_chan_spec *chan, enum iio_event_type type,
632 	enum iio_event_direction dir, int state)
633 {
634 	struct us5182d_data *data = iio_priv(indio_dev);
635 	int ret;
636 	u16 new_th;
637 
638 	mutex_lock(&data->lock);
639 
640 	switch (dir) {
641 	case IIO_EV_DIR_RISING:
642 		if (data->rising_en == state) {
643 			mutex_unlock(&data->lock);
644 			return 0;
645 		}
646 		new_th = US5182D_PXH_TH_DISABLE;
647 		if (state) {
648 			data->power_mode = US5182D_CONTINUOUS;
649 			ret = us5182d_set_power_state(data, true);
650 			if (ret < 0)
651 				goto err;
652 			ret = us5182d_px_enable(data);
653 			if (ret < 0)
654 				goto err_poweroff;
655 			new_th = data->px_high_th;
656 		}
657 		ret = us5182d_setup_prox(indio_dev, dir, new_th);
658 		if (ret < 0)
659 			goto err_poweroff;
660 		data->rising_en = state;
661 		break;
662 	case IIO_EV_DIR_FALLING:
663 		if (data->falling_en == state) {
664 			mutex_unlock(&data->lock);
665 			return 0;
666 		}
667 		new_th =  US5182D_PXL_TH_DISABLE;
668 		if (state) {
669 			data->power_mode = US5182D_CONTINUOUS;
670 			ret = us5182d_set_power_state(data, true);
671 			if (ret < 0)
672 				goto err;
673 			ret = us5182d_px_enable(data);
674 			if (ret < 0)
675 				goto err_poweroff;
676 			new_th = data->px_low_th;
677 		}
678 		ret = us5182d_setup_prox(indio_dev, dir, new_th);
679 		if (ret < 0)
680 			goto err_poweroff;
681 		data->falling_en = state;
682 		break;
683 	default:
684 		ret = -EINVAL;
685 		goto err;
686 	}
687 
688 	if (!state) {
689 		ret = us5182d_set_power_state(data, false);
690 		if (ret < 0)
691 			goto err;
692 	}
693 
694 	if (!data->falling_en && !data->rising_en && !data->default_continuous)
695 		data->power_mode = US5182D_ONESHOT;
696 
697 	mutex_unlock(&data->lock);
698 	return 0;
699 
700 err_poweroff:
701 	if (state)
702 		us5182d_set_power_state(data, false);
703 err:
704 	mutex_unlock(&data->lock);
705 	return ret;
706 }
707 
708 static const struct iio_info us5182d_info = {
709 	.read_raw = us5182d_read_raw,
710 	.write_raw = us5182d_write_raw,
711 	.attrs = &us5182d_attr_group,
712 	.read_event_value = &us5182d_read_thresh,
713 	.write_event_value = &us5182d_write_thresh,
714 	.read_event_config = &us5182d_read_event_config,
715 	.write_event_config = &us5182d_write_event_config,
716 };
717 
718 static int us5182d_reset(struct iio_dev *indio_dev)
719 {
720 	struct us5182d_data *data = iio_priv(indio_dev);
721 
722 	return i2c_smbus_write_byte_data(data->client, US5182D_REG_CFG3,
723 					 US5182D_RESET_CHIP);
724 }
725 
726 static int us5182d_init(struct iio_dev *indio_dev)
727 {
728 	struct us5182d_data *data = iio_priv(indio_dev);
729 	int i, ret;
730 
731 	ret = us5182d_reset(indio_dev);
732 	if (ret < 0)
733 		return ret;
734 
735 	data->opmode = 0;
736 	data->power_mode = US5182D_CONTINUOUS;
737 	data->px_low_th = US5182D_REG_PXL_TH_DEFAULT;
738 	data->px_high_th = US5182D_REG_PXH_TH_DEFAULT;
739 
740 	for (i = 0; i < ARRAY_SIZE(us5182d_regvals); i++) {
741 		ret = i2c_smbus_write_byte_data(data->client,
742 						us5182d_regvals[i].reg,
743 						us5182d_regvals[i].val);
744 		if (ret < 0)
745 			return ret;
746 	}
747 
748 	data->als_enabled = true;
749 	data->px_enabled = true;
750 
751 	if (!data->default_continuous) {
752 		ret = us5182d_shutdown_en(data, US5182D_CFG0_SHUTDOWN_EN);
753 		if (ret < 0)
754 			return ret;
755 		data->power_mode = US5182D_ONESHOT;
756 	}
757 
758 	return ret;
759 }
760 
761 static void us5182d_get_platform_data(struct iio_dev *indio_dev)
762 {
763 	struct us5182d_data *data = iio_priv(indio_dev);
764 
765 	if (device_property_read_u32(&data->client->dev, "upisemi,glass-coef",
766 				     &data->ga))
767 		data->ga = US5182D_GA_RESOLUTION;
768 	if (device_property_read_u16_array(&data->client->dev,
769 					   "upisemi,dark-ths",
770 					   data->us5182d_dark_ths,
771 					   ARRAY_SIZE(us5182d_dark_ths_vals)))
772 		data->us5182d_dark_ths = us5182d_dark_ths_vals;
773 	if (device_property_read_u8(&data->client->dev,
774 				    "upisemi,upper-dark-gain",
775 				    &data->upper_dark_gain))
776 		data->upper_dark_gain = US5182D_REG_AUTO_HDARK_GAIN_DEFAULT;
777 	if (device_property_read_u8(&data->client->dev,
778 				    "upisemi,lower-dark-gain",
779 				    &data->lower_dark_gain))
780 		data->lower_dark_gain = US5182D_REG_AUTO_LDARK_GAIN_DEFAULT;
781 	data->default_continuous = device_property_read_bool(&data->client->dev,
782 							     "upisemi,continuous");
783 }
784 
785 static int  us5182d_dark_gain_config(struct iio_dev *indio_dev)
786 {
787 	struct us5182d_data *data = iio_priv(indio_dev);
788 	int ret;
789 
790 	ret = us5182d_update_dark_th(data, US5182D_CFG1_AGAIN_DEFAULT);
791 	if (ret < 0)
792 		return ret;
793 
794 	ret = i2c_smbus_write_byte_data(data->client,
795 					US5182D_REG_AUTO_LDARK_GAIN,
796 					data->lower_dark_gain);
797 	if (ret < 0)
798 		return ret;
799 
800 	ret = i2c_smbus_write_byte_data(data->client,
801 					US5182D_REG_AUTO_HDARK_GAIN,
802 					data->upper_dark_gain);
803 	if (ret < 0)
804 		return ret;
805 
806 	return i2c_smbus_write_byte_data(data->client, US5182D_REG_DARK_AUTO_EN,
807 					 US5182D_REG_DARK_AUTO_EN_DEFAULT);
808 }
809 
810 static irqreturn_t us5182d_irq_thread_handler(int irq, void *private)
811 {
812 	struct iio_dev *indio_dev = private;
813 	struct us5182d_data *data = iio_priv(indio_dev);
814 	enum iio_event_direction dir;
815 	int ret;
816 	u64 ev;
817 
818 	ret = i2c_smbus_read_byte_data(data->client, US5182D_REG_CFG0);
819 	if (ret < 0) {
820 		dev_err(&data->client->dev, "i2c transfer error in irq\n");
821 		return IRQ_HANDLED;
822 	}
823 
824 	dir = ret & US5182D_CFG0_PROX ? IIO_EV_DIR_RISING : IIO_EV_DIR_FALLING;
825 	ev = IIO_UNMOD_EVENT_CODE(IIO_PROXIMITY, 1, IIO_EV_TYPE_THRESH, dir);
826 
827 	iio_push_event(indio_dev, ev, iio_get_time_ns(indio_dev));
828 
829 	ret = i2c_smbus_write_byte_data(data->client, US5182D_REG_CFG0,
830 					ret & ~US5182D_CFG0_PX_IRQ);
831 	if (ret < 0)
832 		dev_err(&data->client->dev, "i2c transfer error in irq\n");
833 
834 	return IRQ_HANDLED;
835 }
836 
837 static int us5182d_probe(struct i2c_client *client,
838 			 const struct i2c_device_id *id)
839 {
840 	struct us5182d_data *data;
841 	struct iio_dev *indio_dev;
842 	int ret;
843 
844 	indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*data));
845 	if (!indio_dev)
846 		return -ENOMEM;
847 
848 	data = iio_priv(indio_dev);
849 	i2c_set_clientdata(client, indio_dev);
850 	data->client = client;
851 
852 	mutex_init(&data->lock);
853 
854 	indio_dev->dev.parent = &client->dev;
855 	indio_dev->info = &us5182d_info;
856 	indio_dev->name = US5182D_DRV_NAME;
857 	indio_dev->channels = us5182d_channels;
858 	indio_dev->num_channels = ARRAY_SIZE(us5182d_channels);
859 	indio_dev->modes = INDIO_DIRECT_MODE;
860 
861 	ret = i2c_smbus_read_byte_data(data->client, US5182D_REG_CHIPID);
862 	if (ret != US5182D_CHIPID) {
863 		dev_err(&data->client->dev,
864 			"Failed to detect US5182 light chip\n");
865 		return (ret < 0) ? ret : -ENODEV;
866 	}
867 
868 	if (client->irq > 0) {
869 		ret = devm_request_threaded_irq(&client->dev, client->irq, NULL,
870 						us5182d_irq_thread_handler,
871 						IRQF_TRIGGER_LOW | IRQF_ONESHOT,
872 						"us5182d-irq", indio_dev);
873 		if (ret < 0)
874 			return ret;
875 	} else
876 		dev_warn(&client->dev, "no valid irq found\n");
877 
878 	us5182d_get_platform_data(indio_dev);
879 	ret = us5182d_init(indio_dev);
880 	if (ret < 0)
881 		return ret;
882 
883 	ret = us5182d_dark_gain_config(indio_dev);
884 	if (ret < 0)
885 		goto out_err;
886 
887 	if (data->default_continuous) {
888 		ret = pm_runtime_set_active(&client->dev);
889 		if (ret < 0)
890 			goto out_err;
891 	}
892 
893 	pm_runtime_enable(&client->dev);
894 	pm_runtime_set_autosuspend_delay(&client->dev,
895 					 US5182D_SLEEP_MS);
896 	pm_runtime_use_autosuspend(&client->dev);
897 
898 	ret = iio_device_register(indio_dev);
899 	if (ret < 0)
900 		goto out_err;
901 
902 	return 0;
903 
904 out_err:
905 	us5182d_shutdown_en(data, US5182D_CFG0_SHUTDOWN_EN);
906 	return ret;
907 
908 }
909 
910 static int us5182d_remove(struct i2c_client *client)
911 {
912 	struct us5182d_data *data = iio_priv(i2c_get_clientdata(client));
913 
914 	iio_device_unregister(i2c_get_clientdata(client));
915 
916 	pm_runtime_disable(&client->dev);
917 	pm_runtime_set_suspended(&client->dev);
918 
919 	return us5182d_shutdown_en(data, US5182D_CFG0_SHUTDOWN_EN);
920 }
921 
922 #if defined(CONFIG_PM_SLEEP) || defined(CONFIG_PM)
923 static int us5182d_suspend(struct device *dev)
924 {
925 	struct iio_dev *indio_dev = i2c_get_clientdata(to_i2c_client(dev));
926 	struct us5182d_data *data = iio_priv(indio_dev);
927 
928 	if (data->power_mode == US5182D_CONTINUOUS)
929 		return us5182d_shutdown_en(data, US5182D_CFG0_SHUTDOWN_EN);
930 
931 	return 0;
932 }
933 
934 static int us5182d_resume(struct device *dev)
935 {
936 	struct iio_dev *indio_dev = i2c_get_clientdata(to_i2c_client(dev));
937 	struct us5182d_data *data = iio_priv(indio_dev);
938 
939 	if (data->power_mode == US5182D_CONTINUOUS)
940 		return us5182d_shutdown_en(data,
941 					   ~US5182D_CFG0_SHUTDOWN_EN & 0xff);
942 
943 	return 0;
944 }
945 #endif
946 
947 static const struct dev_pm_ops us5182d_pm_ops = {
948 	SET_SYSTEM_SLEEP_PM_OPS(us5182d_suspend, us5182d_resume)
949 	SET_RUNTIME_PM_OPS(us5182d_suspend, us5182d_resume, NULL)
950 };
951 
952 static const struct acpi_device_id us5182d_acpi_match[] = {
953 	{ "USD5182", 0},
954 	{}
955 };
956 
957 MODULE_DEVICE_TABLE(acpi, us5182d_acpi_match);
958 
959 static const struct i2c_device_id us5182d_id[] = {
960 		{"usd5182", 0},
961 		{}
962 };
963 
964 MODULE_DEVICE_TABLE(i2c, us5182d_id);
965 
966 static const struct of_device_id us5182d_of_match[] = {
967 	{ .compatible = "upisemi,usd5182" },
968 	{}
969 };
970 MODULE_DEVICE_TABLE(of, us5182d_of_match);
971 
972 static struct i2c_driver us5182d_driver = {
973 	.driver = {
974 		.name = US5182D_DRV_NAME,
975 		.pm = &us5182d_pm_ops,
976 		.of_match_table = us5182d_of_match,
977 		.acpi_match_table = ACPI_PTR(us5182d_acpi_match),
978 	},
979 	.probe = us5182d_probe,
980 	.remove = us5182d_remove,
981 	.id_table = us5182d_id,
982 
983 };
984 module_i2c_driver(us5182d_driver);
985 
986 MODULE_AUTHOR("Adriana Reus <adriana.reus@intel.com>");
987 MODULE_DESCRIPTION("Driver for us5182d Proximity and Light Sensor");
988 MODULE_LICENSE("GPL v2");
989