1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3 * APDS9160 sensor driver.
4 * Chip is combined proximity and ambient light sensor.
5 * Author: 2024 Mikael Gonella-Bolduc <m.gonella.bolduc@gmail.com>
6 */
7
8 #include <linux/bits.h>
9 #include <linux/bitfield.h>
10 #include <linux/cleanup.h>
11 #include <linux/delay.h>
12 #include <linux/err.h>
13 #include <linux/i2c.h>
14 #include <linux/interrupt.h>
15 #include <linux/module.h>
16 #include <linux/mutex.h>
17 #include <linux/regmap.h>
18 #include <linux/regulator/consumer.h>
19 #include <linux/types.h>
20 #include <linux/units.h>
21
22 #include <linux/iio/iio.h>
23 #include <linux/iio/events.h>
24 #include <linux/iio/sysfs.h>
25
26 #include <linux/unaligned.h>
27
28 #define APDS9160_REGMAP_NAME "apds9160_regmap"
29
30 /* Main control register */
31 #define APDS9160_REG_CTRL 0x00
32 #define APDS9160_CTRL_SWRESET BIT(4) /* 1: Activate reset */
33 #define APDS9160_CTRL_MODE_RGB BIT(2) /* 0: ALS & IR, 1: RGB & IR */
34 #define APDS9160_CTRL_EN_ALS BIT(1) /* 1: ALS active */
35 #define APDS9160_CTLR_EN_PS BIT(0) /* 1: PS active */
36
37 /* Status register */
38 #define APDS9160_SR_LS_INT BIT(4)
39 #define APDS9160_SR_LS_NEW_DATA BIT(3)
40 #define APDS9160_SR_PS_INT BIT(1)
41 #define APDS9160_SR_PS_NEW_DATA BIT(0)
42
43 /* Interrupt configuration registers */
44 #define APDS9160_REG_INT_CFG 0x19
45 #define APDS9160_REG_INT_PST 0x1A
46 #define APDS9160_INT_CFG_EN_LS BIT(2) /* LS int enable */
47 #define APDS9160_INT_CFG_EN_PS BIT(0) /* PS int enable */
48
49 /* Proximity registers */
50 #define APDS9160_REG_PS_LED 0x01
51 #define APDS9160_REG_PS_PULSES 0x02
52 #define APDS9160_REG_PS_MEAS_RATE 0x03
53 #define APDS9160_REG_PS_THRES_HI_LSB 0x1B
54 #define APDS9160_REG_PS_THRES_HI_MSB 0x1C
55 #define APDS9160_REG_PS_THRES_LO_LSB 0x1D
56 #define APDS9160_REG_PS_THRES_LO_MSB 0x1E
57 #define APDS9160_REG_PS_DATA_LSB 0x08
58 #define APDS9160_REG_PS_DATA_MSB 0x09
59 #define APDS9160_REG_PS_CAN_LEVEL_DIG_LSB 0x1F
60 #define APDS9160_REG_PS_CAN_LEVEL_DIG_MSB 0x20
61 #define APDS9160_REG_PS_CAN_LEVEL_ANA_DUR 0x21
62 #define APDS9160_REG_PS_CAN_LEVEL_ANA_CURRENT 0x22
63
64 /* Light sensor registers */
65 #define APDS9160_REG_LS_MEAS_RATE 0x04
66 #define APDS9160_REG_LS_GAIN 0x05
67 #define APDS9160_REG_LS_DATA_CLEAR_LSB 0x0A
68 #define APDS9160_REG_LS_DATA_CLEAR 0x0B
69 #define APDS9160_REG_LS_DATA_CLEAR_MSB 0x0C
70 #define APDS9160_REG_LS_DATA_ALS_LSB 0x0D
71 #define APDS9160_REG_LS_DATA_ALS 0x0E
72 #define APDS9160_REG_LS_DATA_ALS_MSB 0x0F
73 #define APDS9160_REG_LS_THRES_UP_LSB 0x24
74 #define APDS9160_REG_LS_THRES_UP 0x25
75 #define APDS9160_REG_LS_THRES_UP_MSB 0x26
76 #define APDS9160_REG_LS_THRES_LO_LSB 0x27
77 #define APDS9160_REG_LS_THRES_LO 0x28
78 #define APDS9160_REG_LS_THRES_LO_MSB 0x29
79 #define APDS9160_REG_LS_THRES_VAR 0x2A
80
81 /* Part identification number register */
82 #define APDS9160_REG_ID 0x06
83
84 /* Status register */
85 #define APDS9160_REG_SR 0x07
86 #define APDS9160_SR_DATA_ALS BIT(3)
87 #define APDS9160_SR_DATA_PS BIT(0)
88
89 /* Supported ID:s */
90 #define APDS9160_PART_ID_0 0x03
91
92 #define APDS9160_PS_THRES_MAX 0x7FF
93 #define APDS9160_LS_THRES_MAX 0xFFFFF
94 #define APDS9160_CMD_LS_RESOLUTION_25MS 0x04
95 #define APDS9160_CMD_LS_RESOLUTION_50MS 0x03
96 #define APDS9160_CMD_LS_RESOLUTION_100MS 0x02
97 #define APDS9160_CMD_LS_RESOLUTION_200MS 0x01
98 #define APDS9160_PS_DATA_MASK 0x7FF
99
100 #define APDS9160_DEFAULT_LS_GAIN 3
101 #define APDS9160_DEFAULT_LS_RATE 100
102 #define APDS9160_DEFAULT_PS_RATE 100
103 #define APDS9160_DEFAULT_PS_CANCELLATION_LEVEL 0
104 #define APDS9160_DEFAULT_PS_ANALOG_CANCELLATION 0
105 #define APDS9160_DEFAULT_PS_GAIN 1
106 #define APDS9160_DEFAULT_PS_CURRENT 100
107 #define APDS9160_DEFAULT_PS_RESOLUTION_11BITS 0x03
108
109 static const struct reg_default apds9160_reg_defaults[] = {
110 { APDS9160_REG_CTRL, 0x00 }, /* Sensors disabled by default */
111 { APDS9160_REG_PS_LED, 0x33 }, /* 60 kHz frequency, 100 mA */
112 { APDS9160_REG_PS_PULSES, 0x08 }, /* 8 pulses */
113 { APDS9160_REG_PS_MEAS_RATE, 0x05 }, /* 100ms */
114 { APDS9160_REG_LS_MEAS_RATE, 0x22 }, /* 100ms */
115 { APDS9160_REG_LS_GAIN, 0x01 }, /* 3x */
116 { APDS9160_REG_INT_CFG, 0x10 }, /* Interrupts disabled */
117 { APDS9160_REG_INT_PST, 0x00 },
118 { APDS9160_REG_PS_THRES_HI_LSB, 0xFF },
119 { APDS9160_REG_PS_THRES_HI_MSB, 0x07 },
120 { APDS9160_REG_PS_THRES_LO_LSB, 0x00 },
121 { APDS9160_REG_PS_THRES_LO_MSB, 0x00 },
122 { APDS9160_REG_PS_CAN_LEVEL_DIG_LSB, 0x00 },
123 { APDS9160_REG_PS_CAN_LEVEL_DIG_MSB, 0x00 },
124 { APDS9160_REG_PS_CAN_LEVEL_ANA_DUR, 0x00 },
125 { APDS9160_REG_PS_CAN_LEVEL_ANA_CURRENT, 0x00 },
126 { APDS9160_REG_LS_THRES_UP_LSB, 0xFF },
127 { APDS9160_REG_LS_THRES_UP, 0xFF },
128 { APDS9160_REG_LS_THRES_UP_MSB, 0x0F },
129 { APDS9160_REG_LS_THRES_LO_LSB, 0x00 },
130 { APDS9160_REG_LS_THRES_LO, 0x00 },
131 { APDS9160_REG_LS_THRES_LO_MSB, 0x00 },
132 { APDS9160_REG_LS_THRES_VAR, 0x00 },
133 };
134
135 static const struct regmap_range apds9160_readable_ranges[] = {
136 regmap_reg_range(APDS9160_REG_CTRL, APDS9160_REG_LS_THRES_VAR),
137 };
138
139 static const struct regmap_access_table apds9160_readable_table = {
140 .yes_ranges = apds9160_readable_ranges,
141 .n_yes_ranges = ARRAY_SIZE(apds9160_readable_ranges),
142 };
143
144 static const struct regmap_range apds9160_writeable_ranges[] = {
145 regmap_reg_range(APDS9160_REG_CTRL, APDS9160_REG_LS_GAIN),
146 regmap_reg_range(APDS9160_REG_INT_CFG, APDS9160_REG_LS_THRES_VAR),
147 };
148
149 static const struct regmap_access_table apds9160_writeable_table = {
150 .yes_ranges = apds9160_writeable_ranges,
151 .n_yes_ranges = ARRAY_SIZE(apds9160_writeable_ranges),
152 };
153
154 static const struct regmap_range apds9160_volatile_ranges[] = {
155 regmap_reg_range(APDS9160_REG_SR, APDS9160_REG_LS_DATA_ALS_MSB),
156 };
157
158 static const struct regmap_access_table apds9160_volatile_table = {
159 .yes_ranges = apds9160_volatile_ranges,
160 .n_yes_ranges = ARRAY_SIZE(apds9160_volatile_ranges),
161 };
162
163 static const struct regmap_config apds9160_regmap_config = {
164 .name = APDS9160_REGMAP_NAME,
165 .reg_bits = 8,
166 .val_bits = 8,
167 .use_single_read = true,
168 .use_single_write = true,
169
170 .rd_table = &apds9160_readable_table,
171 .wr_table = &apds9160_writeable_table,
172 .volatile_table = &apds9160_volatile_table,
173
174 .reg_defaults = apds9160_reg_defaults,
175 .num_reg_defaults = ARRAY_SIZE(apds9160_reg_defaults),
176 .max_register = 37,
177 .cache_type = REGCACHE_RBTREE,
178 };
179
180 static const struct iio_event_spec apds9160_event_spec[] = {
181 {
182 .type = IIO_EV_TYPE_THRESH,
183 .dir = IIO_EV_DIR_RISING,
184 .mask_separate = BIT(IIO_EV_INFO_VALUE),
185 },
186 {
187 .type = IIO_EV_TYPE_THRESH,
188 .dir = IIO_EV_DIR_FALLING,
189 .mask_separate = BIT(IIO_EV_INFO_VALUE),
190 },
191 {
192 .type = IIO_EV_TYPE_THRESH,
193 .dir = IIO_EV_DIR_EITHER,
194 .mask_separate = BIT(IIO_EV_INFO_ENABLE),
195 },
196 };
197
198 static const struct iio_chan_spec apds9160_channels[] = {
199 {
200 /* Proximity sensor channel */
201 .type = IIO_PROXIMITY,
202 .address = APDS9160_REG_PS_DATA_LSB,
203 .info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
204 .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_INT_TIME) |
205 BIT(IIO_CHAN_INFO_SCALE) |
206 BIT(IIO_CHAN_INFO_CALIBBIAS),
207 .info_mask_separate_available = BIT(IIO_CHAN_INFO_INT_TIME) |
208 BIT(IIO_CHAN_INFO_SCALE),
209 .event_spec = apds9160_event_spec,
210 .num_event_specs = ARRAY_SIZE(apds9160_event_spec),
211 },
212 {
213 /* Proximity sensor led current */
214 .type = IIO_CURRENT,
215 .output = 1,
216 .info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
217 .info_mask_separate_available = BIT(IIO_CHAN_INFO_RAW),
218 },
219 {
220 /* Illuminance */
221 .type = IIO_LIGHT,
222 .address = APDS9160_REG_LS_DATA_ALS_LSB,
223 .info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
224 .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_INT_TIME) |
225 BIT(IIO_CHAN_INFO_HARDWAREGAIN) |
226 BIT(IIO_CHAN_INFO_SCALE),
227 .info_mask_separate_available = BIT(IIO_CHAN_INFO_INT_TIME) |
228 BIT(IIO_CHAN_INFO_SCALE),
229 .event_spec = apds9160_event_spec,
230 .num_event_specs = ARRAY_SIZE(apds9160_event_spec),
231 },
232 {
233 /* Clear channel */
234 .type = IIO_INTENSITY,
235 .address = APDS9160_REG_LS_DATA_CLEAR_LSB,
236 .info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
237 .channel2 = IIO_MOD_LIGHT_CLEAR,
238 .modified = 1,
239 },
240 };
241
242 static const struct iio_chan_spec apds9160_channels_without_events[] = {
243 {
244 /* Proximity sensor channel */
245 .type = IIO_PROXIMITY,
246 .address = APDS9160_REG_PS_DATA_LSB,
247 .info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
248 .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_INT_TIME) |
249 BIT(IIO_CHAN_INFO_SCALE) |
250 BIT(IIO_CHAN_INFO_CALIBBIAS),
251 .info_mask_separate_available = BIT(IIO_CHAN_INFO_INT_TIME) |
252 BIT(IIO_CHAN_INFO_SCALE),
253 },
254 {
255 /* Proximity sensor led current */
256 .type = IIO_CURRENT,
257 .output = 1,
258 .info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
259 .info_mask_separate_available = BIT(IIO_CHAN_INFO_RAW),
260 },
261 {
262 /* Illuminance */
263 .type = IIO_LIGHT,
264 .address = APDS9160_REG_LS_DATA_ALS_LSB,
265 .info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
266 .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_INT_TIME) |
267 BIT(IIO_CHAN_INFO_HARDWAREGAIN) |
268 BIT(IIO_CHAN_INFO_SCALE),
269 .info_mask_separate_available = BIT(IIO_CHAN_INFO_INT_TIME) |
270 BIT(IIO_CHAN_INFO_SCALE),
271 },
272 {
273 /* Clear channel */
274 .type = IIO_INTENSITY,
275 .address = APDS9160_REG_LS_DATA_CLEAR_LSB,
276 .info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
277 .channel2 = IIO_MOD_LIGHT_CLEAR,
278 .modified = 1,
279 },
280 };
281
282 static const int apds9160_als_rate_avail[] = {
283 25, 50, 100, 200
284 };
285
286 static const int apds9160_als_rate_map[][2] = {
287 { 25, 0x00 },
288 { 50, 0x01 },
289 { 100, 0x02 },
290 { 200, 0x03 },
291 };
292
293 static const int apds9160_als_gain_map[][2] = {
294 { 1, 0x00 },
295 { 3, 0x01 },
296 { 6, 0x02 },
297 { 18, 0x03 },
298 { 54, 0x04 },
299 };
300
301 static const int apds9160_ps_gain_avail[] = {
302 1, 2, 4, 8
303 };
304
305 static const int apds9160_ps_gain_map[][2] = {
306 { 1, 0x00 },
307 { 2, 0x01 },
308 { 4, 0x02 },
309 { 8, 0x03 },
310 };
311
312 static const int apds9160_ps_rate_avail[] = {
313 25, 50, 100, 200, 400
314 };
315
316 static const int apds9160_ps_rate_map[][2] = {
317 { 25, 0x03 },
318 { 50, 0x04 },
319 { 100, 0x05 },
320 { 200, 0x06 },
321 { 400, 0x07 },
322 };
323
324 static const int apds9160_ps_led_current_avail[] = {
325 10, 25, 50, 100, 150, 175, 200
326 };
327
328 static const int apds9160_ps_led_current_map[][2] = {
329 { 10, 0x00 },
330 { 25, 0x01 },
331 { 50, 0x02 },
332 { 100, 0x03 },
333 { 150, 0x04 },
334 { 175, 0x05 },
335 { 200, 0x06 },
336 };
337
338 /**
339 * struct apds9160_scale - apds9160 scale mapping definition
340 *
341 * @itime: Integration time in ms
342 * @gain: Gain multiplier
343 * @scale1: lux/count resolution
344 * @scale2: micro lux/count
345 */
346 struct apds9160_scale {
347 int itime;
348 int gain;
349 int scale1;
350 int scale2;
351 };
352
353 /* Scale mapping extracted from datasheet */
354 static const struct apds9160_scale apds9160_als_scale_map[] = {
355 {
356 .itime = 25,
357 .gain = 1,
358 .scale1 = 3,
359 .scale2 = 272000,
360 },
361 {
362 .itime = 25,
363 .gain = 3,
364 .scale1 = 1,
365 .scale2 = 77000,
366 },
367 {
368 .itime = 25,
369 .gain = 6,
370 .scale1 = 0,
371 .scale2 = 525000,
372 },
373 {
374 .itime = 25,
375 .gain = 18,
376 .scale1 = 0,
377 .scale2 = 169000,
378 },
379 {
380 .itime = 25,
381 .gain = 54,
382 .scale1 = 0,
383 .scale2 = 49000,
384 },
385 {
386 .itime = 50,
387 .gain = 1,
388 .scale1 = 1,
389 .scale2 = 639000,
390 },
391 {
392 .itime = 50,
393 .gain = 3,
394 .scale1 = 0,
395 .scale2 = 538000,
396 },
397 {
398 .itime = 50,
399 .gain = 6,
400 .scale1 = 0,
401 .scale2 = 263000,
402 },
403 {
404 .itime = 50,
405 .gain = 18,
406 .scale1 = 0,
407 .scale2 = 84000,
408 },
409 {
410 .itime = 50,
411 .gain = 54,
412 .scale1 = 0,
413 .scale2 = 25000,
414 },
415 {
416 .itime = 100,
417 .gain = 1,
418 .scale1 = 0,
419 .scale2 = 819000,
420 },
421 {
422 .itime = 100,
423 .gain = 3,
424 .scale1 = 0,
425 .scale2 = 269000,
426 },
427 {
428 .itime = 100,
429 .gain = 6,
430 .scale1 = 0,
431 .scale2 = 131000,
432 },
433 {
434 .itime = 100,
435 .gain = 18,
436 .scale1 = 0,
437 .scale2 = 42000,
438 },
439 {
440 .itime = 100,
441 .gain = 54,
442 .scale1 = 0,
443 .scale2 = 12000,
444 },
445 {
446 .itime = 200,
447 .gain = 1,
448 .scale1 = 0,
449 .scale2 = 409000,
450 },
451 {
452 .itime = 200,
453 .gain = 3,
454 .scale1 = 0,
455 .scale2 = 135000,
456 },
457 {
458 .itime = 200,
459 .gain = 6,
460 .scale1 = 0,
461 .scale2 = 66000,
462 },
463 {
464 .itime = 200,
465 .gain = 18,
466 .scale1 = 0,
467 .scale2 = 21000,
468 },
469 {
470 .itime = 200,
471 .gain = 54,
472 .scale1 = 0,
473 .scale2 = 6000,
474 },
475 };
476
477 static const int apds9160_25ms_avail[][2] = {
478 { 3, 272000 },
479 { 1, 77000 },
480 { 0, 525000 },
481 { 0, 169000 },
482 { 0, 49000 },
483 };
484
485 static const int apds9160_50ms_avail[][2] = {
486 { 1, 639000 },
487 { 0, 538000 },
488 { 0, 263000 },
489 { 0, 84000 },
490 { 0, 25000 },
491 };
492
493 static const int apds9160_100ms_avail[][2] = {
494 { 0, 819000 },
495 { 0, 269000 },
496 { 0, 131000 },
497 { 0, 42000 },
498 { 0, 12000 },
499 };
500
501 static const int apds9160_200ms_avail[][2] = {
502 { 0, 409000 },
503 { 0, 135000 },
504 { 0, 66000 },
505 { 0, 21000 },
506 { 0, 6000 },
507 };
508
509 static const struct reg_field apds9160_reg_field_ls_en =
510 REG_FIELD(APDS9160_REG_CTRL, 1, 1);
511
512 static const struct reg_field apds9160_reg_field_ps_en =
513 REG_FIELD(APDS9160_REG_CTRL, 0, 0);
514
515 static const struct reg_field apds9160_reg_field_int_ps =
516 REG_FIELD(APDS9160_REG_INT_CFG, 0, 0);
517
518 static const struct reg_field apds9160_reg_field_int_als =
519 REG_FIELD(APDS9160_REG_INT_CFG, 2, 2);
520
521 static const struct reg_field apds9160_reg_field_ps_overflow =
522 REG_FIELD(APDS9160_REG_PS_DATA_MSB, 3, 3);
523
524 static const struct reg_field apds9160_reg_field_als_rate =
525 REG_FIELD(APDS9160_REG_LS_MEAS_RATE, 0, 2);
526
527 static const struct reg_field apds9160_reg_field_als_gain =
528 REG_FIELD(APDS9160_REG_LS_GAIN, 0, 2);
529
530 static const struct reg_field apds9160_reg_field_ps_rate =
531 REG_FIELD(APDS9160_REG_PS_MEAS_RATE, 0, 2);
532
533 static const struct reg_field apds9160_reg_field_als_res =
534 REG_FIELD(APDS9160_REG_LS_MEAS_RATE, 4, 6);
535
536 static const struct reg_field apds9160_reg_field_ps_current =
537 REG_FIELD(APDS9160_REG_PS_LED, 0, 2);
538
539 static const struct reg_field apds9160_reg_field_ps_gain =
540 REG_FIELD(APDS9160_REG_PS_MEAS_RATE, 6, 7);
541
542 static const struct reg_field apds9160_reg_field_ps_resolution =
543 REG_FIELD(APDS9160_REG_PS_MEAS_RATE, 3, 4);
544
545 struct apds9160_chip {
546 struct i2c_client *client;
547 struct regmap *regmap;
548
549 struct regmap_field *reg_enable_ps;
550 struct regmap_field *reg_enable_als;
551 struct regmap_field *reg_int_ps;
552 struct regmap_field *reg_int_als;
553 struct regmap_field *reg_ps_overflow;
554 struct regmap_field *reg_als_rate;
555 struct regmap_field *reg_als_resolution;
556 struct regmap_field *reg_ps_rate;
557 struct regmap_field *reg_als_gain;
558 struct regmap_field *reg_ps_current;
559 struct regmap_field *reg_ps_gain;
560 struct regmap_field *reg_ps_resolution;
561
562 struct mutex lock; /* protects state and config data */
563
564 /* State data */
565 int als_int;
566 int ps_int;
567
568 /* Configuration values */
569 int als_itime;
570 int als_hwgain;
571 int als_scale1;
572 int als_scale2;
573 int ps_rate;
574 int ps_cancellation_level;
575 int ps_current;
576 int ps_gain;
577 };
578
apds9160_set_ps_rate(struct apds9160_chip * data,int val)579 static int apds9160_set_ps_rate(struct apds9160_chip *data, int val)
580 {
581 int idx;
582
583 for (idx = 0; idx < ARRAY_SIZE(apds9160_ps_rate_map); idx++) {
584 int ret;
585
586 if (apds9160_ps_rate_map[idx][0] != val)
587 continue;
588
589 ret = regmap_field_write(data->reg_ps_rate,
590 apds9160_ps_rate_map[idx][1]);
591 if (ret)
592 return ret;
593 data->ps_rate = val;
594
595 return ret;
596 }
597
598 return -EINVAL;
599 }
600
apds9160_set_ps_gain(struct apds9160_chip * data,int val)601 static int apds9160_set_ps_gain(struct apds9160_chip *data, int val)
602 {
603 int idx;
604
605 for (idx = 0; idx < ARRAY_SIZE(apds9160_ps_gain_map); idx++) {
606 int ret;
607
608 if (apds9160_ps_gain_map[idx][0] != val)
609 continue;
610
611 ret = regmap_field_write(data->reg_ps_gain,
612 apds9160_ps_gain_map[idx][1]);
613 if (ret)
614 return ret;
615 data->ps_gain = val;
616
617 return ret;
618 }
619
620 return -EINVAL;
621 }
622
623 /*
624 * The PS intelligent cancellation level register allows
625 * for an on-chip substraction of the ADC count caused by
626 * unwanted reflected light from PS ADC output.
627 */
apds9160_set_ps_cancellation_level(struct apds9160_chip * data,int val)628 static int apds9160_set_ps_cancellation_level(struct apds9160_chip *data,
629 int val)
630 {
631 int ret;
632 __le16 buf;
633
634 if (val < 0 || val > 0xFFFF)
635 return -EINVAL;
636
637 buf = cpu_to_le16(val);
638 ret = regmap_bulk_write(data->regmap, APDS9160_REG_PS_CAN_LEVEL_DIG_LSB,
639 &buf, 2);
640 if (ret)
641 return ret;
642
643 data->ps_cancellation_level = val;
644
645 return ret;
646 }
647
648 /*
649 * This parameter determines the cancellation pulse duration
650 * in each of the PWM pulse. The cancellation is applied during the
651 * integration phase of the PS measurement.
652 * Duration is programmed in half clock cycles
653 * A duration value of 0 or 1 will not generate any cancellation pulse
654 */
apds9160_set_ps_analog_cancellation(struct apds9160_chip * data,int val)655 static int apds9160_set_ps_analog_cancellation(struct apds9160_chip *data,
656 int val)
657 {
658 if (val < 0 || val > 63)
659 return -EINVAL;
660
661 return regmap_write(data->regmap, APDS9160_REG_PS_CAN_LEVEL_ANA_DUR,
662 val);
663 }
664
665 /*
666 * This parameter works in conjunction with the cancellation pulse duration
667 * The value determines the current used for crosstalk cancellation
668 * Coarse value is in steps of 60 nA
669 * Fine value is in steps of 2.4 nA
670 */
apds9160_set_ps_cancellation_current(struct apds9160_chip * data,int coarse_val,int fine_val)671 static int apds9160_set_ps_cancellation_current(struct apds9160_chip *data,
672 int coarse_val,
673 int fine_val)
674 {
675 int val;
676
677 if (coarse_val < 0 || coarse_val > 4)
678 return -EINVAL;
679
680 if (fine_val < 0 || fine_val > 15)
681 return -EINVAL;
682
683 /* Coarse value at B4:B5 and fine value at B0:B3 */
684 val = (coarse_val << 4) | fine_val;
685
686 return regmap_write(data->regmap, APDS9160_REG_PS_CAN_LEVEL_ANA_CURRENT,
687 val);
688 }
689
apds9160_ps_init_analog_cancellation(struct device * dev,struct apds9160_chip * data)690 static int apds9160_ps_init_analog_cancellation(struct device *dev,
691 struct apds9160_chip *data)
692 {
693 int ret, duration, picoamp, idx, coarse, fine;
694
695 ret = device_property_read_u32(dev,
696 "ps-cancellation-duration", &duration);
697 if (ret || duration == 0) {
698 /* Don't fail since this is not required */
699 return 0;
700 }
701
702 ret = device_property_read_u32(dev,
703 "ps-cancellation-current-picoamp", &picoamp);
704 if (ret)
705 return ret;
706
707 if (picoamp < 60000 || picoamp > 276000 || picoamp % 2400 != 0)
708 return dev_err_probe(dev, -EINVAL,
709 "Invalid cancellation current\n");
710
711 /* Compute required coarse and fine value from requested current */
712 fine = 0;
713 coarse = 0;
714 for (idx = 60000; idx < picoamp; idx += 2400) {
715 if (fine == 15) {
716 fine = 0;
717 coarse++;
718 idx += 21600;
719 } else {
720 fine++;
721 }
722 }
723
724 if (picoamp != idx)
725 dev_warn(dev,
726 "Invalid cancellation current %i, rounding to %i\n",
727 picoamp, idx);
728
729 ret = apds9160_set_ps_analog_cancellation(data, duration);
730 if (ret)
731 return ret;
732
733 return apds9160_set_ps_cancellation_current(data, coarse, fine);
734 }
735
apds9160_set_ps_current(struct apds9160_chip * data,int val)736 static int apds9160_set_ps_current(struct apds9160_chip *data, int val)
737 {
738 int idx;
739
740 for (idx = 0; idx < ARRAY_SIZE(apds9160_ps_led_current_map); idx++) {
741 int ret;
742
743 if (apds9160_ps_led_current_map[idx][0] != val)
744 continue;
745
746 ret = regmap_field_write(
747 data->reg_ps_current,
748 apds9160_ps_led_current_map[idx][1]);
749 if (ret)
750 return ret;
751 data->ps_current = val;
752
753 return ret;
754 }
755
756 return -EINVAL;
757 }
758
apds9160_set_als_gain(struct apds9160_chip * data,int gain)759 static int apds9160_set_als_gain(struct apds9160_chip *data, int gain)
760 {
761 int idx;
762
763 for (idx = 0; idx < ARRAY_SIZE(apds9160_als_gain_map); idx++) {
764 int ret;
765
766 if (gain != apds9160_als_gain_map[idx][0])
767 continue;
768
769 ret = regmap_field_write(data->reg_als_gain,
770 apds9160_als_gain_map[idx][1]);
771 if (ret)
772 return ret;
773 data->als_hwgain = gain;
774
775 return ret;
776 }
777
778 return -EINVAL;
779 }
780
apds9160_set_als_scale(struct apds9160_chip * data,int val,int val2)781 static int apds9160_set_als_scale(struct apds9160_chip *data, int val, int val2)
782 {
783 int idx;
784
785 for (idx = 0; idx < ARRAY_SIZE(apds9160_als_scale_map); idx++) {
786 if (apds9160_als_scale_map[idx].itime == data->als_itime &&
787 apds9160_als_scale_map[idx].scale1 == val &&
788 apds9160_als_scale_map[idx].scale2 == val2) {
789 int ret = apds9160_set_als_gain(data,
790 apds9160_als_scale_map[idx].gain);
791 if (ret)
792 return ret;
793 data->als_scale1 = val;
794 data->als_scale2 = val2;
795
796 return ret;
797 }
798 }
799
800 return -EINVAL;
801 }
802
apds9160_set_als_resolution(struct apds9160_chip * data,int val)803 static int apds9160_set_als_resolution(struct apds9160_chip *data, int val)
804 {
805 switch (val) {
806 case 25:
807 return regmap_field_write(data->reg_als_resolution,
808 APDS9160_CMD_LS_RESOLUTION_25MS);
809 case 50:
810 return regmap_field_write(data->reg_als_resolution,
811 APDS9160_CMD_LS_RESOLUTION_50MS);
812 case 200:
813 return regmap_field_write(data->reg_als_resolution,
814 APDS9160_CMD_LS_RESOLUTION_200MS);
815 default:
816 return regmap_field_write(data->reg_als_resolution,
817 APDS9160_CMD_LS_RESOLUTION_100MS);
818 }
819 }
820
apds9160_set_als_rate(struct apds9160_chip * data,int val)821 static int apds9160_set_als_rate(struct apds9160_chip *data, int val)
822 {
823 int idx;
824
825 for (idx = 0; idx < ARRAY_SIZE(apds9160_als_rate_map); idx++) {
826 if (apds9160_als_rate_map[idx][0] != val)
827 continue;
828
829 return regmap_field_write(data->reg_als_rate,
830 apds9160_als_rate_map[idx][1]);
831 }
832
833 return -EINVAL;
834 }
835
836 /*
837 * Setting the integration time ajusts resolution, rate, scale and gain
838 */
apds9160_set_als_int_time(struct apds9160_chip * data,int val)839 static int apds9160_set_als_int_time(struct apds9160_chip *data, int val)
840 {
841 int ret;
842 int idx;
843
844 ret = apds9160_set_als_rate(data, val);
845 if (ret)
846 return ret;
847
848 /* Match resolution register with rate */
849 ret = apds9160_set_als_resolution(data, val);
850 if (ret)
851 return ret;
852
853 data->als_itime = val;
854
855 /* Set the scale minimum gain */
856 for (idx = 0; idx < ARRAY_SIZE(apds9160_als_scale_map); idx++) {
857 if (data->als_itime != apds9160_als_scale_map[idx].itime)
858 continue;
859
860 return apds9160_set_als_scale(data,
861 apds9160_als_scale_map[idx].scale1,
862 apds9160_als_scale_map[idx].scale2);
863 }
864
865 return -EINVAL;
866 }
867
apds9160_read_avail(struct iio_dev * indio_dev,struct iio_chan_spec const * chan,const int ** vals,int * type,int * length,long mask)868 static int apds9160_read_avail(struct iio_dev *indio_dev,
869 struct iio_chan_spec const *chan,
870 const int **vals, int *type, int *length,
871 long mask)
872 {
873 struct apds9160_chip *data = iio_priv(indio_dev);
874
875 switch (mask) {
876 case IIO_CHAN_INFO_INT_TIME:
877 switch (chan->type) {
878 case IIO_LIGHT:
879 *length = ARRAY_SIZE(apds9160_als_rate_avail);
880 *vals = (const int *)apds9160_als_rate_avail;
881 *type = IIO_VAL_INT;
882
883 return IIO_AVAIL_LIST;
884 case IIO_PROXIMITY:
885 *length = ARRAY_SIZE(apds9160_ps_rate_avail);
886 *vals = (const int *)apds9160_ps_rate_avail;
887 *type = IIO_VAL_INT;
888
889 return IIO_AVAIL_LIST;
890 default:
891 return -EINVAL;
892 }
893 case IIO_CHAN_INFO_SCALE:
894 switch (chan->type) {
895 case IIO_PROXIMITY:
896 *length = ARRAY_SIZE(apds9160_ps_gain_avail);
897 *vals = (const int *)apds9160_ps_gain_avail;
898 *type = IIO_VAL_INT;
899
900 return IIO_AVAIL_LIST;
901 case IIO_LIGHT:
902 /* The available scales changes depending on itime */
903 switch (data->als_itime) {
904 case 25:
905 *length = ARRAY_SIZE(apds9160_25ms_avail) * 2;
906 *vals = (const int *)apds9160_25ms_avail;
907 *type = IIO_VAL_INT_PLUS_MICRO;
908
909 return IIO_AVAIL_LIST;
910 case 50:
911 *length = ARRAY_SIZE(apds9160_50ms_avail) * 2;
912 *vals = (const int *)apds9160_50ms_avail;
913 *type = IIO_VAL_INT_PLUS_MICRO;
914
915 return IIO_AVAIL_LIST;
916 case 100:
917 *length = ARRAY_SIZE(apds9160_100ms_avail) * 2;
918 *vals = (const int *)apds9160_100ms_avail;
919 *type = IIO_VAL_INT_PLUS_MICRO;
920
921 return IIO_AVAIL_LIST;
922 case 200:
923 *length = ARRAY_SIZE(apds9160_200ms_avail) * 2;
924 *vals = (const int *)apds9160_200ms_avail;
925 *type = IIO_VAL_INT_PLUS_MICRO;
926
927 return IIO_AVAIL_LIST;
928 default:
929 return -EINVAL;
930 }
931 default:
932 return -EINVAL;
933 }
934 case IIO_CHAN_INFO_RAW:
935 switch (chan->type) {
936 case IIO_CURRENT:
937 *length = ARRAY_SIZE(apds9160_ps_led_current_avail);
938 *vals = (const int *)apds9160_ps_led_current_avail;
939 *type = IIO_VAL_INT;
940
941 return IIO_AVAIL_LIST;
942 default:
943 return -EINVAL;
944 }
945
946 default:
947 return -EINVAL;
948 }
949 }
950
apds9160_write_raw_get_fmt(struct iio_dev * indio_dev,struct iio_chan_spec const * chan,long mask)951 static int apds9160_write_raw_get_fmt(struct iio_dev *indio_dev,
952 struct iio_chan_spec const *chan,
953 long mask)
954 {
955 switch (mask) {
956 case IIO_CHAN_INFO_INT_TIME:
957 return IIO_VAL_INT;
958 case IIO_CHAN_INFO_CALIBBIAS:
959 return IIO_VAL_INT;
960 case IIO_CHAN_INFO_HARDWAREGAIN:
961 return IIO_VAL_INT;
962 case IIO_CHAN_INFO_RAW:
963 return IIO_VAL_INT;
964 case IIO_CHAN_INFO_SCALE:
965 return IIO_VAL_INT_PLUS_MICRO;
966 default:
967 return -EINVAL;
968 }
969 }
970
apds9160_read_raw(struct iio_dev * indio_dev,struct iio_chan_spec const * chan,int * val,int * val2,long mask)971 static int apds9160_read_raw(struct iio_dev *indio_dev,
972 struct iio_chan_spec const *chan, int *val,
973 int *val2, long mask)
974 {
975 struct apds9160_chip *data = iio_priv(indio_dev);
976 int ret;
977
978 switch (mask) {
979 case IIO_CHAN_INFO_RAW:
980 switch (chan->type) {
981 case IIO_PROXIMITY: {
982 __le16 buf;
983
984 ret = regmap_bulk_read(data->regmap, chan->address,
985 &buf, 2);
986 if (ret)
987 return ret;
988 *val = le16_to_cpu(buf);
989 /* Remove overflow bits from result */
990 *val = FIELD_GET(APDS9160_PS_DATA_MASK, *val);
991
992 return IIO_VAL_INT;
993 }
994 case IIO_LIGHT:
995 case IIO_INTENSITY: {
996 u8 buf[3];
997
998 ret = regmap_bulk_read(data->regmap, chan->address,
999 &buf, 3);
1000 if (ret)
1001 return ret;
1002 *val = get_unaligned_le24(buf);
1003
1004 return IIO_VAL_INT;
1005 }
1006 case IIO_CURRENT:
1007 *val = data->ps_current;
1008
1009 return IIO_VAL_INT;
1010 default:
1011 return -EINVAL;
1012 }
1013 case IIO_CHAN_INFO_HARDWAREGAIN:
1014 switch (chan->type) {
1015 case IIO_LIGHT:
1016 *val = data->als_hwgain;
1017
1018 return IIO_VAL_INT;
1019 default:
1020 return -EINVAL;
1021 }
1022 case IIO_CHAN_INFO_INT_TIME:
1023 switch (chan->type) {
1024 case IIO_PROXIMITY:
1025 *val = data->ps_rate;
1026
1027 return IIO_VAL_INT;
1028 case IIO_LIGHT:
1029 *val = data->als_itime;
1030
1031 return IIO_VAL_INT;
1032 default:
1033 return -EINVAL;
1034 }
1035 case IIO_CHAN_INFO_CALIBBIAS:
1036 switch (chan->type) {
1037 case IIO_PROXIMITY:
1038 *val = data->ps_cancellation_level;
1039
1040 return IIO_VAL_INT;
1041 default:
1042 return -EINVAL;
1043 }
1044 case IIO_CHAN_INFO_SCALE:
1045 switch (chan->type) {
1046 case IIO_PROXIMITY:
1047 *val = data->ps_gain;
1048
1049 return IIO_VAL_INT;
1050 case IIO_LIGHT:
1051 *val = data->als_scale1;
1052 *val2 = data->als_scale2;
1053
1054 return IIO_VAL_INT_PLUS_MICRO;
1055 default:
1056 return -EINVAL;
1057 }
1058 default:
1059 return -EINVAL;
1060 }
1061 };
1062
apds9160_write_raw(struct iio_dev * indio_dev,struct iio_chan_spec const * chan,int val,int val2,long mask)1063 static int apds9160_write_raw(struct iio_dev *indio_dev,
1064 struct iio_chan_spec const *chan, int val,
1065 int val2, long mask)
1066 {
1067 struct apds9160_chip *data = iio_priv(indio_dev);
1068
1069 guard(mutex)(&data->lock);
1070
1071 switch (mask) {
1072 case IIO_CHAN_INFO_INT_TIME:
1073 if (val2 != 0)
1074 return -EINVAL;
1075 switch (chan->type) {
1076 case IIO_PROXIMITY:
1077 return apds9160_set_ps_rate(data, val);
1078 case IIO_LIGHT:
1079 return apds9160_set_als_int_time(data, val);
1080 default:
1081 return -EINVAL;
1082 }
1083 case IIO_CHAN_INFO_SCALE:
1084 switch (chan->type) {
1085 case IIO_PROXIMITY:
1086 return apds9160_set_ps_gain(data, val);
1087 case IIO_LIGHT:
1088 return apds9160_set_als_scale(data, val, val2);
1089 default:
1090 return -EINVAL;
1091 }
1092 case IIO_CHAN_INFO_CALIBBIAS:
1093 if (val2 != 0)
1094 return -EINVAL;
1095 switch (chan->type) {
1096 case IIO_PROXIMITY:
1097 return apds9160_set_ps_cancellation_level(data, val);
1098 default:
1099 return -EINVAL;
1100 }
1101 case IIO_CHAN_INFO_RAW:
1102 if (val2 != 0)
1103 return -EINVAL;
1104 switch (chan->type) {
1105 case IIO_CURRENT:
1106 return apds9160_set_ps_current(data, val);
1107 default:
1108 return -EINVAL;
1109 }
1110 default:
1111 return -EINVAL;
1112 }
1113 }
1114
apds9160_get_thres_reg(const struct iio_chan_spec * chan,enum iio_event_direction dir,u8 * reg)1115 static inline int apds9160_get_thres_reg(const struct iio_chan_spec *chan,
1116 enum iio_event_direction dir, u8 *reg)
1117 {
1118 switch (dir) {
1119 case IIO_EV_DIR_RISING:
1120 switch (chan->type) {
1121 case IIO_PROXIMITY:
1122 *reg = APDS9160_REG_PS_THRES_HI_LSB;
1123 break;
1124 case IIO_LIGHT:
1125 *reg = APDS9160_REG_LS_THRES_UP_LSB;
1126 break;
1127 default:
1128 return -EINVAL;
1129 } break;
1130 case IIO_EV_DIR_FALLING:
1131 switch (chan->type) {
1132 case IIO_PROXIMITY:
1133 *reg = APDS9160_REG_PS_THRES_LO_LSB;
1134 break;
1135 case IIO_LIGHT:
1136 *reg = APDS9160_REG_LS_THRES_LO_LSB;
1137 break;
1138 default:
1139 return -EINVAL;
1140 }
1141 break;
1142 default:
1143 return -EINVAL;
1144 }
1145
1146 return 0;
1147 }
1148
apds9160_read_event(struct iio_dev * indio_dev,const struct iio_chan_spec * chan,enum iio_event_type type,enum iio_event_direction dir,enum iio_event_info info,int * val,int * val2)1149 static int apds9160_read_event(struct iio_dev *indio_dev,
1150 const struct iio_chan_spec *chan,
1151 enum iio_event_type type,
1152 enum iio_event_direction dir,
1153 enum iio_event_info info, int *val, int *val2)
1154 {
1155 u8 reg;
1156 int ret;
1157 struct apds9160_chip *data = iio_priv(indio_dev);
1158
1159 if (info != IIO_EV_INFO_VALUE)
1160 return -EINVAL;
1161
1162 ret = apds9160_get_thres_reg(chan, dir, ®);
1163 if (ret < 0)
1164 return ret;
1165
1166 switch (chan->type) {
1167 case IIO_PROXIMITY: {
1168 __le16 buf;
1169
1170 ret = regmap_bulk_read(data->regmap, reg, &buf, 2);
1171 if (ret < 0)
1172 return ret;
1173 *val = le16_to_cpu(buf);
1174 return IIO_VAL_INT;
1175 }
1176 case IIO_LIGHT: {
1177 u8 buf[3];
1178
1179 ret = regmap_bulk_read(data->regmap, reg, &buf, 3);
1180 if (ret < 0)
1181 return ret;
1182 *val = get_unaligned_le24(buf);
1183 return IIO_VAL_INT;
1184 }
1185 default:
1186 return -EINVAL;
1187 }
1188 }
1189
apds9160_write_event(struct iio_dev * indio_dev,const struct iio_chan_spec * chan,enum iio_event_type type,enum iio_event_direction dir,enum iio_event_info info,int val,int val2)1190 static int apds9160_write_event(struct iio_dev *indio_dev,
1191 const struct iio_chan_spec *chan,
1192 enum iio_event_type type,
1193 enum iio_event_direction dir,
1194 enum iio_event_info info, int val, int val2)
1195 {
1196 u8 reg;
1197 int ret = 0;
1198 struct apds9160_chip *data = iio_priv(indio_dev);
1199
1200 if (info != IIO_EV_INFO_VALUE)
1201 return -EINVAL;
1202
1203 ret = apds9160_get_thres_reg(chan, dir, ®);
1204 if (ret < 0)
1205 return ret;
1206
1207 switch (chan->type) {
1208 case IIO_PROXIMITY: {
1209 __le16 buf;
1210
1211 if (val < 0 || val > APDS9160_PS_THRES_MAX)
1212 return -EINVAL;
1213
1214 buf = cpu_to_le16(val);
1215 return regmap_bulk_write(data->regmap, reg, &buf, 2);
1216 }
1217 case IIO_LIGHT: {
1218 u8 buf[3];
1219
1220 if (val < 0 || val > APDS9160_LS_THRES_MAX)
1221 return -EINVAL;
1222
1223 put_unaligned_le24(val, buf);
1224 return regmap_bulk_write(data->regmap, reg, &buf, 3);
1225 }
1226 default:
1227 return -EINVAL;
1228 }
1229 }
1230
apds9160_read_event_config(struct iio_dev * indio_dev,const struct iio_chan_spec * chan,enum iio_event_type type,enum iio_event_direction dir)1231 static int apds9160_read_event_config(struct iio_dev *indio_dev,
1232 const struct iio_chan_spec *chan,
1233 enum iio_event_type type,
1234 enum iio_event_direction dir)
1235 {
1236 struct apds9160_chip *data = iio_priv(indio_dev);
1237
1238 switch (chan->type) {
1239 case IIO_PROXIMITY:
1240 return data->ps_int;
1241 case IIO_LIGHT:
1242 return data->als_int;
1243 default:
1244 return -EINVAL;
1245 }
1246 }
1247
apds9160_write_event_config(struct iio_dev * indio_dev,const struct iio_chan_spec * chan,enum iio_event_type type,enum iio_event_direction dir,bool state)1248 static int apds9160_write_event_config(struct iio_dev *indio_dev,
1249 const struct iio_chan_spec *chan,
1250 enum iio_event_type type,
1251 enum iio_event_direction dir, bool state)
1252 {
1253 struct apds9160_chip *data = iio_priv(indio_dev);
1254 int ret;
1255
1256 switch (chan->type) {
1257 case IIO_PROXIMITY:
1258 ret = regmap_field_write(data->reg_int_ps, state);
1259 if (ret)
1260 return ret;
1261 data->ps_int = state;
1262
1263 return 0;
1264 case IIO_LIGHT:
1265 ret = regmap_field_write(data->reg_int_als, state);
1266 if (ret)
1267 return ret;
1268 data->als_int = state;
1269
1270 return 0;
1271 default:
1272 return -EINVAL;
1273 }
1274 }
1275
apds9160_irq_handler(int irq,void * private)1276 static irqreturn_t apds9160_irq_handler(int irq, void *private)
1277 {
1278 struct iio_dev *indio_dev = private;
1279 struct apds9160_chip *data = iio_priv(indio_dev);
1280 int ret, status;
1281
1282 /* Reading status register clears the interrupt flag */
1283 ret = regmap_read(data->regmap, APDS9160_REG_SR, &status);
1284 if (ret < 0) {
1285 dev_err_ratelimited(&data->client->dev,
1286 "irq status reg read failed\n");
1287 return IRQ_HANDLED;
1288 }
1289
1290 if ((status & APDS9160_SR_LS_INT) &&
1291 (status & APDS9160_SR_LS_NEW_DATA) && data->als_int) {
1292 iio_push_event(indio_dev,
1293 IIO_UNMOD_EVENT_CODE(IIO_LIGHT, 0,
1294 IIO_EV_TYPE_THRESH,
1295 IIO_EV_DIR_EITHER),
1296 iio_get_time_ns(indio_dev));
1297 }
1298
1299 if ((status & APDS9160_SR_PS_INT) &&
1300 (status & APDS9160_SR_PS_NEW_DATA) && data->ps_int) {
1301 iio_push_event(indio_dev,
1302 IIO_UNMOD_EVENT_CODE(IIO_PROXIMITY, 0,
1303 IIO_EV_TYPE_THRESH,
1304 IIO_EV_DIR_EITHER),
1305 iio_get_time_ns(indio_dev));
1306 }
1307
1308 return IRQ_HANDLED;
1309 }
1310
apds9160_detect(struct apds9160_chip * chip)1311 static int apds9160_detect(struct apds9160_chip *chip)
1312 {
1313 struct i2c_client *client = chip->client;
1314 int ret;
1315 u32 val;
1316
1317 ret = regmap_read(chip->regmap, APDS9160_REG_ID, &val);
1318 if (ret < 0) {
1319 dev_err(&client->dev, "ID read failed\n");
1320 return ret;
1321 }
1322
1323 if (val != APDS9160_PART_ID_0)
1324 dev_info(&client->dev, "Unknown part id %u\n", val);
1325
1326 return 0;
1327 }
1328
apds9160_disable(void * chip)1329 static void apds9160_disable(void *chip)
1330 {
1331 struct apds9160_chip *data = chip;
1332 int ret;
1333
1334 ret = regmap_field_write(data->reg_enable_als, 0);
1335 if (ret)
1336 return;
1337
1338 regmap_field_write(data->reg_enable_ps, 0);
1339 }
1340
apds9160_chip_init(struct apds9160_chip * chip)1341 static int apds9160_chip_init(struct apds9160_chip *chip)
1342 {
1343 int ret;
1344
1345 /* Write default values to interrupt register */
1346 ret = regmap_field_write(chip->reg_int_ps, 0);
1347 chip->ps_int = 0;
1348 if (ret)
1349 return ret;
1350
1351 ret = regmap_field_write(chip->reg_int_als, 0);
1352 chip->als_int = 0;
1353 if (ret)
1354 return ret;
1355
1356 /* Write default values to control register */
1357 ret = regmap_field_write(chip->reg_enable_als, 1);
1358 if (ret)
1359 return ret;
1360
1361 ret = regmap_field_write(chip->reg_enable_ps, 1);
1362 if (ret)
1363 return ret;
1364
1365 /* Write other default values */
1366 ret = regmap_field_write(chip->reg_ps_resolution,
1367 APDS9160_DEFAULT_PS_RESOLUTION_11BITS);
1368 if (ret)
1369 return ret;
1370
1371 /* Write default values to configuration registers */
1372 ret = apds9160_set_ps_current(chip, APDS9160_DEFAULT_PS_CURRENT);
1373 if (ret)
1374 return ret;
1375
1376 ret = apds9160_set_ps_rate(chip, APDS9160_DEFAULT_PS_RATE);
1377 if (ret)
1378 return ret;
1379
1380 ret = apds9160_set_als_int_time(chip, APDS9160_DEFAULT_LS_RATE);
1381 if (ret)
1382 return ret;
1383
1384 ret = apds9160_set_als_scale(chip,
1385 apds9160_100ms_avail[0][0],
1386 apds9160_100ms_avail[0][1]);
1387 if (ret)
1388 return ret;
1389
1390 ret = apds9160_set_ps_gain(chip, APDS9160_DEFAULT_PS_GAIN);
1391 if (ret)
1392 return ret;
1393
1394 ret = apds9160_set_ps_analog_cancellation(
1395 chip, APDS9160_DEFAULT_PS_ANALOG_CANCELLATION);
1396 if (ret)
1397 return ret;
1398
1399 ret = apds9160_set_ps_cancellation_level(
1400 chip, APDS9160_DEFAULT_PS_CANCELLATION_LEVEL);
1401 if (ret)
1402 return ret;
1403
1404 return devm_add_action_or_reset(&chip->client->dev, apds9160_disable,
1405 chip);
1406 }
1407
apds9160_regfield_init(struct apds9160_chip * data)1408 static int apds9160_regfield_init(struct apds9160_chip *data)
1409 {
1410 struct device *dev = &data->client->dev;
1411 struct regmap *regmap = data->regmap;
1412 struct regmap_field *tmp;
1413
1414 tmp = devm_regmap_field_alloc(dev, regmap, apds9160_reg_field_int_als);
1415 if (IS_ERR(tmp))
1416 return PTR_ERR(tmp);
1417 data->reg_int_als = tmp;
1418
1419 tmp = devm_regmap_field_alloc(dev, regmap, apds9160_reg_field_int_ps);
1420 if (IS_ERR(tmp))
1421 return PTR_ERR(tmp);
1422 data->reg_int_ps = tmp;
1423
1424 tmp = devm_regmap_field_alloc(dev, regmap, apds9160_reg_field_ls_en);
1425 if (IS_ERR(tmp))
1426 return PTR_ERR(tmp);
1427 data->reg_enable_als = tmp;
1428
1429 tmp = devm_regmap_field_alloc(dev, regmap, apds9160_reg_field_ps_en);
1430 if (IS_ERR(tmp))
1431 return PTR_ERR(tmp);
1432 data->reg_enable_ps = tmp;
1433
1434 tmp = devm_regmap_field_alloc(dev, regmap,
1435 apds9160_reg_field_ps_overflow);
1436 if (IS_ERR(tmp))
1437 return PTR_ERR(tmp);
1438 data->reg_ps_overflow = tmp;
1439
1440 tmp = devm_regmap_field_alloc(dev, regmap, apds9160_reg_field_als_rate);
1441 if (IS_ERR(tmp))
1442 return PTR_ERR(tmp);
1443 data->reg_als_rate = tmp;
1444
1445 tmp = devm_regmap_field_alloc(dev, regmap, apds9160_reg_field_als_res);
1446 if (IS_ERR(tmp))
1447 return PTR_ERR(tmp);
1448 data->reg_als_resolution = tmp;
1449
1450 tmp = devm_regmap_field_alloc(dev, regmap, apds9160_reg_field_ps_rate);
1451 if (IS_ERR(tmp))
1452 return PTR_ERR(tmp);
1453 data->reg_ps_rate = tmp;
1454
1455 tmp = devm_regmap_field_alloc(dev, regmap, apds9160_reg_field_als_gain);
1456 if (IS_ERR(tmp))
1457 return PTR_ERR(tmp);
1458 data->reg_als_gain = tmp;
1459
1460 tmp = devm_regmap_field_alloc(dev, regmap,
1461 apds9160_reg_field_ps_current);
1462 if (IS_ERR(tmp))
1463 return PTR_ERR(tmp);
1464 data->reg_ps_current = tmp;
1465
1466 tmp = devm_regmap_field_alloc(dev, regmap, apds9160_reg_field_ps_gain);
1467 if (IS_ERR(tmp))
1468 return PTR_ERR(tmp);
1469 data->reg_ps_gain = tmp;
1470
1471 tmp = devm_regmap_field_alloc(dev, regmap,
1472 apds9160_reg_field_ps_resolution);
1473 if (IS_ERR(tmp))
1474 return PTR_ERR(tmp);
1475 data->reg_ps_resolution = tmp;
1476
1477 return 0;
1478 }
1479
1480 static const struct iio_info apds9160_info = {
1481 .read_avail = apds9160_read_avail,
1482 .read_raw = apds9160_read_raw,
1483 .write_raw = apds9160_write_raw,
1484 .write_raw_get_fmt = apds9160_write_raw_get_fmt,
1485 .read_event_value = apds9160_read_event,
1486 .write_event_value = apds9160_write_event,
1487 .read_event_config = apds9160_read_event_config,
1488 .write_event_config = apds9160_write_event_config,
1489 };
1490
1491 static const struct iio_info apds9160_info_no_events = {
1492 .read_avail = apds9160_read_avail,
1493 .read_raw = apds9160_read_raw,
1494 .write_raw = apds9160_write_raw,
1495 .write_raw_get_fmt = apds9160_write_raw_get_fmt,
1496 };
1497
apds9160_probe(struct i2c_client * client)1498 static int apds9160_probe(struct i2c_client *client)
1499 {
1500 struct device *dev = &client->dev;
1501 struct apds9160_chip *chip;
1502 struct iio_dev *indio_dev;
1503 int ret;
1504
1505 indio_dev = devm_iio_device_alloc(dev, sizeof(*chip));
1506 if (!indio_dev)
1507 return -ENOMEM;
1508
1509 ret = devm_regulator_get_enable(dev, "vdd");
1510 if (ret)
1511 return dev_err_probe(dev, ret, "Failed to enable vdd supply\n");
1512
1513 indio_dev->name = "apds9160";
1514 indio_dev->modes = INDIO_DIRECT_MODE;
1515
1516 chip = iio_priv(indio_dev);
1517 chip->client = client;
1518 chip->regmap = devm_regmap_init_i2c(client, &apds9160_regmap_config);
1519 if (IS_ERR(chip->regmap))
1520 return dev_err_probe(dev, PTR_ERR(chip->regmap),
1521 "regmap initialization failed.\n");
1522
1523 chip->client = client;
1524 mutex_init(&chip->lock);
1525
1526 ret = apds9160_detect(chip);
1527 if (ret < 0)
1528 return dev_err_probe(dev, ret, "apds9160 not found\n");
1529
1530 ret = apds9160_regfield_init(chip);
1531 if (ret)
1532 return ret;
1533
1534 ret = apds9160_chip_init(chip);
1535 if (ret)
1536 return ret;
1537
1538 ret = apds9160_ps_init_analog_cancellation(dev, chip);
1539 if (ret)
1540 return ret;
1541
1542 if (client->irq > 0) {
1543 indio_dev->info = &apds9160_info;
1544 indio_dev->channels = apds9160_channels;
1545 indio_dev->num_channels = ARRAY_SIZE(apds9160_channels);
1546 ret = devm_request_threaded_irq(dev, client->irq, NULL,
1547 apds9160_irq_handler,
1548 IRQF_ONESHOT, "apds9160_event",
1549 indio_dev);
1550 if (ret) {
1551 return dev_err_probe(dev, ret,
1552 "request irq (%d) failed\n",
1553 client->irq);
1554 }
1555 } else {
1556 indio_dev->info = &apds9160_info_no_events;
1557 indio_dev->channels = apds9160_channels_without_events;
1558 indio_dev->num_channels =
1559 ARRAY_SIZE(apds9160_channels_without_events);
1560 }
1561
1562 ret = devm_iio_device_register(dev, indio_dev);
1563 if (ret)
1564 return dev_err_probe(dev, ret,
1565 "failed iio device registration\n");
1566
1567 return ret;
1568 }
1569
1570 static const struct of_device_id apds9160_of_match[] = {
1571 { .compatible = "brcm,apds9160" },
1572 { }
1573 };
1574 MODULE_DEVICE_TABLE(of, apds9160_of_match);
1575
1576 static const struct i2c_device_id apds9160_id[] = {
1577 { "apds9160", 0 },
1578 { }
1579 };
1580 MODULE_DEVICE_TABLE(i2c, apds9160_id);
1581
1582 static struct i2c_driver apds9160_driver = {
1583 .driver = {
1584 .name = "apds9160",
1585 .of_match_table = apds9160_of_match,
1586 },
1587 .probe = apds9160_probe,
1588 .id_table = apds9160_id,
1589 };
1590 module_i2c_driver(apds9160_driver);
1591
1592 MODULE_DESCRIPTION("APDS9160 combined ALS and proximity sensor");
1593 MODULE_AUTHOR("Mikael Gonella-Bolduc <m.gonella.bolduc@gmail.com>");
1594 MODULE_LICENSE("GPL");
1595