xref: /linux/drivers/iio/light/us5182d.c (revision e7e2296b0ecf9b6e934f7a1118cee91d4d486a84)
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/mod_devicetable.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 	if (data->power_mode == US5182D_ONESHOT)
365 		return 0;
366 
367 	if (on)
368 		return pm_runtime_resume_and_get(&data->client->dev);
369 
370 	return pm_runtime_put_autosuspend(&data->client->dev);
371 }
372 
373 static int us5182d_read_value(struct us5182d_data *data,
374 			      struct iio_chan_spec const *chan)
375 {
376 	int ret, value;
377 
378 	mutex_lock(&data->lock);
379 
380 	if (data->power_mode == US5182D_ONESHOT) {
381 		ret = us5182d_oneshot_en(data);
382 		if (ret < 0)
383 			goto out_err;
384 	}
385 
386 	ret = us5182d_set_power_state(data, true);
387 	if (ret < 0)
388 		goto out_err;
389 
390 	if (chan->type == IIO_LIGHT)
391 		ret = us5182d_get_als(data);
392 	else
393 		ret = us5182d_get_px(data);
394 	if (ret < 0)
395 		goto out_poweroff;
396 
397 	value = ret;
398 
399 	ret = us5182d_set_power_state(data, false);
400 	if (ret < 0)
401 		goto out_err;
402 
403 	mutex_unlock(&data->lock);
404 	return value;
405 
406 out_poweroff:
407 	us5182d_set_power_state(data, false);
408 out_err:
409 	mutex_unlock(&data->lock);
410 	return ret;
411 }
412 
413 static int us5182d_read_raw(struct iio_dev *indio_dev,
414 			    struct iio_chan_spec const *chan, int *val,
415 			    int *val2, long mask)
416 {
417 	struct us5182d_data *data = iio_priv(indio_dev);
418 	int ret;
419 
420 	switch (mask) {
421 	case IIO_CHAN_INFO_RAW:
422 		ret = us5182d_read_value(data, chan);
423 		if (ret < 0)
424 			return ret;
425 		*val = ret;
426 		return IIO_VAL_INT;
427 	case IIO_CHAN_INFO_SCALE:
428 		ret = i2c_smbus_read_byte_data(data->client, US5182D_REG_CFG1);
429 		if (ret < 0)
430 			return ret;
431 		*val = 0;
432 		*val2 = us5182d_scales[ret & US5182D_AGAIN_MASK];
433 		return IIO_VAL_INT_PLUS_MICRO;
434 	default:
435 		return -EINVAL;
436 	}
437 }
438 
439 /**
440  * us5182d_update_dark_th - update Darh_Th registers
441  * @data:	us5182d_data structure
442  * @index:	index in us5182d_dark_ths array to use for the updated value
443  *
444  * Function needs to be called with a lock held because it needs two i2c write
445  * byte operations as these registers (0x27 0x28) don't work in word mode
446  * accessing.
447  */
448 static int us5182d_update_dark_th(struct us5182d_data *data, int index)
449 {
450 	__be16 dark_th = cpu_to_be16(data->us5182d_dark_ths[index]);
451 	int ret;
452 
453 	ret = i2c_smbus_write_byte_data(data->client, US5182D_REG_UDARK_TH,
454 					((u8 *)&dark_th)[0]);
455 	if (ret < 0)
456 		return ret;
457 
458 	return i2c_smbus_write_byte_data(data->client, US5182D_REG_UDARK_TH + 1,
459 					((u8 *)&dark_th)[1]);
460 }
461 
462 /**
463  * us5182d_apply_scale - update the ALS scale
464  * @data:	us5182d_data structure
465  * @index:	index in us5182d_scales array to use for the updated value
466  *
467  * Function needs to be called with a lock held as we're having more than one
468  * i2c operation.
469  */
470 static int us5182d_apply_scale(struct us5182d_data *data, int index)
471 {
472 	int ret;
473 
474 	ret = i2c_smbus_read_byte_data(data->client, US5182D_REG_CFG1);
475 	if (ret < 0)
476 		return ret;
477 
478 	ret = ret & (~US5182D_AGAIN_MASK);
479 	ret |= index;
480 
481 	ret = i2c_smbus_write_byte_data(data->client, US5182D_REG_CFG1, ret);
482 	if (ret < 0)
483 		return ret;
484 
485 	return us5182d_update_dark_th(data, index);
486 }
487 
488 static int us5182d_write_raw(struct iio_dev *indio_dev,
489 			     struct iio_chan_spec const *chan, int val,
490 			     int val2, long mask)
491 {
492 	struct us5182d_data *data = iio_priv(indio_dev);
493 	int ret, i;
494 
495 	switch (mask) {
496 	case IIO_CHAN_INFO_SCALE:
497 		if (val != 0)
498 			return -EINVAL;
499 		for (i = 0; i < ARRAY_SIZE(us5182d_scales); i++)
500 			if (val2 == us5182d_scales[i]) {
501 				mutex_lock(&data->lock);
502 				ret = us5182d_apply_scale(data, i);
503 				mutex_unlock(&data->lock);
504 				return ret;
505 			}
506 		break;
507 	default:
508 		return -EINVAL;
509 	}
510 
511 	return -EINVAL;
512 }
513 
514 static int us5182d_setup_prox(struct iio_dev *indio_dev,
515 			      enum iio_event_direction dir, u16 val)
516 {
517 	struct us5182d_data *data = iio_priv(indio_dev);
518 
519 	if (dir == IIO_EV_DIR_FALLING)
520 		return i2c_smbus_write_word_data(data->client,
521 						 US5182D_REG_PXL_TH, val);
522 	else if (dir == IIO_EV_DIR_RISING)
523 		return i2c_smbus_write_word_data(data->client,
524 						 US5182D_REG_PXH_TH, val);
525 
526 	return 0;
527 }
528 
529 static int us5182d_read_thresh(struct iio_dev *indio_dev,
530 	const struct iio_chan_spec *chan, enum iio_event_type type,
531 	enum iio_event_direction dir, enum iio_event_info info, int *val,
532 	int *val2)
533 {
534 	struct us5182d_data *data = iio_priv(indio_dev);
535 
536 	switch (dir) {
537 	case IIO_EV_DIR_RISING:
538 		mutex_lock(&data->lock);
539 		*val = data->px_high_th;
540 		mutex_unlock(&data->lock);
541 		break;
542 	case IIO_EV_DIR_FALLING:
543 		mutex_lock(&data->lock);
544 		*val = data->px_low_th;
545 		mutex_unlock(&data->lock);
546 		break;
547 	default:
548 		return -EINVAL;
549 	}
550 
551 	return IIO_VAL_INT;
552 }
553 
554 static int us5182d_write_thresh(struct iio_dev *indio_dev,
555 	const struct iio_chan_spec *chan, enum iio_event_type type,
556 	enum iio_event_direction dir, enum iio_event_info info, int val,
557 	int val2)
558 {
559 	struct us5182d_data *data = iio_priv(indio_dev);
560 	int ret;
561 
562 	if (val < 0 || val > USHRT_MAX || val2 != 0)
563 		return -EINVAL;
564 
565 	switch (dir) {
566 	case IIO_EV_DIR_RISING:
567 		mutex_lock(&data->lock);
568 		if (data->rising_en) {
569 			ret = us5182d_setup_prox(indio_dev, dir, val);
570 			if (ret < 0)
571 				goto err;
572 		}
573 		data->px_high_th = val;
574 		mutex_unlock(&data->lock);
575 		break;
576 	case IIO_EV_DIR_FALLING:
577 		mutex_lock(&data->lock);
578 		if (data->falling_en) {
579 			ret = us5182d_setup_prox(indio_dev, dir, val);
580 			if (ret < 0)
581 				goto err;
582 		}
583 		data->px_low_th = val;
584 		mutex_unlock(&data->lock);
585 		break;
586 	default:
587 		return -EINVAL;
588 	}
589 
590 	return 0;
591 err:
592 	mutex_unlock(&data->lock);
593 	return ret;
594 }
595 
596 static int us5182d_read_event_config(struct iio_dev *indio_dev,
597 	const struct iio_chan_spec *chan, enum iio_event_type type,
598 	enum iio_event_direction dir)
599 {
600 	struct us5182d_data *data = iio_priv(indio_dev);
601 	int ret;
602 
603 	switch (dir) {
604 	case IIO_EV_DIR_RISING:
605 		mutex_lock(&data->lock);
606 		ret = data->rising_en;
607 		mutex_unlock(&data->lock);
608 		break;
609 	case IIO_EV_DIR_FALLING:
610 		mutex_lock(&data->lock);
611 		ret = data->falling_en;
612 		mutex_unlock(&data->lock);
613 		break;
614 	default:
615 		ret = -EINVAL;
616 		break;
617 	}
618 
619 	return ret;
620 }
621 
622 static int us5182d_write_event_config(struct iio_dev *indio_dev,
623 	const struct iio_chan_spec *chan, enum iio_event_type type,
624 	enum iio_event_direction dir, bool state)
625 {
626 	struct us5182d_data *data = iio_priv(indio_dev);
627 	int ret;
628 	u16 new_th;
629 
630 	mutex_lock(&data->lock);
631 
632 	switch (dir) {
633 	case IIO_EV_DIR_RISING:
634 		if (data->rising_en == state) {
635 			mutex_unlock(&data->lock);
636 			return 0;
637 		}
638 		new_th = US5182D_PXH_TH_DISABLE;
639 		if (state) {
640 			data->power_mode = US5182D_CONTINUOUS;
641 			ret = us5182d_set_power_state(data, true);
642 			if (ret < 0)
643 				goto err;
644 			ret = us5182d_px_enable(data);
645 			if (ret < 0)
646 				goto err_poweroff;
647 			new_th = data->px_high_th;
648 		}
649 		ret = us5182d_setup_prox(indio_dev, dir, new_th);
650 		if (ret < 0)
651 			goto err_poweroff;
652 		data->rising_en = state;
653 		break;
654 	case IIO_EV_DIR_FALLING:
655 		if (data->falling_en == state) {
656 			mutex_unlock(&data->lock);
657 			return 0;
658 		}
659 		new_th =  US5182D_PXL_TH_DISABLE;
660 		if (state) {
661 			data->power_mode = US5182D_CONTINUOUS;
662 			ret = us5182d_set_power_state(data, true);
663 			if (ret < 0)
664 				goto err;
665 			ret = us5182d_px_enable(data);
666 			if (ret < 0)
667 				goto err_poweroff;
668 			new_th = data->px_low_th;
669 		}
670 		ret = us5182d_setup_prox(indio_dev, dir, new_th);
671 		if (ret < 0)
672 			goto err_poweroff;
673 		data->falling_en = state;
674 		break;
675 	default:
676 		ret = -EINVAL;
677 		goto err;
678 	}
679 
680 	if (!state) {
681 		ret = us5182d_set_power_state(data, false);
682 		if (ret < 0)
683 			goto err;
684 	}
685 
686 	if (!data->falling_en && !data->rising_en && !data->default_continuous)
687 		data->power_mode = US5182D_ONESHOT;
688 
689 	mutex_unlock(&data->lock);
690 	return 0;
691 
692 err_poweroff:
693 	if (state)
694 		us5182d_set_power_state(data, false);
695 err:
696 	mutex_unlock(&data->lock);
697 	return ret;
698 }
699 
700 static const struct iio_info us5182d_info = {
701 	.read_raw = us5182d_read_raw,
702 	.write_raw = us5182d_write_raw,
703 	.attrs = &us5182d_attr_group,
704 	.read_event_value = &us5182d_read_thresh,
705 	.write_event_value = &us5182d_write_thresh,
706 	.read_event_config = &us5182d_read_event_config,
707 	.write_event_config = &us5182d_write_event_config,
708 };
709 
710 static int us5182d_reset(struct iio_dev *indio_dev)
711 {
712 	struct us5182d_data *data = iio_priv(indio_dev);
713 
714 	return i2c_smbus_write_byte_data(data->client, US5182D_REG_CFG3,
715 					 US5182D_RESET_CHIP);
716 }
717 
718 static int us5182d_init(struct iio_dev *indio_dev)
719 {
720 	struct us5182d_data *data = iio_priv(indio_dev);
721 	int i, ret;
722 
723 	ret = us5182d_reset(indio_dev);
724 	if (ret < 0)
725 		return ret;
726 
727 	data->opmode = 0;
728 	data->power_mode = US5182D_CONTINUOUS;
729 	data->px_low_th = US5182D_REG_PXL_TH_DEFAULT;
730 	data->px_high_th = US5182D_REG_PXH_TH_DEFAULT;
731 
732 	for (i = 0; i < ARRAY_SIZE(us5182d_regvals); i++) {
733 		ret = i2c_smbus_write_byte_data(data->client,
734 						us5182d_regvals[i].reg,
735 						us5182d_regvals[i].val);
736 		if (ret < 0)
737 			return ret;
738 	}
739 
740 	data->als_enabled = true;
741 	data->px_enabled = true;
742 
743 	if (!data->default_continuous) {
744 		ret = us5182d_shutdown_en(data, US5182D_CFG0_SHUTDOWN_EN);
745 		if (ret < 0)
746 			return ret;
747 		data->power_mode = US5182D_ONESHOT;
748 	}
749 
750 	return ret;
751 }
752 
753 static void us5182d_get_platform_data(struct iio_dev *indio_dev)
754 {
755 	struct us5182d_data *data = iio_priv(indio_dev);
756 
757 	if (device_property_read_u32(&data->client->dev, "upisemi,glass-coef",
758 				     &data->ga))
759 		data->ga = US5182D_GA_RESOLUTION;
760 	if (device_property_read_u16_array(&data->client->dev,
761 					   "upisemi,dark-ths",
762 					   data->us5182d_dark_ths,
763 					   ARRAY_SIZE(us5182d_dark_ths_vals)))
764 		data->us5182d_dark_ths = us5182d_dark_ths_vals;
765 	if (device_property_read_u8(&data->client->dev,
766 				    "upisemi,upper-dark-gain",
767 				    &data->upper_dark_gain))
768 		data->upper_dark_gain = US5182D_REG_AUTO_HDARK_GAIN_DEFAULT;
769 	if (device_property_read_u8(&data->client->dev,
770 				    "upisemi,lower-dark-gain",
771 				    &data->lower_dark_gain))
772 		data->lower_dark_gain = US5182D_REG_AUTO_LDARK_GAIN_DEFAULT;
773 	data->default_continuous = device_property_read_bool(&data->client->dev,
774 							     "upisemi,continuous");
775 }
776 
777 static int  us5182d_dark_gain_config(struct iio_dev *indio_dev)
778 {
779 	struct us5182d_data *data = iio_priv(indio_dev);
780 	int ret;
781 
782 	ret = us5182d_update_dark_th(data, US5182D_CFG1_AGAIN_DEFAULT);
783 	if (ret < 0)
784 		return ret;
785 
786 	ret = i2c_smbus_write_byte_data(data->client,
787 					US5182D_REG_AUTO_LDARK_GAIN,
788 					data->lower_dark_gain);
789 	if (ret < 0)
790 		return ret;
791 
792 	ret = i2c_smbus_write_byte_data(data->client,
793 					US5182D_REG_AUTO_HDARK_GAIN,
794 					data->upper_dark_gain);
795 	if (ret < 0)
796 		return ret;
797 
798 	return i2c_smbus_write_byte_data(data->client, US5182D_REG_DARK_AUTO_EN,
799 					 US5182D_REG_DARK_AUTO_EN_DEFAULT);
800 }
801 
802 static irqreturn_t us5182d_irq_thread_handler(int irq, void *private)
803 {
804 	struct iio_dev *indio_dev = private;
805 	struct us5182d_data *data = iio_priv(indio_dev);
806 	enum iio_event_direction dir;
807 	int ret;
808 	u64 ev;
809 
810 	ret = i2c_smbus_read_byte_data(data->client, US5182D_REG_CFG0);
811 	if (ret < 0) {
812 		dev_err(&data->client->dev, "i2c transfer error in irq\n");
813 		return IRQ_HANDLED;
814 	}
815 
816 	dir = ret & US5182D_CFG0_PROX ? IIO_EV_DIR_RISING : IIO_EV_DIR_FALLING;
817 	ev = IIO_UNMOD_EVENT_CODE(IIO_PROXIMITY, 1, IIO_EV_TYPE_THRESH, dir);
818 
819 	iio_push_event(indio_dev, ev, iio_get_time_ns(indio_dev));
820 
821 	ret = i2c_smbus_write_byte_data(data->client, US5182D_REG_CFG0,
822 					ret & ~US5182D_CFG0_PX_IRQ);
823 	if (ret < 0)
824 		dev_err(&data->client->dev, "i2c transfer error in irq\n");
825 
826 	return IRQ_HANDLED;
827 }
828 
829 static int us5182d_probe(struct i2c_client *client)
830 {
831 	struct us5182d_data *data;
832 	struct iio_dev *indio_dev;
833 	int ret;
834 
835 	indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*data));
836 	if (!indio_dev)
837 		return -ENOMEM;
838 
839 	data = iio_priv(indio_dev);
840 	i2c_set_clientdata(client, indio_dev);
841 	data->client = client;
842 
843 	mutex_init(&data->lock);
844 
845 	indio_dev->info = &us5182d_info;
846 	indio_dev->name = US5182D_DRV_NAME;
847 	indio_dev->channels = us5182d_channels;
848 	indio_dev->num_channels = ARRAY_SIZE(us5182d_channels);
849 	indio_dev->modes = INDIO_DIRECT_MODE;
850 
851 	ret = i2c_smbus_read_byte_data(data->client, US5182D_REG_CHIPID);
852 	if (ret != US5182D_CHIPID) {
853 		dev_err(&data->client->dev,
854 			"Failed to detect US5182 light chip\n");
855 		return (ret < 0) ? ret : -ENODEV;
856 	}
857 
858 	if (client->irq > 0) {
859 		ret = devm_request_threaded_irq(&client->dev, client->irq, NULL,
860 						us5182d_irq_thread_handler,
861 						IRQF_TRIGGER_LOW | IRQF_ONESHOT,
862 						"us5182d-irq", indio_dev);
863 		if (ret < 0)
864 			return ret;
865 	} else
866 		dev_warn(&client->dev, "no valid irq found\n");
867 
868 	us5182d_get_platform_data(indio_dev);
869 	ret = us5182d_init(indio_dev);
870 	if (ret < 0)
871 		return ret;
872 
873 	ret = us5182d_dark_gain_config(indio_dev);
874 	if (ret < 0)
875 		goto out_err;
876 
877 	if (data->default_continuous) {
878 		ret = pm_runtime_set_active(&client->dev);
879 		if (ret < 0)
880 			goto out_err;
881 	}
882 
883 	pm_runtime_enable(&client->dev);
884 	pm_runtime_set_autosuspend_delay(&client->dev,
885 					 US5182D_SLEEP_MS);
886 	pm_runtime_use_autosuspend(&client->dev);
887 
888 	ret = iio_device_register(indio_dev);
889 	if (ret < 0)
890 		goto out_err;
891 
892 	return 0;
893 
894 out_err:
895 	us5182d_shutdown_en(data, US5182D_CFG0_SHUTDOWN_EN);
896 	return ret;
897 
898 }
899 
900 static void us5182d_remove(struct i2c_client *client)
901 {
902 	struct us5182d_data *data = iio_priv(i2c_get_clientdata(client));
903 	int ret;
904 
905 	iio_device_unregister(i2c_get_clientdata(client));
906 
907 	pm_runtime_disable(&client->dev);
908 	pm_runtime_set_suspended(&client->dev);
909 
910 	ret = us5182d_shutdown_en(data, US5182D_CFG0_SHUTDOWN_EN);
911 	if (ret)
912 		dev_warn(&client->dev, "Failed to shut down (%pe)\n",
913 			 ERR_PTR(ret));
914 }
915 
916 static int us5182d_suspend(struct device *dev)
917 {
918 	struct iio_dev *indio_dev = i2c_get_clientdata(to_i2c_client(dev));
919 	struct us5182d_data *data = iio_priv(indio_dev);
920 
921 	if (data->power_mode == US5182D_CONTINUOUS)
922 		return us5182d_shutdown_en(data, US5182D_CFG0_SHUTDOWN_EN);
923 
924 	return 0;
925 }
926 
927 static int us5182d_resume(struct device *dev)
928 {
929 	struct iio_dev *indio_dev = i2c_get_clientdata(to_i2c_client(dev));
930 	struct us5182d_data *data = iio_priv(indio_dev);
931 
932 	if (data->power_mode == US5182D_CONTINUOUS)
933 		return us5182d_shutdown_en(data,
934 					   ~US5182D_CFG0_SHUTDOWN_EN & 0xff);
935 
936 	return 0;
937 }
938 
939 static const struct dev_pm_ops us5182d_pm_ops = {
940 	SYSTEM_SLEEP_PM_OPS(us5182d_suspend, us5182d_resume)
941 	RUNTIME_PM_OPS(us5182d_suspend, us5182d_resume, NULL)
942 };
943 
944 static const struct acpi_device_id us5182d_acpi_match[] = {
945 	{ "USD5182", 0 },
946 	{ }
947 };
948 
949 MODULE_DEVICE_TABLE(acpi, us5182d_acpi_match);
950 
951 static const struct i2c_device_id us5182d_id[] = {
952 	{ "usd5182" },
953 	{ }
954 };
955 
956 MODULE_DEVICE_TABLE(i2c, us5182d_id);
957 
958 static const struct of_device_id us5182d_of_match[] = {
959 	{ .compatible = "upisemi,usd5182" },
960 	{ }
961 };
962 MODULE_DEVICE_TABLE(of, us5182d_of_match);
963 
964 static struct i2c_driver us5182d_driver = {
965 	.driver = {
966 		.name = US5182D_DRV_NAME,
967 		.pm = pm_ptr(&us5182d_pm_ops),
968 		.of_match_table = us5182d_of_match,
969 		.acpi_match_table = us5182d_acpi_match,
970 	},
971 	.probe = us5182d_probe,
972 	.remove = us5182d_remove,
973 	.id_table = us5182d_id,
974 
975 };
976 module_i2c_driver(us5182d_driver);
977 
978 MODULE_AUTHOR("Adriana Reus <adriana.reus@intel.com>");
979 MODULE_DESCRIPTION("Driver for us5182d Proximity and Light Sensor");
980 MODULE_LICENSE("GPL v2");
981