xref: /linux/drivers/iio/light/apds9306.c (revision 7ec462100ef9142344ddbf86f2c3008b97acddbe)
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,int 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 				       int 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 		if (state)
1129 			return regmap_field_write(rf->int_thresh_var_en, 1);
1130 		else
1131 			return regmap_field_write(rf->int_thresh_var_en, 0);
1132 	default:
1133 		return -EINVAL;
1134 	}
1135 }
1136 
1137 static const struct iio_info apds9306_info_no_events = {
1138 	.read_avail = apds9306_read_avail,
1139 	.read_raw = apds9306_read_raw,
1140 	.write_raw = apds9306_write_raw,
1141 	.write_raw_get_fmt = apds9306_write_raw_get_fmt,
1142 };
1143 
1144 static const struct iio_info apds9306_info = {
1145 	.read_avail = apds9306_read_avail,
1146 	.read_raw = apds9306_read_raw,
1147 	.write_raw = apds9306_write_raw,
1148 	.write_raw_get_fmt = apds9306_write_raw_get_fmt,
1149 	.read_event_value = apds9306_read_event,
1150 	.write_event_value = apds9306_write_event,
1151 	.read_event_config = apds9306_read_event_config,
1152 	.write_event_config = apds9306_write_event_config,
1153 	.event_attrs = &apds9306_event_attr_group,
1154 };
1155 
apds9306_init_iio_gts(struct apds9306_data * data)1156 static int apds9306_init_iio_gts(struct apds9306_data *data)
1157 {
1158 	int i, ret, part_id;
1159 
1160 	ret = regmap_read(data->regmap, APDS9306_PART_ID_REG, &part_id);
1161 	if (ret)
1162 		return ret;
1163 
1164 	for (i = 0; i < ARRAY_SIZE(apds9306_gts_mul); i++)
1165 		if (part_id == apds9306_gts_mul[i].part_id)
1166 			break;
1167 
1168 	if (i == ARRAY_SIZE(apds9306_gts_mul))
1169 		return -ENOENT;
1170 
1171 	return devm_iio_init_iio_gts(data->dev,
1172 				     apds9306_gts_mul[i].max_scale_int,
1173 				     apds9306_gts_mul[i].max_scale_nano,
1174 				     apds9306_gains, ARRAY_SIZE(apds9306_gains),
1175 				     apds9306_itimes, ARRAY_SIZE(apds9306_itimes),
1176 				     &data->gts);
1177 }
1178 
apds9306_powerdown(void * ptr)1179 static void apds9306_powerdown(void *ptr)
1180 {
1181 	struct apds9306_data *data = (struct apds9306_data *)ptr;
1182 	struct apds9306_regfields *rf = &data->rf;
1183 	int ret;
1184 
1185 	ret = regmap_field_write(rf->int_thresh_var_en, 0);
1186 	if (ret)
1187 		return;
1188 
1189 	ret = regmap_field_write(rf->int_en, 0);
1190 	if (ret)
1191 		return;
1192 
1193 	apds9306_power_state(data, false);
1194 }
1195 
apds9306_device_init(struct apds9306_data * data)1196 static int apds9306_device_init(struct apds9306_data *data)
1197 {
1198 	struct apds9306_regfields *rf = &data->rf;
1199 	int ret;
1200 
1201 	ret = apds9306_init_iio_gts(data);
1202 	if (ret)
1203 		return ret;
1204 
1205 	ret = regmap_field_write(rf->intg_time, APDS9306_MEAS_MODE_100MS);
1206 	if (ret)
1207 		return ret;
1208 
1209 	ret = regmap_field_write(rf->repeat_rate, APDS9306_SAMP_FREQ_10HZ);
1210 	if (ret)
1211 		return ret;
1212 
1213 	ret = regmap_field_write(rf->gain, APDS9306_GSEL_3X);
1214 	if (ret)
1215 		return ret;
1216 
1217 	ret = regmap_field_write(rf->int_src, APDS9306_INT_SRC_ALS);
1218 	if (ret)
1219 		return ret;
1220 
1221 	ret = regmap_field_write(rf->int_en, 0);
1222 	if (ret)
1223 		return ret;
1224 
1225 	return regmap_field_write(rf->int_thresh_var_en, 0);
1226 }
1227 
apds9306_pm_init(struct apds9306_data * data)1228 static int apds9306_pm_init(struct apds9306_data *data)
1229 {
1230 	struct device *dev = data->dev;
1231 	int ret;
1232 
1233 	ret = apds9306_power_state(data, true);
1234 	if (ret)
1235 		return ret;
1236 
1237 	ret = pm_runtime_set_active(dev);
1238 	if (ret)
1239 		return ret;
1240 
1241 	ret = devm_pm_runtime_enable(dev);
1242 	if (ret)
1243 		return ret;
1244 
1245 	pm_runtime_set_autosuspend_delay(dev, 5000);
1246 	pm_runtime_use_autosuspend(dev);
1247 	pm_runtime_get(dev);
1248 
1249 	return 0;
1250 }
1251 
apds9306_probe(struct i2c_client * client)1252 static int apds9306_probe(struct i2c_client *client)
1253 {
1254 	struct device *dev = &client->dev;
1255 	struct apds9306_data *data;
1256 	struct iio_dev *indio_dev;
1257 	int ret;
1258 
1259 	indio_dev = devm_iio_device_alloc(dev, sizeof(*data));
1260 	if (!indio_dev)
1261 		return -ENOMEM;
1262 
1263 	data = iio_priv(indio_dev);
1264 
1265 	mutex_init(&data->mutex);
1266 
1267 	data->regmap = devm_regmap_init_i2c(client, &apds9306_regmap);
1268 	if (IS_ERR(data->regmap))
1269 		return dev_err_probe(dev, PTR_ERR(data->regmap),
1270 				     "regmap initialization failed\n");
1271 
1272 	data->dev = dev;
1273 	i2c_set_clientdata(client, indio_dev);
1274 
1275 	ret = apds9306_regfield_init(data);
1276 	if (ret)
1277 		return dev_err_probe(dev, ret, "regfield initialization failed\n");
1278 
1279 	ret = devm_regulator_get_enable(dev, "vdd");
1280 	if (ret)
1281 		return dev_err_probe(dev, ret, "Failed to enable regulator\n");
1282 
1283 	indio_dev->name = "apds9306";
1284 	indio_dev->modes = INDIO_DIRECT_MODE;
1285 	if (client->irq) {
1286 		indio_dev->info = &apds9306_info;
1287 		indio_dev->channels = apds9306_channels_with_events;
1288 		indio_dev->num_channels = ARRAY_SIZE(apds9306_channels_with_events);
1289 		ret = devm_request_threaded_irq(dev, client->irq, NULL,
1290 						apds9306_irq_handler, IRQF_ONESHOT,
1291 						"apds9306_event", indio_dev);
1292 		if (ret)
1293 			return dev_err_probe(dev, ret,
1294 					     "failed to assign interrupt.\n");
1295 	} else {
1296 		indio_dev->info = &apds9306_info_no_events;
1297 		indio_dev->channels = apds9306_channels_without_events;
1298 		indio_dev->num_channels =
1299 				ARRAY_SIZE(apds9306_channels_without_events);
1300 	}
1301 
1302 	ret = apds9306_pm_init(data);
1303 	if (ret)
1304 		return dev_err_probe(dev, ret, "failed pm init\n");
1305 
1306 	ret = apds9306_device_init(data);
1307 	if (ret)
1308 		return dev_err_probe(dev, ret, "failed to init device\n");
1309 
1310 	ret = devm_add_action_or_reset(dev, apds9306_powerdown, data);
1311 	if (ret)
1312 		return dev_err_probe(dev, ret, "failed to add action or reset\n");
1313 
1314 	ret = devm_iio_device_register(dev, indio_dev);
1315 	if (ret)
1316 		return dev_err_probe(dev, ret, "failed iio device registration\n");
1317 
1318 	pm_runtime_put_autosuspend(dev);
1319 
1320 	return 0;
1321 }
1322 
apds9306_runtime_suspend(struct device * dev)1323 static int apds9306_runtime_suspend(struct device *dev)
1324 {
1325 	struct apds9306_data *data = iio_priv(dev_get_drvdata(dev));
1326 
1327 	return apds9306_power_state(data, false);
1328 }
1329 
apds9306_runtime_resume(struct device * dev)1330 static int apds9306_runtime_resume(struct device *dev)
1331 {
1332 	struct apds9306_data *data = iio_priv(dev_get_drvdata(dev));
1333 
1334 	return apds9306_power_state(data, true);
1335 }
1336 
1337 static DEFINE_RUNTIME_DEV_PM_OPS(apds9306_pm_ops,
1338 				 apds9306_runtime_suspend,
1339 				 apds9306_runtime_resume,
1340 				 NULL);
1341 
1342 static const struct of_device_id apds9306_of_match[] = {
1343 	{ .compatible = "avago,apds9306" },
1344 	{ }
1345 };
1346 MODULE_DEVICE_TABLE(of, apds9306_of_match);
1347 
1348 static struct i2c_driver apds9306_driver = {
1349 	.driver = {
1350 		.name = "apds9306",
1351 		.pm = pm_ptr(&apds9306_pm_ops),
1352 		.of_match_table = apds9306_of_match,
1353 	},
1354 	.probe = apds9306_probe,
1355 };
1356 module_i2c_driver(apds9306_driver);
1357 
1358 MODULE_AUTHOR("Subhajit Ghosh <subhajit.ghosh@tweaklogic.com>");
1359 MODULE_DESCRIPTION("APDS9306 Ambient Light Sensor driver");
1360 MODULE_LICENSE("GPL");
1361 MODULE_IMPORT_NS(IIO_GTS_HELPER);
1362