1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3 * apds9960.c - Support for Avago APDS9960 gesture/RGB/ALS/proximity sensor
4 *
5 * Copyright (C) 2015, 2018
6 * Author: Matt Ranostay <matt.ranostay@konsulko.com>
7 *
8 * TODO: gesture + proximity calib offsets
9 */
10
11 #include <linux/acpi.h>
12 #include <linux/module.h>
13 #include <linux/init.h>
14 #include <linux/interrupt.h>
15 #include <linux/delay.h>
16 #include <linux/mutex.h>
17 #include <linux/err.h>
18 #include <linux/irq.h>
19 #include <linux/i2c.h>
20 #include <linux/pm_runtime.h>
21 #include <linux/regmap.h>
22 #include <linux/iio/iio.h>
23 #include <linux/iio/buffer.h>
24 #include <linux/iio/events.h>
25 #include <linux/iio/kfifo_buf.h>
26 #include <linux/iio/sysfs.h>
27
28 #define APDS9960_DRV_NAME "apds9960"
29
30 #define APDS9960_REG_RAM_START 0x00
31 #define APDS9960_REG_RAM_END 0x7f
32
33 #define APDS9960_REG_ENABLE 0x80
34 #define APDS9960_REG_ATIME 0x81
35 #define APDS9960_REG_WTIME 0x83
36
37 #define APDS9960_REG_AILTL 0x84
38 #define APDS9960_REG_AILTH 0x85
39 #define APDS9960_REG_AIHTL 0x86
40 #define APDS9960_REG_AIHTH 0x87
41
42 #define APDS9960_REG_PILT 0x89
43 #define APDS9960_REG_PIHT 0x8b
44 #define APDS9960_REG_PERS 0x8c
45
46 #define APDS9960_REG_CONFIG_1 0x8d
47 #define APDS9960_REG_PPULSE 0x8e
48
49 #define APDS9960_REG_CONTROL 0x8f
50 #define APDS9960_REG_CONTROL_AGAIN_MASK 0x03
51 #define APDS9960_REG_CONTROL_PGAIN_MASK 0x0c
52 #define APDS9960_REG_CONTROL_AGAIN_MASK_SHIFT 0
53 #define APDS9960_REG_CONTROL_PGAIN_MASK_SHIFT 2
54
55 #define APDS9960_REG_CONFIG_2 0x90
56 #define APDS9960_REG_ID 0x92
57
58 #define APDS9960_REG_STATUS 0x93
59 #define APDS9960_REG_STATUS_PS_INT BIT(5)
60 #define APDS9960_REG_STATUS_ALS_INT BIT(4)
61 #define APDS9960_REG_STATUS_GINT BIT(2)
62
63 #define APDS9960_REG_PDATA 0x9c
64 #define APDS9960_REG_POFFSET_UR 0x9d
65 #define APDS9960_REG_POFFSET_DL 0x9e
66 #define APDS9960_REG_CONFIG_3 0x9f
67
68 #define APDS9960_REG_GPENTH 0xa0
69 #define APDS9960_REG_GEXTH 0xa1
70
71 #define APDS9960_REG_GCONF_1 0xa2
72 #define APDS9960_REG_GCONF_1_GFIFO_THRES_MASK 0xc0
73 #define APDS9960_REG_GCONF_1_GFIFO_THRES_MASK_SHIFT 6
74
75 #define APDS9960_REG_GCONF_2 0xa3
76 #define APDS9960_REG_GCONF_2_GGAIN_MASK 0x60
77 #define APDS9960_REG_GCONF_2_GGAIN_MASK_SHIFT 5
78
79 #define APDS9960_REG_GOFFSET_U 0xa4
80 #define APDS9960_REG_GOFFSET_D 0xa5
81 #define APDS9960_REG_GPULSE 0xa6
82 #define APDS9960_REG_GOFFSET_L 0xa7
83 #define APDS9960_REG_GOFFSET_R 0xa9
84 #define APDS9960_REG_GCONF_3 0xaa
85
86 #define APDS9960_REG_GCONF_4 0xab
87 #define APDS9960_REG_GFLVL 0xae
88 #define APDS9960_REG_GSTATUS 0xaf
89
90 #define APDS9960_REG_IFORCE 0xe4
91 #define APDS9960_REG_PICLEAR 0xe5
92 #define APDS9960_REG_CICLEAR 0xe6
93 #define APDS9960_REG_AICLEAR 0xe7
94
95 #define APDS9960_DEFAULT_PERS 0x33
96 #define APDS9960_DEFAULT_GPENTH 0x50
97 #define APDS9960_DEFAULT_GEXTH 0x40
98
99 #define APDS9960_MAX_PXS_THRES_VAL 255
100 #define APDS9960_MAX_ALS_THRES_VAL 0xffff
101 #define APDS9960_MAX_INT_TIME_IN_US 1000000
102
103 enum apds9960_als_channel_idx {
104 IDX_ALS_CLEAR, IDX_ALS_RED, IDX_ALS_GREEN, IDX_ALS_BLUE,
105 };
106
107 #define APDS9960_REG_ALS_BASE 0x94
108 #define APDS9960_REG_ALS_CHANNEL(_colour) \
109 (APDS9960_REG_ALS_BASE + (IDX_ALS_##_colour * 2))
110
111 enum apds9960_gesture_channel_idx {
112 IDX_DIR_UP, IDX_DIR_DOWN, IDX_DIR_LEFT, IDX_DIR_RIGHT,
113 };
114
115 #define APDS9960_REG_GFIFO_BASE 0xfc
116 #define APDS9960_REG_GFIFO_DIR(_dir) \
117 (APDS9960_REG_GFIFO_BASE + IDX_DIR_##_dir)
118
119 struct apds9960_data {
120 struct i2c_client *client;
121 struct iio_dev *indio_dev;
122 struct mutex lock;
123
124 /* regmap fields */
125 struct regmap *regmap;
126 struct regmap_field *reg_int_als;
127 struct regmap_field *reg_int_ges;
128 struct regmap_field *reg_int_pxs;
129
130 struct regmap_field *reg_enable_als;
131 struct regmap_field *reg_enable_ges;
132 struct regmap_field *reg_enable_pxs;
133
134 /* state */
135 bool als_int;
136 bool pxs_int;
137 int gesture_mode_running;
138
139 /* gain values */
140 int als_gain;
141 int pxs_gain;
142
143 /* integration time value in us */
144 int als_adc_int_us;
145
146 /* gesture buffer */
147 u8 buffer[4]; /* 4 8-bit channels */
148
149 /* calibration value buffer */
150 int calibbias[5];
151 };
152
153 enum {
154 APDS9960_CHAN_PROXIMITY,
155 APDS9960_CHAN_GESTURE_UP,
156 APDS9960_CHAN_GESTURE_DOWN,
157 APDS9960_CHAN_GESTURE_LEFT,
158 APDS9960_CHAN_GESTURE_RIGHT,
159 };
160
161 static const unsigned int apds9960_offset_regs[][2] = {
162 [APDS9960_CHAN_PROXIMITY] = {APDS9960_REG_POFFSET_UR, APDS9960_REG_POFFSET_DL},
163 [APDS9960_CHAN_GESTURE_UP] = {APDS9960_REG_GOFFSET_U, 0},
164 [APDS9960_CHAN_GESTURE_DOWN] = {APDS9960_REG_GOFFSET_D, 0},
165 [APDS9960_CHAN_GESTURE_LEFT] = {APDS9960_REG_GOFFSET_L, 0},
166 [APDS9960_CHAN_GESTURE_RIGHT] = {APDS9960_REG_GOFFSET_R, 0},
167 };
168
169 static const struct reg_default apds9960_reg_defaults[] = {
170 /* Default ALS integration time = 2.48ms */
171 { APDS9960_REG_ATIME, 0xff },
172 };
173
174 static const struct regmap_range apds9960_volatile_ranges[] = {
175 regmap_reg_range(APDS9960_REG_STATUS,
176 APDS9960_REG_PDATA),
177 regmap_reg_range(APDS9960_REG_GFLVL,
178 APDS9960_REG_GSTATUS),
179 regmap_reg_range(APDS9960_REG_GFIFO_DIR(UP),
180 APDS9960_REG_GFIFO_DIR(RIGHT)),
181 regmap_reg_range(APDS9960_REG_IFORCE,
182 APDS9960_REG_AICLEAR),
183 };
184
185 static const struct regmap_access_table apds9960_volatile_table = {
186 .yes_ranges = apds9960_volatile_ranges,
187 .n_yes_ranges = ARRAY_SIZE(apds9960_volatile_ranges),
188 };
189
190 static const struct regmap_range apds9960_precious_ranges[] = {
191 regmap_reg_range(APDS9960_REG_RAM_START, APDS9960_REG_RAM_END),
192 };
193
194 static const struct regmap_access_table apds9960_precious_table = {
195 .yes_ranges = apds9960_precious_ranges,
196 .n_yes_ranges = ARRAY_SIZE(apds9960_precious_ranges),
197 };
198
199 static const struct regmap_range apds9960_readable_ranges[] = {
200 regmap_reg_range(APDS9960_REG_ENABLE,
201 APDS9960_REG_GSTATUS),
202 regmap_reg_range(APDS9960_REG_GFIFO_DIR(UP),
203 APDS9960_REG_GFIFO_DIR(RIGHT)),
204 };
205
206 static const struct regmap_access_table apds9960_readable_table = {
207 .yes_ranges = apds9960_readable_ranges,
208 .n_yes_ranges = ARRAY_SIZE(apds9960_readable_ranges),
209 };
210
211 static const struct regmap_range apds9960_writeable_ranges[] = {
212 regmap_reg_range(APDS9960_REG_ENABLE, APDS9960_REG_CONFIG_2),
213 regmap_reg_range(APDS9960_REG_POFFSET_UR, APDS9960_REG_GCONF_4),
214 regmap_reg_range(APDS9960_REG_IFORCE, APDS9960_REG_AICLEAR),
215 };
216
217 static const struct regmap_access_table apds9960_writeable_table = {
218 .yes_ranges = apds9960_writeable_ranges,
219 .n_yes_ranges = ARRAY_SIZE(apds9960_writeable_ranges),
220 };
221
222 static const struct regmap_config apds9960_regmap_config = {
223 .name = "apds9960_regmap",
224 .reg_bits = 8,
225 .val_bits = 8,
226 .use_single_read = true,
227 .use_single_write = true,
228
229 .volatile_table = &apds9960_volatile_table,
230 .precious_table = &apds9960_precious_table,
231 .rd_table = &apds9960_readable_table,
232 .wr_table = &apds9960_writeable_table,
233
234 .reg_defaults = apds9960_reg_defaults,
235 .num_reg_defaults = ARRAY_SIZE(apds9960_reg_defaults),
236 .max_register = APDS9960_REG_GFIFO_DIR(RIGHT),
237 .cache_type = REGCACHE_MAPLE,
238 };
239
240 static const struct iio_event_spec apds9960_pxs_event_spec[] = {
241 {
242 .type = IIO_EV_TYPE_THRESH,
243 .dir = IIO_EV_DIR_RISING,
244 .mask_separate = BIT(IIO_EV_INFO_VALUE),
245 },
246 {
247 .type = IIO_EV_TYPE_THRESH,
248 .dir = IIO_EV_DIR_FALLING,
249 .mask_separate = BIT(IIO_EV_INFO_VALUE),
250 },
251 {
252 .type = IIO_EV_TYPE_THRESH,
253 .mask_separate = BIT(IIO_EV_INFO_ENABLE),
254 },
255 };
256
257 static const struct iio_event_spec apds9960_als_event_spec[] = {
258 {
259 .type = IIO_EV_TYPE_THRESH,
260 .dir = IIO_EV_DIR_RISING,
261 .mask_separate = BIT(IIO_EV_INFO_VALUE),
262 },
263 {
264 .type = IIO_EV_TYPE_THRESH,
265 .dir = IIO_EV_DIR_FALLING,
266 .mask_separate = BIT(IIO_EV_INFO_VALUE),
267 },
268 {
269 .type = IIO_EV_TYPE_THRESH,
270 .mask_separate = BIT(IIO_EV_INFO_ENABLE),
271 },
272 };
273
274 #define APDS9960_GESTURE_CHANNEL(_dir, _si) { \
275 .type = IIO_PROXIMITY, \
276 .info_mask_separate = BIT(IIO_CHAN_INFO_CALIBBIAS), \
277 .channel = _si + 1, \
278 .scan_index = _si, \
279 .indexed = 1, \
280 .scan_type = { \
281 .sign = 'u', \
282 .realbits = 8, \
283 .storagebits = 8, \
284 }, \
285 }
286
287 #define APDS9960_INTENSITY_CHANNEL(_colour) { \
288 .type = IIO_INTENSITY, \
289 .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \
290 .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE) | \
291 BIT(IIO_CHAN_INFO_INT_TIME), \
292 .channel2 = IIO_MOD_LIGHT_##_colour, \
293 .address = APDS9960_REG_ALS_CHANNEL(_colour), \
294 .modified = 1, \
295 .scan_index = -1, \
296 }
297
298 static const unsigned long apds9960_scan_masks[] = {0xf, 0};
299
300 static const struct iio_chan_spec apds9960_channels[] = {
301 {
302 .type = IIO_PROXIMITY,
303 .address = APDS9960_REG_PDATA,
304 .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
305 BIT(IIO_CHAN_INFO_CALIBBIAS),
306 .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE),
307 .channel = 0,
308 .indexed = 0,
309 .scan_index = -1,
310
311 .event_spec = apds9960_pxs_event_spec,
312 .num_event_specs = ARRAY_SIZE(apds9960_pxs_event_spec),
313 },
314 /* Gesture Sensor */
315 APDS9960_GESTURE_CHANNEL(UP, 0),
316 APDS9960_GESTURE_CHANNEL(DOWN, 1),
317 APDS9960_GESTURE_CHANNEL(LEFT, 2),
318 APDS9960_GESTURE_CHANNEL(RIGHT, 3),
319 /* ALS */
320 {
321 .type = IIO_INTENSITY,
322 .info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
323 .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE) |
324 BIT(IIO_CHAN_INFO_INT_TIME),
325 .channel2 = IIO_MOD_LIGHT_CLEAR,
326 .address = APDS9960_REG_ALS_CHANNEL(CLEAR),
327 .modified = 1,
328 .scan_index = -1,
329
330 .event_spec = apds9960_als_event_spec,
331 .num_event_specs = ARRAY_SIZE(apds9960_als_event_spec),
332 },
333 /* RGB Sensor */
334 APDS9960_INTENSITY_CHANNEL(RED),
335 APDS9960_INTENSITY_CHANNEL(GREEN),
336 APDS9960_INTENSITY_CHANNEL(BLUE),
337 };
338
apds9960_set_calibbias(struct apds9960_data * data,struct iio_chan_spec const * chan,int calibbias)339 static int apds9960_set_calibbias(struct apds9960_data *data,
340 struct iio_chan_spec const *chan, int calibbias)
341 {
342 int ret, i;
343
344 if (calibbias < S8_MIN || calibbias > S8_MAX)
345 return -EINVAL;
346
347 guard(mutex)(&data->lock);
348 for (i = 0; i < 2; i++) {
349 if (apds9960_offset_regs[chan->channel][i] == 0)
350 break;
351
352 ret = regmap_write(data->regmap, apds9960_offset_regs[chan->channel][i], calibbias);
353 if (ret < 0)
354 return ret;
355 }
356 data->calibbias[chan->channel] = calibbias;
357
358 return 0;
359 }
360
361 /* integration time in us */
362 static const int apds9960_int_time[][2] = {
363 { 28000, 246},
364 {100000, 219},
365 {200000, 182},
366 {700000, 0}
367 };
368
369 /* gain mapping */
370 static const int apds9960_pxs_gain_map[] = {1, 2, 4, 8};
371 static const int apds9960_als_gain_map[] = {1, 4, 16, 64};
372
373 static IIO_CONST_ATTR(proximity_scale_available, "1 2 4 8");
374 static IIO_CONST_ATTR(intensity_scale_available, "1 4 16 64");
375 static IIO_CONST_ATTR_INT_TIME_AVAIL("0.028 0.1 0.2 0.7");
376
377 static struct attribute *apds9960_attributes[] = {
378 &iio_const_attr_proximity_scale_available.dev_attr.attr,
379 &iio_const_attr_intensity_scale_available.dev_attr.attr,
380 &iio_const_attr_integration_time_available.dev_attr.attr,
381 NULL,
382 };
383
384 static const struct attribute_group apds9960_attribute_group = {
385 .attrs = apds9960_attributes,
386 };
387
388 static const struct reg_field apds9960_reg_field_int_als =
389 REG_FIELD(APDS9960_REG_ENABLE, 4, 4);
390
391 static const struct reg_field apds9960_reg_field_int_ges =
392 REG_FIELD(APDS9960_REG_GCONF_4, 1, 1);
393
394 static const struct reg_field apds9960_reg_field_int_pxs =
395 REG_FIELD(APDS9960_REG_ENABLE, 5, 5);
396
397 static const struct reg_field apds9960_reg_field_enable_als =
398 REG_FIELD(APDS9960_REG_ENABLE, 1, 1);
399
400 static const struct reg_field apds9960_reg_field_enable_ges =
401 REG_FIELD(APDS9960_REG_ENABLE, 6, 6);
402
403 static const struct reg_field apds9960_reg_field_enable_pxs =
404 REG_FIELD(APDS9960_REG_ENABLE, 2, 2);
405
apds9960_set_it_time(struct apds9960_data * data,int val2)406 static int apds9960_set_it_time(struct apds9960_data *data, int val2)
407 {
408 int ret = -EINVAL;
409 int idx;
410
411 for (idx = 0; idx < ARRAY_SIZE(apds9960_int_time); idx++) {
412 if (apds9960_int_time[idx][0] == val2) {
413 mutex_lock(&data->lock);
414 ret = regmap_write(data->regmap, APDS9960_REG_ATIME,
415 apds9960_int_time[idx][1]);
416 if (!ret)
417 data->als_adc_int_us = val2;
418 mutex_unlock(&data->lock);
419 break;
420 }
421 }
422
423 return ret;
424 }
425
apds9960_set_pxs_gain(struct apds9960_data * data,int val)426 static int apds9960_set_pxs_gain(struct apds9960_data *data, int val)
427 {
428 int ret = -EINVAL;
429 int idx;
430
431 for (idx = 0; idx < ARRAY_SIZE(apds9960_pxs_gain_map); idx++) {
432 if (apds9960_pxs_gain_map[idx] == val) {
433 /* pxs + gesture gains are mirrored */
434 mutex_lock(&data->lock);
435 ret = regmap_update_bits(data->regmap,
436 APDS9960_REG_CONTROL,
437 APDS9960_REG_CONTROL_PGAIN_MASK,
438 idx << APDS9960_REG_CONTROL_PGAIN_MASK_SHIFT);
439 if (ret) {
440 mutex_unlock(&data->lock);
441 break;
442 }
443
444 ret = regmap_update_bits(data->regmap,
445 APDS9960_REG_GCONF_2,
446 APDS9960_REG_GCONF_2_GGAIN_MASK,
447 idx << APDS9960_REG_GCONF_2_GGAIN_MASK_SHIFT);
448 if (!ret)
449 data->pxs_gain = idx;
450 mutex_unlock(&data->lock);
451 break;
452 }
453 }
454
455 return ret;
456 }
457
apds9960_set_als_gain(struct apds9960_data * data,int val)458 static int apds9960_set_als_gain(struct apds9960_data *data, int val)
459 {
460 int ret = -EINVAL;
461 int idx;
462
463 for (idx = 0; idx < ARRAY_SIZE(apds9960_als_gain_map); idx++) {
464 if (apds9960_als_gain_map[idx] == val) {
465 mutex_lock(&data->lock);
466 ret = regmap_update_bits(data->regmap,
467 APDS9960_REG_CONTROL,
468 APDS9960_REG_CONTROL_AGAIN_MASK, idx);
469 if (!ret)
470 data->als_gain = idx;
471 mutex_unlock(&data->lock);
472 break;
473 }
474 }
475
476 return ret;
477 }
478
479 #ifdef CONFIG_PM
apds9960_set_power_state(struct apds9960_data * data,bool on)480 static int apds9960_set_power_state(struct apds9960_data *data, bool on)
481 {
482 struct device *dev = &data->client->dev;
483 int ret = 0;
484
485 mutex_lock(&data->lock);
486
487 if (on) {
488 int suspended;
489
490 suspended = pm_runtime_suspended(dev);
491 ret = pm_runtime_get_sync(dev);
492
493 /* Allow one integration cycle before allowing a reading */
494 if (suspended)
495 usleep_range(data->als_adc_int_us,
496 APDS9960_MAX_INT_TIME_IN_US);
497 } else {
498 ret = pm_runtime_put_autosuspend(dev);
499 }
500
501 mutex_unlock(&data->lock);
502
503 return ret;
504 }
505 #else
apds9960_set_power_state(struct apds9960_data * data,bool on)506 static int apds9960_set_power_state(struct apds9960_data *data, bool on)
507 {
508 return 0;
509 }
510 #endif
511
apds9960_read_raw(struct iio_dev * indio_dev,struct iio_chan_spec const * chan,int * val,int * val2,long mask)512 static int apds9960_read_raw(struct iio_dev *indio_dev,
513 struct iio_chan_spec const *chan,
514 int *val, int *val2, long mask)
515 {
516 struct apds9960_data *data = iio_priv(indio_dev);
517 __le16 buf;
518 int ret = -EINVAL;
519
520 if (data->gesture_mode_running)
521 return -EBUSY;
522
523 switch (mask) {
524 case IIO_CHAN_INFO_RAW:
525 apds9960_set_power_state(data, true);
526 switch (chan->type) {
527 case IIO_PROXIMITY:
528 ret = regmap_read(data->regmap, chan->address, val);
529 if (!ret)
530 ret = IIO_VAL_INT;
531 break;
532 case IIO_INTENSITY:
533 ret = regmap_bulk_read(data->regmap, chan->address,
534 &buf, 2);
535 if (!ret) {
536 ret = IIO_VAL_INT;
537 *val = le16_to_cpu(buf);
538 }
539 break;
540 default:
541 ret = -EINVAL;
542 }
543 apds9960_set_power_state(data, false);
544 break;
545 case IIO_CHAN_INFO_INT_TIME:
546 /* RGB + ALS sensors only have integration time */
547 mutex_lock(&data->lock);
548 switch (chan->type) {
549 case IIO_INTENSITY:
550 *val = 0;
551 *val2 = data->als_adc_int_us;
552 ret = IIO_VAL_INT_PLUS_MICRO;
553 break;
554 default:
555 ret = -EINVAL;
556 }
557 mutex_unlock(&data->lock);
558 break;
559 case IIO_CHAN_INFO_SCALE:
560 mutex_lock(&data->lock);
561 switch (chan->type) {
562 case IIO_PROXIMITY:
563 *val = apds9960_pxs_gain_map[data->pxs_gain];
564 ret = IIO_VAL_INT;
565 break;
566 case IIO_INTENSITY:
567 *val = apds9960_als_gain_map[data->als_gain];
568 ret = IIO_VAL_INT;
569 break;
570 default:
571 ret = -EINVAL;
572 }
573 mutex_unlock(&data->lock);
574 break;
575 case IIO_CHAN_INFO_CALIBBIAS:
576 mutex_lock(&data->lock);
577 *val = data->calibbias[chan->channel];
578 ret = IIO_VAL_INT;
579 mutex_unlock(&data->lock);
580 break;
581 }
582
583 return ret;
584 };
585
apds9960_write_raw(struct iio_dev * indio_dev,struct iio_chan_spec const * chan,int val,int val2,long mask)586 static int apds9960_write_raw(struct iio_dev *indio_dev,
587 struct iio_chan_spec const *chan,
588 int val, int val2, long mask)
589 {
590 struct apds9960_data *data = iio_priv(indio_dev);
591
592 switch (mask) {
593 case IIO_CHAN_INFO_INT_TIME:
594 /* RGB + ALS sensors only have int time */
595 switch (chan->type) {
596 case IIO_INTENSITY:
597 if (val != 0)
598 return -EINVAL;
599 return apds9960_set_it_time(data, val2);
600 default:
601 return -EINVAL;
602 }
603 case IIO_CHAN_INFO_SCALE:
604 if (val2 != 0)
605 return -EINVAL;
606 switch (chan->type) {
607 case IIO_PROXIMITY:
608 return apds9960_set_pxs_gain(data, val);
609 case IIO_INTENSITY:
610 return apds9960_set_als_gain(data, val);
611 default:
612 return -EINVAL;
613 }
614 case IIO_CHAN_INFO_CALIBBIAS:
615 if (val2 != 0)
616 return -EINVAL;
617 return apds9960_set_calibbias(data, chan, val);
618 default:
619 return -EINVAL;
620 }
621
622 return 0;
623 }
624
apds9960_get_thres_reg(const struct iio_chan_spec * chan,enum iio_event_direction dir,u8 * reg)625 static inline int apds9960_get_thres_reg(const struct iio_chan_spec *chan,
626 enum iio_event_direction dir,
627 u8 *reg)
628 {
629 switch (dir) {
630 case IIO_EV_DIR_RISING:
631 switch (chan->type) {
632 case IIO_PROXIMITY:
633 *reg = APDS9960_REG_PIHT;
634 break;
635 case IIO_INTENSITY:
636 *reg = APDS9960_REG_AIHTL;
637 break;
638 default:
639 return -EINVAL;
640 }
641 break;
642 case IIO_EV_DIR_FALLING:
643 switch (chan->type) {
644 case IIO_PROXIMITY:
645 *reg = APDS9960_REG_PILT;
646 break;
647 case IIO_INTENSITY:
648 *reg = APDS9960_REG_AILTL;
649 break;
650 default:
651 return -EINVAL;
652 }
653 break;
654 default:
655 return -EINVAL;
656 }
657
658 return 0;
659 }
660
apds9960_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)661 static int apds9960_read_event(struct iio_dev *indio_dev,
662 const struct iio_chan_spec *chan,
663 enum iio_event_type type,
664 enum iio_event_direction dir,
665 enum iio_event_info info,
666 int *val, int *val2)
667 {
668 u8 reg;
669 __le16 buf;
670 int ret = 0;
671 struct apds9960_data *data = iio_priv(indio_dev);
672
673 if (info != IIO_EV_INFO_VALUE)
674 return -EINVAL;
675
676 ret = apds9960_get_thres_reg(chan, dir, ®);
677 if (ret < 0)
678 return ret;
679
680 if (chan->type == IIO_PROXIMITY) {
681 ret = regmap_read(data->regmap, reg, val);
682 if (ret < 0)
683 return ret;
684 } else if (chan->type == IIO_INTENSITY) {
685 ret = regmap_bulk_read(data->regmap, reg, &buf, 2);
686 if (ret < 0)
687 return ret;
688 *val = le16_to_cpu(buf);
689 } else
690 return -EINVAL;
691
692 *val2 = 0;
693
694 return IIO_VAL_INT;
695 }
696
apds9960_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)697 static int apds9960_write_event(struct iio_dev *indio_dev,
698 const struct iio_chan_spec *chan,
699 enum iio_event_type type,
700 enum iio_event_direction dir,
701 enum iio_event_info info,
702 int val, int val2)
703 {
704 u8 reg;
705 __le16 buf;
706 int ret = 0;
707 struct apds9960_data *data = iio_priv(indio_dev);
708
709 if (info != IIO_EV_INFO_VALUE)
710 return -EINVAL;
711
712 ret = apds9960_get_thres_reg(chan, dir, ®);
713 if (ret < 0)
714 return ret;
715
716 if (chan->type == IIO_PROXIMITY) {
717 if (val < 0 || val > APDS9960_MAX_PXS_THRES_VAL)
718 return -EINVAL;
719 ret = regmap_write(data->regmap, reg, val);
720 if (ret < 0)
721 return ret;
722 } else if (chan->type == IIO_INTENSITY) {
723 if (val < 0 || val > APDS9960_MAX_ALS_THRES_VAL)
724 return -EINVAL;
725 buf = cpu_to_le16(val);
726 ret = regmap_bulk_write(data->regmap, reg, &buf, 2);
727 if (ret < 0)
728 return ret;
729 } else
730 return -EINVAL;
731
732 return 0;
733 }
734
apds9960_read_event_config(struct iio_dev * indio_dev,const struct iio_chan_spec * chan,enum iio_event_type type,enum iio_event_direction dir)735 static int apds9960_read_event_config(struct iio_dev *indio_dev,
736 const struct iio_chan_spec *chan,
737 enum iio_event_type type,
738 enum iio_event_direction dir)
739 {
740 struct apds9960_data *data = iio_priv(indio_dev);
741
742 switch (chan->type) {
743 case IIO_PROXIMITY:
744 return data->pxs_int;
745 case IIO_INTENSITY:
746 return data->als_int;
747 default:
748 return -EINVAL;
749 }
750 }
751
apds9960_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)752 static int apds9960_write_event_config(struct iio_dev *indio_dev,
753 const struct iio_chan_spec *chan,
754 enum iio_event_type type,
755 enum iio_event_direction dir,
756 bool state)
757 {
758 struct apds9960_data *data = iio_priv(indio_dev);
759 int ret;
760
761 switch (chan->type) {
762 case IIO_PROXIMITY:
763 if (data->pxs_int == state)
764 return -EINVAL;
765
766 ret = regmap_field_write(data->reg_int_pxs, state);
767 if (ret)
768 return ret;
769 data->pxs_int = state;
770 apds9960_set_power_state(data, state);
771 break;
772 case IIO_INTENSITY:
773 if (data->als_int == state)
774 return -EINVAL;
775
776 ret = regmap_field_write(data->reg_int_als, state);
777 if (ret)
778 return ret;
779 data->als_int = state;
780 apds9960_set_power_state(data, state);
781 break;
782 default:
783 return -EINVAL;
784 }
785
786 return 0;
787 }
788
789 static const struct iio_info apds9960_info = {
790 .attrs = &apds9960_attribute_group,
791 .read_raw = apds9960_read_raw,
792 .write_raw = apds9960_write_raw,
793 .read_event_value = apds9960_read_event,
794 .write_event_value = apds9960_write_event,
795 .read_event_config = apds9960_read_event_config,
796 .write_event_config = apds9960_write_event_config,
797
798 };
799
apds9660_fifo_is_empty(struct apds9960_data * data)800 static inline int apds9660_fifo_is_empty(struct apds9960_data *data)
801 {
802 int cnt;
803 int ret;
804
805 ret = regmap_read(data->regmap, APDS9960_REG_GFLVL, &cnt);
806 if (ret)
807 return ret;
808
809 return cnt;
810 }
811
apds9960_read_gesture_fifo(struct apds9960_data * data)812 static void apds9960_read_gesture_fifo(struct apds9960_data *data)
813 {
814 int ret, cnt = 0;
815
816 mutex_lock(&data->lock);
817 data->gesture_mode_running = 1;
818
819 while (cnt || (cnt = apds9660_fifo_is_empty(data) > 0)) {
820 ret = regmap_bulk_read(data->regmap, APDS9960_REG_GFIFO_BASE,
821 &data->buffer, 4);
822
823 if (ret)
824 goto err_read;
825
826 iio_push_to_buffers(data->indio_dev, data->buffer);
827 cnt--;
828 }
829
830 err_read:
831 data->gesture_mode_running = 0;
832 mutex_unlock(&data->lock);
833 }
834
apds9960_interrupt_handler(int irq,void * private)835 static irqreturn_t apds9960_interrupt_handler(int irq, void *private)
836 {
837 struct iio_dev *indio_dev = private;
838 struct apds9960_data *data = iio_priv(indio_dev);
839 int ret, status;
840
841 ret = regmap_read(data->regmap, APDS9960_REG_STATUS, &status);
842 if (ret < 0) {
843 dev_err(&data->client->dev, "irq status reg read failed\n");
844 return IRQ_HANDLED;
845 }
846
847 if ((status & APDS9960_REG_STATUS_ALS_INT) && data->als_int) {
848 iio_push_event(indio_dev,
849 IIO_UNMOD_EVENT_CODE(IIO_INTENSITY, 0,
850 IIO_EV_TYPE_THRESH,
851 IIO_EV_DIR_EITHER),
852 iio_get_time_ns(indio_dev));
853 regmap_write(data->regmap, APDS9960_REG_CICLEAR, 1);
854 }
855
856 if ((status & APDS9960_REG_STATUS_PS_INT) && data->pxs_int) {
857 iio_push_event(indio_dev,
858 IIO_UNMOD_EVENT_CODE(IIO_PROXIMITY, 0,
859 IIO_EV_TYPE_THRESH,
860 IIO_EV_DIR_EITHER),
861 iio_get_time_ns(indio_dev));
862 regmap_write(data->regmap, APDS9960_REG_PICLEAR, 1);
863 }
864
865 if (status & APDS9960_REG_STATUS_GINT)
866 apds9960_read_gesture_fifo(data);
867
868 return IRQ_HANDLED;
869 }
870
apds9960_set_powermode(struct apds9960_data * data,bool state)871 static int apds9960_set_powermode(struct apds9960_data *data, bool state)
872 {
873 return regmap_update_bits(data->regmap, APDS9960_REG_ENABLE, 1, state);
874 }
875
apds9960_buffer_postenable(struct iio_dev * indio_dev)876 static int apds9960_buffer_postenable(struct iio_dev *indio_dev)
877 {
878 struct apds9960_data *data = iio_priv(indio_dev);
879 int ret;
880
881 ret = regmap_field_write(data->reg_int_ges, 1);
882 if (ret)
883 return ret;
884
885 ret = regmap_field_write(data->reg_enable_ges, 1);
886 if (ret)
887 return ret;
888
889 pm_runtime_get_sync(&data->client->dev);
890
891 return 0;
892 }
893
apds9960_buffer_predisable(struct iio_dev * indio_dev)894 static int apds9960_buffer_predisable(struct iio_dev *indio_dev)
895 {
896 struct apds9960_data *data = iio_priv(indio_dev);
897 int ret;
898
899 ret = regmap_field_write(data->reg_enable_ges, 0);
900 if (ret)
901 return ret;
902
903 ret = regmap_field_write(data->reg_int_ges, 0);
904 if (ret)
905 return ret;
906
907 pm_runtime_put_autosuspend(&data->client->dev);
908
909 return 0;
910 }
911
912 static const struct iio_buffer_setup_ops apds9960_buffer_setup_ops = {
913 .postenable = apds9960_buffer_postenable,
914 .predisable = apds9960_buffer_predisable,
915 };
916
apds9960_regfield_init(struct apds9960_data * data)917 static int apds9960_regfield_init(struct apds9960_data *data)
918 {
919 struct device *dev = &data->client->dev;
920 struct regmap *regmap = data->regmap;
921
922 data->reg_int_als = devm_regmap_field_alloc(dev, regmap,
923 apds9960_reg_field_int_als);
924 if (IS_ERR(data->reg_int_als)) {
925 dev_err(dev, "INT ALS reg field init failed\n");
926 return PTR_ERR(data->reg_int_als);
927 }
928
929 data->reg_int_ges = devm_regmap_field_alloc(dev, regmap,
930 apds9960_reg_field_int_ges);
931 if (IS_ERR(data->reg_int_ges)) {
932 dev_err(dev, "INT gesture reg field init failed\n");
933 return PTR_ERR(data->reg_int_ges);
934 }
935
936 data->reg_int_pxs = devm_regmap_field_alloc(dev, regmap,
937 apds9960_reg_field_int_pxs);
938 if (IS_ERR(data->reg_int_pxs)) {
939 dev_err(dev, "INT pxs reg field init failed\n");
940 return PTR_ERR(data->reg_int_pxs);
941 }
942
943 data->reg_enable_als = devm_regmap_field_alloc(dev, regmap,
944 apds9960_reg_field_enable_als);
945 if (IS_ERR(data->reg_enable_als)) {
946 dev_err(dev, "Enable ALS reg field init failed\n");
947 return PTR_ERR(data->reg_enable_als);
948 }
949
950 data->reg_enable_ges = devm_regmap_field_alloc(dev, regmap,
951 apds9960_reg_field_enable_ges);
952 if (IS_ERR(data->reg_enable_ges)) {
953 dev_err(dev, "Enable gesture reg field init failed\n");
954 return PTR_ERR(data->reg_enable_ges);
955 }
956
957 data->reg_enable_pxs = devm_regmap_field_alloc(dev, regmap,
958 apds9960_reg_field_enable_pxs);
959 if (IS_ERR(data->reg_enable_pxs)) {
960 dev_err(dev, "Enable PXS reg field init failed\n");
961 return PTR_ERR(data->reg_enable_pxs);
962 }
963
964 return 0;
965 }
966
apds9960_chip_init(struct apds9960_data * data)967 static int apds9960_chip_init(struct apds9960_data *data)
968 {
969 int ret;
970
971 /* Default IT for ALS of 28 ms */
972 ret = apds9960_set_it_time(data, 28000);
973 if (ret)
974 return ret;
975
976 /* Ensure gesture interrupt is OFF */
977 ret = regmap_field_write(data->reg_int_ges, 0);
978 if (ret)
979 return ret;
980
981 /* Disable gesture sensor, since polling is useless from user-space */
982 ret = regmap_field_write(data->reg_enable_ges, 0);
983 if (ret)
984 return ret;
985
986 /* Ensure proximity interrupt is OFF */
987 ret = regmap_field_write(data->reg_int_pxs, 0);
988 if (ret)
989 return ret;
990
991 /* Enable proximity sensor for polling */
992 ret = regmap_field_write(data->reg_enable_pxs, 1);
993 if (ret)
994 return ret;
995
996 /* Ensure ALS interrupt is OFF */
997 ret = regmap_field_write(data->reg_int_als, 0);
998 if (ret)
999 return ret;
1000
1001 /* Enable ALS sensor for polling */
1002 ret = regmap_field_write(data->reg_enable_als, 1);
1003 if (ret)
1004 return ret;
1005 /*
1006 * When enabled trigger an interrupt after 3 readings
1007 * outside threshold for ALS + PXS
1008 */
1009 ret = regmap_write(data->regmap, APDS9960_REG_PERS,
1010 APDS9960_DEFAULT_PERS);
1011 if (ret)
1012 return ret;
1013
1014 /*
1015 * Wait for 4 event outside gesture threshold to prevent interrupt
1016 * flooding.
1017 */
1018 ret = regmap_update_bits(data->regmap, APDS9960_REG_GCONF_1,
1019 APDS9960_REG_GCONF_1_GFIFO_THRES_MASK,
1020 BIT(0) << APDS9960_REG_GCONF_1_GFIFO_THRES_MASK_SHIFT);
1021 if (ret)
1022 return ret;
1023
1024 /* Default ENTER and EXIT thresholds for the GESTURE engine. */
1025 ret = regmap_write(data->regmap, APDS9960_REG_GPENTH,
1026 APDS9960_DEFAULT_GPENTH);
1027 if (ret)
1028 return ret;
1029
1030 ret = regmap_write(data->regmap, APDS9960_REG_GEXTH,
1031 APDS9960_DEFAULT_GEXTH);
1032 if (ret)
1033 return ret;
1034
1035 return apds9960_set_powermode(data, 1);
1036 }
1037
apds9960_probe(struct i2c_client * client)1038 static int apds9960_probe(struct i2c_client *client)
1039 {
1040 struct apds9960_data *data;
1041 struct iio_dev *indio_dev;
1042 int ret;
1043
1044 indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*data));
1045 if (!indio_dev)
1046 return -ENOMEM;
1047
1048 indio_dev->info = &apds9960_info;
1049 indio_dev->name = APDS9960_DRV_NAME;
1050 indio_dev->channels = apds9960_channels;
1051 indio_dev->num_channels = ARRAY_SIZE(apds9960_channels);
1052 indio_dev->available_scan_masks = apds9960_scan_masks;
1053 indio_dev->modes = INDIO_DIRECT_MODE;
1054
1055 ret = devm_iio_kfifo_buffer_setup(&client->dev, indio_dev,
1056 &apds9960_buffer_setup_ops);
1057 if (ret)
1058 return ret;
1059
1060 data = iio_priv(indio_dev);
1061 i2c_set_clientdata(client, indio_dev);
1062
1063 data->regmap = devm_regmap_init_i2c(client, &apds9960_regmap_config);
1064 if (IS_ERR(data->regmap)) {
1065 dev_err(&client->dev, "regmap initialization failed.\n");
1066 return PTR_ERR(data->regmap);
1067 }
1068
1069 data->client = client;
1070 data->indio_dev = indio_dev;
1071 mutex_init(&data->lock);
1072
1073 ret = pm_runtime_set_active(&client->dev);
1074 if (ret)
1075 goto error_power_down;
1076
1077 pm_runtime_enable(&client->dev);
1078 pm_runtime_set_autosuspend_delay(&client->dev, 5000);
1079 pm_runtime_use_autosuspend(&client->dev);
1080
1081 apds9960_set_power_state(data, true);
1082
1083 ret = apds9960_regfield_init(data);
1084 if (ret)
1085 goto error_power_down;
1086
1087 ret = apds9960_chip_init(data);
1088 if (ret)
1089 goto error_power_down;
1090
1091 if (client->irq <= 0) {
1092 dev_err(&client->dev, "no valid irq defined\n");
1093 ret = -EINVAL;
1094 goto error_power_down;
1095 }
1096 ret = devm_request_threaded_irq(&client->dev, client->irq,
1097 NULL, apds9960_interrupt_handler,
1098 IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
1099 "apds9960_event",
1100 indio_dev);
1101 if (ret) {
1102 dev_err(&client->dev, "request irq (%d) failed\n", client->irq);
1103 goto error_power_down;
1104 }
1105
1106 ret = iio_device_register(indio_dev);
1107 if (ret)
1108 goto error_power_down;
1109
1110 apds9960_set_power_state(data, false);
1111
1112 return 0;
1113
1114 error_power_down:
1115 apds9960_set_power_state(data, false);
1116
1117 return ret;
1118 }
1119
apds9960_remove(struct i2c_client * client)1120 static void apds9960_remove(struct i2c_client *client)
1121 {
1122 struct iio_dev *indio_dev = i2c_get_clientdata(client);
1123 struct apds9960_data *data = iio_priv(indio_dev);
1124
1125 iio_device_unregister(indio_dev);
1126 pm_runtime_disable(&client->dev);
1127 pm_runtime_set_suspended(&client->dev);
1128 apds9960_set_powermode(data, 0);
1129 }
1130
1131 #ifdef CONFIG_PM
apds9960_runtime_suspend(struct device * dev)1132 static int apds9960_runtime_suspend(struct device *dev)
1133 {
1134 struct apds9960_data *data =
1135 iio_priv(i2c_get_clientdata(to_i2c_client(dev)));
1136
1137 return apds9960_set_powermode(data, 0);
1138 }
1139
apds9960_runtime_resume(struct device * dev)1140 static int apds9960_runtime_resume(struct device *dev)
1141 {
1142 struct apds9960_data *data =
1143 iio_priv(i2c_get_clientdata(to_i2c_client(dev)));
1144
1145 return apds9960_set_powermode(data, 1);
1146 }
1147 #endif
1148
1149 static const struct dev_pm_ops apds9960_pm_ops = {
1150 SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend,
1151 pm_runtime_force_resume)
1152 SET_RUNTIME_PM_OPS(apds9960_runtime_suspend,
1153 apds9960_runtime_resume, NULL)
1154 };
1155
1156 static const struct i2c_device_id apds9960_id[] = {
1157 { "apds9960" },
1158 { }
1159 };
1160 MODULE_DEVICE_TABLE(i2c, apds9960_id);
1161
1162 static const struct acpi_device_id apds9960_acpi_match[] = {
1163 { "MSHW0184" },
1164 { }
1165 };
1166 MODULE_DEVICE_TABLE(acpi, apds9960_acpi_match);
1167
1168 static const struct of_device_id apds9960_of_match[] = {
1169 { .compatible = "avago,apds9960" },
1170 { }
1171 };
1172 MODULE_DEVICE_TABLE(of, apds9960_of_match);
1173
1174 static struct i2c_driver apds9960_driver = {
1175 .driver = {
1176 .name = APDS9960_DRV_NAME,
1177 .of_match_table = apds9960_of_match,
1178 .pm = &apds9960_pm_ops,
1179 .acpi_match_table = apds9960_acpi_match,
1180 },
1181 .probe = apds9960_probe,
1182 .remove = apds9960_remove,
1183 .id_table = apds9960_id,
1184 };
1185 module_i2c_driver(apds9960_driver);
1186
1187 MODULE_AUTHOR("Matt Ranostay <matt.ranostay@konsulko.com>");
1188 MODULE_DESCRIPTION("APDS9960 Gesture/RGB/ALS/Proximity sensor");
1189 MODULE_LICENSE("GPL");
1190