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 <asm/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 */
81struct 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 */
107static 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
119static 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
129static 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 */
147struct 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 */
174struct 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
197static 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
212static 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
221static 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
242static 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
268static 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 */
291static IIO_CONST_ATTR(thresh_either_period_available, "[0 1 15]");
292
293/* ALS_THRESH_VAR available */
294static IIO_CONST_ATTR(thresh_adaptive_either_values_available, "[0 1 7]");
295
296static 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
302static const struct attribute_group apds9306_event_attr_group = {
303	.attrs = apds9306_event_attributes,
304};
305
306static const struct regmap_range apds9306_readable_ranges[] = {
307	regmap_reg_range(APDS9306_MAIN_CTRL_REG, APDS9306_ALS_THRES_VAR_REG)
308};
309
310static 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
315static 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
320static const struct regmap_range apds9306_precious_ranges[] = {
321	regmap_reg_range(APDS9306_MAIN_STATUS_REG, APDS9306_MAIN_STATUS_REG)
322};
323
324static 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
329static 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
334static 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
339static 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
344static 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
356static const struct reg_field apds9306_rf_sw_reset =
357	REG_FIELD(APDS9306_MAIN_CTRL_REG, 4, 4);
358
359static const struct reg_field apds9306_rf_en =
360	REG_FIELD(APDS9306_MAIN_CTRL_REG, 1, 1);
361
362static const struct reg_field apds9306_rf_intg_time =
363	REG_FIELD(APDS9306_ALS_MEAS_RATE_REG, 4, 6);
364
365static const struct reg_field apds9306_rf_repeat_rate =
366	REG_FIELD(APDS9306_ALS_MEAS_RATE_REG, 0, 2);
367
368static const struct reg_field apds9306_rf_gain =
369	REG_FIELD(APDS9306_ALS_GAIN_REG, 0, 2);
370
371static const struct reg_field apds9306_rf_int_src =
372	REG_FIELD(APDS9306_INT_CFG_REG, 4, 5);
373
374static const struct reg_field apds9306_rf_int_thresh_var_en =
375	REG_FIELD(APDS9306_INT_CFG_REG, 3, 3);
376
377static const struct reg_field apds9306_rf_int_en =
378	REG_FIELD(APDS9306_INT_CFG_REG, 2, 2);
379
380static const struct reg_field apds9306_rf_int_persist_val =
381	REG_FIELD(APDS9306_INT_PERSISTENCE_REG, 4, 7);
382
383static const struct reg_field apds9306_rf_int_thresh_var_val =
384	REG_FIELD(APDS9306_ALS_THRES_VAR_REG, 0, 2);
385
386static 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
446static 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
464static 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
546static 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
564static 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 (ret < 0)
587		return ret;
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
628static 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
647static 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
662static 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
686static 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
720static 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
737static 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
747static 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
769static 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
790static 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
807static 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
817static 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
867static 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
890static 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
906static 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
928static 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
977static 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
1008static 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
1030static 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
1070static 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
1137static 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
1144static 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
1156static 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
1179static 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
1196static 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
1228static 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
1252static 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
1323static 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
1330static 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
1337static DEFINE_RUNTIME_DEV_PM_OPS(apds9306_pm_ops,
1338				 apds9306_runtime_suspend,
1339				 apds9306_runtime_resume,
1340				 NULL);
1341
1342static const struct of_device_id apds9306_of_match[] = {
1343	{ .compatible = "avago,apds9306" },
1344	{ }
1345};
1346MODULE_DEVICE_TABLE(of, apds9306_of_match);
1347
1348static 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};
1356module_i2c_driver(apds9306_driver);
1357
1358MODULE_AUTHOR("Subhajit Ghosh <subhajit.ghosh@tweaklogic.com>");
1359MODULE_DESCRIPTION("APDS9306 Ambient Light Sensor driver");
1360MODULE_LICENSE("GPL");
1361MODULE_IMPORT_NS(IIO_GTS_HELPER);
1362