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