1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3 * APDS-9306/APDS-9306-065 Ambient Light Sensor
4 * I2C Address: 0x52
5 * Datasheet: https://docs.broadcom.com/doc/AV02-4755EN
6 *
7 * Copyright (C) 2024 Subhajit Ghosh <subhajit.ghosh@tweaklogic.com>
8 */
9
10 #include <linux/bits.h>
11 #include <linux/cleanup.h>
12 #include <linux/delay.h>
13 #include <linux/err.h>
14 #include <linux/i2c.h>
15 #include <linux/interrupt.h>
16 #include <linux/minmax.h>
17 #include <linux/module.h>
18 #include <linux/mutex.h>
19 #include <linux/pm.h>
20 #include <linux/pm_runtime.h>
21 #include <linux/regmap.h>
22 #include <linux/regulator/consumer.h>
23 #include <linux/types.h>
24 #include <linux/units.h>
25
26 #include <linux/iio/iio.h>
27 #include <linux/iio/iio-gts-helper.h>
28 #include <linux/iio/events.h>
29 #include <linux/iio/sysfs.h>
30
31 #include <linux/unaligned.h>
32
33 #define APDS9306_MAIN_CTRL_REG 0x00
34 #define APDS9306_ALS_MEAS_RATE_REG 0x04
35 #define APDS9306_ALS_GAIN_REG 0x05
36 #define APDS9306_PART_ID_REG 0x06
37 #define APDS9306_MAIN_STATUS_REG 0x07
38 #define APDS9306_CLEAR_DATA_0_REG 0x0A
39 #define APDS9306_CLEAR_DATA_1_REG 0x0B
40 #define APDS9306_CLEAR_DATA_2_REG 0x0C
41 #define APDS9306_ALS_DATA_0_REG 0x0D
42 #define APDS9306_ALS_DATA_1_REG 0x0E
43 #define APDS9306_ALS_DATA_2_REG 0x0F
44 #define APDS9306_INT_CFG_REG 0x19
45 #define APDS9306_INT_PERSISTENCE_REG 0x1A
46 #define APDS9306_ALS_THRES_UP_0_REG 0x21
47 #define APDS9306_ALS_THRES_UP_1_REG 0x22
48 #define APDS9306_ALS_THRES_UP_2_REG 0x23
49 #define APDS9306_ALS_THRES_LOW_0_REG 0x24
50 #define APDS9306_ALS_THRES_LOW_1_REG 0x25
51 #define APDS9306_ALS_THRES_LOW_2_REG 0x26
52 #define APDS9306_ALS_THRES_VAR_REG 0x27
53
54 #define APDS9306_ALS_INT_STAT_MASK BIT(4)
55 #define APDS9306_ALS_DATA_STAT_MASK BIT(3)
56
57 #define APDS9306_ALS_THRES_VAL_MAX (BIT(20) - 1)
58 #define APDS9306_ALS_THRES_VAR_NUM_VALS 8
59 #define APDS9306_ALS_PERSIST_NUM_VALS 16
60 #define APDS9306_ALS_READ_DATA_DELAY_US (20 * USEC_PER_MSEC)
61 #define APDS9306_NUM_REPEAT_RATES 7
62 #define APDS9306_INT_SRC_CLEAR 0
63 #define APDS9306_INT_SRC_ALS 1
64 #define APDS9306_SAMP_FREQ_10HZ 0
65
66 /**
67 * struct part_id_gts_multiplier - Part no. and corresponding gts multiplier
68 *
69 * GTS (Gain Time Scale) are helper functions for Light sensors which along
70 * with hardware gains also has gains associated with Integration times.
71 *
72 * There are two variants of the device with slightly different characteristics,
73 * they have same ADC count for different Lux levels as mentioned in the
74 * datasheet. This multiplier array is used to store the derived Lux per count
75 * value for the two variants to be used by the GTS helper functions.
76 *
77 * @part_id: Part ID of the device
78 * @max_scale_int: Multiplier for iio_init_iio_gts()
79 * @max_scale_nano: Multiplier for iio_init_iio_gts()
80 */
81 struct part_id_gts_multiplier {
82 int part_id;
83 int max_scale_int;
84 int max_scale_nano;
85 };
86
87 /*
88 * As per the datasheet, at HW Gain = 3x, Integration time 100mS (32x),
89 * typical 2000 ADC counts are observed for 49.8 uW per sq cm (340.134 lux)
90 * for apds9306 and 43 uW per sq cm (293.69 lux) for apds9306-065.
91 * Assuming lux per count is linear across all integration time ranges.
92 *
93 * Lux = (raw + offset) * scale; offset can be any value by userspace.
94 * HG = Hardware Gain; ITG = Gain by changing integration time.
95 * Scale table by IIO GTS Helpers = (1 / HG) * (1 / ITG) * Multiplier.
96 *
97 * The Lux values provided in the datasheet are at ITG=32x and HG=3x,
98 * at typical 2000 count for both variants of the device.
99 *
100 * Lux per ADC count at 3x and 32x for apds9306 = 340.134 / 2000
101 * Lux per ADC count at 3x and 32x for apds9306-065 = 293.69 / 2000
102 *
103 * The Multiplier for the scale table provided to userspace:
104 * IIO GTS scale Multiplier for apds9306 = (340.134 / 2000) * 32 * 3 = 16.326432
105 * and for apds9306-065 = (293.69 / 2000) * 32 * 3 = 14.09712
106 */
107 static const struct part_id_gts_multiplier apds9306_gts_mul[] = {
108 {
109 .part_id = 0xB1,
110 .max_scale_int = 16,
111 .max_scale_nano = 3264320,
112 }, {
113 .part_id = 0xB3,
114 .max_scale_int = 14,
115 .max_scale_nano = 9712000,
116 },
117 };
118
119 static const int apds9306_repeat_rate_freq[APDS9306_NUM_REPEAT_RATES][2] = {
120 { 40, 0 },
121 { 20, 0 },
122 { 10, 0 },
123 { 5, 0 },
124 { 2, 0 },
125 { 1, 0 },
126 { 0, 500000 },
127 };
128
129 static const int apds9306_repeat_rate_period[APDS9306_NUM_REPEAT_RATES] = {
130 25000, 50000, 100000, 200000, 500000, 1000000, 2000000,
131 };
132
133 /**
134 * struct apds9306_regfields - apds9306 regmap fields definitions
135 *
136 * @sw_reset: Software reset regfield
137 * @en: Enable regfield
138 * @intg_time: Resolution regfield
139 * @repeat_rate: Measurement Rate regfield
140 * @gain: Hardware gain regfield
141 * @int_src: Interrupt channel regfield
142 * @int_thresh_var_en: Interrupt variance threshold regfield
143 * @int_en: Interrupt enable regfield
144 * @int_persist_val: Interrupt persistence regfield
145 * @int_thresh_var_val: Interrupt threshold variance value regfield
146 */
147 struct apds9306_regfields {
148 struct regmap_field *sw_reset;
149 struct regmap_field *en;
150 struct regmap_field *intg_time;
151 struct regmap_field *repeat_rate;
152 struct regmap_field *gain;
153 struct regmap_field *int_src;
154 struct regmap_field *int_thresh_var_en;
155 struct regmap_field *int_en;
156 struct regmap_field *int_persist_val;
157 struct regmap_field *int_thresh_var_val;
158 };
159
160 /**
161 * struct apds9306_data - apds9306 private data and registers definitions
162 *
163 * @dev: Pointer to the device structure
164 * @gts: IIO Gain Time Scale structure
165 * @mutex: Lock for protecting adc reads, device settings changes where
166 * some calculations are required before or after setting or
167 * getting the raw settings values from regmap writes or reads
168 * respectively.
169 * @regmap: Regmap structure pointer
170 * @rf: Regmap register fields structure
171 * @nlux_per_count: Nano lux per ADC count for a particular model
172 * @read_data_available: Flag set by IRQ handler for ADC data available
173 */
174 struct apds9306_data {
175 struct device *dev;
176 struct iio_gts gts;
177
178 struct mutex mutex;
179
180 struct regmap *regmap;
181 struct apds9306_regfields rf;
182
183 int nlux_per_count;
184 int read_data_available;
185 };
186
187 /*
188 * Available scales with gain 1x - 18x, timings 3.125, 25, 50, 100, 200, 400 ms
189 * Time impacts to gain: 1x, 8x, 16x, 32x, 64x, 128x
190 */
191 #define APDS9306_GSEL_1X 0x00
192 #define APDS9306_GSEL_3X 0x01
193 #define APDS9306_GSEL_6X 0x02
194 #define APDS9306_GSEL_9X 0x03
195 #define APDS9306_GSEL_18X 0x04
196
197 static const struct iio_gain_sel_pair apds9306_gains[] = {
198 GAIN_SCALE_GAIN(1, APDS9306_GSEL_1X),
199 GAIN_SCALE_GAIN(3, APDS9306_GSEL_3X),
200 GAIN_SCALE_GAIN(6, APDS9306_GSEL_6X),
201 GAIN_SCALE_GAIN(9, APDS9306_GSEL_9X),
202 GAIN_SCALE_GAIN(18, APDS9306_GSEL_18X),
203 };
204
205 #define APDS9306_MEAS_MODE_400MS 0x00
206 #define APDS9306_MEAS_MODE_200MS 0x01
207 #define APDS9306_MEAS_MODE_100MS 0x02
208 #define APDS9306_MEAS_MODE_50MS 0x03
209 #define APDS9306_MEAS_MODE_25MS 0x04
210 #define APDS9306_MEAS_MODE_3125US 0x05
211
212 static const struct iio_itime_sel_mul apds9306_itimes[] = {
213 GAIN_SCALE_ITIME_US(400000, APDS9306_MEAS_MODE_400MS, BIT(7)),
214 GAIN_SCALE_ITIME_US(200000, APDS9306_MEAS_MODE_200MS, BIT(6)),
215 GAIN_SCALE_ITIME_US(100000, APDS9306_MEAS_MODE_100MS, BIT(5)),
216 GAIN_SCALE_ITIME_US(50000, APDS9306_MEAS_MODE_50MS, BIT(4)),
217 GAIN_SCALE_ITIME_US(25000, APDS9306_MEAS_MODE_25MS, BIT(3)),
218 GAIN_SCALE_ITIME_US(3125, APDS9306_MEAS_MODE_3125US, BIT(0)),
219 };
220
221 static const struct iio_event_spec apds9306_event_spec[] = {
222 {
223 .type = IIO_EV_TYPE_THRESH,
224 .dir = IIO_EV_DIR_RISING,
225 .mask_shared_by_all = BIT(IIO_EV_INFO_VALUE),
226 }, {
227 .type = IIO_EV_TYPE_THRESH,
228 .dir = IIO_EV_DIR_FALLING,
229 .mask_shared_by_all = BIT(IIO_EV_INFO_VALUE),
230 }, {
231 .type = IIO_EV_TYPE_THRESH,
232 .dir = IIO_EV_DIR_EITHER,
233 .mask_shared_by_all = BIT(IIO_EV_INFO_PERIOD),
234 .mask_separate = BIT(IIO_EV_INFO_ENABLE),
235 }, {
236 .type = IIO_EV_TYPE_THRESH_ADAPTIVE,
237 .mask_shared_by_all = BIT(IIO_EV_INFO_VALUE) |
238 BIT(IIO_EV_INFO_ENABLE),
239 },
240 };
241
242 static const struct iio_chan_spec apds9306_channels_with_events[] = {
243 {
244 .type = IIO_LIGHT,
245 .info_mask_shared_by_all = BIT(IIO_CHAN_INFO_INT_TIME) |
246 BIT(IIO_CHAN_INFO_SAMP_FREQ),
247 .info_mask_shared_by_all_available = BIT(IIO_CHAN_INFO_INT_TIME) |
248 BIT(IIO_CHAN_INFO_SAMP_FREQ),
249 .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
250 BIT(IIO_CHAN_INFO_SCALE),
251 .info_mask_separate_available = BIT(IIO_CHAN_INFO_SCALE),
252 .event_spec = apds9306_event_spec,
253 .num_event_specs = ARRAY_SIZE(apds9306_event_spec),
254 }, {
255 .type = IIO_INTENSITY,
256 .info_mask_shared_by_all = BIT(IIO_CHAN_INFO_INT_TIME) |
257 BIT(IIO_CHAN_INFO_SAMP_FREQ),
258 .info_mask_shared_by_all_available = BIT(IIO_CHAN_INFO_INT_TIME) |
259 BIT(IIO_CHAN_INFO_SAMP_FREQ),
260 .channel2 = IIO_MOD_LIGHT_CLEAR,
261 .info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
262 .modified = 1,
263 .event_spec = apds9306_event_spec,
264 .num_event_specs = ARRAY_SIZE(apds9306_event_spec),
265 },
266 };
267
268 static const struct iio_chan_spec apds9306_channels_without_events[] = {
269 {
270 .type = IIO_LIGHT,
271 .info_mask_shared_by_all = BIT(IIO_CHAN_INFO_INT_TIME) |
272 BIT(IIO_CHAN_INFO_SAMP_FREQ),
273 .info_mask_shared_by_all_available = BIT(IIO_CHAN_INFO_INT_TIME) |
274 BIT(IIO_CHAN_INFO_SAMP_FREQ),
275 .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
276 BIT(IIO_CHAN_INFO_SCALE),
277 .info_mask_separate_available = BIT(IIO_CHAN_INFO_SCALE),
278 }, {
279 .type = IIO_INTENSITY,
280 .info_mask_shared_by_all = BIT(IIO_CHAN_INFO_INT_TIME) |
281 BIT(IIO_CHAN_INFO_SAMP_FREQ),
282 .info_mask_shared_by_all_available = BIT(IIO_CHAN_INFO_INT_TIME) |
283 BIT(IIO_CHAN_INFO_SAMP_FREQ),
284 .info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
285 .modified = 1,
286 .channel2 = IIO_MOD_LIGHT_CLEAR,
287 },
288 };
289
290 /* INT_PERSISTENCE available */
291 static IIO_CONST_ATTR(thresh_either_period_available, "[0 1 15]");
292
293 /* ALS_THRESH_VAR available */
294 static IIO_CONST_ATTR(thresh_adaptive_either_values_available, "[0 1 7]");
295
296 static struct attribute *apds9306_event_attributes[] = {
297 &iio_const_attr_thresh_either_period_available.dev_attr.attr,
298 &iio_const_attr_thresh_adaptive_either_values_available.dev_attr.attr,
299 NULL
300 };
301
302 static const struct attribute_group apds9306_event_attr_group = {
303 .attrs = apds9306_event_attributes,
304 };
305
306 static const struct regmap_range apds9306_readable_ranges[] = {
307 regmap_reg_range(APDS9306_MAIN_CTRL_REG, APDS9306_ALS_THRES_VAR_REG)
308 };
309
310 static const struct regmap_range apds9306_writable_ranges[] = {
311 regmap_reg_range(APDS9306_MAIN_CTRL_REG, APDS9306_ALS_GAIN_REG),
312 regmap_reg_range(APDS9306_INT_CFG_REG, APDS9306_ALS_THRES_VAR_REG)
313 };
314
315 static const struct regmap_range apds9306_volatile_ranges[] = {
316 regmap_reg_range(APDS9306_MAIN_STATUS_REG, APDS9306_MAIN_STATUS_REG),
317 regmap_reg_range(APDS9306_CLEAR_DATA_0_REG, APDS9306_ALS_DATA_2_REG)
318 };
319
320 static const struct regmap_range apds9306_precious_ranges[] = {
321 regmap_reg_range(APDS9306_MAIN_STATUS_REG, APDS9306_MAIN_STATUS_REG)
322 };
323
324 static const struct regmap_access_table apds9306_readable_table = {
325 .yes_ranges = apds9306_readable_ranges,
326 .n_yes_ranges = ARRAY_SIZE(apds9306_readable_ranges)
327 };
328
329 static const struct regmap_access_table apds9306_writable_table = {
330 .yes_ranges = apds9306_writable_ranges,
331 .n_yes_ranges = ARRAY_SIZE(apds9306_writable_ranges)
332 };
333
334 static const struct regmap_access_table apds9306_volatile_table = {
335 .yes_ranges = apds9306_volatile_ranges,
336 .n_yes_ranges = ARRAY_SIZE(apds9306_volatile_ranges)
337 };
338
339 static const struct regmap_access_table apds9306_precious_table = {
340 .yes_ranges = apds9306_precious_ranges,
341 .n_yes_ranges = ARRAY_SIZE(apds9306_precious_ranges)
342 };
343
344 static const struct regmap_config apds9306_regmap = {
345 .name = "apds9306_regmap",
346 .reg_bits = 8,
347 .val_bits = 8,
348 .rd_table = &apds9306_readable_table,
349 .wr_table = &apds9306_writable_table,
350 .volatile_table = &apds9306_volatile_table,
351 .precious_table = &apds9306_precious_table,
352 .max_register = APDS9306_ALS_THRES_VAR_REG,
353 .cache_type = REGCACHE_RBTREE,
354 };
355
356 static const struct reg_field apds9306_rf_sw_reset =
357 REG_FIELD(APDS9306_MAIN_CTRL_REG, 4, 4);
358
359 static const struct reg_field apds9306_rf_en =
360 REG_FIELD(APDS9306_MAIN_CTRL_REG, 1, 1);
361
362 static const struct reg_field apds9306_rf_intg_time =
363 REG_FIELD(APDS9306_ALS_MEAS_RATE_REG, 4, 6);
364
365 static const struct reg_field apds9306_rf_repeat_rate =
366 REG_FIELD(APDS9306_ALS_MEAS_RATE_REG, 0, 2);
367
368 static const struct reg_field apds9306_rf_gain =
369 REG_FIELD(APDS9306_ALS_GAIN_REG, 0, 2);
370
371 static const struct reg_field apds9306_rf_int_src =
372 REG_FIELD(APDS9306_INT_CFG_REG, 4, 5);
373
374 static const struct reg_field apds9306_rf_int_thresh_var_en =
375 REG_FIELD(APDS9306_INT_CFG_REG, 3, 3);
376
377 static const struct reg_field apds9306_rf_int_en =
378 REG_FIELD(APDS9306_INT_CFG_REG, 2, 2);
379
380 static const struct reg_field apds9306_rf_int_persist_val =
381 REG_FIELD(APDS9306_INT_PERSISTENCE_REG, 4, 7);
382
383 static const struct reg_field apds9306_rf_int_thresh_var_val =
384 REG_FIELD(APDS9306_ALS_THRES_VAR_REG, 0, 2);
385
apds9306_regfield_init(struct apds9306_data * data)386 static int apds9306_regfield_init(struct apds9306_data *data)
387 {
388 struct device *dev = data->dev;
389 struct regmap *regmap = data->regmap;
390 struct regmap_field *tmp;
391 struct apds9306_regfields *rf = &data->rf;
392
393 tmp = devm_regmap_field_alloc(dev, regmap, apds9306_rf_sw_reset);
394 if (IS_ERR(tmp))
395 return PTR_ERR(tmp);
396 rf->sw_reset = tmp;
397
398 tmp = devm_regmap_field_alloc(dev, regmap, apds9306_rf_en);
399 if (IS_ERR(tmp))
400 return PTR_ERR(tmp);
401 rf->en = tmp;
402
403 tmp = devm_regmap_field_alloc(dev, regmap, apds9306_rf_intg_time);
404 if (IS_ERR(tmp))
405 return PTR_ERR(tmp);
406 rf->intg_time = tmp;
407
408 tmp = devm_regmap_field_alloc(dev, regmap, apds9306_rf_repeat_rate);
409 if (IS_ERR(tmp))
410 return PTR_ERR(tmp);
411 rf->repeat_rate = tmp;
412
413 tmp = devm_regmap_field_alloc(dev, regmap, apds9306_rf_gain);
414 if (IS_ERR(tmp))
415 return PTR_ERR(tmp);
416 rf->gain = tmp;
417
418 tmp = devm_regmap_field_alloc(dev, regmap, apds9306_rf_int_src);
419 if (IS_ERR(tmp))
420 return PTR_ERR(tmp);
421 rf->int_src = tmp;
422
423 tmp = devm_regmap_field_alloc(dev, regmap, apds9306_rf_int_thresh_var_en);
424 if (IS_ERR(tmp))
425 return PTR_ERR(tmp);
426 rf->int_thresh_var_en = tmp;
427
428 tmp = devm_regmap_field_alloc(dev, regmap, apds9306_rf_int_en);
429 if (IS_ERR(tmp))
430 return PTR_ERR(tmp);
431 rf->int_en = tmp;
432
433 tmp = devm_regmap_field_alloc(dev, regmap, apds9306_rf_int_persist_val);
434 if (IS_ERR(tmp))
435 return PTR_ERR(tmp);
436 rf->int_persist_val = tmp;
437
438 tmp = devm_regmap_field_alloc(dev, regmap, apds9306_rf_int_thresh_var_val);
439 if (IS_ERR(tmp))
440 return PTR_ERR(tmp);
441 rf->int_thresh_var_val = tmp;
442
443 return 0;
444 }
445
apds9306_power_state(struct apds9306_data * data,bool state)446 static int apds9306_power_state(struct apds9306_data *data, bool state)
447 {
448 struct apds9306_regfields *rf = &data->rf;
449 int ret;
450
451 /* Reset not included as it causes ugly I2C bus error */
452 if (state) {
453 ret = regmap_field_write(rf->en, 1);
454 if (ret)
455 return ret;
456 /* 5ms wake up time */
457 fsleep(5000);
458 return 0;
459 }
460
461 return regmap_field_write(rf->en, 0);
462 }
463
apds9306_read_data(struct apds9306_data * data,int * val,int reg)464 static int apds9306_read_data(struct apds9306_data *data, int *val, int reg)
465 {
466 struct device *dev = data->dev;
467 struct iio_dev *indio_dev = dev_to_iio_dev(dev);
468 struct apds9306_regfields *rf = &data->rf;
469 u64 ev_code;
470 int ret, delay, intg_time, intg_time_idx, repeat_rate_idx, int_src;
471 int status = 0;
472 u8 buff[3];
473
474 ret = pm_runtime_resume_and_get(data->dev);
475 if (ret)
476 return ret;
477
478 ret = regmap_field_read(rf->intg_time, &intg_time_idx);
479 if (ret)
480 return ret;
481
482 ret = regmap_field_read(rf->repeat_rate, &repeat_rate_idx);
483 if (ret)
484 return ret;
485
486 ret = regmap_field_read(rf->int_src, &int_src);
487 if (ret)
488 return ret;
489
490 intg_time = iio_gts_find_int_time_by_sel(&data->gts, intg_time_idx);
491 if (intg_time < 0)
492 return intg_time;
493
494 /* Whichever is greater - integration time period or sampling period. */
495 delay = max(intg_time, apds9306_repeat_rate_period[repeat_rate_idx]);
496
497 /*
498 * Clear stale data flag that might have been set by the interrupt
499 * handler if it got data available flag set in the status reg.
500 */
501 data->read_data_available = 0;
502
503 /*
504 * If this function runs parallel with the interrupt handler, either
505 * this reads and clears the status registers or the interrupt handler
506 * does. The interrupt handler sets a flag for read data available
507 * in our private structure which we read here.
508 */
509 ret = regmap_read_poll_timeout(data->regmap, APDS9306_MAIN_STATUS_REG,
510 status, data->read_data_available ||
511 (status & (APDS9306_ALS_DATA_STAT_MASK |
512 APDS9306_ALS_INT_STAT_MASK)),
513 APDS9306_ALS_READ_DATA_DELAY_US, delay * 2);
514 if (ret)
515 return ret;
516
517 /* If we reach here before the interrupt handler we push an event */
518 if ((status & APDS9306_ALS_INT_STAT_MASK)) {
519 if (int_src == APDS9306_INT_SRC_ALS)
520 ev_code = IIO_UNMOD_EVENT_CODE(IIO_LIGHT, 0,
521 IIO_EV_TYPE_THRESH,
522 IIO_EV_DIR_EITHER);
523 else
524 ev_code = IIO_MOD_EVENT_CODE(IIO_INTENSITY, 0,
525 IIO_MOD_LIGHT_CLEAR,
526 IIO_EV_TYPE_THRESH,
527 IIO_EV_DIR_EITHER);
528
529 iio_push_event(indio_dev, ev_code, iio_get_time_ns(indio_dev));
530 }
531
532 ret = regmap_bulk_read(data->regmap, reg, buff, sizeof(buff));
533 if (ret) {
534 dev_err_ratelimited(dev, "read data failed\n");
535 return ret;
536 }
537
538 *val = get_unaligned_le24(&buff);
539
540 pm_runtime_mark_last_busy(data->dev);
541 pm_runtime_put_autosuspend(data->dev);
542
543 return 0;
544 }
545
apds9306_intg_time_get(struct apds9306_data * data,int * val2)546 static int apds9306_intg_time_get(struct apds9306_data *data, int *val2)
547 {
548 struct apds9306_regfields *rf = &data->rf;
549 int ret, intg_time_idx;
550
551 ret = regmap_field_read(rf->intg_time, &intg_time_idx);
552 if (ret)
553 return ret;
554
555 ret = iio_gts_find_int_time_by_sel(&data->gts, intg_time_idx);
556 if (ret < 0)
557 return ret;
558
559 *val2 = ret;
560
561 return 0;
562 }
563
apds9306_intg_time_set(struct apds9306_data * data,int val2)564 static int apds9306_intg_time_set(struct apds9306_data *data, int val2)
565 {
566 struct device *dev = data->dev;
567 struct apds9306_regfields *rf = &data->rf;
568 int ret, intg_old, gain_old, gain_new, gain_new_closest, intg_time_idx;
569 int gain_idx;
570 bool ok;
571
572 if (!iio_gts_valid_time(&data->gts, val2)) {
573 dev_err_ratelimited(dev, "Unsupported integration time %u\n", val2);
574 return -EINVAL;
575 }
576
577 ret = regmap_field_read(rf->intg_time, &intg_time_idx);
578 if (ret)
579 return ret;
580
581 ret = regmap_field_read(rf->gain, &gain_idx);
582 if (ret)
583 return ret;
584
585 intg_old = iio_gts_find_int_time_by_sel(&data->gts, intg_time_idx);
586 if (intg_old < 0)
587 return intg_old;
588
589 if (intg_old == val2)
590 return 0;
591
592 gain_old = iio_gts_find_gain_by_sel(&data->gts, gain_idx);
593 if (gain_old < 0)
594 return gain_old;
595
596 iio_gts_find_new_gain_by_old_gain_time(&data->gts, gain_old, intg_old,
597 val2, &gain_new);
598
599 if (gain_new < 0) {
600 dev_err_ratelimited(dev, "Unsupported gain with time\n");
601 return gain_new;
602 }
603
604 gain_new_closest = iio_find_closest_gain_low(&data->gts, gain_new, &ok);
605 if (gain_new_closest < 0) {
606 gain_new_closest = iio_gts_get_min_gain(&data->gts);
607 if (gain_new_closest < 0)
608 return gain_new_closest;
609 }
610 if (!ok)
611 dev_dbg(dev, "Unable to find optimum gain, setting minimum");
612
613 ret = iio_gts_find_sel_by_int_time(&data->gts, val2);
614 if (ret < 0)
615 return ret;
616
617 ret = regmap_field_write(rf->intg_time, ret);
618 if (ret)
619 return ret;
620
621 ret = iio_gts_find_sel_by_gain(&data->gts, gain_new_closest);
622 if (ret < 0)
623 return ret;
624
625 return regmap_field_write(rf->gain, ret);
626 }
627
apds9306_sampling_freq_get(struct apds9306_data * data,int * val,int * val2)628 static int apds9306_sampling_freq_get(struct apds9306_data *data, int *val,
629 int *val2)
630 {
631 struct apds9306_regfields *rf = &data->rf;
632 int ret, repeat_rate_idx;
633
634 ret = regmap_field_read(rf->repeat_rate, &repeat_rate_idx);
635 if (ret)
636 return ret;
637
638 if (repeat_rate_idx >= ARRAY_SIZE(apds9306_repeat_rate_freq))
639 return -EINVAL;
640
641 *val = apds9306_repeat_rate_freq[repeat_rate_idx][0];
642 *val2 = apds9306_repeat_rate_freq[repeat_rate_idx][1];
643
644 return 0;
645 }
646
apds9306_sampling_freq_set(struct apds9306_data * data,int val,int val2)647 static int apds9306_sampling_freq_set(struct apds9306_data *data, int val,
648 int val2)
649 {
650 struct apds9306_regfields *rf = &data->rf;
651 int i;
652
653 for (i = 0; i < ARRAY_SIZE(apds9306_repeat_rate_freq); i++) {
654 if (apds9306_repeat_rate_freq[i][0] == val &&
655 apds9306_repeat_rate_freq[i][1] == val2)
656 return regmap_field_write(rf->repeat_rate, i);
657 }
658
659 return -EINVAL;
660 }
661
apds9306_scale_get(struct apds9306_data * data,int * val,int * val2)662 static int apds9306_scale_get(struct apds9306_data *data, int *val, int *val2)
663 {
664 struct apds9306_regfields *rf = &data->rf;
665 int gain, intg, ret, intg_time_idx, gain_idx;
666
667 ret = regmap_field_read(rf->gain, &gain_idx);
668 if (ret)
669 return ret;
670
671 ret = regmap_field_read(rf->intg_time, &intg_time_idx);
672 if (ret)
673 return ret;
674
675 gain = iio_gts_find_gain_by_sel(&data->gts, gain_idx);
676 if (gain < 0)
677 return gain;
678
679 intg = iio_gts_find_int_time_by_sel(&data->gts, intg_time_idx);
680 if (intg < 0)
681 return intg;
682
683 return iio_gts_get_scale(&data->gts, gain, intg, val, val2);
684 }
685
apds9306_scale_set(struct apds9306_data * data,int val,int val2)686 static int apds9306_scale_set(struct apds9306_data *data, int val, int val2)
687 {
688 struct apds9306_regfields *rf = &data->rf;
689 int i, ret, time_sel, gain_sel, intg_time_idx;
690
691 ret = regmap_field_read(rf->intg_time, &intg_time_idx);
692 if (ret)
693 return ret;
694
695 ret = iio_gts_find_gain_sel_for_scale_using_time(&data->gts,
696 intg_time_idx, val, val2, &gain_sel);
697 if (ret) {
698 for (i = 0; i < data->gts.num_itime; i++) {
699 time_sel = data->gts.itime_table[i].sel;
700
701 if (time_sel == intg_time_idx)
702 continue;
703
704 ret = iio_gts_find_gain_sel_for_scale_using_time(&data->gts,
705 time_sel, val, val2, &gain_sel);
706 if (!ret)
707 break;
708 }
709 if (ret)
710 return -EINVAL;
711
712 ret = regmap_field_write(rf->intg_time, time_sel);
713 if (ret)
714 return ret;
715 }
716
717 return regmap_field_write(rf->gain, gain_sel);
718 }
719
apds9306_event_period_get(struct apds9306_data * data,int * val)720 static int apds9306_event_period_get(struct apds9306_data *data, int *val)
721 {
722 struct apds9306_regfields *rf = &data->rf;
723 int period, ret;
724
725 ret = regmap_field_read(rf->int_persist_val, &period);
726 if (ret)
727 return ret;
728
729 if (!in_range(period, 0, APDS9306_ALS_PERSIST_NUM_VALS))
730 return -EINVAL;
731
732 *val = period;
733
734 return ret;
735 }
736
apds9306_event_period_set(struct apds9306_data * data,int val)737 static int apds9306_event_period_set(struct apds9306_data *data, int val)
738 {
739 struct apds9306_regfields *rf = &data->rf;
740
741 if (!in_range(val, 0, APDS9306_ALS_PERSIST_NUM_VALS))
742 return -EINVAL;
743
744 return regmap_field_write(rf->int_persist_val, val);
745 }
746
apds9306_event_thresh_get(struct apds9306_data * data,int dir,int * val)747 static int apds9306_event_thresh_get(struct apds9306_data *data, int dir,
748 int *val)
749 {
750 int var, ret;
751 u8 buff[3];
752
753 if (dir == IIO_EV_DIR_RISING)
754 var = APDS9306_ALS_THRES_UP_0_REG;
755 else if (dir == IIO_EV_DIR_FALLING)
756 var = APDS9306_ALS_THRES_LOW_0_REG;
757 else
758 return -EINVAL;
759
760 ret = regmap_bulk_read(data->regmap, var, buff, sizeof(buff));
761 if (ret)
762 return ret;
763
764 *val = get_unaligned_le24(&buff);
765
766 return 0;
767 }
768
apds9306_event_thresh_set(struct apds9306_data * data,int dir,int val)769 static int apds9306_event_thresh_set(struct apds9306_data *data, int dir,
770 int val)
771 {
772 int var;
773 u8 buff[3];
774
775 if (dir == IIO_EV_DIR_RISING)
776 var = APDS9306_ALS_THRES_UP_0_REG;
777 else if (dir == IIO_EV_DIR_FALLING)
778 var = APDS9306_ALS_THRES_LOW_0_REG;
779 else
780 return -EINVAL;
781
782 if (!in_range(val, 0, APDS9306_ALS_THRES_VAL_MAX))
783 return -EINVAL;
784
785 put_unaligned_le24(val, buff);
786
787 return regmap_bulk_write(data->regmap, var, buff, sizeof(buff));
788 }
789
apds9306_event_thresh_adaptive_get(struct apds9306_data * data,int * val)790 static int apds9306_event_thresh_adaptive_get(struct apds9306_data *data, int *val)
791 {
792 struct apds9306_regfields *rf = &data->rf;
793 int thr_adpt, ret;
794
795 ret = regmap_field_read(rf->int_thresh_var_val, &thr_adpt);
796 if (ret)
797 return ret;
798
799 if (!in_range(thr_adpt, 0, APDS9306_ALS_THRES_VAR_NUM_VALS))
800 return -EINVAL;
801
802 *val = thr_adpt;
803
804 return ret;
805 }
806
apds9306_event_thresh_adaptive_set(struct apds9306_data * data,int val)807 static int apds9306_event_thresh_adaptive_set(struct apds9306_data *data, int val)
808 {
809 struct apds9306_regfields *rf = &data->rf;
810
811 if (!in_range(val, 0, APDS9306_ALS_THRES_VAR_NUM_VALS))
812 return -EINVAL;
813
814 return regmap_field_write(rf->int_thresh_var_val, val);
815 }
816
apds9306_read_raw(struct iio_dev * indio_dev,struct iio_chan_spec const * chan,int * val,int * val2,long mask)817 static int apds9306_read_raw(struct iio_dev *indio_dev,
818 struct iio_chan_spec const *chan, int *val,
819 int *val2, long mask)
820 {
821 struct apds9306_data *data = iio_priv(indio_dev);
822 int ret, reg;
823
824 switch (mask) {
825 case IIO_CHAN_INFO_RAW:
826 if (chan->channel2 == IIO_MOD_LIGHT_CLEAR)
827 reg = APDS9306_CLEAR_DATA_0_REG;
828 else
829 reg = APDS9306_ALS_DATA_0_REG;
830 /*
831 * Changing device parameters during adc operation, resets
832 * the ADC which has to avoided.
833 */
834 ret = iio_device_claim_direct_mode(indio_dev);
835 if (ret)
836 return ret;
837 ret = apds9306_read_data(data, val, reg);
838 iio_device_release_direct_mode(indio_dev);
839 if (ret)
840 return ret;
841
842 return IIO_VAL_INT;
843 case IIO_CHAN_INFO_INT_TIME:
844 ret = apds9306_intg_time_get(data, val2);
845 if (ret)
846 return ret;
847 *val = 0;
848
849 return IIO_VAL_INT_PLUS_MICRO;
850 case IIO_CHAN_INFO_SAMP_FREQ:
851 ret = apds9306_sampling_freq_get(data, val, val2);
852 if (ret)
853 return ret;
854
855 return IIO_VAL_INT_PLUS_MICRO;
856 case IIO_CHAN_INFO_SCALE:
857 ret = apds9306_scale_get(data, val, val2);
858 if (ret)
859 return ret;
860
861 return IIO_VAL_INT_PLUS_NANO;
862 default:
863 return -EINVAL;
864 }
865 };
866
apds9306_read_avail(struct iio_dev * indio_dev,struct iio_chan_spec const * chan,const int ** vals,int * type,int * length,long mask)867 static int apds9306_read_avail(struct iio_dev *indio_dev,
868 struct iio_chan_spec const *chan,
869 const int **vals, int *type, int *length,
870 long mask)
871 {
872 struct apds9306_data *data = iio_priv(indio_dev);
873
874 switch (mask) {
875 case IIO_CHAN_INFO_INT_TIME:
876 return iio_gts_avail_times(&data->gts, vals, type, length);
877 case IIO_CHAN_INFO_SCALE:
878 return iio_gts_all_avail_scales(&data->gts, vals, type, length);
879 case IIO_CHAN_INFO_SAMP_FREQ:
880 *length = ARRAY_SIZE(apds9306_repeat_rate_freq) * 2;
881 *vals = (const int *)apds9306_repeat_rate_freq;
882 *type = IIO_VAL_INT_PLUS_MICRO;
883
884 return IIO_AVAIL_LIST;
885 default:
886 return -EINVAL;
887 }
888 }
889
apds9306_write_raw_get_fmt(struct iio_dev * indio_dev,struct iio_chan_spec const * chan,long mask)890 static int apds9306_write_raw_get_fmt(struct iio_dev *indio_dev,
891 struct iio_chan_spec const *chan,
892 long mask)
893 {
894 switch (mask) {
895 case IIO_CHAN_INFO_SCALE:
896 return IIO_VAL_INT_PLUS_NANO;
897 case IIO_CHAN_INFO_INT_TIME:
898 return IIO_VAL_INT_PLUS_MICRO;
899 case IIO_CHAN_INFO_SAMP_FREQ:
900 return IIO_VAL_INT_PLUS_MICRO;
901 default:
902 return -EINVAL;
903 }
904 }
905
apds9306_write_raw(struct iio_dev * indio_dev,struct iio_chan_spec const * chan,int val,int val2,long mask)906 static int apds9306_write_raw(struct iio_dev *indio_dev,
907 struct iio_chan_spec const *chan, int val,
908 int val2, long mask)
909 {
910 struct apds9306_data *data = iio_priv(indio_dev);
911
912 guard(mutex)(&data->mutex);
913
914 switch (mask) {
915 case IIO_CHAN_INFO_INT_TIME:
916 if (val)
917 return -EINVAL;
918 return apds9306_intg_time_set(data, val2);
919 case IIO_CHAN_INFO_SCALE:
920 return apds9306_scale_set(data, val, val2);
921 case IIO_CHAN_INFO_SAMP_FREQ:
922 return apds9306_sampling_freq_set(data, val, val2);
923 default:
924 return -EINVAL;
925 }
926 }
927
apds9306_irq_handler(int irq,void * priv)928 static irqreturn_t apds9306_irq_handler(int irq, void *priv)
929 {
930 struct iio_dev *indio_dev = priv;
931 struct apds9306_data *data = iio_priv(indio_dev);
932 struct apds9306_regfields *rf = &data->rf;
933 u64 ev_code;
934 int ret, status, int_src;
935
936 /*
937 * The interrupt line is released and the interrupt flag is
938 * cleared as a result of reading the status register. All the
939 * status flags are cleared as a result of this read.
940 */
941 ret = regmap_read(data->regmap, APDS9306_MAIN_STATUS_REG, &status);
942 if (ret < 0) {
943 dev_err_ratelimited(data->dev, "status reg read failed\n");
944 return IRQ_HANDLED;
945 }
946
947 ret = regmap_field_read(rf->int_src, &int_src);
948 if (ret)
949 return ret;
950
951 if ((status & APDS9306_ALS_INT_STAT_MASK)) {
952 if (int_src == APDS9306_INT_SRC_ALS)
953 ev_code = IIO_UNMOD_EVENT_CODE(IIO_LIGHT, 0,
954 IIO_EV_TYPE_THRESH,
955 IIO_EV_DIR_EITHER);
956 else
957 ev_code = IIO_MOD_EVENT_CODE(IIO_INTENSITY, 0,
958 IIO_MOD_LIGHT_CLEAR,
959 IIO_EV_TYPE_THRESH,
960 IIO_EV_DIR_EITHER);
961
962 iio_push_event(indio_dev, ev_code, iio_get_time_ns(indio_dev));
963 }
964
965 /*
966 * If a one-shot read through sysfs is underway at the same time
967 * as this interrupt handler is executing and a read data available
968 * flag was set, this flag is set to inform read_poll_timeout()
969 * to exit.
970 */
971 if ((status & APDS9306_ALS_DATA_STAT_MASK))
972 data->read_data_available = 1;
973
974 return IRQ_HANDLED;
975 }
976
apds9306_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)977 static int apds9306_read_event(struct iio_dev *indio_dev,
978 const struct iio_chan_spec *chan,
979 enum iio_event_type type,
980 enum iio_event_direction dir,
981 enum iio_event_info info,
982 int *val, int *val2)
983 {
984 struct apds9306_data *data = iio_priv(indio_dev);
985 int ret;
986
987 switch (type) {
988 case IIO_EV_TYPE_THRESH:
989 if (dir == IIO_EV_DIR_EITHER && info == IIO_EV_INFO_PERIOD)
990 ret = apds9306_event_period_get(data, val);
991 else
992 ret = apds9306_event_thresh_get(data, dir, val);
993 if (ret)
994 return ret;
995
996 return IIO_VAL_INT;
997 case IIO_EV_TYPE_THRESH_ADAPTIVE:
998 ret = apds9306_event_thresh_adaptive_get(data, val);
999 if (ret)
1000 return ret;
1001
1002 return IIO_VAL_INT;
1003 default:
1004 return -EINVAL;
1005 }
1006 }
1007
apds9306_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)1008 static int apds9306_write_event(struct iio_dev *indio_dev,
1009 const struct iio_chan_spec *chan,
1010 enum iio_event_type type,
1011 enum iio_event_direction dir,
1012 enum iio_event_info info,
1013 int val, int val2)
1014 {
1015 struct apds9306_data *data = iio_priv(indio_dev);
1016
1017 switch (type) {
1018 case IIO_EV_TYPE_THRESH:
1019 if (dir == IIO_EV_DIR_EITHER && info == IIO_EV_INFO_PERIOD)
1020 return apds9306_event_period_set(data, val);
1021
1022 return apds9306_event_thresh_set(data, dir, val);
1023 case IIO_EV_TYPE_THRESH_ADAPTIVE:
1024 return apds9306_event_thresh_adaptive_set(data, val);
1025 default:
1026 return -EINVAL;
1027 }
1028 }
1029
apds9306_read_event_config(struct iio_dev * indio_dev,const struct iio_chan_spec * chan,enum iio_event_type type,enum iio_event_direction dir)1030 static int apds9306_read_event_config(struct iio_dev *indio_dev,
1031 const struct iio_chan_spec *chan,
1032 enum iio_event_type type,
1033 enum iio_event_direction dir)
1034 {
1035 struct apds9306_data *data = iio_priv(indio_dev);
1036 struct apds9306_regfields *rf = &data->rf;
1037 int int_en, int_src, ret;
1038
1039 switch (type) {
1040 case IIO_EV_TYPE_THRESH: {
1041 guard(mutex)(&data->mutex);
1042
1043 ret = regmap_field_read(rf->int_src, &int_src);
1044 if (ret)
1045 return ret;
1046
1047 ret = regmap_field_read(rf->int_en, &int_en);
1048 if (ret)
1049 return ret;
1050
1051 if (chan->type == IIO_LIGHT)
1052 return int_en && (int_src == APDS9306_INT_SRC_ALS);
1053
1054 if (chan->type == IIO_INTENSITY)
1055 return int_en && (int_src == APDS9306_INT_SRC_CLEAR);
1056
1057 return -EINVAL;
1058 }
1059 case IIO_EV_TYPE_THRESH_ADAPTIVE:
1060 ret = regmap_field_read(rf->int_thresh_var_en, &int_en);
1061 if (ret)
1062 return ret;
1063
1064 return int_en;
1065 default:
1066 return -EINVAL;
1067 }
1068 }
1069
apds9306_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)1070 static int apds9306_write_event_config(struct iio_dev *indio_dev,
1071 const struct iio_chan_spec *chan,
1072 enum iio_event_type type,
1073 enum iio_event_direction dir,
1074 bool state)
1075 {
1076 struct apds9306_data *data = iio_priv(indio_dev);
1077 struct apds9306_regfields *rf = &data->rf;
1078 int ret, enabled;
1079
1080 switch (type) {
1081 case IIO_EV_TYPE_THRESH: {
1082 guard(mutex)(&data->mutex);
1083
1084 ret = regmap_field_read(rf->int_en, &enabled);
1085 if (ret)
1086 return ret;
1087
1088 /*
1089 * If interrupt is enabled, the channel is set before enabling
1090 * the interrupt. In case of disable, no need to switch
1091 * channels. In case of different channel is selected while
1092 * interrupt in on, just change the channel.
1093 */
1094 if (state) {
1095 if (chan->type == IIO_LIGHT)
1096 ret = regmap_field_write(rf->int_src, 1);
1097 else if (chan->type == IIO_INTENSITY)
1098 ret = regmap_field_write(rf->int_src, 0);
1099 else
1100 return -EINVAL;
1101
1102 if (ret)
1103 return ret;
1104
1105 if (enabled)
1106 return 0;
1107
1108 ret = regmap_field_write(rf->int_en, 1);
1109 if (ret)
1110 return ret;
1111
1112 return pm_runtime_resume_and_get(data->dev);
1113 } else {
1114 if (!enabled)
1115 return 0;
1116
1117 ret = regmap_field_write(rf->int_en, 0);
1118 if (ret)
1119 return ret;
1120
1121 pm_runtime_mark_last_busy(data->dev);
1122 pm_runtime_put_autosuspend(data->dev);
1123
1124 return 0;
1125 }
1126 }
1127 case IIO_EV_TYPE_THRESH_ADAPTIVE:
1128 return regmap_field_write(rf->int_thresh_var_en, state);
1129 default:
1130 return -EINVAL;
1131 }
1132 }
1133
1134 static const struct iio_info apds9306_info_no_events = {
1135 .read_avail = apds9306_read_avail,
1136 .read_raw = apds9306_read_raw,
1137 .write_raw = apds9306_write_raw,
1138 .write_raw_get_fmt = apds9306_write_raw_get_fmt,
1139 };
1140
1141 static const struct iio_info apds9306_info = {
1142 .read_avail = apds9306_read_avail,
1143 .read_raw = apds9306_read_raw,
1144 .write_raw = apds9306_write_raw,
1145 .write_raw_get_fmt = apds9306_write_raw_get_fmt,
1146 .read_event_value = apds9306_read_event,
1147 .write_event_value = apds9306_write_event,
1148 .read_event_config = apds9306_read_event_config,
1149 .write_event_config = apds9306_write_event_config,
1150 .event_attrs = &apds9306_event_attr_group,
1151 };
1152
apds9306_init_iio_gts(struct apds9306_data * data)1153 static int apds9306_init_iio_gts(struct apds9306_data *data)
1154 {
1155 int i, ret, part_id;
1156
1157 ret = regmap_read(data->regmap, APDS9306_PART_ID_REG, &part_id);
1158 if (ret)
1159 return ret;
1160
1161 for (i = 0; i < ARRAY_SIZE(apds9306_gts_mul); i++)
1162 if (part_id == apds9306_gts_mul[i].part_id)
1163 break;
1164
1165 if (i == ARRAY_SIZE(apds9306_gts_mul))
1166 return -ENOENT;
1167
1168 return devm_iio_init_iio_gts(data->dev,
1169 apds9306_gts_mul[i].max_scale_int,
1170 apds9306_gts_mul[i].max_scale_nano,
1171 apds9306_gains, ARRAY_SIZE(apds9306_gains),
1172 apds9306_itimes, ARRAY_SIZE(apds9306_itimes),
1173 &data->gts);
1174 }
1175
apds9306_powerdown(void * ptr)1176 static void apds9306_powerdown(void *ptr)
1177 {
1178 struct apds9306_data *data = (struct apds9306_data *)ptr;
1179 struct apds9306_regfields *rf = &data->rf;
1180 int ret;
1181
1182 ret = regmap_field_write(rf->int_thresh_var_en, 0);
1183 if (ret)
1184 return;
1185
1186 ret = regmap_field_write(rf->int_en, 0);
1187 if (ret)
1188 return;
1189
1190 apds9306_power_state(data, false);
1191 }
1192
apds9306_device_init(struct apds9306_data * data)1193 static int apds9306_device_init(struct apds9306_data *data)
1194 {
1195 struct apds9306_regfields *rf = &data->rf;
1196 int ret;
1197
1198 ret = apds9306_init_iio_gts(data);
1199 if (ret)
1200 return ret;
1201
1202 ret = regmap_field_write(rf->intg_time, APDS9306_MEAS_MODE_100MS);
1203 if (ret)
1204 return ret;
1205
1206 ret = regmap_field_write(rf->repeat_rate, APDS9306_SAMP_FREQ_10HZ);
1207 if (ret)
1208 return ret;
1209
1210 ret = regmap_field_write(rf->gain, APDS9306_GSEL_3X);
1211 if (ret)
1212 return ret;
1213
1214 ret = regmap_field_write(rf->int_src, APDS9306_INT_SRC_ALS);
1215 if (ret)
1216 return ret;
1217
1218 ret = regmap_field_write(rf->int_en, 0);
1219 if (ret)
1220 return ret;
1221
1222 return regmap_field_write(rf->int_thresh_var_en, 0);
1223 }
1224
apds9306_pm_init(struct apds9306_data * data)1225 static int apds9306_pm_init(struct apds9306_data *data)
1226 {
1227 struct device *dev = data->dev;
1228 int ret;
1229
1230 ret = apds9306_power_state(data, true);
1231 if (ret)
1232 return ret;
1233
1234 ret = pm_runtime_set_active(dev);
1235 if (ret)
1236 return ret;
1237
1238 ret = devm_pm_runtime_enable(dev);
1239 if (ret)
1240 return ret;
1241
1242 pm_runtime_set_autosuspend_delay(dev, 5000);
1243 pm_runtime_use_autosuspend(dev);
1244 pm_runtime_get(dev);
1245
1246 return 0;
1247 }
1248
apds9306_probe(struct i2c_client * client)1249 static int apds9306_probe(struct i2c_client *client)
1250 {
1251 struct device *dev = &client->dev;
1252 struct apds9306_data *data;
1253 struct iio_dev *indio_dev;
1254 int ret;
1255
1256 indio_dev = devm_iio_device_alloc(dev, sizeof(*data));
1257 if (!indio_dev)
1258 return -ENOMEM;
1259
1260 data = iio_priv(indio_dev);
1261
1262 mutex_init(&data->mutex);
1263
1264 data->regmap = devm_regmap_init_i2c(client, &apds9306_regmap);
1265 if (IS_ERR(data->regmap))
1266 return dev_err_probe(dev, PTR_ERR(data->regmap),
1267 "regmap initialization failed\n");
1268
1269 data->dev = dev;
1270 i2c_set_clientdata(client, indio_dev);
1271
1272 ret = apds9306_regfield_init(data);
1273 if (ret)
1274 return dev_err_probe(dev, ret, "regfield initialization failed\n");
1275
1276 ret = devm_regulator_get_enable(dev, "vdd");
1277 if (ret)
1278 return dev_err_probe(dev, ret, "Failed to enable regulator\n");
1279
1280 indio_dev->name = "apds9306";
1281 indio_dev->modes = INDIO_DIRECT_MODE;
1282 if (client->irq) {
1283 indio_dev->info = &apds9306_info;
1284 indio_dev->channels = apds9306_channels_with_events;
1285 indio_dev->num_channels = ARRAY_SIZE(apds9306_channels_with_events);
1286 ret = devm_request_threaded_irq(dev, client->irq, NULL,
1287 apds9306_irq_handler, IRQF_ONESHOT,
1288 "apds9306_event", indio_dev);
1289 if (ret)
1290 return dev_err_probe(dev, ret,
1291 "failed to assign interrupt.\n");
1292 } else {
1293 indio_dev->info = &apds9306_info_no_events;
1294 indio_dev->channels = apds9306_channels_without_events;
1295 indio_dev->num_channels =
1296 ARRAY_SIZE(apds9306_channels_without_events);
1297 }
1298
1299 ret = apds9306_pm_init(data);
1300 if (ret)
1301 return dev_err_probe(dev, ret, "failed pm init\n");
1302
1303 ret = apds9306_device_init(data);
1304 if (ret)
1305 return dev_err_probe(dev, ret, "failed to init device\n");
1306
1307 ret = devm_add_action_or_reset(dev, apds9306_powerdown, data);
1308 if (ret)
1309 return dev_err_probe(dev, ret, "failed to add action or reset\n");
1310
1311 ret = devm_iio_device_register(dev, indio_dev);
1312 if (ret)
1313 return dev_err_probe(dev, ret, "failed iio device registration\n");
1314
1315 pm_runtime_put_autosuspend(dev);
1316
1317 return 0;
1318 }
1319
apds9306_runtime_suspend(struct device * dev)1320 static int apds9306_runtime_suspend(struct device *dev)
1321 {
1322 struct apds9306_data *data = iio_priv(dev_get_drvdata(dev));
1323
1324 return apds9306_power_state(data, false);
1325 }
1326
apds9306_runtime_resume(struct device * dev)1327 static int apds9306_runtime_resume(struct device *dev)
1328 {
1329 struct apds9306_data *data = iio_priv(dev_get_drvdata(dev));
1330
1331 return apds9306_power_state(data, true);
1332 }
1333
1334 static DEFINE_RUNTIME_DEV_PM_OPS(apds9306_pm_ops,
1335 apds9306_runtime_suspend,
1336 apds9306_runtime_resume,
1337 NULL);
1338
1339 static const struct of_device_id apds9306_of_match[] = {
1340 { .compatible = "avago,apds9306" },
1341 { }
1342 };
1343 MODULE_DEVICE_TABLE(of, apds9306_of_match);
1344
1345 static struct i2c_driver apds9306_driver = {
1346 .driver = {
1347 .name = "apds9306",
1348 .pm = pm_ptr(&apds9306_pm_ops),
1349 .of_match_table = apds9306_of_match,
1350 },
1351 .probe = apds9306_probe,
1352 };
1353 module_i2c_driver(apds9306_driver);
1354
1355 MODULE_AUTHOR("Subhajit Ghosh <subhajit.ghosh@tweaklogic.com>");
1356 MODULE_DESCRIPTION("APDS9306 Ambient Light Sensor driver");
1357 MODULE_LICENSE("GPL");
1358 MODULE_IMPORT_NS("IIO_GTS_HELPER");
1359