File Index
Files and directories
Sign in
FILE

apds9960.c

File preview with syntax highlighting.

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