blob: f24b687bd152c2534b6ebd42eb4ae3d585c61523 [file] [log] [blame]
Adriana Reusc14f8ab2015-09-16 11:14:11 +03001/*
2 * Copyright (c) 2015 Intel Corporation
3 *
4 * Driver for UPISEMI us5182d Proximity and Ambient Light Sensor.
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License version 2 as published by
8 * the Free Software Foundation.
9 *
10 * This program is distributed in the hope it will be useful, but WITHOUT
11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
13 * more details.
14 *
15 * To do: Interrupt support.
16 */
17
18#include <linux/kernel.h>
19#include <linux/module.h>
20#include <linux/acpi.h>
21#include <linux/delay.h>
22#include <linux/i2c.h>
23#include <linux/iio/iio.h>
24#include <linux/iio/sysfs.h>
25#include <linux/mutex.h>
Adriana Reusf0e5f572015-11-24 12:59:51 +020026#include <linux/pm.h>
27#include <linux/pm_runtime.h>
Adriana Reusc14f8ab2015-09-16 11:14:11 +030028
29#define US5182D_REG_CFG0 0x00
30#define US5182D_CFG0_ONESHOT_EN BIT(6)
31#define US5182D_CFG0_SHUTDOWN_EN BIT(7)
32#define US5182D_CFG0_WORD_ENABLE BIT(0)
33
34#define US5182D_REG_CFG1 0x01
35#define US5182D_CFG1_ALS_RES16 BIT(4)
36#define US5182D_CFG1_AGAIN_DEFAULT 0x00
37
38#define US5182D_REG_CFG2 0x02
39#define US5182D_CFG2_PX_RES16 BIT(4)
40#define US5182D_CFG2_PXGAIN_DEFAULT BIT(2)
41
42#define US5182D_REG_CFG3 0x03
43#define US5182D_CFG3_LED_CURRENT100 (BIT(4) | BIT(5))
44
45#define US5182D_REG_CFG4 0x10
46
47/*
48 * Registers for tuning the auto dark current cancelling feature.
49 * DARK_TH(reg 0x27,0x28) - threshold (counts) for auto dark cancelling.
50 * when ALS > DARK_TH --> ALS_Code = ALS - Upper(0x2A) * Dark
51 * when ALS < DARK_TH --> ALS_Code = ALS - Lower(0x29) * Dark
52 */
53#define US5182D_REG_UDARK_TH 0x27
54#define US5182D_REG_DARK_AUTO_EN 0x2b
55#define US5182D_REG_AUTO_LDARK_GAIN 0x29
56#define US5182D_REG_AUTO_HDARK_GAIN 0x2a
57
58#define US5182D_OPMODE_ALS 0x01
59#define US5182D_OPMODE_PX 0x02
60#define US5182D_OPMODE_SHIFT 4
61
62#define US5182D_REG_DARK_AUTO_EN_DEFAULT 0x80
63#define US5182D_REG_AUTO_LDARK_GAIN_DEFAULT 0x16
64#define US5182D_REG_AUTO_HDARK_GAIN_DEFAULT 0x00
65
66#define US5182D_REG_ADL 0x0c
67#define US5182D_REG_PDL 0x0e
68
69#define US5182D_REG_MODE_STORE 0x21
70#define US5182D_STORE_MODE 0x01
71
72#define US5182D_REG_CHIPID 0xb2
73
74#define US5182D_OPMODE_MASK GENMASK(5, 4)
75#define US5182D_AGAIN_MASK 0x07
76#define US5182D_RESET_CHIP 0x01
77
78#define US5182D_CHIPID 0x26
79#define US5182D_DRV_NAME "us5182d"
80
81#define US5182D_GA_RESOLUTION 1000
82
83#define US5182D_READ_BYTE 1
84#define US5182D_READ_WORD 2
85#define US5182D_OPSTORE_SLEEP_TIME 20 /* ms */
Adriana Reusf0e5f572015-11-24 12:59:51 +020086#define US5182D_SLEEP_MS 3000 /* ms */
Adriana Reusc14f8ab2015-09-16 11:14:11 +030087
88/* Available ranges: [12354, 7065, 3998, 2202, 1285, 498, 256, 138] lux */
89static const int us5182d_scales[] = {188500, 107800, 61000, 33600, 19600, 7600,
90 3900, 2100};
91
92/*
93 * Experimental thresholds that work with US5182D sensor on evaluation board
94 * roughly between 12-32 lux
95 */
96static u16 us5182d_dark_ths_vals[] = {170, 200, 512, 512, 800, 2000, 4000,
97 8000};
98
99enum mode {
100 US5182D_ALS_PX,
101 US5182D_ALS_ONLY,
102 US5182D_PX_ONLY
103};
104
Adriana Reusc3304c22015-11-24 12:59:48 +0200105enum pmode {
106 US5182D_CONTINUOUS,
107 US5182D_ONESHOT
108};
109
Adriana Reusc14f8ab2015-09-16 11:14:11 +0300110struct us5182d_data {
111 struct i2c_client *client;
112 struct mutex lock;
113
114 /* Glass attenuation factor */
115 u32 ga;
116
117 /* Dark gain tuning */
118 u8 lower_dark_gain;
119 u8 upper_dark_gain;
120 u16 *us5182d_dark_ths;
121
122 u8 opmode;
Adriana Reusc3304c22015-11-24 12:59:48 +0200123 u8 power_mode;
124
Adriana Reusa22a3c52015-11-24 12:59:50 +0200125 bool als_enabled;
126 bool px_enabled;
127
Adriana Reusc3304c22015-11-24 12:59:48 +0200128 bool default_continuous;
Adriana Reusc14f8ab2015-09-16 11:14:11 +0300129};
130
131static IIO_CONST_ATTR(in_illuminance_scale_available,
132 "0.0021 0.0039 0.0076 0.0196 0.0336 0.061 0.1078 0.1885");
133
134static struct attribute *us5182d_attrs[] = {
135 &iio_const_attr_in_illuminance_scale_available.dev_attr.attr,
136 NULL
137};
138
139static const struct attribute_group us5182d_attr_group = {
140 .attrs = us5182d_attrs,
141};
142
143static const struct {
144 u8 reg;
145 u8 val;
146} us5182d_regvals[] = {
Adriana Reusc3304c22015-11-24 12:59:48 +0200147 {US5182D_REG_CFG0, US5182D_CFG0_WORD_ENABLE},
Adriana Reusc14f8ab2015-09-16 11:14:11 +0300148 {US5182D_REG_CFG1, US5182D_CFG1_ALS_RES16},
149 {US5182D_REG_CFG2, (US5182D_CFG2_PX_RES16 |
150 US5182D_CFG2_PXGAIN_DEFAULT)},
151 {US5182D_REG_CFG3, US5182D_CFG3_LED_CURRENT100},
Adriana Reusc14f8ab2015-09-16 11:14:11 +0300152 {US5182D_REG_CFG4, 0x00},
153};
154
155static const struct iio_chan_spec us5182d_channels[] = {
156 {
157 .type = IIO_LIGHT,
158 .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
159 BIT(IIO_CHAN_INFO_SCALE),
160 },
161 {
162 .type = IIO_PROXIMITY,
163 .info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
164 }
165};
166
167static int us5182d_get_als(struct us5182d_data *data)
168{
169 int ret;
170 unsigned long result;
171
172 ret = i2c_smbus_read_word_data(data->client,
173 US5182D_REG_ADL);
174 if (ret < 0)
175 return ret;
176
177 result = ret * data->ga / US5182D_GA_RESOLUTION;
178 if (result > 0xffff)
179 result = 0xffff;
180
181 return result;
182}
183
Adriana Reusc3304c22015-11-24 12:59:48 +0200184static int us5182d_oneshot_en(struct us5182d_data *data)
Adriana Reusc14f8ab2015-09-16 11:14:11 +0300185{
186 int ret;
187
188 ret = i2c_smbus_read_byte_data(data->client, US5182D_REG_CFG0);
189 if (ret < 0)
190 return ret;
191
192 /*
193 * In oneshot mode the chip will power itself down after taking the
194 * required measurement.
195 */
196 ret = ret | US5182D_CFG0_ONESHOT_EN;
197
Adriana Reusc3304c22015-11-24 12:59:48 +0200198 return i2c_smbus_write_byte_data(data->client, US5182D_REG_CFG0, ret);
199}
200
201static int us5182d_set_opmode(struct us5182d_data *data, u8 mode)
202{
203 int ret;
204
205 if (mode == data->opmode)
206 return 0;
207
208 ret = i2c_smbus_read_byte_data(data->client, US5182D_REG_CFG0);
209 if (ret < 0)
210 return ret;
211
Adriana Reusc14f8ab2015-09-16 11:14:11 +0300212 /* update mode */
213 ret = ret & ~US5182D_OPMODE_MASK;
214 ret = ret | (mode << US5182D_OPMODE_SHIFT);
215
216 /*
217 * After updating the operating mode, the chip requires that
218 * the operation is stored, by writing 1 in the STORE_MODE
219 * register (auto-clearing).
220 */
221 ret = i2c_smbus_write_byte_data(data->client, US5182D_REG_CFG0, ret);
222 if (ret < 0)
223 return ret;
224
Adriana Reusc14f8ab2015-09-16 11:14:11 +0300225 ret = i2c_smbus_write_byte_data(data->client, US5182D_REG_MODE_STORE,
226 US5182D_STORE_MODE);
227 if (ret < 0)
228 return ret;
229
230 data->opmode = mode;
231 msleep(US5182D_OPSTORE_SLEEP_TIME);
232
233 return 0;
234}
235
Adriana Reusa22a3c52015-11-24 12:59:50 +0200236static int us5182d_als_enable(struct us5182d_data *data)
237{
238 int ret;
239 u8 mode;
240
Adriana Reus58e90422015-12-14 14:24:45 +0200241 if (data->power_mode == US5182D_ONESHOT) {
242 ret = us5182d_set_opmode(data, US5182D_ALS_ONLY);
243 if (ret < 0)
244 return ret;
245 data->px_enabled = false;
246 }
Adriana Reusa22a3c52015-11-24 12:59:50 +0200247
248 if (data->als_enabled)
249 return 0;
250
251 mode = data->px_enabled ? US5182D_ALS_PX : US5182D_ALS_ONLY;
252
253 ret = us5182d_set_opmode(data, mode);
254 if (ret < 0)
255 return ret;
256
257 data->als_enabled = true;
258
259 return 0;
260}
261
262static int us5182d_px_enable(struct us5182d_data *data)
263{
264 int ret;
265 u8 mode;
266
Adriana Reus58e90422015-12-14 14:24:45 +0200267 if (data->power_mode == US5182D_ONESHOT) {
268 ret = us5182d_set_opmode(data, US5182D_PX_ONLY);
269 if (ret < 0)
270 return ret;
271 data->als_enabled = false;
272 }
Adriana Reusa22a3c52015-11-24 12:59:50 +0200273
274 if (data->px_enabled)
275 return 0;
276
277 mode = data->als_enabled ? US5182D_ALS_PX : US5182D_PX_ONLY;
278
279 ret = us5182d_set_opmode(data, mode);
280 if (ret < 0)
281 return ret;
282
283 data->px_enabled = true;
284
285 return 0;
286}
287
Adriana Reusc3304c22015-11-24 12:59:48 +0200288static int us5182d_shutdown_en(struct us5182d_data *data, u8 state)
289{
290 int ret;
291
292 if (data->power_mode == US5182D_ONESHOT)
293 return 0;
294
295 ret = i2c_smbus_read_byte_data(data->client, US5182D_REG_CFG0);
296 if (ret < 0)
297 return ret;
298
299 ret = ret & ~US5182D_CFG0_SHUTDOWN_EN;
300 ret = ret | state;
301
Adriana Reusa22a3c52015-11-24 12:59:50 +0200302 ret = i2c_smbus_write_byte_data(data->client, US5182D_REG_CFG0, ret);
303 if (ret < 0)
304 return ret;
305
306 if (state & US5182D_CFG0_SHUTDOWN_EN) {
307 data->als_enabled = false;
308 data->px_enabled = false;
309 }
310
311 return ret;
Adriana Reusc3304c22015-11-24 12:59:48 +0200312}
313
Adriana Reusf0e5f572015-11-24 12:59:51 +0200314
315static int us5182d_set_power_state(struct us5182d_data *data, bool on)
316{
317 int ret;
318
319 if (data->power_mode == US5182D_ONESHOT)
320 return 0;
321
322 if (on) {
323 ret = pm_runtime_get_sync(&data->client->dev);
324 if (ret < 0)
325 pm_runtime_put_noidle(&data->client->dev);
326 } else {
327 pm_runtime_mark_last_busy(&data->client->dev);
328 ret = pm_runtime_put_autosuspend(&data->client->dev);
329 }
330
331 return ret;
332}
333
Adriana Reusc14f8ab2015-09-16 11:14:11 +0300334static int us5182d_read_raw(struct iio_dev *indio_dev,
335 struct iio_chan_spec const *chan, int *val,
336 int *val2, long mask)
337{
338 struct us5182d_data *data = iio_priv(indio_dev);
339 int ret;
340
341 switch (mask) {
342 case IIO_CHAN_INFO_RAW:
343 switch (chan->type) {
344 case IIO_LIGHT:
345 mutex_lock(&data->lock);
Adriana Reusc3304c22015-11-24 12:59:48 +0200346 if (data->power_mode == US5182D_ONESHOT) {
347 ret = us5182d_oneshot_en(data);
348 if (ret < 0)
349 goto out_err;
350 }
Adriana Reusf0e5f572015-11-24 12:59:51 +0200351 ret = us5182d_set_power_state(data, true);
Adriana Reusc14f8ab2015-09-16 11:14:11 +0300352 if (ret < 0)
353 goto out_err;
Adriana Reusf0e5f572015-11-24 12:59:51 +0200354 ret = us5182d_als_enable(data);
355 if (ret < 0)
356 goto out_poweroff;
Adriana Reusc14f8ab2015-09-16 11:14:11 +0300357 ret = us5182d_get_als(data);
358 if (ret < 0)
Adriana Reusf0e5f572015-11-24 12:59:51 +0200359 goto out_poweroff;
360 *val = ret;
361 ret = us5182d_set_power_state(data, false);
362 if (ret < 0)
Adriana Reusc14f8ab2015-09-16 11:14:11 +0300363 goto out_err;
364 mutex_unlock(&data->lock);
Adriana Reusc14f8ab2015-09-16 11:14:11 +0300365 return IIO_VAL_INT;
366 case IIO_PROXIMITY:
367 mutex_lock(&data->lock);
Adriana Reusc3304c22015-11-24 12:59:48 +0200368 if (data->power_mode == US5182D_ONESHOT) {
369 ret = us5182d_oneshot_en(data);
370 if (ret < 0)
371 goto out_err;
372 }
Adriana Reusf0e5f572015-11-24 12:59:51 +0200373 ret = us5182d_set_power_state(data, true);
Adriana Reusc14f8ab2015-09-16 11:14:11 +0300374 if (ret < 0)
375 goto out_err;
Adriana Reusf0e5f572015-11-24 12:59:51 +0200376 ret = us5182d_px_enable(data);
377 if (ret < 0)
378 goto out_poweroff;
Adriana Reusc14f8ab2015-09-16 11:14:11 +0300379 ret = i2c_smbus_read_word_data(data->client,
380 US5182D_REG_PDL);
381 if (ret < 0)
Adriana Reusf0e5f572015-11-24 12:59:51 +0200382 goto out_poweroff;
383 *val = ret;
384 ret = us5182d_set_power_state(data, false);
385 if (ret < 0)
Adriana Reusc14f8ab2015-09-16 11:14:11 +0300386 goto out_err;
387 mutex_unlock(&data->lock);
Adriana Reusf0e5f572015-11-24 12:59:51 +0200388 return IIO_VAL_INT;
Adriana Reusc14f8ab2015-09-16 11:14:11 +0300389 default:
390 return -EINVAL;
391 }
392
393 case IIO_CHAN_INFO_SCALE:
394 ret = i2c_smbus_read_byte_data(data->client, US5182D_REG_CFG1);
395 if (ret < 0)
396 return ret;
397
398 *val = 0;
399 *val2 = us5182d_scales[ret & US5182D_AGAIN_MASK];
400
401 return IIO_VAL_INT_PLUS_MICRO;
402 default:
403 return -EINVAL;
404 }
405
406 return -EINVAL;
Adriana Reusf0e5f572015-11-24 12:59:51 +0200407
408out_poweroff:
409 us5182d_set_power_state(data, false);
Adriana Reusc14f8ab2015-09-16 11:14:11 +0300410out_err:
411 mutex_unlock(&data->lock);
412 return ret;
413}
414
415/**
416 * us5182d_update_dark_th - update Darh_Th registers
417 * @data us5182d_data structure
418 * @index index in us5182d_dark_ths array to use for the updated value
419 *
420 * Function needs to be called with a lock held because it needs two i2c write
421 * byte operations as these registers (0x27 0x28) don't work in word mode
422 * accessing.
423 */
424static int us5182d_update_dark_th(struct us5182d_data *data, int index)
425{
426 __be16 dark_th = cpu_to_be16(data->us5182d_dark_ths[index]);
427 int ret;
428
429 ret = i2c_smbus_write_byte_data(data->client, US5182D_REG_UDARK_TH,
430 ((u8 *)&dark_th)[0]);
431 if (ret < 0)
432 return ret;
433
434 return i2c_smbus_write_byte_data(data->client, US5182D_REG_UDARK_TH + 1,
435 ((u8 *)&dark_th)[1]);
436}
437
438/**
439 * us5182d_apply_scale - update the ALS scale
440 * @data us5182d_data structure
441 * @index index in us5182d_scales array to use for the updated value
442 *
443 * Function needs to be called with a lock held as we're having more than one
444 * i2c operation.
445 */
446static int us5182d_apply_scale(struct us5182d_data *data, int index)
447{
448 int ret;
449
450 ret = i2c_smbus_read_byte_data(data->client, US5182D_REG_CFG1);
451 if (ret < 0)
452 return ret;
453
454 ret = ret & (~US5182D_AGAIN_MASK);
455 ret |= index;
456
457 ret = i2c_smbus_write_byte_data(data->client, US5182D_REG_CFG1, ret);
458 if (ret < 0)
459 return ret;
460
461 return us5182d_update_dark_th(data, index);
462}
463
464static int us5182d_write_raw(struct iio_dev *indio_dev,
465 struct iio_chan_spec const *chan, int val,
466 int val2, long mask)
467{
468 struct us5182d_data *data = iio_priv(indio_dev);
469 int ret, i;
470
471 switch (mask) {
472 case IIO_CHAN_INFO_SCALE:
473 if (val != 0)
474 return -EINVAL;
475 for (i = 0; i < ARRAY_SIZE(us5182d_scales); i++)
476 if (val2 == us5182d_scales[i]) {
477 mutex_lock(&data->lock);
478 ret = us5182d_apply_scale(data, i);
479 mutex_unlock(&data->lock);
480 return ret;
481 }
482 break;
483 default:
484 return -EINVAL;
485 }
486
487 return -EINVAL;
488}
489
490static const struct iio_info us5182d_info = {
491 .driver_module = THIS_MODULE,
492 .read_raw = us5182d_read_raw,
493 .write_raw = us5182d_write_raw,
494 .attrs = &us5182d_attr_group,
495};
496
497static int us5182d_reset(struct iio_dev *indio_dev)
498{
499 struct us5182d_data *data = iio_priv(indio_dev);
500
501 return i2c_smbus_write_byte_data(data->client, US5182D_REG_CFG3,
502 US5182D_RESET_CHIP);
503}
504
505static int us5182d_init(struct iio_dev *indio_dev)
506{
507 struct us5182d_data *data = iio_priv(indio_dev);
508 int i, ret;
509
510 ret = us5182d_reset(indio_dev);
511 if (ret < 0)
512 return ret;
513
514 data->opmode = 0;
Adriana Reusc3304c22015-11-24 12:59:48 +0200515 data->power_mode = US5182D_CONTINUOUS;
Adriana Reusc14f8ab2015-09-16 11:14:11 +0300516 for (i = 0; i < ARRAY_SIZE(us5182d_regvals); i++) {
517 ret = i2c_smbus_write_byte_data(data->client,
518 us5182d_regvals[i].reg,
519 us5182d_regvals[i].val);
520 if (ret < 0)
521 return ret;
522 }
523
Adriana Reusa22a3c52015-11-24 12:59:50 +0200524 data->als_enabled = true;
525 data->px_enabled = true;
526
Adriana Reusc3304c22015-11-24 12:59:48 +0200527 if (!data->default_continuous) {
528 ret = us5182d_shutdown_en(data, US5182D_CFG0_SHUTDOWN_EN);
529 if (ret < 0)
530 return ret;
531 data->power_mode = US5182D_ONESHOT;
532 }
533
Adriana Reusc3304c22015-11-24 12:59:48 +0200534 return ret;
Adriana Reusc14f8ab2015-09-16 11:14:11 +0300535}
536
537static void us5182d_get_platform_data(struct iio_dev *indio_dev)
538{
539 struct us5182d_data *data = iio_priv(indio_dev);
540
541 if (device_property_read_u32(&data->client->dev, "upisemi,glass-coef",
542 &data->ga))
543 data->ga = US5182D_GA_RESOLUTION;
544 if (device_property_read_u16_array(&data->client->dev,
545 "upisemi,dark-ths",
546 data->us5182d_dark_ths,
547 ARRAY_SIZE(us5182d_dark_ths_vals)))
548 data->us5182d_dark_ths = us5182d_dark_ths_vals;
549 if (device_property_read_u8(&data->client->dev,
550 "upisemi,upper-dark-gain",
551 &data->upper_dark_gain))
552 data->upper_dark_gain = US5182D_REG_AUTO_HDARK_GAIN_DEFAULT;
553 if (device_property_read_u8(&data->client->dev,
554 "upisemi,lower-dark-gain",
555 &data->lower_dark_gain))
556 data->lower_dark_gain = US5182D_REG_AUTO_LDARK_GAIN_DEFAULT;
Adriana Reusc3304c22015-11-24 12:59:48 +0200557 data->default_continuous = device_property_read_bool(&data->client->dev,
558 "upisemi,continuous");
Adriana Reusc14f8ab2015-09-16 11:14:11 +0300559}
560
561static int us5182d_dark_gain_config(struct iio_dev *indio_dev)
562{
563 struct us5182d_data *data = iio_priv(indio_dev);
564 int ret;
565
566 ret = us5182d_update_dark_th(data, US5182D_CFG1_AGAIN_DEFAULT);
567 if (ret < 0)
568 return ret;
569
570 ret = i2c_smbus_write_byte_data(data->client,
571 US5182D_REG_AUTO_LDARK_GAIN,
572 data->lower_dark_gain);
573 if (ret < 0)
574 return ret;
575
576 ret = i2c_smbus_write_byte_data(data->client,
577 US5182D_REG_AUTO_HDARK_GAIN,
578 data->upper_dark_gain);
579 if (ret < 0)
580 return ret;
581
582 return i2c_smbus_write_byte_data(data->client, US5182D_REG_DARK_AUTO_EN,
583 US5182D_REG_DARK_AUTO_EN_DEFAULT);
584}
585
586static int us5182d_probe(struct i2c_client *client,
587 const struct i2c_device_id *id)
588{
589 struct us5182d_data *data;
590 struct iio_dev *indio_dev;
591 int ret;
592
593 indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*data));
594 if (!indio_dev)
595 return -ENOMEM;
596
597 data = iio_priv(indio_dev);
598 i2c_set_clientdata(client, indio_dev);
599 data->client = client;
600
601 mutex_init(&data->lock);
602
603 indio_dev->dev.parent = &client->dev;
604 indio_dev->info = &us5182d_info;
605 indio_dev->name = US5182D_DRV_NAME;
606 indio_dev->channels = us5182d_channels;
607 indio_dev->num_channels = ARRAY_SIZE(us5182d_channels);
608 indio_dev->modes = INDIO_DIRECT_MODE;
609
610 ret = i2c_smbus_read_byte_data(data->client, US5182D_REG_CHIPID);
611 if (ret != US5182D_CHIPID) {
612 dev_err(&data->client->dev,
613 "Failed to detect US5182 light chip\n");
614 return (ret < 0) ? ret : -ENODEV;
615 }
616
617 us5182d_get_platform_data(indio_dev);
618 ret = us5182d_init(indio_dev);
619 if (ret < 0)
620 return ret;
621
622 ret = us5182d_dark_gain_config(indio_dev);
623 if (ret < 0)
Adriana Reusc3304c22015-11-24 12:59:48 +0200624 goto out_err;
Adriana Reusc14f8ab2015-09-16 11:14:11 +0300625
Adriana Reusf0e5f572015-11-24 12:59:51 +0200626 if (data->default_continuous) {
627 pm_runtime_set_active(&client->dev);
628 if (ret < 0)
629 goto out_err;
630 }
631
632 pm_runtime_enable(&client->dev);
633 pm_runtime_set_autosuspend_delay(&client->dev,
634 US5182D_SLEEP_MS);
635 pm_runtime_use_autosuspend(&client->dev);
636
Adriana Reusc3304c22015-11-24 12:59:48 +0200637 ret = iio_device_register(indio_dev);
638 if (ret < 0)
639 goto out_err;
640
641 return 0;
642
643out_err:
644 us5182d_shutdown_en(data, US5182D_CFG0_SHUTDOWN_EN);
645 return ret;
646
Adriana Reusc14f8ab2015-09-16 11:14:11 +0300647}
648
649static int us5182d_remove(struct i2c_client *client)
650{
Adriana Reusc3304c22015-11-24 12:59:48 +0200651 struct us5182d_data *data = iio_priv(i2c_get_clientdata(client));
652
Adriana Reusc14f8ab2015-09-16 11:14:11 +0300653 iio_device_unregister(i2c_get_clientdata(client));
Adriana Reusc3304c22015-11-24 12:59:48 +0200654
Adriana Reusf0e5f572015-11-24 12:59:51 +0200655 pm_runtime_disable(&client->dev);
656 pm_runtime_set_suspended(&client->dev);
657
Adriana Reusc3304c22015-11-24 12:59:48 +0200658 return us5182d_shutdown_en(data, US5182D_CFG0_SHUTDOWN_EN);
Adriana Reusc14f8ab2015-09-16 11:14:11 +0300659}
660
Adriana Reusf0e5f572015-11-24 12:59:51 +0200661#if defined(CONFIG_PM_SLEEP) || defined(CONFIG_PM)
662static int us5182d_suspend(struct device *dev)
663{
664 struct iio_dev *indio_dev = i2c_get_clientdata(to_i2c_client(dev));
665 struct us5182d_data *data = iio_priv(indio_dev);
666
667 if (data->power_mode == US5182D_CONTINUOUS)
668 return us5182d_shutdown_en(data, US5182D_CFG0_SHUTDOWN_EN);
669
670 return 0;
671}
672
673static int us5182d_resume(struct device *dev)
674{
675 struct iio_dev *indio_dev = i2c_get_clientdata(to_i2c_client(dev));
676 struct us5182d_data *data = iio_priv(indio_dev);
677
678 if (data->power_mode == US5182D_CONTINUOUS)
679 return us5182d_shutdown_en(data,
680 ~US5182D_CFG0_SHUTDOWN_EN & 0xff);
681
682 return 0;
683}
684#endif
685
686static const struct dev_pm_ops us5182d_pm_ops = {
687 SET_SYSTEM_SLEEP_PM_OPS(us5182d_suspend, us5182d_resume)
688 SET_RUNTIME_PM_OPS(us5182d_suspend, us5182d_resume, NULL)
689};
690
Adriana Reusc14f8ab2015-09-16 11:14:11 +0300691static const struct acpi_device_id us5182d_acpi_match[] = {
692 { "USD5182", 0},
693 {}
694};
695
696MODULE_DEVICE_TABLE(acpi, us5182d_acpi_match);
697
698static const struct i2c_device_id us5182d_id[] = {
699 {"usd5182", 0},
700 {}
701};
702
703MODULE_DEVICE_TABLE(i2c, us5182d_id);
704
705static struct i2c_driver us5182d_driver = {
706 .driver = {
707 .name = US5182D_DRV_NAME,
Adriana Reusf0e5f572015-11-24 12:59:51 +0200708 .pm = &us5182d_pm_ops,
Adriana Reusc14f8ab2015-09-16 11:14:11 +0300709 .acpi_match_table = ACPI_PTR(us5182d_acpi_match),
710 },
711 .probe = us5182d_probe,
712 .remove = us5182d_remove,
713 .id_table = us5182d_id,
714
715};
716module_i2c_driver(us5182d_driver);
717
718MODULE_AUTHOR("Adriana Reus <adriana.reus@intel.com>");
719MODULE_DESCRIPTION("Driver for us5182d Proximity and Light Sensor");
720MODULE_LICENSE("GPL v2");