Linux Audio

Check our new training course

Loading...
Note: File does not exist in v3.1.
   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 */
  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 = 326432000,
 112	}, {
 113		.part_id = 0xB3,
 114		.max_scale_int = 14,
 115		.max_scale_nano = 97120000,
 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 (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
 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				       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
1134static 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
1141static 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
1153static 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
1176static 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
1193static 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
1225static 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
1249static 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
1320static 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
1327static 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
1334static DEFINE_RUNTIME_DEV_PM_OPS(apds9306_pm_ops,
1335				 apds9306_runtime_suspend,
1336				 apds9306_runtime_resume,
1337				 NULL);
1338
1339static const struct of_device_id apds9306_of_match[] = {
1340	{ .compatible = "avago,apds9306" },
1341	{ }
1342};
1343MODULE_DEVICE_TABLE(of, apds9306_of_match);
1344
1345static 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};
1353module_i2c_driver(apds9306_driver);
1354
1355MODULE_AUTHOR("Subhajit Ghosh <subhajit.ghosh@tweaklogic.com>");
1356MODULE_DESCRIPTION("APDS9306 Ambient Light Sensor driver");
1357MODULE_LICENSE("GPL");
1358MODULE_IMPORT_NS("IIO_GTS_HELPER");