Linux Audio

Check our new training course

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