File Index
Files and directories
Sign in
FILE

vcnl4000.c

File preview with syntax highlighting.

linux-6.19.14/drivers/iio/light/vcnl4000.c C
   1// SPDX-License-Identifier: GPL-2.0-only
   2/*
   3 * vcnl4000.c - Support for Vishay VCNL4000/4010/4020/4040/4200 combined ambient
   4 * light and proximity sensor
   5 *
   6 * Copyright 2012 Peter Meerwald <pmeerw@pmeerw.net>
   7 * Copyright 2019 Pursim SPC
   8 * Copyright 2020 Mathieu Othacehe <m.othacehe@gmail.com>
   9 *
  10 * IIO driver for:
  11 *   VCNL4000/10/20 (7-bit I2C slave address 0x13)
  12 *   VCNL4040 (7-bit I2C slave address 0x60)
  13 *   VCNL4200 (7-bit I2C slave address 0x51)
  14 *
  15 * TODO:
  16 *   allow to adjust IR current
  17 *   interrupts (VCNL4040, VCNL4200)
  18 */
  19
  20#include <linux/bitfield.h>
  21#include <linux/module.h>
  22#include <linux/i2c.h>
  23#include <linux/err.h>
  24#include <linux/delay.h>
  25#include <linux/pm_runtime.h>
  26#include <linux/interrupt.h>
  27#include <linux/units.h>
  28
  29#include <linux/iio/buffer.h>
  30#include <linux/iio/events.h>
  31#include <linux/iio/iio.h>
  32#include <linux/iio/sysfs.h>
  33#include <linux/iio/trigger.h>
  34#include <linux/iio/trigger_consumer.h>
  35#include <linux/iio/triggered_buffer.h>
  36
  37#define VCNL4000_DRV_NAME "vcnl4000"
  38#define VCNL4000_PROD_ID	0x01
  39#define VCNL4010_PROD_ID	0x02 /* for VCNL4020, VCNL4010 */
  40#define VCNL4040_PROD_ID	0x86
  41#define VCNL4200_PROD_ID	0x58
  42
  43#define VCNL4000_COMMAND	0x80 /* Command register */
  44#define VCNL4000_PROD_REV	0x81 /* Product ID and Revision ID */
  45#define VCNL4010_PROX_RATE      0x82 /* Proximity rate */
  46#define VCNL4000_LED_CURRENT	0x83 /* IR LED current for proximity mode */
  47#define VCNL4000_AL_PARAM	0x84 /* Ambient light parameter register */
  48#define VCNL4010_ALS_PARAM      0x84 /* ALS rate */
  49#define VCNL4000_AL_RESULT_HI	0x85 /* Ambient light result register, MSB */
  50#define VCNL4000_AL_RESULT_LO	0x86 /* Ambient light result register, LSB */
  51#define VCNL4000_PS_RESULT_HI	0x87 /* Proximity result register, MSB */
  52#define VCNL4000_PS_RESULT_LO	0x88 /* Proximity result register, LSB */
  53#define VCNL4000_PS_MEAS_FREQ	0x89 /* Proximity test signal frequency */
  54#define VCNL4010_INT_CTRL	0x89 /* Interrupt control */
  55#define VCNL4000_PS_MOD_ADJ	0x8a /* Proximity modulator timing adjustment */
  56#define VCNL4010_LOW_THR_HI     0x8a /* Low threshold, MSB */
  57#define VCNL4010_LOW_THR_LO     0x8b /* Low threshold, LSB */
  58#define VCNL4010_HIGH_THR_HI    0x8c /* High threshold, MSB */
  59#define VCNL4010_HIGH_THR_LO    0x8d /* High threshold, LSB */
  60#define VCNL4010_ISR		0x8e /* Interrupt status */
  61
  62#define VCNL4200_AL_CONF	0x00 /* Ambient light configuration */
  63#define VCNL4200_PS_CONF1	0x03 /* Proximity configuration */
  64#define VCNL4200_PS_CONF3	0x04 /* Proximity configuration */
  65#define VCNL4040_PS_THDL_LM	0x06 /* Proximity threshold low */
  66#define VCNL4040_PS_THDH_LM	0x07 /* Proximity threshold high */
  67#define VCNL4040_ALS_THDL_LM	0x02 /* Ambient light threshold low */
  68#define VCNL4040_ALS_THDH_LM	0x01 /* Ambient light threshold high */
  69#define VCNL4200_PS_DATA	0x08 /* Proximity data */
  70#define VCNL4200_AL_DATA	0x09 /* Ambient light data */
  71#define VCNL4040_INT_FLAGS	0x0b /* Interrupt register */
  72#define VCNL4200_INT_FLAGS	0x0d /* Interrupt register */
  73#define VCNL4200_DEV_ID		0x0e /* Device ID, slave address and version */
  74
  75#define VCNL4040_DEV_ID		0x0c /* Device ID and version */
  76
  77/* Bit masks for COMMAND register */
  78#define VCNL4000_AL_RDY		BIT(6) /* ALS data ready? */
  79#define VCNL4000_PS_RDY		BIT(5) /* proximity data ready? */
  80#define VCNL4000_AL_OD		BIT(4) /* start on-demand ALS measurement */
  81#define VCNL4000_PS_OD		BIT(3) /* start on-demand proximity measurement */
  82#define VCNL4000_ALS_EN		BIT(2) /* start ALS measurement */
  83#define VCNL4000_PROX_EN	BIT(1) /* start proximity measurement */
  84#define VCNL4000_SELF_TIMED_EN	BIT(0) /* start self-timed measurement */
  85
  86#define VCNL4040_ALS_CONF_ALS_SHUTDOWN	BIT(0)
  87#define VCNL4040_ALS_CONF_IT		GENMASK(7, 6) /* Ambient integration time */
  88#define VCNL4040_ALS_CONF_INT_EN	BIT(1) /* Ambient light Interrupt enable */
  89#define VCNL4040_ALS_CONF_PERS	GENMASK(3, 2) /* Ambient interrupt persistence setting */
  90#define VCNL4040_PS_CONF1_PS_SHUTDOWN	BIT(0)
  91#define VCNL4040_PS_CONF2_PS_IT	GENMASK(3, 1) /* Proximity integration time */
  92#define VCNL4040_CONF1_PS_PERS	GENMASK(5, 4) /* Proximity interrupt persistence setting */
  93#define VCNL4040_PS_CONF2_PS_HD		BIT(11)	/* Proximity high definition */
  94#define VCNL4040_PS_CONF2_PS_INT	GENMASK(9, 8) /* Proximity interrupt mode */
  95#define VCNL4040_PS_CONF3_MPS		GENMASK(6, 5) /* Proximity multi pulse number */
  96#define VCNL4040_PS_MS_LED_I		GENMASK(10, 8) /* Proximity current */
  97#define VCNL4040_PS_IF_AWAY		BIT(8) /* Proximity event cross low threshold */
  98#define VCNL4040_PS_IF_CLOSE		BIT(9) /* Proximity event cross high threshold */
  99#define VCNL4040_ALS_RISING		BIT(12) /* Ambient Light cross high threshold */
 100#define VCNL4040_ALS_FALLING		BIT(13) /* Ambient Light cross low threshold */
 101
 102/* Bit masks for interrupt registers. */
 103#define VCNL4010_INT_THR_SEL	BIT(0) /* Select threshold interrupt source */
 104#define VCNL4010_INT_THR_EN	BIT(1) /* Threshold interrupt type */
 105#define VCNL4010_INT_ALS_EN	BIT(2) /* Enable on ALS data ready */
 106#define VCNL4010_INT_PROX_EN	BIT(3) /* Enable on proximity data ready */
 107
 108#define VCNL4010_INT_THR_HIGH	0 /* High threshold exceeded */
 109#define VCNL4010_INT_THR_LOW	1 /* Low threshold exceeded */
 110#define VCNL4010_INT_ALS	2 /* ALS data ready */
 111#define VCNL4010_INT_PROXIMITY	3 /* Proximity data ready */
 112
 113#define VCNL4010_INT_THR \
 114	(BIT(VCNL4010_INT_THR_LOW) | BIT(VCNL4010_INT_THR_HIGH))
 115#define VCNL4010_INT_DRDY \
 116	(BIT(VCNL4010_INT_PROXIMITY) | BIT(VCNL4010_INT_ALS))
 117
 118#define VCNL4040_CONF3_PS_MPS_16BITS	3	/* 8 multi pulses */
 119#define VCNL4040_CONF3_PS_LED_I_16BITS	3	/* 120 mA */
 120
 121#define VCNL4040_CONF3_PS_SAMPLE_16BITS \
 122	(FIELD_PREP(VCNL4040_PS_CONF3_MPS, VCNL4040_CONF3_PS_MPS_16BITS) | \
 123	 FIELD_PREP(VCNL4040_PS_MS_LED_I, VCNL4040_CONF3_PS_LED_I_16BITS))
 124
 125static const int vcnl4010_prox_sampling_frequency[][2] = {
 126	{1, 950000},
 127	{3, 906250},
 128	{7, 812500},
 129	{16, 625000},
 130	{31, 250000},
 131	{62, 500000},
 132	{125, 0},
 133	{250, 0},
 134};
 135
 136static const int vcnl4040_ps_it_times[][2] = {
 137	{0, 100},
 138	{0, 150},
 139	{0, 200},
 140	{0, 250},
 141	{0, 300},
 142	{0, 350},
 143	{0, 400},
 144	{0, 800},
 145};
 146
 147static const int vcnl4200_ps_it_times[][2] = {
 148	{0, 96},
 149	{0, 144},
 150	{0, 192},
 151	{0, 384},
 152	{0, 768},
 153	{0, 864},
 154};
 155
 156static const int vcnl4040_als_it_times[][2] = {
 157	{0, 80000},
 158	{0, 160000},
 159	{0, 320000},
 160	{0, 640000},
 161};
 162
 163static const int vcnl4200_als_it_times[][2] = {
 164	{0, 50000},
 165	{0, 100000},
 166	{0, 200000},
 167	{0, 400000},
 168};
 169
 170static const int vcnl4040_ps_calibbias_ua[][2] = {
 171	{0, 50000},
 172	{0, 75000},
 173	{0, 100000},
 174	{0, 120000},
 175	{0, 140000},
 176	{0, 160000},
 177	{0, 180000},
 178	{0, 200000},
 179};
 180
 181static const int vcnl4040_als_persistence[] = {1, 2, 4, 8};
 182static const int vcnl4040_ps_persistence[] = {1, 2, 3, 4};
 183static const int vcnl4040_ps_oversampling_ratio[] = {1, 2, 4, 8};
 184
 185#define VCNL4000_SLEEP_DELAY_MS	2000 /* before we enter pm_runtime_suspend */
 186
 187enum vcnl4000_device_ids {
 188	VCNL4000,
 189	VCNL4010,
 190	VCNL4040,
 191	VCNL4200,
 192};
 193
 194struct vcnl4200_channel {
 195	u8 reg;
 196	ktime_t last_measurement;
 197	ktime_t sampling_rate;
 198	struct mutex lock;
 199};
 200
 201struct vcnl4000_data {
 202	struct i2c_client *client;
 203	enum vcnl4000_device_ids id;
 204	int rev;
 205	int al_scale;
 206	int ps_scale;
 207	u8 ps_int;		/* proximity interrupt mode */
 208	u8 als_int;		/* ambient light interrupt mode*/
 209	const struct vcnl4000_chip_spec *chip_spec;
 210	struct mutex vcnl4000_lock;
 211	struct vcnl4200_channel vcnl4200_al;
 212	struct vcnl4200_channel vcnl4200_ps;
 213	uint32_t near_level;
 214};
 215
 216struct vcnl4000_chip_spec {
 217	const char *prod;
 218	struct iio_chan_spec const *channels;
 219	const int num_channels;
 220	const struct iio_info *info;
 221	const struct iio_buffer_setup_ops *buffer_setup_ops;
 222	int (*init)(struct vcnl4000_data *data);
 223	int (*measure_light)(struct vcnl4000_data *data, int *val);
 224	int (*measure_proximity)(struct vcnl4000_data *data, int *val);
 225	int (*set_power_state)(struct vcnl4000_data *data, bool on);
 226	irqreturn_t (*irq_thread)(int irq, void *priv);
 227	irqreturn_t (*trig_buffer_func)(int irq, void *priv);
 228
 229	u8 int_reg;
 230	const int(*ps_it_times)[][2];
 231	const int num_ps_it_times;
 232	const int(*als_it_times)[][2];
 233	const int num_als_it_times;
 234	const unsigned int ulux_step;
 235};
 236
 237static const struct i2c_device_id vcnl4000_id[] = {
 238	{ "vcnl4000", VCNL4000 },
 239	{ "vcnl4010", VCNL4010 },
 240	{ "vcnl4020", VCNL4010 },
 241	{ "vcnl4040", VCNL4040 },
 242	{ "vcnl4200", VCNL4200 },
 243	{ }
 244};
 245MODULE_DEVICE_TABLE(i2c, vcnl4000_id);
 246
 247static int vcnl4000_set_power_state(struct vcnl4000_data *data, bool on)
 248{
 249	/* no suspend op */
 250	return 0;
 251}
 252
 253static int vcnl4000_init(struct vcnl4000_data *data)
 254{
 255	int ret, prod_id;
 256
 257	ret = i2c_smbus_read_byte_data(data->client, VCNL4000_PROD_REV);
 258	if (ret < 0)
 259		return ret;
 260
 261	prod_id = ret >> 4;
 262	switch (prod_id) {
 263	case VCNL4000_PROD_ID:
 264		if (data->id != VCNL4000)
 265			dev_warn(&data->client->dev,
 266					"wrong device id, use vcnl4000");
 267		break;
 268	case VCNL4010_PROD_ID:
 269		if (data->id != VCNL4010)
 270			dev_warn(&data->client->dev,
 271					"wrong device id, use vcnl4010/4020");
 272		break;
 273	default:
 274		return -ENODEV;
 275	}
 276
 277	data->rev = ret & 0xf;
 278	data->al_scale = 250000;
 279
 280	return data->chip_spec->set_power_state(data, true);
 281};
 282
 283static ssize_t vcnl4000_write_als_enable(struct vcnl4000_data *data, bool en)
 284{
 285	int ret;
 286
 287	mutex_lock(&data->vcnl4000_lock);
 288
 289	ret = i2c_smbus_read_word_data(data->client, VCNL4200_AL_CONF);
 290	if (ret < 0)
 291		goto out;
 292
 293	if (en)
 294		ret &= ~VCNL4040_ALS_CONF_ALS_SHUTDOWN;
 295	else
 296		ret |= VCNL4040_ALS_CONF_ALS_SHUTDOWN;
 297
 298	ret = i2c_smbus_write_word_data(data->client, VCNL4200_AL_CONF, ret);
 299
 300out:
 301	mutex_unlock(&data->vcnl4000_lock);
 302
 303	return ret;
 304}
 305
 306static ssize_t vcnl4000_write_ps_enable(struct vcnl4000_data *data, bool en)
 307{
 308	int ret;
 309
 310	mutex_lock(&data->vcnl4000_lock);
 311
 312	ret = i2c_smbus_read_word_data(data->client, VCNL4200_PS_CONF1);
 313	if (ret < 0)
 314		goto out;
 315
 316	if (en)
 317		ret &= ~VCNL4040_PS_CONF1_PS_SHUTDOWN;
 318	else
 319		ret |= VCNL4040_PS_CONF1_PS_SHUTDOWN;
 320
 321	ret = i2c_smbus_write_word_data(data->client, VCNL4200_PS_CONF1, ret);
 322
 323out:
 324	mutex_unlock(&data->vcnl4000_lock);
 325
 326	return ret;
 327}
 328
 329static int vcnl4200_set_power_state(struct vcnl4000_data *data, bool on)
 330{
 331	int ret;
 332
 333	/* Do not power down if interrupts are enabled */
 334	if (!on && (data->ps_int || data->als_int))
 335		return 0;
 336
 337	ret = vcnl4000_write_als_enable(data, on);
 338	if (ret < 0)
 339		return ret;
 340
 341	ret = vcnl4000_write_ps_enable(data, on);
 342	if (ret < 0)
 343		return ret;
 344
 345	if (on) {
 346		/* Wait at least one integration cycle before fetching data */
 347		data->vcnl4200_al.last_measurement = ktime_get();
 348		data->vcnl4200_ps.last_measurement = ktime_get();
 349	}
 350
 351	return 0;
 352}
 353
 354static int vcnl4200_init(struct vcnl4000_data *data)
 355{
 356	int ret, id;
 357	u16 regval;
 358
 359	ret = i2c_smbus_read_word_data(data->client, VCNL4200_DEV_ID);
 360	if (ret < 0)
 361		return ret;
 362
 363	id = ret & 0xff;
 364
 365	if (id != VCNL4200_PROD_ID) {
 366		ret = i2c_smbus_read_word_data(data->client, VCNL4040_DEV_ID);
 367		if (ret < 0)
 368			return ret;
 369
 370		id = ret & 0xff;
 371
 372		if (id != VCNL4040_PROD_ID)
 373			return -ENODEV;
 374	}
 375
 376	dev_dbg(&data->client->dev, "device id 0x%x", id);
 377
 378	data->rev = (ret >> 8) & 0xf;
 379	data->ps_int = 0;
 380	data->als_int = 0;
 381
 382	data->vcnl4200_al.reg = VCNL4200_AL_DATA;
 383	data->vcnl4200_ps.reg = VCNL4200_PS_DATA;
 384	switch (id) {
 385	case VCNL4200_PROD_ID:
 386		/* Default wait time is 50ms, add 20% tolerance. */
 387		data->vcnl4200_al.sampling_rate = ktime_set(0, 60000 * 1000);
 388		/* Default wait time is 4.8ms, add 20% tolerance. */
 389		data->vcnl4200_ps.sampling_rate = ktime_set(0, 5760 * 1000);
 390		break;
 391	case VCNL4040_PROD_ID:
 392		/* Default wait time is 80ms, add 20% tolerance. */
 393		data->vcnl4200_al.sampling_rate = ktime_set(0, 96000 * 1000);
 394		/* Default wait time is 5ms, add 20% tolerance. */
 395		data->vcnl4200_ps.sampling_rate = ktime_set(0, 6000 * 1000);
 396		break;
 397	}
 398	data->al_scale = data->chip_spec->ulux_step;
 399	data->ps_scale = 16;
 400	mutex_init(&data->vcnl4200_al.lock);
 401	mutex_init(&data->vcnl4200_ps.lock);
 402
 403	/* Use 16 bits proximity sensor readings */
 404	ret = i2c_smbus_read_word_data(data->client, VCNL4200_PS_CONF1);
 405	if (ret < 0)
 406		return ret;
 407
 408	regval = ret | VCNL4040_PS_CONF2_PS_HD;
 409	ret = i2c_smbus_write_word_data(data->client, VCNL4200_PS_CONF1,
 410					regval);
 411	if (ret < 0)
 412		return ret;
 413
 414	/* Align proximity sensor sample rate to 16 bits data width */
 415	ret = i2c_smbus_read_word_data(data->client, VCNL4200_PS_CONF3);
 416	if (ret < 0)
 417		return ret;
 418
 419	regval = ret | VCNL4040_CONF3_PS_SAMPLE_16BITS;
 420	ret = i2c_smbus_write_word_data(data->client, VCNL4200_PS_CONF3,
 421					regval);
 422	if (ret < 0)
 423		return ret;
 424
 425	ret = data->chip_spec->set_power_state(data, true);
 426	if (ret < 0)
 427		return ret;
 428
 429	return 0;
 430};
 431
 432static int vcnl4000_read_data(struct vcnl4000_data *data, u8 data_reg, int *val)
 433{
 434	s32 ret;
 435
 436	ret = i2c_smbus_read_word_swapped(data->client, data_reg);
 437	if (ret < 0)
 438		return ret;
 439
 440	*val = ret;
 441	return 0;
 442}
 443
 444static int vcnl4000_write_data(struct vcnl4000_data *data, u8 data_reg, int val)
 445{
 446	if (val > U16_MAX)
 447		return -ERANGE;
 448
 449	return i2c_smbus_write_word_swapped(data->client, data_reg, val);
 450}
 451
 452
 453static int vcnl4000_measure(struct vcnl4000_data *data, u8 req_mask,
 454				u8 rdy_mask, u8 data_reg, int *val)
 455{
 456	int tries = 20;
 457	int ret;
 458
 459	mutex_lock(&data->vcnl4000_lock);
 460
 461	ret = i2c_smbus_write_byte_data(data->client, VCNL4000_COMMAND,
 462					req_mask);
 463	if (ret < 0)
 464		goto fail;
 465
 466	/* wait for data to become ready */
 467	while (tries--) {
 468		ret = i2c_smbus_read_byte_data(data->client, VCNL4000_COMMAND);
 469		if (ret < 0)
 470			goto fail;
 471		if (ret & rdy_mask)
 472			break;
 473		msleep(20); /* measurement takes up to 100 ms */
 474	}
 475
 476	if (tries < 0) {
 477		dev_err(&data->client->dev,
 478			"vcnl4000_measure() failed, data not ready\n");
 479		ret = -EIO;
 480		goto fail;
 481	}
 482
 483	ret = vcnl4000_read_data(data, data_reg, val);
 484	if (ret < 0)
 485		goto fail;
 486
 487	mutex_unlock(&data->vcnl4000_lock);
 488
 489	return 0;
 490
 491fail:
 492	mutex_unlock(&data->vcnl4000_lock);
 493	return ret;
 494}
 495
 496static int vcnl4200_measure(struct vcnl4000_data *data,
 497		struct vcnl4200_channel *chan, int *val)
 498{
 499	int ret;
 500	s64 delta;
 501	ktime_t next_measurement;
 502
 503	mutex_lock(&chan->lock);
 504
 505	next_measurement = ktime_add(chan->last_measurement,
 506			chan->sampling_rate);
 507	delta = ktime_us_delta(next_measurement, ktime_get());
 508	if (delta > 0)
 509		usleep_range(delta, delta + 500);
 510	chan->last_measurement = ktime_get();
 511
 512	mutex_unlock(&chan->lock);
 513
 514	ret = i2c_smbus_read_word_data(data->client, chan->reg);
 515	if (ret < 0)
 516		return ret;
 517
 518	*val = ret;
 519
 520	return 0;
 521}
 522
 523static int vcnl4000_measure_light(struct vcnl4000_data *data, int *val)
 524{
 525	return vcnl4000_measure(data,
 526			VCNL4000_AL_OD, VCNL4000_AL_RDY,
 527			VCNL4000_AL_RESULT_HI, val);
 528}
 529
 530static int vcnl4200_measure_light(struct vcnl4000_data *data, int *val)
 531{
 532	return vcnl4200_measure(data, &data->vcnl4200_al, val);
 533}
 534
 535static int vcnl4000_measure_proximity(struct vcnl4000_data *data, int *val)
 536{
 537	return vcnl4000_measure(data,
 538			VCNL4000_PS_OD, VCNL4000_PS_RDY,
 539			VCNL4000_PS_RESULT_HI, val);
 540}
 541
 542static int vcnl4200_measure_proximity(struct vcnl4000_data *data, int *val)
 543{
 544	return vcnl4200_measure(data, &data->vcnl4200_ps, val);
 545}
 546
 547static int vcnl4010_read_proxy_samp_freq(struct vcnl4000_data *data, int *val,
 548					 int *val2)
 549{
 550	int ret;
 551
 552	ret = i2c_smbus_read_byte_data(data->client, VCNL4010_PROX_RATE);
 553	if (ret < 0)
 554		return ret;
 555
 556	if (ret >= ARRAY_SIZE(vcnl4010_prox_sampling_frequency))
 557		return -EINVAL;
 558
 559	*val = vcnl4010_prox_sampling_frequency[ret][0];
 560	*val2 = vcnl4010_prox_sampling_frequency[ret][1];
 561
 562	return 0;
 563}
 564
 565static bool vcnl4010_is_in_periodic_mode(struct vcnl4000_data *data)
 566{
 567	int ret;
 568
 569	ret = i2c_smbus_read_byte_data(data->client, VCNL4000_COMMAND);
 570	if (ret < 0)
 571		return false;
 572
 573	return !!(ret & VCNL4000_SELF_TIMED_EN);
 574}
 575
 576static int vcnl4000_set_pm_runtime_state(struct vcnl4000_data *data, bool on)
 577{
 578	struct device *dev = &data->client->dev;
 579
 580	if (on)
 581		return pm_runtime_resume_and_get(dev);
 582
 583	return pm_runtime_put_autosuspend(dev);
 584}
 585
 586static int vcnl4040_read_als_it(struct vcnl4000_data *data, int *val, int *val2)
 587{
 588	int ret;
 589
 590	ret = i2c_smbus_read_word_data(data->client, VCNL4200_AL_CONF);
 591	if (ret < 0)
 592		return ret;
 593
 594	ret = FIELD_GET(VCNL4040_ALS_CONF_IT, ret);
 595	if (ret >= data->chip_spec->num_als_it_times)
 596		return -EINVAL;
 597
 598	*val = (*data->chip_spec->als_it_times)[ret][0];
 599	*val2 = (*data->chip_spec->als_it_times)[ret][1];
 600
 601	return 0;
 602}
 603
 604static ssize_t vcnl4040_write_als_it(struct vcnl4000_data *data, int val)
 605{
 606	unsigned int i;
 607	int ret;
 608	u16 regval;
 609
 610	for (i = 0; i < data->chip_spec->num_als_it_times; i++) {
 611		if (val == (*data->chip_spec->als_it_times)[i][1])
 612			break;
 613	}
 614
 615	if (i == data->chip_spec->num_als_it_times)
 616		return -EINVAL;
 617
 618	data->vcnl4200_al.sampling_rate = ktime_set(0, val * 1200);
 619	data->al_scale = div_u64(mul_u32_u32(data->chip_spec->ulux_step,
 620			 (*data->chip_spec->als_it_times)[0][1]),
 621			 val);
 622
 623	mutex_lock(&data->vcnl4000_lock);
 624
 625	ret = i2c_smbus_read_word_data(data->client, VCNL4200_AL_CONF);
 626	if (ret < 0)
 627		goto out_unlock;
 628
 629	regval = FIELD_PREP(VCNL4040_ALS_CONF_IT, i);
 630	regval |= (ret & ~VCNL4040_ALS_CONF_IT);
 631	ret = i2c_smbus_write_word_data(data->client,
 632					VCNL4200_AL_CONF,
 633					regval);
 634
 635out_unlock:
 636	mutex_unlock(&data->vcnl4000_lock);
 637	return ret;
 638}
 639
 640static int vcnl4040_read_ps_it(struct vcnl4000_data *data, int *val, int *val2)
 641{
 642	int ret;
 643
 644	ret = i2c_smbus_read_word_data(data->client, VCNL4200_PS_CONF1);
 645	if (ret < 0)
 646		return ret;
 647
 648	ret = FIELD_GET(VCNL4040_PS_CONF2_PS_IT, ret);
 649
 650	if (ret >= data->chip_spec->num_ps_it_times)
 651		return -EINVAL;
 652
 653	*val = (*data->chip_spec->ps_it_times)[ret][0];
 654	*val2 = (*data->chip_spec->ps_it_times)[ret][1];
 655
 656	return 0;
 657}
 658
 659static ssize_t vcnl4040_write_ps_it(struct vcnl4000_data *data, int val)
 660{
 661	unsigned int i;
 662	int ret, index = -1;
 663	u16 regval;
 664
 665	for (i = 0; i < data->chip_spec->num_ps_it_times; i++) {
 666		if (val == (*data->chip_spec->ps_it_times)[i][1]) {
 667			index = i;
 668			break;
 669		}
 670	}
 671
 672	if (index < 0)
 673		return -EINVAL;
 674
 675	data->vcnl4200_ps.sampling_rate = ktime_set(0, val * 60 * NSEC_PER_USEC);
 676
 677	mutex_lock(&data->vcnl4000_lock);
 678
 679	ret = i2c_smbus_read_word_data(data->client, VCNL4200_PS_CONF1);
 680	if (ret < 0)
 681		goto out;
 682
 683	regval = (ret & ~VCNL4040_PS_CONF2_PS_IT) |
 684	    FIELD_PREP(VCNL4040_PS_CONF2_PS_IT, index);
 685	ret = i2c_smbus_write_word_data(data->client, VCNL4200_PS_CONF1,
 686					regval);
 687
 688out:
 689	mutex_unlock(&data->vcnl4000_lock);
 690	return ret;
 691}
 692
 693static ssize_t vcnl4040_read_als_period(struct vcnl4000_data *data, int *val, int *val2)
 694{
 695	int ret, ret_pers, it;
 696	int64_t val_c;
 697
 698	ret = i2c_smbus_read_word_data(data->client, VCNL4200_AL_CONF);
 699	if (ret < 0)
 700		return ret;
 701
 702	ret_pers = FIELD_GET(VCNL4040_ALS_CONF_PERS, ret);
 703	if (ret_pers >= ARRAY_SIZE(vcnl4040_als_persistence))
 704		return -EINVAL;
 705
 706	it = FIELD_GET(VCNL4040_ALS_CONF_IT, ret);
 707	if (it >= data->chip_spec->num_als_it_times)
 708		return -EINVAL;
 709
 710	val_c = mul_u32_u32((*data->chip_spec->als_it_times)[it][1],
 711			    vcnl4040_als_persistence[ret_pers]);
 712	*val = div_u64_rem(val_c, MICRO, val2);
 713
 714	return IIO_VAL_INT_PLUS_MICRO;
 715}
 716
 717static ssize_t vcnl4040_write_als_period(struct vcnl4000_data *data, int val, int val2)
 718{
 719	unsigned int i;
 720	int ret, it;
 721	u16 regval;
 722	u64 val_n = mul_u32_u32(val, MICRO) + val2;
 723
 724	ret = i2c_smbus_read_word_data(data->client, VCNL4200_AL_CONF);
 725	if (ret < 0)
 726		return ret;
 727
 728	it = FIELD_GET(VCNL4040_ALS_CONF_IT, ret);
 729	if (it >= data->chip_spec->num_als_it_times)
 730		return -EINVAL;
 731
 732	for (i = 0; i < ARRAY_SIZE(vcnl4040_als_persistence) - 1; i++) {
 733		if (val_n < mul_u32_u32(vcnl4040_als_persistence[i],
 734					(*data->chip_spec->als_it_times)[it][1]))
 735			break;
 736	}
 737
 738	mutex_lock(&data->vcnl4000_lock);
 739
 740	ret = i2c_smbus_read_word_data(data->client, VCNL4200_AL_CONF);
 741	if (ret < 0)
 742		goto out_unlock;
 743
 744	regval = FIELD_PREP(VCNL4040_ALS_CONF_PERS, i);
 745	regval |= (ret & ~VCNL4040_ALS_CONF_PERS);
 746	ret = i2c_smbus_write_word_data(data->client, VCNL4200_AL_CONF,
 747					regval);
 748
 749out_unlock:
 750	mutex_unlock(&data->vcnl4000_lock);
 751	return ret;
 752}
 753
 754static ssize_t vcnl4040_read_ps_period(struct vcnl4000_data *data, int *val, int *val2)
 755{
 756	int ret, ret_pers, it;
 757
 758	ret = i2c_smbus_read_word_data(data->client, VCNL4200_PS_CONF1);
 759	if (ret < 0)
 760		return ret;
 761
 762	ret_pers = FIELD_GET(VCNL4040_CONF1_PS_PERS, ret);
 763	if (ret_pers >= ARRAY_SIZE(vcnl4040_ps_persistence))
 764		return -EINVAL;
 765
 766	it = FIELD_GET(VCNL4040_PS_CONF2_PS_IT, ret);
 767	if (it >= data->chip_spec->num_ps_it_times)
 768		return -EINVAL;
 769
 770	*val = (*data->chip_spec->ps_it_times)[it][0];
 771	*val2 = (*data->chip_spec->ps_it_times)[it][1] *
 772		vcnl4040_ps_persistence[ret_pers];
 773
 774	return IIO_VAL_INT_PLUS_MICRO;
 775}
 776
 777static ssize_t vcnl4040_write_ps_period(struct vcnl4000_data *data, int val, int val2)
 778{
 779	int ret, it, i;
 780	u16 regval;
 781
 782	ret = i2c_smbus_read_word_data(data->client, VCNL4200_PS_CONF1);
 783	if (ret < 0)
 784		return ret;
 785
 786	it = FIELD_GET(VCNL4040_PS_CONF2_PS_IT, ret);
 787	if (it >= data->chip_spec->num_ps_it_times)
 788		return -EINVAL;
 789
 790	if (val > 0)
 791		i = ARRAY_SIZE(vcnl4040_ps_persistence) - 1;
 792	else {
 793		for (i = 0; i < ARRAY_SIZE(vcnl4040_ps_persistence) - 1; i++) {
 794			if (val2 <= vcnl4040_ps_persistence[i] *
 795					(*data->chip_spec->ps_it_times)[it][1])
 796				break;
 797		}
 798	}
 799
 800	mutex_lock(&data->vcnl4000_lock);
 801
 802	ret = i2c_smbus_read_word_data(data->client, VCNL4200_PS_CONF1);
 803	if (ret < 0)
 804		goto out_unlock;
 805
 806	regval = FIELD_PREP(VCNL4040_CONF1_PS_PERS, i);
 807	regval |= (ret & ~VCNL4040_CONF1_PS_PERS);
 808	ret = i2c_smbus_write_word_data(data->client, VCNL4200_PS_CONF1,
 809					regval);
 810
 811out_unlock:
 812	mutex_unlock(&data->vcnl4000_lock);
 813	return ret;
 814}
 815
 816static ssize_t vcnl4040_read_ps_oversampling_ratio(struct vcnl4000_data *data, int *val)
 817{
 818	int ret;
 819
 820	ret = i2c_smbus_read_word_data(data->client, VCNL4200_PS_CONF3);
 821	if (ret < 0)
 822		return ret;
 823
 824	ret = FIELD_GET(VCNL4040_PS_CONF3_MPS, ret);
 825	if (ret >= ARRAY_SIZE(vcnl4040_ps_oversampling_ratio))
 826		return -EINVAL;
 827
 828	*val = vcnl4040_ps_oversampling_ratio[ret];
 829
 830	return ret;
 831}
 832
 833static ssize_t vcnl4040_write_ps_oversampling_ratio(struct vcnl4000_data *data, int val)
 834{
 835	unsigned int i;
 836	int ret;
 837	u16 regval;
 838
 839	for (i = 0; i < ARRAY_SIZE(vcnl4040_ps_oversampling_ratio); i++) {
 840		if (val == vcnl4040_ps_oversampling_ratio[i])
 841			break;
 842	}
 843
 844	if (i >= ARRAY_SIZE(vcnl4040_ps_oversampling_ratio))
 845		return -EINVAL;
 846
 847	mutex_lock(&data->vcnl4000_lock);
 848
 849	ret = i2c_smbus_read_word_data(data->client, VCNL4200_PS_CONF3);
 850	if (ret < 0)
 851		goto out_unlock;
 852
 853	regval = FIELD_PREP(VCNL4040_PS_CONF3_MPS, i);
 854	regval |= (ret & ~VCNL4040_PS_CONF3_MPS);
 855	ret = i2c_smbus_write_word_data(data->client, VCNL4200_PS_CONF3,
 856					regval);
 857
 858out_unlock:
 859	mutex_unlock(&data->vcnl4000_lock);
 860	return ret;
 861}
 862
 863static ssize_t vcnl4040_read_ps_calibbias(struct vcnl4000_data *data, int *val, int *val2)
 864{
 865	int ret;
 866
 867	ret = i2c_smbus_read_word_data(data->client, VCNL4200_PS_CONF3);
 868	if (ret < 0)
 869		return ret;
 870
 871	ret = FIELD_GET(VCNL4040_PS_MS_LED_I, ret);
 872	if (ret >= ARRAY_SIZE(vcnl4040_ps_calibbias_ua))
 873		return -EINVAL;
 874
 875	*val = vcnl4040_ps_calibbias_ua[ret][0];
 876	*val2 = vcnl4040_ps_calibbias_ua[ret][1];
 877
 878	return ret;
 879}
 880
 881static ssize_t vcnl4040_write_ps_calibbias(struct vcnl4000_data *data, int val)
 882{
 883	unsigned int i;
 884	int ret;
 885	u16 regval;
 886
 887	for (i = 0; i < ARRAY_SIZE(vcnl4040_ps_calibbias_ua); i++) {
 888		if (val == vcnl4040_ps_calibbias_ua[i][1])
 889			break;
 890	}
 891
 892	if (i >= ARRAY_SIZE(vcnl4040_ps_calibbias_ua))
 893		return -EINVAL;
 894
 895	mutex_lock(&data->vcnl4000_lock);
 896
 897	ret = i2c_smbus_read_word_data(data->client, VCNL4200_PS_CONF3);
 898	if (ret < 0)
 899		goto out_unlock;
 900
 901	regval = (ret & ~VCNL4040_PS_MS_LED_I);
 902	regval |= FIELD_PREP(VCNL4040_PS_MS_LED_I, i);
 903	ret = i2c_smbus_write_word_data(data->client, VCNL4200_PS_CONF3,
 904					regval);
 905
 906out_unlock:
 907	mutex_unlock(&data->vcnl4000_lock);
 908	return ret;
 909}
 910
 911static int vcnl4000_read_raw(struct iio_dev *indio_dev,
 912				struct iio_chan_spec const *chan,
 913				int *val, int *val2, long mask)
 914{
 915	int ret;
 916	struct vcnl4000_data *data = iio_priv(indio_dev);
 917
 918	switch (mask) {
 919	case IIO_CHAN_INFO_RAW:
 920		ret = vcnl4000_set_pm_runtime_state(data, true);
 921		if  (ret < 0)
 922			return ret;
 923
 924		switch (chan->type) {
 925		case IIO_LIGHT:
 926			ret = data->chip_spec->measure_light(data, val);
 927			if (!ret)
 928				ret = IIO_VAL_INT;
 929			break;
 930		case IIO_PROXIMITY:
 931			ret = data->chip_spec->measure_proximity(data, val);
 932			*val2 = data->ps_scale;
 933			if (!ret)
 934				ret = IIO_VAL_FRACTIONAL;
 935			break;
 936		default:
 937			ret = -EINVAL;
 938		}
 939		vcnl4000_set_pm_runtime_state(data, false);
 940		return ret;
 941	case IIO_CHAN_INFO_SCALE:
 942		if (chan->type != IIO_LIGHT)
 943			return -EINVAL;
 944
 945		*val = 0;
 946		*val2 = data->al_scale;
 947		return IIO_VAL_INT_PLUS_MICRO;
 948	case IIO_CHAN_INFO_INT_TIME:
 949		switch (chan->type) {
 950		case IIO_LIGHT:
 951			ret = vcnl4040_read_als_it(data, val, val2);
 952			break;
 953		case IIO_PROXIMITY:
 954			ret = vcnl4040_read_ps_it(data, val, val2);
 955			break;
 956		default:
 957			return -EINVAL;
 958		}
 959		if (ret < 0)
 960			return ret;
 961		return IIO_VAL_INT_PLUS_MICRO;
 962	case IIO_CHAN_INFO_OVERSAMPLING_RATIO:
 963		switch (chan->type) {
 964		case IIO_PROXIMITY:
 965			ret = vcnl4040_read_ps_oversampling_ratio(data, val);
 966			if (ret < 0)
 967				return ret;
 968			return IIO_VAL_INT;
 969		default:
 970			return -EINVAL;
 971		}
 972	case IIO_CHAN_INFO_CALIBBIAS:
 973		switch (chan->type) {
 974		case IIO_PROXIMITY:
 975			ret = vcnl4040_read_ps_calibbias(data, val, val2);
 976			if (ret < 0)
 977				return ret;
 978			return IIO_VAL_INT_PLUS_MICRO;
 979		default:
 980			return -EINVAL;
 981		}
 982	default:
 983		return -EINVAL;
 984	}
 985}
 986
 987static int vcnl4040_write_raw(struct iio_dev *indio_dev,
 988			      struct iio_chan_spec const *chan,
 989			      int val, int val2, long mask)
 990{
 991	struct vcnl4000_data *data = iio_priv(indio_dev);
 992
 993	switch (mask) {
 994	case IIO_CHAN_INFO_INT_TIME:
 995		if (val != 0)
 996			return -EINVAL;
 997		switch (chan->type) {
 998		case IIO_LIGHT:
 999			return vcnl4040_write_als_it(data, val2);
1000		case IIO_PROXIMITY:
1001			return vcnl4040_write_ps_it(data, val2);
1002		default:
1003			return -EINVAL;
1004		}
1005	case IIO_CHAN_INFO_OVERSAMPLING_RATIO:
1006		switch (chan->type) {
1007		case IIO_PROXIMITY:
1008			return vcnl4040_write_ps_oversampling_ratio(data, val);
1009		default:
1010			return -EINVAL;
1011		}
1012	case IIO_CHAN_INFO_CALIBBIAS:
1013		switch (chan->type) {
1014		case IIO_PROXIMITY:
1015			return vcnl4040_write_ps_calibbias(data, val2);
1016		default:
1017			return -EINVAL;
1018		}
1019	default:
1020		return -EINVAL;
1021	}
1022}
1023
1024static int vcnl4040_read_avail(struct iio_dev *indio_dev,
1025			       struct iio_chan_spec const *chan,
1026			       const int **vals, int *type, int *length,
1027			       long mask)
1028{
1029	struct vcnl4000_data *data = iio_priv(indio_dev);
1030
1031	switch (mask) {
1032	case IIO_CHAN_INFO_INT_TIME:
1033		switch (chan->type) {
1034		case IIO_LIGHT:
1035			*vals = (int *)(*data->chip_spec->als_it_times);
1036			*length = 2 * data->chip_spec->num_als_it_times;
1037			break;
1038		case IIO_PROXIMITY:
1039			*vals = (int *)(*data->chip_spec->ps_it_times);
1040			*length = 2 * data->chip_spec->num_ps_it_times;
1041			break;
1042		default:
1043			return -EINVAL;
1044		}
1045		*type = IIO_VAL_INT_PLUS_MICRO;
1046		return IIO_AVAIL_LIST;
1047	case IIO_CHAN_INFO_OVERSAMPLING_RATIO:
1048		switch (chan->type) {
1049		case IIO_PROXIMITY:
1050			*vals = (int *)vcnl4040_ps_oversampling_ratio;
1051			*length = ARRAY_SIZE(vcnl4040_ps_oversampling_ratio);
1052			*type = IIO_VAL_INT;
1053			return IIO_AVAIL_LIST;
1054		default:
1055			return -EINVAL;
1056		}
1057	case IIO_CHAN_INFO_CALIBBIAS:
1058		switch (chan->type) {
1059		case IIO_PROXIMITY:
1060			*vals = (int *)vcnl4040_ps_calibbias_ua;
1061			*length = 2 * ARRAY_SIZE(vcnl4040_ps_calibbias_ua);
1062			*type = IIO_VAL_INT_PLUS_MICRO;
1063			return IIO_AVAIL_LIST;
1064		default:
1065			return -EINVAL;
1066		}
1067	default:
1068		return -EINVAL;
1069	}
1070}
1071
1072static int vcnl4010_read_raw(struct iio_dev *indio_dev,
1073			     struct iio_chan_spec const *chan,
1074			     int *val, int *val2, long mask)
1075{
1076	int ret;
1077	struct vcnl4000_data *data = iio_priv(indio_dev);
1078
1079	switch (mask) {
1080	case IIO_CHAN_INFO_RAW:
1081	case IIO_CHAN_INFO_SCALE:
1082		if (!iio_device_claim_direct(indio_dev))
1083			return -EBUSY;
1084
1085		/* Protect against event capture. */
1086		if (vcnl4010_is_in_periodic_mode(data)) {
1087			ret = -EBUSY;
1088		} else {
1089			ret = vcnl4000_read_raw(indio_dev, chan, val, val2,
1090						mask);
1091		}
1092
1093		iio_device_release_direct(indio_dev);
1094		return ret;
1095	case IIO_CHAN_INFO_SAMP_FREQ:
1096		switch (chan->type) {
1097		case IIO_PROXIMITY:
1098			ret = vcnl4010_read_proxy_samp_freq(data, val, val2);
1099			if (ret < 0)
1100				return ret;
1101			return IIO_VAL_INT_PLUS_MICRO;
1102		default:
1103			return -EINVAL;
1104		}
1105	default:
1106		return -EINVAL;
1107	}
1108}
1109
1110static int vcnl4010_read_avail(struct iio_dev *indio_dev,
1111			       struct iio_chan_spec const *chan,
1112			       const int **vals, int *type, int *length,
1113			       long mask)
1114{
1115	switch (mask) {
1116	case IIO_CHAN_INFO_SAMP_FREQ:
1117		*vals = (int *)vcnl4010_prox_sampling_frequency;
1118		*type = IIO_VAL_INT_PLUS_MICRO;
1119		*length = 2 * ARRAY_SIZE(vcnl4010_prox_sampling_frequency);
1120		return IIO_AVAIL_LIST;
1121	default:
1122		return -EINVAL;
1123	}
1124}
1125
1126static int vcnl4010_write_proxy_samp_freq(struct vcnl4000_data *data, int val,
1127					  int val2)
1128{
1129	unsigned int i;
1130	int index = -1;
1131
1132	for (i = 0; i < ARRAY_SIZE(vcnl4010_prox_sampling_frequency); i++) {
1133		if (val == vcnl4010_prox_sampling_frequency[i][0] &&
1134		    val2 == vcnl4010_prox_sampling_frequency[i][1]) {
1135			index = i;
1136			break;
1137		}
1138	}
1139
1140	if (index < 0)
1141		return -EINVAL;
1142
1143	return i2c_smbus_write_byte_data(data->client, VCNL4010_PROX_RATE,
1144					 index);
1145}
1146
1147static int vcnl4010_write_raw(struct iio_dev *indio_dev,
1148			      struct iio_chan_spec const *chan,
1149			      int val, int val2, long mask)
1150{
1151	int ret;
1152	struct vcnl4000_data *data = iio_priv(indio_dev);
1153
1154	if (!iio_device_claim_direct(indio_dev))
1155		return -EBUSY;
1156
1157	/* Protect against event capture. */
1158	if (vcnl4010_is_in_periodic_mode(data)) {
1159		ret = -EBUSY;
1160		goto end;
1161	}
1162
1163	switch (mask) {
1164	case IIO_CHAN_INFO_SAMP_FREQ:
1165		switch (chan->type) {
1166		case IIO_PROXIMITY:
1167			ret = vcnl4010_write_proxy_samp_freq(data, val, val2);
1168			goto end;
1169		default:
1170			ret = -EINVAL;
1171			goto end;
1172		}
1173	default:
1174		ret = -EINVAL;
1175		goto end;
1176	}
1177
1178end:
1179	iio_device_release_direct(indio_dev);
1180	return ret;
1181}
1182
1183static int vcnl4010_read_event(struct iio_dev *indio_dev,
1184			       const struct iio_chan_spec *chan,
1185			       enum iio_event_type type,
1186			       enum iio_event_direction dir,
1187			       enum iio_event_info info,
1188			       int *val, int *val2)
1189{
1190	int ret;
1191	struct vcnl4000_data *data = iio_priv(indio_dev);
1192
1193	switch (info) {
1194	case IIO_EV_INFO_VALUE:
1195		switch (dir) {
1196		case IIO_EV_DIR_RISING:
1197			ret = vcnl4000_read_data(data, VCNL4010_HIGH_THR_HI,
1198						 val);
1199			if (ret < 0)
1200				return ret;
1201			return IIO_VAL_INT;
1202		case IIO_EV_DIR_FALLING:
1203			ret = vcnl4000_read_data(data, VCNL4010_LOW_THR_HI,
1204						 val);
1205			if (ret < 0)
1206				return ret;
1207			return IIO_VAL_INT;
1208		default:
1209			return -EINVAL;
1210		}
1211	default:
1212		return -EINVAL;
1213	}
1214}
1215
1216static int vcnl4010_write_event(struct iio_dev *indio_dev,
1217				const struct iio_chan_spec *chan,
1218				enum iio_event_type type,
1219				enum iio_event_direction dir,
1220				enum iio_event_info info,
1221				int val, int val2)
1222{
1223	int ret;
1224	struct vcnl4000_data *data = iio_priv(indio_dev);
1225
1226	switch (info) {
1227	case IIO_EV_INFO_VALUE:
1228		switch (dir) {
1229		case IIO_EV_DIR_RISING:
1230			ret = vcnl4000_write_data(data, VCNL4010_HIGH_THR_HI,
1231						  val);
1232			if (ret < 0)
1233				return ret;
1234			return IIO_VAL_INT;
1235		case IIO_EV_DIR_FALLING:
1236			ret = vcnl4000_write_data(data, VCNL4010_LOW_THR_HI,
1237						  val);
1238			if (ret < 0)
1239				return ret;
1240			return IIO_VAL_INT;
1241		default:
1242			return -EINVAL;
1243		}
1244	default:
1245		return -EINVAL;
1246	}
1247}
1248
1249static int vcnl4040_read_event(struct iio_dev *indio_dev,
1250			       const struct iio_chan_spec *chan,
1251			       enum iio_event_type type,
1252			       enum iio_event_direction dir,
1253			       enum iio_event_info info,
1254			       int *val, int *val2)
1255{
1256	int ret;
1257	struct vcnl4000_data *data = iio_priv(indio_dev);
1258
1259	switch (chan->type) {
1260	case IIO_LIGHT:
1261		switch (info) {
1262		case IIO_EV_INFO_PERIOD:
1263			return vcnl4040_read_als_period(data, val, val2);
1264		case IIO_EV_INFO_VALUE:
1265			switch (dir) {
1266			case IIO_EV_DIR_RISING:
1267				ret = i2c_smbus_read_word_data(data->client,
1268							       VCNL4040_ALS_THDH_LM);
1269				break;
1270			case IIO_EV_DIR_FALLING:
1271				ret = i2c_smbus_read_word_data(data->client,
1272							       VCNL4040_ALS_THDL_LM);
1273				break;
1274			default:
1275				return -EINVAL;
1276			}
1277			break;
1278		default:
1279			return -EINVAL;
1280		}
1281		break;
1282	case IIO_PROXIMITY:
1283		switch (info) {
1284		case IIO_EV_INFO_PERIOD:
1285			return vcnl4040_read_ps_period(data, val, val2);
1286		case IIO_EV_INFO_VALUE:
1287			switch (dir) {
1288			case IIO_EV_DIR_RISING:
1289				ret = i2c_smbus_read_word_data(data->client,
1290							       VCNL4040_PS_THDH_LM);
1291				break;
1292			case IIO_EV_DIR_FALLING:
1293				ret = i2c_smbus_read_word_data(data->client,
1294							       VCNL4040_PS_THDL_LM);
1295				break;
1296			default:
1297				return -EINVAL;
1298			}
1299			break;
1300		default:
1301			return -EINVAL;
1302		}
1303		break;
1304	default:
1305		return -EINVAL;
1306	}
1307	if (ret < 0)
1308		return ret;
1309	*val = ret;
1310	return IIO_VAL_INT;
1311}
1312
1313static int vcnl4040_write_event(struct iio_dev *indio_dev,
1314				const struct iio_chan_spec *chan,
1315				enum iio_event_type type,
1316				enum iio_event_direction dir,
1317				enum iio_event_info info,
1318				int val, int val2)
1319{
1320	int ret;
1321	struct vcnl4000_data *data = iio_priv(indio_dev);
1322
1323	switch (chan->type) {
1324	case IIO_LIGHT:
1325		switch (info) {
1326		case IIO_EV_INFO_PERIOD:
1327			return vcnl4040_write_als_period(data, val, val2);
1328		case IIO_EV_INFO_VALUE:
1329			switch (dir) {
1330			case IIO_EV_DIR_RISING:
1331				ret = i2c_smbus_write_word_data(data->client,
1332								VCNL4040_ALS_THDH_LM,
1333								val);
1334				break;
1335			case IIO_EV_DIR_FALLING:
1336				ret = i2c_smbus_write_word_data(data->client,
1337								VCNL4040_ALS_THDL_LM,
1338								val);
1339				break;
1340			default:
1341				return -EINVAL;
1342			}
1343			break;
1344		default:
1345			return -EINVAL;
1346		}
1347		break;
1348	case IIO_PROXIMITY:
1349		switch (info) {
1350		case IIO_EV_INFO_PERIOD:
1351			return vcnl4040_write_ps_period(data, val, val2);
1352		case IIO_EV_INFO_VALUE:
1353			switch (dir) {
1354			case IIO_EV_DIR_RISING:
1355				ret = i2c_smbus_write_word_data(data->client,
1356								VCNL4040_PS_THDH_LM,
1357								val);
1358				break;
1359			case IIO_EV_DIR_FALLING:
1360				ret = i2c_smbus_write_word_data(data->client,
1361								VCNL4040_PS_THDL_LM,
1362								val);
1363				break;
1364			default:
1365				return -EINVAL;
1366			}
1367			break;
1368		default:
1369			return -EINVAL;
1370		}
1371		break;
1372	default:
1373		return -EINVAL;
1374	}
1375	if (ret < 0)
1376		return ret;
1377	return IIO_VAL_INT;
1378}
1379
1380static bool vcnl4010_is_thr_enabled(struct vcnl4000_data *data)
1381{
1382	int ret;
1383
1384	ret = i2c_smbus_read_byte_data(data->client, VCNL4010_INT_CTRL);
1385	if (ret < 0)
1386		return false;
1387
1388	return !!(ret & VCNL4010_INT_THR_EN);
1389}
1390
1391static int vcnl4010_read_event_config(struct iio_dev *indio_dev,
1392				      const struct iio_chan_spec *chan,
1393				      enum iio_event_type type,
1394				      enum iio_event_direction dir)
1395{
1396	struct vcnl4000_data *data = iio_priv(indio_dev);
1397
1398	switch (chan->type) {
1399	case IIO_PROXIMITY:
1400		return vcnl4010_is_thr_enabled(data);
1401	default:
1402		return -EINVAL;
1403	}
1404}
1405
1406static int vcnl4010_config_threshold_enable(struct vcnl4000_data *data)
1407{
1408	int ret;
1409
1410	/* Enable periodic measurement of proximity data. */
1411	ret = i2c_smbus_write_byte_data(data->client, VCNL4000_COMMAND,
1412					VCNL4000_SELF_TIMED_EN | VCNL4000_PROX_EN);
1413	if (ret < 0)
1414		return ret;
1415
1416	/*
1417	 * Enable interrupts on threshold, for proximity data by
1418	 * default.
1419	 */
1420	return i2c_smbus_write_byte_data(data->client, VCNL4010_INT_CTRL,
1421					 VCNL4010_INT_THR_EN);
1422}
1423
1424static int vcnl4010_config_threshold_disable(struct vcnl4000_data *data)
1425{
1426	int ret;
1427
1428	if (!vcnl4010_is_thr_enabled(data))
1429		return 0;
1430
1431	ret = i2c_smbus_write_byte_data(data->client, VCNL4000_COMMAND, 0);
1432	if (ret < 0)
1433		return ret;
1434
1435	return i2c_smbus_write_byte_data(data->client, VCNL4010_INT_CTRL, 0);
1436}
1437
1438static int vcnl4010_config_threshold(struct iio_dev *indio_dev, bool state)
1439{
1440	struct vcnl4000_data *data = iio_priv(indio_dev);
1441	int ret;
1442
1443	if (state) {
1444		if (!iio_device_claim_direct(indio_dev))
1445			return -EBUSY;
1446		ret = vcnl4010_config_threshold_enable(data);
1447		iio_device_release_direct(indio_dev);
1448		return ret;
1449	} else {
1450		return vcnl4010_config_threshold_disable(data);
1451	}
1452}
1453
1454static int vcnl4010_write_event_config(struct iio_dev *indio_dev,
1455				       const struct iio_chan_spec *chan,
1456				       enum iio_event_type type,
1457				       enum iio_event_direction dir,
1458				       bool state)
1459{
1460	switch (chan->type) {
1461	case IIO_PROXIMITY:
1462		return vcnl4010_config_threshold(indio_dev, state);
1463	default:
1464		return -EINVAL;
1465	}
1466}
1467
1468static int vcnl4040_read_event_config(struct iio_dev *indio_dev,
1469				      const struct iio_chan_spec *chan,
1470				      enum iio_event_type type,
1471				      enum iio_event_direction dir)
1472{
1473	int ret;
1474	struct vcnl4000_data *data = iio_priv(indio_dev);
1475
1476	switch (chan->type) {
1477	case IIO_LIGHT:
1478		ret = i2c_smbus_read_word_data(data->client, VCNL4200_AL_CONF);
1479		if (ret < 0)
1480			return ret;
1481
1482		data->als_int = FIELD_GET(VCNL4040_ALS_CONF_INT_EN, ret);
1483
1484		return data->als_int;
1485	case IIO_PROXIMITY:
1486		ret = i2c_smbus_read_word_data(data->client, VCNL4200_PS_CONF1);
1487		if (ret < 0)
1488			return ret;
1489
1490		data->ps_int = FIELD_GET(VCNL4040_PS_CONF2_PS_INT, ret);
1491
1492		return (dir == IIO_EV_DIR_RISING) ?
1493			FIELD_GET(VCNL4040_PS_IF_AWAY, ret) :
1494			FIELD_GET(VCNL4040_PS_IF_CLOSE, ret);
1495	default:
1496		return -EINVAL;
1497	}
1498}
1499
1500static int vcnl4040_write_event_config(struct iio_dev *indio_dev,
1501				       const struct iio_chan_spec *chan,
1502				       enum iio_event_type type,
1503				       enum iio_event_direction dir,
1504				       bool state)
1505{
1506	int ret = -EINVAL;
1507	u16 val, mask;
1508	struct vcnl4000_data *data = iio_priv(indio_dev);
1509
1510	mutex_lock(&data->vcnl4000_lock);
1511
1512	switch (chan->type) {
1513	case IIO_LIGHT:
1514		ret = i2c_smbus_read_word_data(data->client, VCNL4200_AL_CONF);
1515		if (ret < 0)
1516			goto out;
1517
1518		mask = VCNL4040_ALS_CONF_INT_EN;
1519		if (state)
1520			val = (ret | mask);
1521		else
1522			val = (ret & ~mask);
1523
1524		data->als_int = FIELD_GET(VCNL4040_ALS_CONF_INT_EN, val);
1525		ret = i2c_smbus_write_word_data(data->client, VCNL4200_AL_CONF,
1526						val);
1527		break;
1528	case IIO_PROXIMITY:
1529		ret = i2c_smbus_read_word_data(data->client, VCNL4200_PS_CONF1);
1530		if (ret < 0)
1531			goto out;
1532
1533		if (dir == IIO_EV_DIR_RISING)
1534			mask = VCNL4040_PS_IF_AWAY;
1535		else
1536			mask = VCNL4040_PS_IF_CLOSE;
1537
1538		val = state ? (ret | mask) : (ret & ~mask);
1539
1540		data->ps_int = FIELD_GET(VCNL4040_PS_CONF2_PS_INT, val);
1541		ret = i2c_smbus_write_word_data(data->client, VCNL4200_PS_CONF1,
1542						val);
1543		break;
1544	default:
1545		break;
1546	}
1547
1548out:
1549	mutex_unlock(&data->vcnl4000_lock);
1550
1551	return ret;
1552}
1553
1554static irqreturn_t vcnl4040_irq_thread(int irq, void *p)
1555{
1556	struct iio_dev *indio_dev = p;
1557	struct vcnl4000_data *data = iio_priv(indio_dev);
1558	int ret;
1559
1560	ret = i2c_smbus_read_word_data(data->client, data->chip_spec->int_reg);
1561	if (ret < 0)
1562		return IRQ_HANDLED;
1563
1564	if (ret & VCNL4040_PS_IF_CLOSE) {
1565		iio_push_event(indio_dev,
1566			       IIO_UNMOD_EVENT_CODE(IIO_PROXIMITY, 0,
1567						    IIO_EV_TYPE_THRESH,
1568						    IIO_EV_DIR_RISING),
1569			       iio_get_time_ns(indio_dev));
1570	}
1571
1572	if (ret & VCNL4040_PS_IF_AWAY) {
1573		iio_push_event(indio_dev,
1574			       IIO_UNMOD_EVENT_CODE(IIO_PROXIMITY, 0,
1575						    IIO_EV_TYPE_THRESH,
1576						    IIO_EV_DIR_FALLING),
1577			       iio_get_time_ns(indio_dev));
1578	}
1579
1580	if (ret & VCNL4040_ALS_FALLING) {
1581		iio_push_event(indio_dev,
1582			       IIO_UNMOD_EVENT_CODE(IIO_LIGHT, 0,
1583						    IIO_EV_TYPE_THRESH,
1584						    IIO_EV_DIR_FALLING),
1585			       iio_get_time_ns(indio_dev));
1586	}
1587
1588	if (ret & VCNL4040_ALS_RISING) {
1589		iio_push_event(indio_dev,
1590			       IIO_UNMOD_EVENT_CODE(IIO_LIGHT, 0,
1591						    IIO_EV_TYPE_THRESH,
1592						    IIO_EV_DIR_RISING),
1593			       iio_get_time_ns(indio_dev));
1594	}
1595
1596	return IRQ_HANDLED;
1597}
1598
1599static ssize_t vcnl4000_read_near_level(struct iio_dev *indio_dev,
1600					uintptr_t priv,
1601					const struct iio_chan_spec *chan,
1602					char *buf)
1603{
1604	struct vcnl4000_data *data = iio_priv(indio_dev);
1605
1606	return sprintf(buf, "%u\n", data->near_level);
1607}
1608
1609static irqreturn_t vcnl4010_irq_thread(int irq, void *p)
1610{
1611	struct iio_dev *indio_dev = p;
1612	struct vcnl4000_data *data = iio_priv(indio_dev);
1613	unsigned long isr;
1614	int ret;
1615
1616	ret = i2c_smbus_read_byte_data(data->client, VCNL4010_ISR);
1617	if (ret < 0)
1618		goto end;
1619
1620	isr = ret;
1621
1622	if (isr & VCNL4010_INT_THR) {
1623		if (test_bit(VCNL4010_INT_THR_LOW, &isr)) {
1624			iio_push_event(indio_dev,
1625				       IIO_UNMOD_EVENT_CODE(
1626					       IIO_PROXIMITY,
1627					       1,
1628					       IIO_EV_TYPE_THRESH,
1629					       IIO_EV_DIR_FALLING),
1630				       iio_get_time_ns(indio_dev));
1631		}
1632
1633		if (test_bit(VCNL4010_INT_THR_HIGH, &isr)) {
1634			iio_push_event(indio_dev,
1635				       IIO_UNMOD_EVENT_CODE(
1636					       IIO_PROXIMITY,
1637					       1,
1638					       IIO_EV_TYPE_THRESH,
1639					       IIO_EV_DIR_RISING),
1640				       iio_get_time_ns(indio_dev));
1641		}
1642
1643		i2c_smbus_write_byte_data(data->client, VCNL4010_ISR,
1644					  isr & VCNL4010_INT_THR);
1645	}
1646
1647	if (isr & VCNL4010_INT_DRDY && iio_buffer_enabled(indio_dev))
1648		iio_trigger_poll_nested(indio_dev->trig);
1649
1650end:
1651	return IRQ_HANDLED;
1652}
1653
1654static irqreturn_t vcnl4010_trigger_handler(int irq, void *p)
1655{
1656	struct iio_poll_func *pf = p;
1657	struct iio_dev *indio_dev = pf->indio_dev;
1658	struct vcnl4000_data *data = iio_priv(indio_dev);
1659	const unsigned long *active_scan_mask = indio_dev->active_scan_mask;
1660	struct {
1661		u16 chan;
1662		aligned_s64 ts;
1663	} scan = { };
1664	bool data_read = false;
1665	unsigned long isr;
1666	int val = 0;
1667	int ret;
1668
1669	ret = i2c_smbus_read_byte_data(data->client, VCNL4010_ISR);
1670	if (ret < 0)
1671		goto end;
1672
1673	isr = ret;
1674
1675	if (test_bit(0, active_scan_mask)) {
1676		if (test_bit(VCNL4010_INT_PROXIMITY, &isr)) {
1677			ret = vcnl4000_read_data(data,
1678						 VCNL4000_PS_RESULT_HI,
1679						 &val);
1680			if (ret < 0)
1681				goto end;
1682
1683			scan.chan = val;
1684			data_read = true;
1685		}
1686	}
1687
1688	ret = i2c_smbus_write_byte_data(data->client, VCNL4010_ISR,
1689					isr & VCNL4010_INT_DRDY);
1690	if (ret < 0)
1691		goto end;
1692
1693	if (!data_read)
1694		goto end;
1695
1696	iio_push_to_buffers_with_ts(indio_dev, &scan, sizeof(scan),
1697				    iio_get_time_ns(indio_dev));
1698
1699end:
1700	iio_trigger_notify_done(indio_dev->trig);
1701	return IRQ_HANDLED;
1702}
1703
1704static int vcnl4010_buffer_postenable(struct iio_dev *indio_dev)
1705{
1706	struct vcnl4000_data *data = iio_priv(indio_dev);
1707	int ret;
1708	int cmd;
1709
1710	/* Do not enable the buffer if we are already capturing events. */
1711	if (vcnl4010_is_in_periodic_mode(data))
1712		return -EBUSY;
1713
1714	ret = i2c_smbus_write_byte_data(data->client, VCNL4010_INT_CTRL,
1715					VCNL4010_INT_PROX_EN);
1716	if (ret < 0)
1717		return ret;
1718
1719	cmd = VCNL4000_SELF_TIMED_EN | VCNL4000_PROX_EN;
1720	return i2c_smbus_write_byte_data(data->client, VCNL4000_COMMAND, cmd);
1721}
1722
1723static int vcnl4010_buffer_predisable(struct iio_dev *indio_dev)
1724{
1725	struct vcnl4000_data *data = iio_priv(indio_dev);
1726	int ret;
1727
1728	ret = i2c_smbus_write_byte_data(data->client, VCNL4010_INT_CTRL, 0);
1729	if (ret < 0)
1730		return ret;
1731
1732	return i2c_smbus_write_byte_data(data->client, VCNL4000_COMMAND, 0);
1733}
1734
1735static const struct iio_buffer_setup_ops vcnl4010_buffer_ops = {
1736	.postenable = &vcnl4010_buffer_postenable,
1737	.predisable = &vcnl4010_buffer_predisable,
1738};
1739
1740static const struct iio_chan_spec_ext_info vcnl4000_ext_info[] = {
1741	{
1742		.name = "nearlevel",
1743		.shared = IIO_SEPARATE,
1744		.read = vcnl4000_read_near_level,
1745	},
1746	{ }
1747};
1748
1749static const struct iio_event_spec vcnl4000_event_spec[] = {
1750	{
1751		.type = IIO_EV_TYPE_THRESH,
1752		.dir = IIO_EV_DIR_RISING,
1753		.mask_separate = BIT(IIO_EV_INFO_VALUE),
1754	}, {
1755		.type = IIO_EV_TYPE_THRESH,
1756		.dir = IIO_EV_DIR_FALLING,
1757		.mask_separate = BIT(IIO_EV_INFO_VALUE),
1758	}, {
1759		.type = IIO_EV_TYPE_THRESH,
1760		.dir = IIO_EV_DIR_EITHER,
1761		.mask_separate = BIT(IIO_EV_INFO_ENABLE),
1762	}
1763};
1764
1765static const struct iio_event_spec vcnl4040_als_event_spec[] = {
1766	{
1767		.type = IIO_EV_TYPE_THRESH,
1768		.dir = IIO_EV_DIR_RISING,
1769		.mask_separate = BIT(IIO_EV_INFO_VALUE),
1770	}, {
1771		.type = IIO_EV_TYPE_THRESH,
1772		.dir = IIO_EV_DIR_FALLING,
1773		.mask_separate = BIT(IIO_EV_INFO_VALUE),
1774	}, {
1775		.type = IIO_EV_TYPE_THRESH,
1776		.dir = IIO_EV_DIR_EITHER,
1777		.mask_separate = BIT(IIO_EV_INFO_ENABLE) | BIT(IIO_EV_INFO_PERIOD),
1778	},
1779};
1780
1781static const struct iio_event_spec vcnl4040_event_spec[] = {
1782	{
1783		.type = IIO_EV_TYPE_THRESH,
1784		.dir = IIO_EV_DIR_RISING,
1785		.mask_separate = BIT(IIO_EV_INFO_VALUE) | BIT(IIO_EV_INFO_ENABLE),
1786	}, {
1787		.type = IIO_EV_TYPE_THRESH,
1788		.dir = IIO_EV_DIR_FALLING,
1789		.mask_separate = BIT(IIO_EV_INFO_VALUE) | BIT(IIO_EV_INFO_ENABLE),
1790	}, {
1791		.type = IIO_EV_TYPE_THRESH,
1792		.dir = IIO_EV_DIR_EITHER,
1793		.mask_separate = BIT(IIO_EV_INFO_PERIOD),
1794	},
1795};
1796
1797static const struct iio_chan_spec vcnl4000_channels[] = {
1798	{
1799		.type = IIO_LIGHT,
1800		.info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
1801			BIT(IIO_CHAN_INFO_SCALE),
1802	}, {
1803		.type = IIO_PROXIMITY,
1804		.info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
1805		.ext_info = vcnl4000_ext_info,
1806	}
1807};
1808
1809static const struct iio_chan_spec vcnl4010_channels[] = {
1810	{
1811		.type = IIO_LIGHT,
1812		.scan_index = -1,
1813		.info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
1814			BIT(IIO_CHAN_INFO_SCALE),
1815	}, {
1816		.type = IIO_PROXIMITY,
1817		.scan_index = 0,
1818		.info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
1819			BIT(IIO_CHAN_INFO_SAMP_FREQ),
1820		.info_mask_separate_available = BIT(IIO_CHAN_INFO_SAMP_FREQ),
1821		.event_spec = vcnl4000_event_spec,
1822		.num_event_specs = ARRAY_SIZE(vcnl4000_event_spec),
1823		.ext_info = vcnl4000_ext_info,
1824		.scan_type = {
1825			.sign = 'u',
1826			.realbits = 16,
1827			.storagebits = 16,
1828			.endianness = IIO_CPU,
1829		},
1830	},
1831	IIO_CHAN_SOFT_TIMESTAMP(1),
1832};
1833
1834static const struct iio_chan_spec vcnl4040_channels[] = {
1835	{
1836		.type = IIO_LIGHT,
1837		.info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
1838			BIT(IIO_CHAN_INFO_SCALE) |
1839			BIT(IIO_CHAN_INFO_INT_TIME),
1840		.info_mask_separate_available = BIT(IIO_CHAN_INFO_INT_TIME),
1841		.event_spec = vcnl4040_als_event_spec,
1842		.num_event_specs = ARRAY_SIZE(vcnl4040_als_event_spec),
1843	}, {
1844		.type = IIO_PROXIMITY,
1845		.info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
1846			BIT(IIO_CHAN_INFO_INT_TIME) |
1847			BIT(IIO_CHAN_INFO_OVERSAMPLING_RATIO) |
1848			BIT(IIO_CHAN_INFO_CALIBBIAS),
1849		.info_mask_separate_available = BIT(IIO_CHAN_INFO_INT_TIME) |
1850			BIT(IIO_CHAN_INFO_OVERSAMPLING_RATIO) |
1851			BIT(IIO_CHAN_INFO_CALIBBIAS),
1852		.ext_info = vcnl4000_ext_info,
1853		.event_spec = vcnl4040_event_spec,
1854		.num_event_specs = ARRAY_SIZE(vcnl4040_event_spec),
1855	}
1856};
1857
1858static const struct iio_info vcnl4000_info = {
1859	.read_raw = vcnl4000_read_raw,
1860};
1861
1862static const struct iio_info vcnl4010_info = {
1863	.read_raw = vcnl4010_read_raw,
1864	.read_avail = vcnl4010_read_avail,
1865	.write_raw = vcnl4010_write_raw,
1866	.read_event_value = vcnl4010_read_event,
1867	.write_event_value = vcnl4010_write_event,
1868	.read_event_config = vcnl4010_read_event_config,
1869	.write_event_config = vcnl4010_write_event_config,
1870};
1871
1872static const struct iio_info vcnl4040_info = {
1873	.read_raw = vcnl4000_read_raw,
1874	.write_raw = vcnl4040_write_raw,
1875	.read_event_value = vcnl4040_read_event,
1876	.write_event_value = vcnl4040_write_event,
1877	.read_event_config = vcnl4040_read_event_config,
1878	.write_event_config = vcnl4040_write_event_config,
1879	.read_avail = vcnl4040_read_avail,
1880};
1881
1882static const struct vcnl4000_chip_spec vcnl4000_chip_spec_cfg[] = {
1883	[VCNL4000] = {
1884		.prod = "VCNL4000",
1885		.init = vcnl4000_init,
1886		.measure_light = vcnl4000_measure_light,
1887		.measure_proximity = vcnl4000_measure_proximity,
1888		.set_power_state = vcnl4000_set_power_state,
1889		.channels = vcnl4000_channels,
1890		.num_channels = ARRAY_SIZE(vcnl4000_channels),
1891		.info = &vcnl4000_info,
1892	},
1893	[VCNL4010] = {
1894		.prod = "VCNL4010/4020",
1895		.init = vcnl4000_init,
1896		.measure_light = vcnl4000_measure_light,
1897		.measure_proximity = vcnl4000_measure_proximity,
1898		.set_power_state = vcnl4000_set_power_state,
1899		.channels = vcnl4010_channels,
1900		.num_channels = ARRAY_SIZE(vcnl4010_channels),
1901		.info = &vcnl4010_info,
1902		.irq_thread = vcnl4010_irq_thread,
1903		.trig_buffer_func = vcnl4010_trigger_handler,
1904		.buffer_setup_ops = &vcnl4010_buffer_ops,
1905	},
1906	[VCNL4040] = {
1907		.prod = "VCNL4040",
1908		.init = vcnl4200_init,
1909		.measure_light = vcnl4200_measure_light,
1910		.measure_proximity = vcnl4200_measure_proximity,
1911		.set_power_state = vcnl4200_set_power_state,
1912		.channels = vcnl4040_channels,
1913		.num_channels = ARRAY_SIZE(vcnl4040_channels),
1914		.info = &vcnl4040_info,
1915		.irq_thread = vcnl4040_irq_thread,
1916		.int_reg = VCNL4040_INT_FLAGS,
1917		.ps_it_times = &vcnl4040_ps_it_times,
1918		.num_ps_it_times = ARRAY_SIZE(vcnl4040_ps_it_times),
1919		.als_it_times = &vcnl4040_als_it_times,
1920		.num_als_it_times = ARRAY_SIZE(vcnl4040_als_it_times),
1921		.ulux_step = 100000,
1922	},
1923	[VCNL4200] = {
1924		.prod = "VCNL4200",
1925		.init = vcnl4200_init,
1926		.measure_light = vcnl4200_measure_light,
1927		.measure_proximity = vcnl4200_measure_proximity,
1928		.set_power_state = vcnl4200_set_power_state,
1929		.channels = vcnl4040_channels,
1930		.num_channels = ARRAY_SIZE(vcnl4000_channels),
1931		.info = &vcnl4040_info,
1932		.irq_thread = vcnl4040_irq_thread,
1933		.int_reg = VCNL4200_INT_FLAGS,
1934		.ps_it_times = &vcnl4200_ps_it_times,
1935		.num_ps_it_times = ARRAY_SIZE(vcnl4200_ps_it_times),
1936		.als_it_times = &vcnl4200_als_it_times,
1937		.num_als_it_times = ARRAY_SIZE(vcnl4200_als_it_times),
1938		.ulux_step = 24000,
1939	},
1940};
1941
1942static const struct iio_trigger_ops vcnl4010_trigger_ops = {
1943	.validate_device = iio_trigger_validate_own_device,
1944};
1945
1946static int vcnl4010_probe_trigger(struct iio_dev *indio_dev)
1947{
1948	struct vcnl4000_data *data = iio_priv(indio_dev);
1949	struct i2c_client *client = data->client;
1950	struct iio_trigger *trigger;
1951
1952	trigger = devm_iio_trigger_alloc(&client->dev, "%s-dev%d",
1953					 indio_dev->name,
1954					 iio_device_id(indio_dev));
1955	if (!trigger)
1956		return -ENOMEM;
1957
1958	trigger->ops = &vcnl4010_trigger_ops;
1959	iio_trigger_set_drvdata(trigger, indio_dev);
1960
1961	return devm_iio_trigger_register(&client->dev, trigger);
1962}
1963
1964static int vcnl4000_probe(struct i2c_client *client)
1965{
1966	const struct i2c_device_id *id = i2c_client_get_device_id(client);
1967	struct vcnl4000_data *data;
1968	struct iio_dev *indio_dev;
1969	int ret;
1970
1971	indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*data));
1972	if (!indio_dev)
1973		return -ENOMEM;
1974
1975	data = iio_priv(indio_dev);
1976	i2c_set_clientdata(client, indio_dev);
1977	data->client = client;
1978	data->id = id->driver_data;
1979	data->chip_spec = &vcnl4000_chip_spec_cfg[data->id];
1980
1981	mutex_init(&data->vcnl4000_lock);
1982
1983	ret = data->chip_spec->init(data);
1984	if (ret < 0)
1985		return ret;
1986
1987	dev_dbg(&client->dev, "%s Ambient light/proximity sensor, Rev: %02x\n",
1988		data->chip_spec->prod, data->rev);
1989
1990	if (device_property_read_u32(&client->dev, "proximity-near-level",
1991				     &data->near_level))
1992		data->near_level = 0;
1993
1994	indio_dev->info = data->chip_spec->info;
1995	indio_dev->channels = data->chip_spec->channels;
1996	indio_dev->num_channels = data->chip_spec->num_channels;
1997	indio_dev->name = VCNL4000_DRV_NAME;
1998	indio_dev->modes = INDIO_DIRECT_MODE;
1999
2000	if (data->chip_spec->trig_buffer_func &&
2001	    data->chip_spec->buffer_setup_ops) {
2002		ret = devm_iio_triggered_buffer_setup(&client->dev, indio_dev,
2003						      NULL,
2004						      data->chip_spec->trig_buffer_func,
2005						      data->chip_spec->buffer_setup_ops);
2006		if (ret < 0) {
2007			dev_err(&client->dev,
2008				"unable to setup iio triggered buffer\n");
2009			return ret;
2010		}
2011	}
2012
2013	if (client->irq && data->chip_spec->irq_thread) {
2014		ret = devm_request_threaded_irq(&client->dev, client->irq,
2015						NULL, data->chip_spec->irq_thread,
2016						IRQF_TRIGGER_FALLING |
2017						IRQF_ONESHOT,
2018						"vcnl4000_irq",
2019						indio_dev);
2020		if (ret < 0) {
2021			dev_err(&client->dev, "irq request failed\n");
2022			return ret;
2023		}
2024
2025		ret = vcnl4010_probe_trigger(indio_dev);
2026		if (ret < 0)
2027			return ret;
2028	}
2029
2030	ret = pm_runtime_set_active(&client->dev);
2031	if (ret < 0)
2032		goto fail_poweroff;
2033
2034	ret = iio_device_register(indio_dev);
2035	if (ret < 0)
2036		goto fail_poweroff;
2037
2038	pm_runtime_enable(&client->dev);
2039	pm_runtime_set_autosuspend_delay(&client->dev, VCNL4000_SLEEP_DELAY_MS);
2040	pm_runtime_use_autosuspend(&client->dev);
2041
2042	return 0;
2043fail_poweroff:
2044	data->chip_spec->set_power_state(data, false);
2045	return ret;
2046}
2047
2048static const struct of_device_id vcnl_4000_of_match[] = {
2049	{
2050		.compatible = "vishay,vcnl4000",
2051		.data = (void *)VCNL4000,
2052	},
2053	{
2054		.compatible = "vishay,vcnl4010",
2055		.data = (void *)VCNL4010,
2056	},
2057	{
2058		.compatible = "vishay,vcnl4020",
2059		.data = (void *)VCNL4010,
2060	},
2061	{
2062		.compatible = "vishay,vcnl4040",
2063		.data = (void *)VCNL4040,
2064	},
2065	{
2066		.compatible = "vishay,vcnl4200",
2067		.data = (void *)VCNL4200,
2068	},
2069	{ }
2070};
2071MODULE_DEVICE_TABLE(of, vcnl_4000_of_match);
2072
2073static void vcnl4000_remove(struct i2c_client *client)
2074{
2075	struct iio_dev *indio_dev = i2c_get_clientdata(client);
2076	struct vcnl4000_data *data = iio_priv(indio_dev);
2077	int ret;
2078
2079	pm_runtime_dont_use_autosuspend(&client->dev);
2080	pm_runtime_disable(&client->dev);
2081	iio_device_unregister(indio_dev);
2082	pm_runtime_set_suspended(&client->dev);
2083
2084	ret = data->chip_spec->set_power_state(data, false);
2085	if (ret)
2086		dev_warn(&client->dev, "Failed to power down (%pe)\n",
2087			 ERR_PTR(ret));
2088}
2089
2090static int vcnl4000_runtime_suspend(struct device *dev)
2091{
2092	struct iio_dev *indio_dev = i2c_get_clientdata(to_i2c_client(dev));
2093	struct vcnl4000_data *data = iio_priv(indio_dev);
2094
2095	return data->chip_spec->set_power_state(data, false);
2096}
2097
2098static int vcnl4000_runtime_resume(struct device *dev)
2099{
2100	struct iio_dev *indio_dev = i2c_get_clientdata(to_i2c_client(dev));
2101	struct vcnl4000_data *data = iio_priv(indio_dev);
2102
2103	return data->chip_spec->set_power_state(data, true);
2104}
2105
2106static DEFINE_RUNTIME_DEV_PM_OPS(vcnl4000_pm_ops, vcnl4000_runtime_suspend,
2107				 vcnl4000_runtime_resume, NULL);
2108
2109static struct i2c_driver vcnl4000_driver = {
2110	.driver = {
2111		.name   = VCNL4000_DRV_NAME,
2112		.pm	= pm_ptr(&vcnl4000_pm_ops),
2113		.of_match_table = vcnl_4000_of_match,
2114	},
2115	.probe = vcnl4000_probe,
2116	.id_table = vcnl4000_id,
2117	.remove	= vcnl4000_remove,
2118};
2119
2120module_i2c_driver(vcnl4000_driver);
2121
2122MODULE_AUTHOR("Peter Meerwald <pmeerw@pmeerw.net>");
2123MODULE_AUTHOR("Mathieu Othacehe <m.othacehe@gmail.com>");
2124MODULE_DESCRIPTION("Vishay VCNL4000 proximity/ambient light sensor driver");
2125MODULE_LICENSE("GPL");
~/ Read-only file preview.