]> git.proxmox.com Git - mirror_ubuntu-bionic-kernel.git/blame - drivers/iio/light/rpr0521.c
iio: adis16400: Change unsigned to unsigned int
[mirror_ubuntu-bionic-kernel.git] / drivers / iio / light / rpr0521.c
CommitLineData
efa86e9f
DB
1/*
2 * RPR-0521 ROHM Ambient Light and Proximity Sensor
3 *
4 * Copyright (c) 2015, Intel Corporation.
5 *
6 * This file is subject to the terms and conditions of version 2 of
7 * the GNU General Public License. See the file COPYING in the main
8 * directory of this archive for more details.
9 *
10 * IIO driver for RPR-0521RS (7-bit I2C slave address 0x38).
11 *
484c314b 12 * TODO: illuminance channel, buffer
efa86e9f
DB
13 */
14
15#include <linux/module.h>
16#include <linux/init.h>
17#include <linux/i2c.h>
18#include <linux/regmap.h>
19#include <linux/delay.h>
20#include <linux/acpi.h>
21
22#include <linux/iio/iio.h>
23#include <linux/iio/sysfs.h>
24#include <linux/pm_runtime.h>
25
26#define RPR0521_REG_SYSTEM_CTRL 0x40
27#define RPR0521_REG_MODE_CTRL 0x41
28#define RPR0521_REG_ALS_CTRL 0x42
29#define RPR0521_REG_PXS_CTRL 0x43
30#define RPR0521_REG_PXS_DATA 0x44 /* 16-bit, little endian */
31#define RPR0521_REG_ALS_DATA0 0x46 /* 16-bit, little endian */
32#define RPR0521_REG_ALS_DATA1 0x48 /* 16-bit, little endian */
734c4423 33#define RPR0521_REG_PS_OFFSET_LSB 0x53
efa86e9f
DB
34#define RPR0521_REG_ID 0x92
35
36#define RPR0521_MODE_ALS_MASK BIT(7)
37#define RPR0521_MODE_PXS_MASK BIT(6)
38#define RPR0521_MODE_MEAS_TIME_MASK GENMASK(3, 0)
39#define RPR0521_ALS_DATA0_GAIN_MASK GENMASK(5, 4)
40#define RPR0521_ALS_DATA0_GAIN_SHIFT 4
41#define RPR0521_ALS_DATA1_GAIN_MASK GENMASK(3, 2)
42#define RPR0521_ALS_DATA1_GAIN_SHIFT 2
43#define RPR0521_PXS_GAIN_MASK GENMASK(5, 4)
44#define RPR0521_PXS_GAIN_SHIFT 4
45
46#define RPR0521_MODE_ALS_ENABLE BIT(7)
47#define RPR0521_MODE_ALS_DISABLE 0x00
48#define RPR0521_MODE_PXS_ENABLE BIT(6)
49#define RPR0521_MODE_PXS_DISABLE 0x00
50
51#define RPR0521_MANUFACT_ID 0xE0
52#define RPR0521_DEFAULT_MEAS_TIME 0x06 /* ALS - 100ms, PXS - 100ms */
53
54#define RPR0521_DRV_NAME "RPR0521"
55#define RPR0521_REGMAP_NAME "rpr0521_regmap"
56
57#define RPR0521_SLEEP_DELAY_MS 2000
58
59#define RPR0521_ALS_SCALE_AVAIL "0.007812 0.015625 0.5 1"
60#define RPR0521_PXS_SCALE_AVAIL "0.125 0.5 1"
61
62struct rpr0521_gain {
63 int scale;
64 int uscale;
65};
66
67static const struct rpr0521_gain rpr0521_als_gain[4] = {
68 {1, 0}, /* x1 */
69 {0, 500000}, /* x2 */
70 {0, 15625}, /* x64 */
71 {0, 7812}, /* x128 */
72};
73
74static const struct rpr0521_gain rpr0521_pxs_gain[3] = {
75 {1, 0}, /* x1 */
76 {0, 500000}, /* x2 */
77 {0, 125000}, /* x4 */
78};
79
80enum rpr0521_channel {
9ece370b 81 RPR0521_CHAN_PXS,
efa86e9f
DB
82 RPR0521_CHAN_ALS_DATA0,
83 RPR0521_CHAN_ALS_DATA1,
efa86e9f
DB
84};
85
86struct rpr0521_reg_desc {
87 u8 address;
88 u8 device_mask;
89};
90
91static const struct rpr0521_reg_desc rpr0521_data_reg[] = {
9ece370b
MK
92 [RPR0521_CHAN_PXS] = {
93 .address = RPR0521_REG_PXS_DATA,
94 .device_mask = RPR0521_MODE_PXS_MASK,
95 },
efa86e9f
DB
96 [RPR0521_CHAN_ALS_DATA0] = {
97 .address = RPR0521_REG_ALS_DATA0,
98 .device_mask = RPR0521_MODE_ALS_MASK,
99 },
100 [RPR0521_CHAN_ALS_DATA1] = {
101 .address = RPR0521_REG_ALS_DATA1,
102 .device_mask = RPR0521_MODE_ALS_MASK,
103 },
efa86e9f
DB
104};
105
106static const struct rpr0521_gain_info {
107 u8 reg;
108 u8 mask;
109 u8 shift;
110 const struct rpr0521_gain *gain;
111 int size;
112} rpr0521_gain[] = {
9ece370b
MK
113 [RPR0521_CHAN_PXS] = {
114 .reg = RPR0521_REG_PXS_CTRL,
115 .mask = RPR0521_PXS_GAIN_MASK,
116 .shift = RPR0521_PXS_GAIN_SHIFT,
117 .gain = rpr0521_pxs_gain,
118 .size = ARRAY_SIZE(rpr0521_pxs_gain),
119 },
efa86e9f
DB
120 [RPR0521_CHAN_ALS_DATA0] = {
121 .reg = RPR0521_REG_ALS_CTRL,
122 .mask = RPR0521_ALS_DATA0_GAIN_MASK,
123 .shift = RPR0521_ALS_DATA0_GAIN_SHIFT,
124 .gain = rpr0521_als_gain,
125 .size = ARRAY_SIZE(rpr0521_als_gain),
126 },
127 [RPR0521_CHAN_ALS_DATA1] = {
128 .reg = RPR0521_REG_ALS_CTRL,
129 .mask = RPR0521_ALS_DATA1_GAIN_MASK,
130 .shift = RPR0521_ALS_DATA1_GAIN_SHIFT,
131 .gain = rpr0521_als_gain,
132 .size = ARRAY_SIZE(rpr0521_als_gain),
133 },
efa86e9f
DB
134};
135
c91a88ef
MK
136struct rpr0521_samp_freq {
137 int als_hz;
138 int als_uhz;
139 int pxs_hz;
140 int pxs_uhz;
141};
142
143static const struct rpr0521_samp_freq rpr0521_samp_freq_i[13] = {
144/* {ALS, PXS}, W==currently writable option */
145 {0, 0, 0, 0}, /* W0000, 0=standby */
146 {0, 0, 100, 0}, /* 0001 */
147 {0, 0, 25, 0}, /* 0010 */
148 {0, 0, 10, 0}, /* 0011 */
149 {0, 0, 2, 500000}, /* 0100 */
150 {10, 0, 20, 0}, /* 0101 */
151 {10, 0, 10, 0}, /* W0110 */
152 {10, 0, 2, 500000}, /* 0111 */
153 {2, 500000, 20, 0}, /* 1000, measurement 100ms, sleep 300ms */
154 {2, 500000, 10, 0}, /* 1001, measurement 100ms, sleep 300ms */
155 {2, 500000, 0, 0}, /* 1010, high sensitivity mode */
156 {2, 500000, 2, 500000}, /* W1011, high sensitivity mode */
157 {20, 0, 20, 0} /* 1100, ALS_data x 0.5, see specification P.18 */
158};
159
efa86e9f
DB
160struct rpr0521_data {
161 struct i2c_client *client;
162
163 /* protect device params updates (e.g state, gain) */
164 struct mutex lock;
165
166 /* device active status */
167 bool als_dev_en;
168 bool pxs_dev_en;
169
484c314b 170 /* optimize runtime pm ops - enable/disable device only if needed */
efa86e9f
DB
171 bool als_ps_need_en;
172 bool pxs_ps_need_en;
484c314b
MK
173 bool als_need_dis;
174 bool pxs_need_dis;
efa86e9f
DB
175
176 struct regmap *regmap;
177};
178
179static IIO_CONST_ATTR(in_intensity_scale_available, RPR0521_ALS_SCALE_AVAIL);
180static IIO_CONST_ATTR(in_proximity_scale_available, RPR0521_PXS_SCALE_AVAIL);
181
c91a88ef
MK
182/*
183 * Start with easy freq first, whole table of freq combinations is more
184 * complicated.
185 */
186static IIO_CONST_ATTR_SAMP_FREQ_AVAIL("2.5 10");
187
efa86e9f
DB
188static struct attribute *rpr0521_attributes[] = {
189 &iio_const_attr_in_intensity_scale_available.dev_attr.attr,
190 &iio_const_attr_in_proximity_scale_available.dev_attr.attr,
c91a88ef 191 &iio_const_attr_sampling_frequency_available.dev_attr.attr,
efa86e9f
DB
192 NULL,
193};
194
195static const struct attribute_group rpr0521_attribute_group = {
196 .attrs = rpr0521_attributes,
197};
198
199static const struct iio_chan_spec rpr0521_channels[] = {
9ece370b
MK
200 {
201 .type = IIO_PROXIMITY,
202 .address = RPR0521_CHAN_PXS,
203 .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
204 BIT(IIO_CHAN_INFO_OFFSET) |
205 BIT(IIO_CHAN_INFO_SCALE),
206 .info_mask_shared_by_all = BIT(IIO_CHAN_INFO_SAMP_FREQ),
207 },
efa86e9f
DB
208 {
209 .type = IIO_INTENSITY,
210 .modified = 1,
211 .address = RPR0521_CHAN_ALS_DATA0,
212 .channel2 = IIO_MOD_LIGHT_BOTH,
213 .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
214 BIT(IIO_CHAN_INFO_SCALE),
c91a88ef 215 .info_mask_shared_by_all = BIT(IIO_CHAN_INFO_SAMP_FREQ),
efa86e9f
DB
216 },
217 {
218 .type = IIO_INTENSITY,
219 .modified = 1,
220 .address = RPR0521_CHAN_ALS_DATA1,
221 .channel2 = IIO_MOD_LIGHT_IR,
222 .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
223 BIT(IIO_CHAN_INFO_SCALE),
c91a88ef 224 .info_mask_shared_by_all = BIT(IIO_CHAN_INFO_SAMP_FREQ),
efa86e9f 225 },
efa86e9f
DB
226};
227
228static int rpr0521_als_enable(struct rpr0521_data *data, u8 status)
229{
230 int ret;
231
232 ret = regmap_update_bits(data->regmap, RPR0521_REG_MODE_CTRL,
233 RPR0521_MODE_ALS_MASK,
234 status);
235 if (ret < 0)
236 return ret;
237
f87fa261
MK
238 if (status & RPR0521_MODE_ALS_MASK)
239 data->als_dev_en = true;
240 else
241 data->als_dev_en = false;
efa86e9f
DB
242
243 return 0;
244}
245
246static int rpr0521_pxs_enable(struct rpr0521_data *data, u8 status)
247{
248 int ret;
249
250 ret = regmap_update_bits(data->regmap, RPR0521_REG_MODE_CTRL,
251 RPR0521_MODE_PXS_MASK,
252 status);
253 if (ret < 0)
254 return ret;
255
f87fa261
MK
256 if (status & RPR0521_MODE_PXS_MASK)
257 data->pxs_dev_en = true;
258 else
259 data->pxs_dev_en = false;
efa86e9f
DB
260
261 return 0;
262}
263
264/**
265 * rpr0521_set_power_state - handles runtime PM state and sensors enabled status
266 *
267 * @data: rpr0521 device private data
268 * @on: state to be set for devices in @device_mask
269 * @device_mask: bitmask specifying for which device we need to update @on state
270 *
484c314b
MK
271 * Calls for this function must be balanced so that each ON should have matching
272 * OFF. Otherwise pm usage_count gets out of sync.
efa86e9f
DB
273 */
274static int rpr0521_set_power_state(struct rpr0521_data *data, bool on,
275 u8 device_mask)
276{
277#ifdef CONFIG_PM
278 int ret;
efa86e9f
DB
279
280 if (device_mask & RPR0521_MODE_ALS_MASK) {
484c314b
MK
281 data->als_ps_need_en = on;
282 data->als_need_dis = !on;
efa86e9f
DB
283 }
284
285 if (device_mask & RPR0521_MODE_PXS_MASK) {
484c314b
MK
286 data->pxs_ps_need_en = on;
287 data->pxs_need_dis = !on;
efa86e9f
DB
288 }
289
484c314b
MK
290 /*
291 * On: _resume() is called only when we are suspended
292 * Off: _suspend() is called after delay if _resume() is not
293 * called before that.
294 * Note: If either measurement is re-enabled before _suspend(),
295 * both stay enabled until _suspend().
296 */
efa86e9f
DB
297 if (on) {
298 ret = pm_runtime_get_sync(&data->client->dev);
299 } else {
300 pm_runtime_mark_last_busy(&data->client->dev);
301 ret = pm_runtime_put_autosuspend(&data->client->dev);
302 }
303 if (ret < 0) {
304 dev_err(&data->client->dev,
305 "Failed: rpr0521_set_power_state for %d, ret %d\n",
306 on, ret);
307 if (on)
308 pm_runtime_put_noidle(&data->client->dev);
309
310 return ret;
311 }
484c314b
MK
312
313 if (on) {
314 /* If _resume() was not called, enable measurement now. */
315 if (data->als_ps_need_en) {
316 ret = rpr0521_als_enable(data, RPR0521_MODE_ALS_ENABLE);
317 if (ret)
318 return ret;
319 data->als_ps_need_en = false;
320 }
321
322 if (data->pxs_ps_need_en) {
323 ret = rpr0521_pxs_enable(data, RPR0521_MODE_PXS_ENABLE);
324 if (ret)
325 return ret;
326 data->pxs_ps_need_en = false;
327 }
328 }
efa86e9f
DB
329#endif
330 return 0;
331}
332
333static int rpr0521_get_gain(struct rpr0521_data *data, int chan,
334 int *val, int *val2)
335{
336 int ret, reg, idx;
337
338 ret = regmap_read(data->regmap, rpr0521_gain[chan].reg, &reg);
339 if (ret < 0)
340 return ret;
341
342 idx = (rpr0521_gain[chan].mask & reg) >> rpr0521_gain[chan].shift;
343 *val = rpr0521_gain[chan].gain[idx].scale;
344 *val2 = rpr0521_gain[chan].gain[idx].uscale;
345
346 return 0;
347}
348
349static int rpr0521_set_gain(struct rpr0521_data *data, int chan,
350 int val, int val2)
351{
352 int i, idx = -EINVAL;
353
354 /* get gain index */
355 for (i = 0; i < rpr0521_gain[chan].size; i++)
356 if (val == rpr0521_gain[chan].gain[i].scale &&
357 val2 == rpr0521_gain[chan].gain[i].uscale) {
358 idx = i;
359 break;
360 }
361
362 if (idx < 0)
363 return idx;
364
365 return regmap_update_bits(data->regmap, rpr0521_gain[chan].reg,
366 rpr0521_gain[chan].mask,
367 idx << rpr0521_gain[chan].shift);
368}
369
c91a88ef
MK
370static int rpr0521_read_samp_freq(struct rpr0521_data *data,
371 enum iio_chan_type chan_type,
372 int *val, int *val2)
373{
374 int reg, ret;
375
376 ret = regmap_read(data->regmap, RPR0521_REG_MODE_CTRL, &reg);
377 if (ret < 0)
378 return ret;
379
380 reg &= RPR0521_MODE_MEAS_TIME_MASK;
381 if (reg >= ARRAY_SIZE(rpr0521_samp_freq_i))
382 return -EINVAL;
383
384 switch (chan_type) {
385 case IIO_INTENSITY:
386 *val = rpr0521_samp_freq_i[reg].als_hz;
387 *val2 = rpr0521_samp_freq_i[reg].als_uhz;
388 return 0;
389
390 case IIO_PROXIMITY:
391 *val = rpr0521_samp_freq_i[reg].pxs_hz;
392 *val2 = rpr0521_samp_freq_i[reg].pxs_uhz;
393 return 0;
394
395 default:
396 return -EINVAL;
397 }
398}
399
400static int rpr0521_write_samp_freq_common(struct rpr0521_data *data,
401 enum iio_chan_type chan_type,
402 int val, int val2)
403{
404 int i;
405
406 /*
407 * Ignore channel
408 * both pxs and als are setup only to same freq because of simplicity
409 */
410 switch (val) {
411 case 0:
412 i = 0;
413 break;
414
415 case 2:
416 if (val2 != 500000)
417 return -EINVAL;
418
419 i = 11;
420 break;
421
422 case 10:
423 i = 6;
424 break;
425
426 default:
427 return -EINVAL;
428 }
429
430 return regmap_update_bits(data->regmap,
431 RPR0521_REG_MODE_CTRL,
432 RPR0521_MODE_MEAS_TIME_MASK,
433 i);
434}
435
734c4423
MK
436static int rpr0521_read_ps_offset(struct rpr0521_data *data, int *offset)
437{
438 int ret;
439 __le16 buffer;
440
441 ret = regmap_bulk_read(data->regmap,
442 RPR0521_REG_PS_OFFSET_LSB, &buffer, sizeof(buffer));
443
444 if (ret < 0) {
445 dev_err(&data->client->dev, "Failed to read PS OFFSET register\n");
446 return ret;
447 }
448 *offset = le16_to_cpu(buffer);
449
450 return ret;
451}
452
453static int rpr0521_write_ps_offset(struct rpr0521_data *data, int offset)
454{
455 int ret;
456 __le16 buffer;
457
458 buffer = cpu_to_le16(offset & 0x3ff);
459 ret = regmap_raw_write(data->regmap,
460 RPR0521_REG_PS_OFFSET_LSB, &buffer, sizeof(buffer));
461
462 if (ret < 0) {
463 dev_err(&data->client->dev, "Failed to write PS OFFSET register\n");
464 return ret;
465 }
466
467 return ret;
468}
469
efa86e9f
DB
470static int rpr0521_read_raw(struct iio_dev *indio_dev,
471 struct iio_chan_spec const *chan, int *val,
472 int *val2, long mask)
473{
474 struct rpr0521_data *data = iio_priv(indio_dev);
475 int ret;
476 u8 device_mask;
477 __le16 raw_data;
478
479 switch (mask) {
480 case IIO_CHAN_INFO_RAW:
481 if (chan->type != IIO_INTENSITY && chan->type != IIO_PROXIMITY)
482 return -EINVAL;
483
484 device_mask = rpr0521_data_reg[chan->address].device_mask;
485
486 mutex_lock(&data->lock);
487 ret = rpr0521_set_power_state(data, true, device_mask);
488 if (ret < 0) {
489 mutex_unlock(&data->lock);
490 return ret;
491 }
492
493 ret = regmap_bulk_read(data->regmap,
494 rpr0521_data_reg[chan->address].address,
ae591650 495 &raw_data, sizeof(raw_data));
efa86e9f
DB
496 if (ret < 0) {
497 rpr0521_set_power_state(data, false, device_mask);
498 mutex_unlock(&data->lock);
499 return ret;
500 }
501
502 ret = rpr0521_set_power_state(data, false, device_mask);
503 mutex_unlock(&data->lock);
504 if (ret < 0)
505 return ret;
506
507 *val = le16_to_cpu(raw_data);
508
509 return IIO_VAL_INT;
624c389e 510
efa86e9f
DB
511 case IIO_CHAN_INFO_SCALE:
512 mutex_lock(&data->lock);
513 ret = rpr0521_get_gain(data, chan->address, val, val2);
514 mutex_unlock(&data->lock);
515 if (ret < 0)
516 return ret;
517
518 return IIO_VAL_INT_PLUS_MICRO;
624c389e 519
c91a88ef
MK
520 case IIO_CHAN_INFO_SAMP_FREQ:
521 mutex_lock(&data->lock);
522 ret = rpr0521_read_samp_freq(data, chan->type, val, val2);
523 mutex_unlock(&data->lock);
524 if (ret < 0)
525 return ret;
526
527 return IIO_VAL_INT_PLUS_MICRO;
528
734c4423
MK
529 case IIO_CHAN_INFO_OFFSET:
530 mutex_lock(&data->lock);
531 ret = rpr0521_read_ps_offset(data, val);
532 mutex_unlock(&data->lock);
533 if (ret < 0)
534 return ret;
535
536 return IIO_VAL_INT;
537
efa86e9f
DB
538 default:
539 return -EINVAL;
540 }
541}
542
543static int rpr0521_write_raw(struct iio_dev *indio_dev,
544 struct iio_chan_spec const *chan, int val,
545 int val2, long mask)
546{
547 struct rpr0521_data *data = iio_priv(indio_dev);
548 int ret;
549
550 switch (mask) {
551 case IIO_CHAN_INFO_SCALE:
552 mutex_lock(&data->lock);
553 ret = rpr0521_set_gain(data, chan->address, val, val2);
554 mutex_unlock(&data->lock);
555
556 return ret;
624c389e 557
c91a88ef
MK
558 case IIO_CHAN_INFO_SAMP_FREQ:
559 mutex_lock(&data->lock);
560 ret = rpr0521_write_samp_freq_common(data, chan->type,
561 val, val2);
562 mutex_unlock(&data->lock);
563
564 return ret;
565
734c4423
MK
566 case IIO_CHAN_INFO_OFFSET:
567 mutex_lock(&data->lock);
568 ret = rpr0521_write_ps_offset(data, val);
569 mutex_unlock(&data->lock);
570
571 return ret;
572
efa86e9f
DB
573 default:
574 return -EINVAL;
575 }
576}
577
578static const struct iio_info rpr0521_info = {
579 .driver_module = THIS_MODULE,
580 .read_raw = rpr0521_read_raw,
581 .write_raw = rpr0521_write_raw,
582 .attrs = &rpr0521_attribute_group,
583};
584
585static int rpr0521_init(struct rpr0521_data *data)
586{
587 int ret;
588 int id;
589
590 ret = regmap_read(data->regmap, RPR0521_REG_ID, &id);
591 if (ret < 0) {
592 dev_err(&data->client->dev, "Failed to read REG_ID register\n");
593 return ret;
594 }
595
596 if (id != RPR0521_MANUFACT_ID) {
597 dev_err(&data->client->dev, "Wrong id, got %x, expected %x\n",
598 id, RPR0521_MANUFACT_ID);
599 return -ENODEV;
600 }
601
602 /* set default measurement time - 100 ms for both ALS and PS */
603 ret = regmap_update_bits(data->regmap, RPR0521_REG_MODE_CTRL,
604 RPR0521_MODE_MEAS_TIME_MASK,
605 RPR0521_DEFAULT_MEAS_TIME);
606 if (ret) {
607 pr_err("regmap_update_bits returned %d\n", ret);
608 return ret;
609 }
610
484c314b 611#ifndef CONFIG_PM
efa86e9f
DB
612 ret = rpr0521_als_enable(data, RPR0521_MODE_ALS_ENABLE);
613 if (ret < 0)
614 return ret;
615 ret = rpr0521_pxs_enable(data, RPR0521_MODE_PXS_ENABLE);
616 if (ret < 0)
617 return ret;
484c314b 618#endif
efa86e9f
DB
619
620 return 0;
621}
622
623static int rpr0521_poweroff(struct rpr0521_data *data)
624{
625 int ret;
626
627 ret = regmap_update_bits(data->regmap, RPR0521_REG_MODE_CTRL,
628 RPR0521_MODE_ALS_MASK |
629 RPR0521_MODE_PXS_MASK,
630 RPR0521_MODE_ALS_DISABLE |
631 RPR0521_MODE_PXS_DISABLE);
632 if (ret < 0)
633 return ret;
634
635 data->als_dev_en = false;
636 data->pxs_dev_en = false;
637
638 return 0;
639}
640
641static bool rpr0521_is_volatile_reg(struct device *dev, unsigned int reg)
642{
643 switch (reg) {
644 case RPR0521_REG_MODE_CTRL:
645 case RPR0521_REG_ALS_CTRL:
646 case RPR0521_REG_PXS_CTRL:
647 return false;
648 default:
649 return true;
650 }
651}
652
653static const struct regmap_config rpr0521_regmap_config = {
654 .name = RPR0521_REGMAP_NAME,
655
656 .reg_bits = 8,
657 .val_bits = 8,
658
659 .max_register = RPR0521_REG_ID,
660 .cache_type = REGCACHE_RBTREE,
661 .volatile_reg = rpr0521_is_volatile_reg,
662};
663
664static int rpr0521_probe(struct i2c_client *client,
665 const struct i2c_device_id *id)
666{
667 struct rpr0521_data *data;
668 struct iio_dev *indio_dev;
669 struct regmap *regmap;
670 int ret;
671
672 indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*data));
673 if (!indio_dev)
674 return -ENOMEM;
675
676 regmap = devm_regmap_init_i2c(client, &rpr0521_regmap_config);
677 if (IS_ERR(regmap)) {
678 dev_err(&client->dev, "regmap_init failed!\n");
679 return PTR_ERR(regmap);
680 }
681
682 data = iio_priv(indio_dev);
683 i2c_set_clientdata(client, indio_dev);
684 data->client = client;
685 data->regmap = regmap;
686
687 mutex_init(&data->lock);
688
689 indio_dev->dev.parent = &client->dev;
690 indio_dev->info = &rpr0521_info;
691 indio_dev->name = RPR0521_DRV_NAME;
692 indio_dev->channels = rpr0521_channels;
693 indio_dev->num_channels = ARRAY_SIZE(rpr0521_channels);
694 indio_dev->modes = INDIO_DIRECT_MODE;
695
696 ret = rpr0521_init(data);
697 if (ret < 0) {
698 dev_err(&client->dev, "rpr0521 chip init failed\n");
699 return ret;
700 }
efa86e9f
DB
701
702 ret = pm_runtime_set_active(&client->dev);
703 if (ret < 0)
12d74949 704 goto err_poweroff;
efa86e9f
DB
705
706 pm_runtime_enable(&client->dev);
707 pm_runtime_set_autosuspend_delay(&client->dev, RPR0521_SLEEP_DELAY_MS);
708 pm_runtime_use_autosuspend(&client->dev);
709
12d74949
MK
710 ret = iio_device_register(indio_dev);
711 if (ret)
712 goto err_pm_disable;
713
714 return 0;
715
716err_pm_disable:
717 pm_runtime_disable(&client->dev);
718 pm_runtime_set_suspended(&client->dev);
719 pm_runtime_put_noidle(&client->dev);
720err_poweroff:
721 rpr0521_poweroff(data);
722
723 return ret;
efa86e9f
DB
724}
725
726static int rpr0521_remove(struct i2c_client *client)
727{
728 struct iio_dev *indio_dev = i2c_get_clientdata(client);
729
7d0ead5c
AR
730 iio_device_unregister(indio_dev);
731
efa86e9f
DB
732 pm_runtime_disable(&client->dev);
733 pm_runtime_set_suspended(&client->dev);
734 pm_runtime_put_noidle(&client->dev);
735
efa86e9f
DB
736 rpr0521_poweroff(iio_priv(indio_dev));
737
738 return 0;
739}
740
741#ifdef CONFIG_PM
742static int rpr0521_runtime_suspend(struct device *dev)
743{
744 struct iio_dev *indio_dev = i2c_get_clientdata(to_i2c_client(dev));
745 struct rpr0521_data *data = iio_priv(indio_dev);
746 int ret;
747
efa86e9f 748 mutex_lock(&data->lock);
484c314b
MK
749 /* If measurements are enabled, enable them on resume */
750 if (!data->als_need_dis)
751 data->als_ps_need_en = data->als_dev_en;
752 if (!data->pxs_need_dis)
753 data->pxs_ps_need_en = data->pxs_dev_en;
754
755 /* disable channels and sets {als,pxs}_dev_en to false */
efa86e9f 756 ret = rpr0521_poweroff(data);
484c314b 757 regcache_mark_dirty(data->regmap);
efa86e9f
DB
758 mutex_unlock(&data->lock);
759
760 return ret;
761}
762
763static int rpr0521_runtime_resume(struct device *dev)
764{
765 struct iio_dev *indio_dev = i2c_get_clientdata(to_i2c_client(dev));
766 struct rpr0521_data *data = iio_priv(indio_dev);
767 int ret;
768
484c314b 769 regcache_sync(data->regmap);
efa86e9f
DB
770 if (data->als_ps_need_en) {
771 ret = rpr0521_als_enable(data, RPR0521_MODE_ALS_ENABLE);
772 if (ret < 0)
773 return ret;
774 data->als_ps_need_en = false;
775 }
776
777 if (data->pxs_ps_need_en) {
778 ret = rpr0521_pxs_enable(data, RPR0521_MODE_PXS_ENABLE);
779 if (ret < 0)
780 return ret;
781 data->pxs_ps_need_en = false;
782 }
484c314b 783 msleep(100); //wait for first measurement result
efa86e9f
DB
784
785 return 0;
786}
787#endif
788
789static const struct dev_pm_ops rpr0521_pm_ops = {
790 SET_RUNTIME_PM_OPS(rpr0521_runtime_suspend,
791 rpr0521_runtime_resume, NULL)
792};
793
794static const struct acpi_device_id rpr0521_acpi_match[] = {
795 {"RPR0521", 0},
796 { }
797};
798MODULE_DEVICE_TABLE(acpi, rpr0521_acpi_match);
799
800static const struct i2c_device_id rpr0521_id[] = {
801 {"rpr0521", 0},
802 { }
803};
804
805MODULE_DEVICE_TABLE(i2c, rpr0521_id);
806
807static struct i2c_driver rpr0521_driver = {
808 .driver = {
809 .name = RPR0521_DRV_NAME,
810 .pm = &rpr0521_pm_ops,
811 .acpi_match_table = ACPI_PTR(rpr0521_acpi_match),
812 },
813 .probe = rpr0521_probe,
814 .remove = rpr0521_remove,
815 .id_table = rpr0521_id,
816};
817
818module_i2c_driver(rpr0521_driver);
819
820MODULE_AUTHOR("Daniel Baluta <daniel.baluta@intel.com>");
821MODULE_DESCRIPTION("RPR0521 ROHM Ambient Light and Proximity Sensor driver");
822MODULE_LICENSE("GPL v2");