blob: 256c4bc12d2193cce9ddd473e467e25d01986cd7 [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
241 if (data->power_mode == US5182D_ONESHOT)
242 return us5182d_set_opmode(data, US5182D_ALS_ONLY);
243
244 if (data->als_enabled)
245 return 0;
246
247 mode = data->px_enabled ? US5182D_ALS_PX : US5182D_ALS_ONLY;
248
249 ret = us5182d_set_opmode(data, mode);
250 if (ret < 0)
251 return ret;
252
253 data->als_enabled = true;
254
255 return 0;
256}
257
258static int us5182d_px_enable(struct us5182d_data *data)
259{
260 int ret;
261 u8 mode;
262
263 if (data->power_mode == US5182D_ONESHOT)
264 return us5182d_set_opmode(data, US5182D_PX_ONLY);
265
266 if (data->px_enabled)
267 return 0;
268
269 mode = data->als_enabled ? US5182D_ALS_PX : US5182D_PX_ONLY;
270
271 ret = us5182d_set_opmode(data, mode);
272 if (ret < 0)
273 return ret;
274
275 data->px_enabled = true;
276
277 return 0;
278}
279
Adriana Reusc3304c22015-11-24 12:59:48 +0200280static int us5182d_shutdown_en(struct us5182d_data *data, u8 state)
281{
282 int ret;
283
284 if (data->power_mode == US5182D_ONESHOT)
285 return 0;
286
287 ret = i2c_smbus_read_byte_data(data->client, US5182D_REG_CFG0);
288 if (ret < 0)
289 return ret;
290
291 ret = ret & ~US5182D_CFG0_SHUTDOWN_EN;
292 ret = ret | state;
293
Adriana Reusa22a3c52015-11-24 12:59:50 +0200294 ret = i2c_smbus_write_byte_data(data->client, US5182D_REG_CFG0, ret);
295 if (ret < 0)
296 return ret;
297
298 if (state & US5182D_CFG0_SHUTDOWN_EN) {
299 data->als_enabled = false;
300 data->px_enabled = false;
301 }
302
303 return ret;
Adriana Reusc3304c22015-11-24 12:59:48 +0200304}
305
Adriana Reusf0e5f572015-11-24 12:59:51 +0200306
307static int us5182d_set_power_state(struct us5182d_data *data, bool on)
308{
309 int ret;
310
311 if (data->power_mode == US5182D_ONESHOT)
312 return 0;
313
314 if (on) {
315 ret = pm_runtime_get_sync(&data->client->dev);
316 if (ret < 0)
317 pm_runtime_put_noidle(&data->client->dev);
318 } else {
319 pm_runtime_mark_last_busy(&data->client->dev);
320 ret = pm_runtime_put_autosuspend(&data->client->dev);
321 }
322
323 return ret;
324}
325
Adriana Reusc14f8ab2015-09-16 11:14:11 +0300326static int us5182d_read_raw(struct iio_dev *indio_dev,
327 struct iio_chan_spec const *chan, int *val,
328 int *val2, long mask)
329{
330 struct us5182d_data *data = iio_priv(indio_dev);
331 int ret;
332
333 switch (mask) {
334 case IIO_CHAN_INFO_RAW:
335 switch (chan->type) {
336 case IIO_LIGHT:
337 mutex_lock(&data->lock);
Adriana Reusc3304c22015-11-24 12:59:48 +0200338 if (data->power_mode == US5182D_ONESHOT) {
339 ret = us5182d_oneshot_en(data);
340 if (ret < 0)
341 goto out_err;
342 }
Adriana Reusf0e5f572015-11-24 12:59:51 +0200343 ret = us5182d_set_power_state(data, true);
Adriana Reusc14f8ab2015-09-16 11:14:11 +0300344 if (ret < 0)
345 goto out_err;
Adriana Reusf0e5f572015-11-24 12:59:51 +0200346 ret = us5182d_als_enable(data);
347 if (ret < 0)
348 goto out_poweroff;
Adriana Reusc14f8ab2015-09-16 11:14:11 +0300349 ret = us5182d_get_als(data);
350 if (ret < 0)
Adriana Reusf0e5f572015-11-24 12:59:51 +0200351 goto out_poweroff;
352 *val = ret;
353 ret = us5182d_set_power_state(data, false);
354 if (ret < 0)
Adriana Reusc14f8ab2015-09-16 11:14:11 +0300355 goto out_err;
356 mutex_unlock(&data->lock);
Adriana Reusc14f8ab2015-09-16 11:14:11 +0300357 return IIO_VAL_INT;
358 case IIO_PROXIMITY:
359 mutex_lock(&data->lock);
Adriana Reusc3304c22015-11-24 12:59:48 +0200360 if (data->power_mode == US5182D_ONESHOT) {
361 ret = us5182d_oneshot_en(data);
362 if (ret < 0)
363 goto out_err;
364 }
Adriana Reusf0e5f572015-11-24 12:59:51 +0200365 ret = us5182d_set_power_state(data, true);
Adriana Reusc14f8ab2015-09-16 11:14:11 +0300366 if (ret < 0)
367 goto out_err;
Adriana Reusf0e5f572015-11-24 12:59:51 +0200368 ret = us5182d_px_enable(data);
369 if (ret < 0)
370 goto out_poweroff;
Adriana Reusc14f8ab2015-09-16 11:14:11 +0300371 ret = i2c_smbus_read_word_data(data->client,
372 US5182D_REG_PDL);
373 if (ret < 0)
Adriana Reusf0e5f572015-11-24 12:59:51 +0200374 goto out_poweroff;
375 *val = ret;
376 ret = us5182d_set_power_state(data, false);
377 if (ret < 0)
Adriana Reusc14f8ab2015-09-16 11:14:11 +0300378 goto out_err;
379 mutex_unlock(&data->lock);
Adriana Reusf0e5f572015-11-24 12:59:51 +0200380 return IIO_VAL_INT;
Adriana Reusc14f8ab2015-09-16 11:14:11 +0300381 default:
382 return -EINVAL;
383 }
384
385 case IIO_CHAN_INFO_SCALE:
386 ret = i2c_smbus_read_byte_data(data->client, US5182D_REG_CFG1);
387 if (ret < 0)
388 return ret;
389
390 *val = 0;
391 *val2 = us5182d_scales[ret & US5182D_AGAIN_MASK];
392
393 return IIO_VAL_INT_PLUS_MICRO;
394 default:
395 return -EINVAL;
396 }
397
398 return -EINVAL;
Adriana Reusf0e5f572015-11-24 12:59:51 +0200399
400out_poweroff:
401 us5182d_set_power_state(data, false);
Adriana Reusc14f8ab2015-09-16 11:14:11 +0300402out_err:
403 mutex_unlock(&data->lock);
404 return ret;
405}
406
407/**
408 * us5182d_update_dark_th - update Darh_Th registers
409 * @data us5182d_data structure
410 * @index index in us5182d_dark_ths array to use for the updated value
411 *
412 * Function needs to be called with a lock held because it needs two i2c write
413 * byte operations as these registers (0x27 0x28) don't work in word mode
414 * accessing.
415 */
416static int us5182d_update_dark_th(struct us5182d_data *data, int index)
417{
418 __be16 dark_th = cpu_to_be16(data->us5182d_dark_ths[index]);
419 int ret;
420
421 ret = i2c_smbus_write_byte_data(data->client, US5182D_REG_UDARK_TH,
422 ((u8 *)&dark_th)[0]);
423 if (ret < 0)
424 return ret;
425
426 return i2c_smbus_write_byte_data(data->client, US5182D_REG_UDARK_TH + 1,
427 ((u8 *)&dark_th)[1]);
428}
429
430/**
431 * us5182d_apply_scale - update the ALS scale
432 * @data us5182d_data structure
433 * @index index in us5182d_scales array to use for the updated value
434 *
435 * Function needs to be called with a lock held as we're having more than one
436 * i2c operation.
437 */
438static int us5182d_apply_scale(struct us5182d_data *data, int index)
439{
440 int ret;
441
442 ret = i2c_smbus_read_byte_data(data->client, US5182D_REG_CFG1);
443 if (ret < 0)
444 return ret;
445
446 ret = ret & (~US5182D_AGAIN_MASK);
447 ret |= index;
448
449 ret = i2c_smbus_write_byte_data(data->client, US5182D_REG_CFG1, ret);
450 if (ret < 0)
451 return ret;
452
453 return us5182d_update_dark_th(data, index);
454}
455
456static int us5182d_write_raw(struct iio_dev *indio_dev,
457 struct iio_chan_spec const *chan, int val,
458 int val2, long mask)
459{
460 struct us5182d_data *data = iio_priv(indio_dev);
461 int ret, i;
462
463 switch (mask) {
464 case IIO_CHAN_INFO_SCALE:
465 if (val != 0)
466 return -EINVAL;
467 for (i = 0; i < ARRAY_SIZE(us5182d_scales); i++)
468 if (val2 == us5182d_scales[i]) {
469 mutex_lock(&data->lock);
470 ret = us5182d_apply_scale(data, i);
471 mutex_unlock(&data->lock);
472 return ret;
473 }
474 break;
475 default:
476 return -EINVAL;
477 }
478
479 return -EINVAL;
480}
481
482static const struct iio_info us5182d_info = {
483 .driver_module = THIS_MODULE,
484 .read_raw = us5182d_read_raw,
485 .write_raw = us5182d_write_raw,
486 .attrs = &us5182d_attr_group,
487};
488
489static int us5182d_reset(struct iio_dev *indio_dev)
490{
491 struct us5182d_data *data = iio_priv(indio_dev);
492
493 return i2c_smbus_write_byte_data(data->client, US5182D_REG_CFG3,
494 US5182D_RESET_CHIP);
495}
496
497static int us5182d_init(struct iio_dev *indio_dev)
498{
499 struct us5182d_data *data = iio_priv(indio_dev);
500 int i, ret;
501
502 ret = us5182d_reset(indio_dev);
503 if (ret < 0)
504 return ret;
505
506 data->opmode = 0;
Adriana Reusc3304c22015-11-24 12:59:48 +0200507 data->power_mode = US5182D_CONTINUOUS;
Adriana Reusc14f8ab2015-09-16 11:14:11 +0300508 for (i = 0; i < ARRAY_SIZE(us5182d_regvals); i++) {
509 ret = i2c_smbus_write_byte_data(data->client,
510 us5182d_regvals[i].reg,
511 us5182d_regvals[i].val);
512 if (ret < 0)
513 return ret;
514 }
515
Adriana Reusa22a3c52015-11-24 12:59:50 +0200516 data->als_enabled = true;
517 data->px_enabled = true;
518
Adriana Reusc3304c22015-11-24 12:59:48 +0200519 if (!data->default_continuous) {
520 ret = us5182d_shutdown_en(data, US5182D_CFG0_SHUTDOWN_EN);
521 if (ret < 0)
522 return ret;
523 data->power_mode = US5182D_ONESHOT;
524 }
525
Adriana Reusc3304c22015-11-24 12:59:48 +0200526 return ret;
Adriana Reusc14f8ab2015-09-16 11:14:11 +0300527}
528
529static void us5182d_get_platform_data(struct iio_dev *indio_dev)
530{
531 struct us5182d_data *data = iio_priv(indio_dev);
532
533 if (device_property_read_u32(&data->client->dev, "upisemi,glass-coef",
534 &data->ga))
535 data->ga = US5182D_GA_RESOLUTION;
536 if (device_property_read_u16_array(&data->client->dev,
537 "upisemi,dark-ths",
538 data->us5182d_dark_ths,
539 ARRAY_SIZE(us5182d_dark_ths_vals)))
540 data->us5182d_dark_ths = us5182d_dark_ths_vals;
541 if (device_property_read_u8(&data->client->dev,
542 "upisemi,upper-dark-gain",
543 &data->upper_dark_gain))
544 data->upper_dark_gain = US5182D_REG_AUTO_HDARK_GAIN_DEFAULT;
545 if (device_property_read_u8(&data->client->dev,
546 "upisemi,lower-dark-gain",
547 &data->lower_dark_gain))
548 data->lower_dark_gain = US5182D_REG_AUTO_LDARK_GAIN_DEFAULT;
Adriana Reusc3304c22015-11-24 12:59:48 +0200549 data->default_continuous = device_property_read_bool(&data->client->dev,
550 "upisemi,continuous");
Adriana Reusc14f8ab2015-09-16 11:14:11 +0300551}
552
553static int us5182d_dark_gain_config(struct iio_dev *indio_dev)
554{
555 struct us5182d_data *data = iio_priv(indio_dev);
556 int ret;
557
558 ret = us5182d_update_dark_th(data, US5182D_CFG1_AGAIN_DEFAULT);
559 if (ret < 0)
560 return ret;
561
562 ret = i2c_smbus_write_byte_data(data->client,
563 US5182D_REG_AUTO_LDARK_GAIN,
564 data->lower_dark_gain);
565 if (ret < 0)
566 return ret;
567
568 ret = i2c_smbus_write_byte_data(data->client,
569 US5182D_REG_AUTO_HDARK_GAIN,
570 data->upper_dark_gain);
571 if (ret < 0)
572 return ret;
573
574 return i2c_smbus_write_byte_data(data->client, US5182D_REG_DARK_AUTO_EN,
575 US5182D_REG_DARK_AUTO_EN_DEFAULT);
576}
577
578static int us5182d_probe(struct i2c_client *client,
579 const struct i2c_device_id *id)
580{
581 struct us5182d_data *data;
582 struct iio_dev *indio_dev;
583 int ret;
584
585 indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*data));
586 if (!indio_dev)
587 return -ENOMEM;
588
589 data = iio_priv(indio_dev);
590 i2c_set_clientdata(client, indio_dev);
591 data->client = client;
592
593 mutex_init(&data->lock);
594
595 indio_dev->dev.parent = &client->dev;
596 indio_dev->info = &us5182d_info;
597 indio_dev->name = US5182D_DRV_NAME;
598 indio_dev->channels = us5182d_channels;
599 indio_dev->num_channels = ARRAY_SIZE(us5182d_channels);
600 indio_dev->modes = INDIO_DIRECT_MODE;
601
602 ret = i2c_smbus_read_byte_data(data->client, US5182D_REG_CHIPID);
603 if (ret != US5182D_CHIPID) {
604 dev_err(&data->client->dev,
605 "Failed to detect US5182 light chip\n");
606 return (ret < 0) ? ret : -ENODEV;
607 }
608
609 us5182d_get_platform_data(indio_dev);
610 ret = us5182d_init(indio_dev);
611 if (ret < 0)
612 return ret;
613
614 ret = us5182d_dark_gain_config(indio_dev);
615 if (ret < 0)
Adriana Reusc3304c22015-11-24 12:59:48 +0200616 goto out_err;
Adriana Reusc14f8ab2015-09-16 11:14:11 +0300617
Adriana Reusf0e5f572015-11-24 12:59:51 +0200618 if (data->default_continuous) {
619 pm_runtime_set_active(&client->dev);
620 if (ret < 0)
621 goto out_err;
622 }
623
624 pm_runtime_enable(&client->dev);
625 pm_runtime_set_autosuspend_delay(&client->dev,
626 US5182D_SLEEP_MS);
627 pm_runtime_use_autosuspend(&client->dev);
628
Adriana Reusc3304c22015-11-24 12:59:48 +0200629 ret = iio_device_register(indio_dev);
630 if (ret < 0)
631 goto out_err;
632
633 return 0;
634
635out_err:
636 us5182d_shutdown_en(data, US5182D_CFG0_SHUTDOWN_EN);
637 return ret;
638
Adriana Reusc14f8ab2015-09-16 11:14:11 +0300639}
640
641static int us5182d_remove(struct i2c_client *client)
642{
Adriana Reusc3304c22015-11-24 12:59:48 +0200643 struct us5182d_data *data = iio_priv(i2c_get_clientdata(client));
644
Adriana Reusc14f8ab2015-09-16 11:14:11 +0300645 iio_device_unregister(i2c_get_clientdata(client));
Adriana Reusc3304c22015-11-24 12:59:48 +0200646
Adriana Reusf0e5f572015-11-24 12:59:51 +0200647 pm_runtime_disable(&client->dev);
648 pm_runtime_set_suspended(&client->dev);
649
Adriana Reusc3304c22015-11-24 12:59:48 +0200650 return us5182d_shutdown_en(data, US5182D_CFG0_SHUTDOWN_EN);
Adriana Reusc14f8ab2015-09-16 11:14:11 +0300651}
652
Adriana Reusf0e5f572015-11-24 12:59:51 +0200653#if defined(CONFIG_PM_SLEEP) || defined(CONFIG_PM)
654static int us5182d_suspend(struct device *dev)
655{
656 struct iio_dev *indio_dev = i2c_get_clientdata(to_i2c_client(dev));
657 struct us5182d_data *data = iio_priv(indio_dev);
658
659 if (data->power_mode == US5182D_CONTINUOUS)
660 return us5182d_shutdown_en(data, US5182D_CFG0_SHUTDOWN_EN);
661
662 return 0;
663}
664
665static int us5182d_resume(struct device *dev)
666{
667 struct iio_dev *indio_dev = i2c_get_clientdata(to_i2c_client(dev));
668 struct us5182d_data *data = iio_priv(indio_dev);
669
670 if (data->power_mode == US5182D_CONTINUOUS)
671 return us5182d_shutdown_en(data,
672 ~US5182D_CFG0_SHUTDOWN_EN & 0xff);
673
674 return 0;
675}
676#endif
677
678static const struct dev_pm_ops us5182d_pm_ops = {
679 SET_SYSTEM_SLEEP_PM_OPS(us5182d_suspend, us5182d_resume)
680 SET_RUNTIME_PM_OPS(us5182d_suspend, us5182d_resume, NULL)
681};
682
Adriana Reusc14f8ab2015-09-16 11:14:11 +0300683static const struct acpi_device_id us5182d_acpi_match[] = {
684 { "USD5182", 0},
685 {}
686};
687
688MODULE_DEVICE_TABLE(acpi, us5182d_acpi_match);
689
690static const struct i2c_device_id us5182d_id[] = {
691 {"usd5182", 0},
692 {}
693};
694
695MODULE_DEVICE_TABLE(i2c, us5182d_id);
696
697static struct i2c_driver us5182d_driver = {
698 .driver = {
699 .name = US5182D_DRV_NAME,
Adriana Reusf0e5f572015-11-24 12:59:51 +0200700 .pm = &us5182d_pm_ops,
Adriana Reusc14f8ab2015-09-16 11:14:11 +0300701 .acpi_match_table = ACPI_PTR(us5182d_acpi_match),
702 },
703 .probe = us5182d_probe,
704 .remove = us5182d_remove,
705 .id_table = us5182d_id,
706
707};
708module_i2c_driver(us5182d_driver);
709
710MODULE_AUTHOR("Adriana Reus <adriana.reus@intel.com>");
711MODULE_DESCRIPTION("Driver for us5182d Proximity and Light Sensor");
712MODULE_LICENSE("GPL v2");