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/module.h> 21 #include <linux/i2c.h> 22 #include <linux/err.h> 23 #include <linux/delay.h> 24 #include <linux/pm_runtime.h> 25 #include <linux/interrupt.h> 26 27 #include <linux/iio/buffer.h> 28 #include <linux/iio/events.h> 29 #include <linux/iio/iio.h> 30 #include <linux/iio/sysfs.h> 31 #include <linux/iio/trigger.h> 32 #include <linux/iio/trigger_consumer.h> 33 #include <linux/iio/triggered_buffer.h> 34 35 #define VCNL4000_DRV_NAME "vcnl4000" 36 #define VCNL4000_PROD_ID 0x01 37 #define VCNL4010_PROD_ID 0x02 /* for VCNL4020, VCNL4010 */ 38 #define VCNL4040_PROD_ID 0x86 39 #define VCNL4200_PROD_ID 0x58 40 41 #define VCNL4000_COMMAND 0x80 /* Command register */ 42 #define VCNL4000_PROD_REV 0x81 /* Product ID and Revision ID */ 43 #define VCNL4010_PROX_RATE 0x82 /* Proximity rate */ 44 #define VCNL4000_LED_CURRENT 0x83 /* IR LED current for proximity mode */ 45 #define VCNL4000_AL_PARAM 0x84 /* Ambient light parameter register */ 46 #define VCNL4010_ALS_PARAM 0x84 /* ALS rate */ 47 #define VCNL4000_AL_RESULT_HI 0x85 /* Ambient light result register, MSB */ 48 #define VCNL4000_AL_RESULT_LO 0x86 /* Ambient light result register, LSB */ 49 #define VCNL4000_PS_RESULT_HI 0x87 /* Proximity result register, MSB */ 50 #define VCNL4000_PS_RESULT_LO 0x88 /* Proximity result register, LSB */ 51 #define VCNL4000_PS_MEAS_FREQ 0x89 /* Proximity test signal frequency */ 52 #define VCNL4010_INT_CTRL 0x89 /* Interrupt control */ 53 #define VCNL4000_PS_MOD_ADJ 0x8a /* Proximity modulator timing adjustment */ 54 #define VCNL4010_LOW_THR_HI 0x8a /* Low threshold, MSB */ 55 #define VCNL4010_LOW_THR_LO 0x8b /* Low threshold, LSB */ 56 #define VCNL4010_HIGH_THR_HI 0x8c /* High threshold, MSB */ 57 #define VCNL4010_HIGH_THR_LO 0x8d /* High threshold, LSB */ 58 #define VCNL4010_ISR 0x8e /* Interrupt status */ 59 60 #define VCNL4200_AL_CONF 0x00 /* Ambient light configuration */ 61 #define VCNL4200_PS_CONF1 0x03 /* Proximity configuration */ 62 #define VCNL4200_PS_DATA 0x08 /* Proximity data */ 63 #define VCNL4200_AL_DATA 0x09 /* Ambient light data */ 64 #define VCNL4200_DEV_ID 0x0e /* Device ID, slave address and version */ 65 66 #define VCNL4040_DEV_ID 0x0c /* Device ID and version */ 67 68 /* Bit masks for COMMAND register */ 69 #define VCNL4000_AL_RDY BIT(6) /* ALS data ready? */ 70 #define VCNL4000_PS_RDY BIT(5) /* proximity data ready? */ 71 #define VCNL4000_AL_OD BIT(4) /* start on-demand ALS measurement */ 72 #define VCNL4000_PS_OD BIT(3) /* start on-demand proximity measurement */ 73 #define VCNL4000_ALS_EN BIT(2) /* start ALS measurement */ 74 #define VCNL4000_PROX_EN BIT(1) /* start proximity measurement */ 75 #define VCNL4000_SELF_TIMED_EN BIT(0) /* start self-timed measurement */ 76 77 /* Bit masks for interrupt registers. */ 78 #define VCNL4010_INT_THR_SEL BIT(0) /* Select threshold interrupt source */ 79 #define VCNL4010_INT_THR_EN BIT(1) /* Threshold interrupt type */ 80 #define VCNL4010_INT_ALS_EN BIT(2) /* Enable on ALS data ready */ 81 #define VCNL4010_INT_PROX_EN BIT(3) /* Enable on proximity data ready */ 82 83 #define VCNL4010_INT_THR_HIGH 0 /* High threshold exceeded */ 84 #define VCNL4010_INT_THR_LOW 1 /* Low threshold exceeded */ 85 #define VCNL4010_INT_ALS 2 /* ALS data ready */ 86 #define VCNL4010_INT_PROXIMITY 3 /* Proximity data ready */ 87 88 #define VCNL4010_INT_THR \ 89 (BIT(VCNL4010_INT_THR_LOW) | BIT(VCNL4010_INT_THR_HIGH)) 90 #define VCNL4010_INT_DRDY \ 91 (BIT(VCNL4010_INT_PROXIMITY) | BIT(VCNL4010_INT_ALS)) 92 93 static const int vcnl4010_prox_sampling_frequency[][2] = { 94 {1, 950000}, 95 {3, 906250}, 96 {7, 812500}, 97 {16, 625000}, 98 {31, 250000}, 99 {62, 500000}, 100 {125, 0}, 101 {250, 0}, 102 }; 103 104 #define VCNL4000_SLEEP_DELAY_MS 2000 /* before we enter pm_runtime_suspend */ 105 106 enum vcnl4000_device_ids { 107 VCNL4000, 108 VCNL4010, 109 VCNL4040, 110 VCNL4200, 111 }; 112 113 struct vcnl4200_channel { 114 u8 reg; 115 ktime_t last_measurement; 116 ktime_t sampling_rate; 117 struct mutex lock; 118 }; 119 120 struct vcnl4000_data { 121 struct i2c_client *client; 122 enum vcnl4000_device_ids id; 123 int rev; 124 int al_scale; 125 const struct vcnl4000_chip_spec *chip_spec; 126 struct mutex vcnl4000_lock; 127 struct vcnl4200_channel vcnl4200_al; 128 struct vcnl4200_channel vcnl4200_ps; 129 uint32_t near_level; 130 }; 131 132 struct vcnl4000_chip_spec { 133 const char *prod; 134 struct iio_chan_spec const *channels; 135 const int num_channels; 136 const struct iio_info *info; 137 bool irq_support; 138 int (*init)(struct vcnl4000_data *data); 139 int (*measure_light)(struct vcnl4000_data *data, int *val); 140 int (*measure_proximity)(struct vcnl4000_data *data, int *val); 141 int (*set_power_state)(struct vcnl4000_data *data, bool on); 142 }; 143 144 static const struct i2c_device_id vcnl4000_id[] = { 145 { "vcnl4000", VCNL4000 }, 146 { "vcnl4010", VCNL4010 }, 147 { "vcnl4020", VCNL4010 }, 148 { "vcnl4040", VCNL4040 }, 149 { "vcnl4200", VCNL4200 }, 150 { } 151 }; 152 MODULE_DEVICE_TABLE(i2c, vcnl4000_id); 153 154 static int vcnl4000_set_power_state(struct vcnl4000_data *data, bool on) 155 { 156 /* no suspend op */ 157 return 0; 158 } 159 160 static int vcnl4000_init(struct vcnl4000_data *data) 161 { 162 int ret, prod_id; 163 164 ret = i2c_smbus_read_byte_data(data->client, VCNL4000_PROD_REV); 165 if (ret < 0) 166 return ret; 167 168 prod_id = ret >> 4; 169 switch (prod_id) { 170 case VCNL4000_PROD_ID: 171 if (data->id != VCNL4000) 172 dev_warn(&data->client->dev, 173 "wrong device id, use vcnl4000"); 174 break; 175 case VCNL4010_PROD_ID: 176 if (data->id != VCNL4010) 177 dev_warn(&data->client->dev, 178 "wrong device id, use vcnl4010/4020"); 179 break; 180 default: 181 return -ENODEV; 182 } 183 184 data->rev = ret & 0xf; 185 data->al_scale = 250000; 186 mutex_init(&data->vcnl4000_lock); 187 188 return data->chip_spec->set_power_state(data, true); 189 }; 190 191 static int vcnl4200_set_power_state(struct vcnl4000_data *data, bool on) 192 { 193 u16 val = on ? 0 /* power on */ : 1 /* shut down */; 194 int ret; 195 196 ret = i2c_smbus_write_word_data(data->client, VCNL4200_AL_CONF, val); 197 if (ret < 0) 198 return ret; 199 200 ret = i2c_smbus_write_word_data(data->client, VCNL4200_PS_CONF1, val); 201 if (ret < 0) 202 return ret; 203 204 if (on) { 205 /* Wait at least one integration cycle before fetching data */ 206 data->vcnl4200_al.last_measurement = ktime_get(); 207 data->vcnl4200_ps.last_measurement = ktime_get(); 208 } 209 210 return 0; 211 } 212 213 static int vcnl4200_init(struct vcnl4000_data *data) 214 { 215 int ret, id; 216 217 ret = i2c_smbus_read_word_data(data->client, VCNL4200_DEV_ID); 218 if (ret < 0) 219 return ret; 220 221 id = ret & 0xff; 222 223 if (id != VCNL4200_PROD_ID) { 224 ret = i2c_smbus_read_word_data(data->client, VCNL4040_DEV_ID); 225 if (ret < 0) 226 return ret; 227 228 id = ret & 0xff; 229 230 if (id != VCNL4040_PROD_ID) 231 return -ENODEV; 232 } 233 234 dev_dbg(&data->client->dev, "device id 0x%x", id); 235 236 data->rev = (ret >> 8) & 0xf; 237 238 data->vcnl4200_al.reg = VCNL4200_AL_DATA; 239 data->vcnl4200_ps.reg = VCNL4200_PS_DATA; 240 switch (id) { 241 case VCNL4200_PROD_ID: 242 /* Default wait time is 50ms, add 20% tolerance. */ 243 data->vcnl4200_al.sampling_rate = ktime_set(0, 60000 * 1000); 244 /* Default wait time is 4.8ms, add 20% tolerance. */ 245 data->vcnl4200_ps.sampling_rate = ktime_set(0, 5760 * 1000); 246 data->al_scale = 24000; 247 break; 248 case VCNL4040_PROD_ID: 249 /* Default wait time is 80ms, add 20% tolerance. */ 250 data->vcnl4200_al.sampling_rate = ktime_set(0, 96000 * 1000); 251 /* Default wait time is 5ms, add 20% tolerance. */ 252 data->vcnl4200_ps.sampling_rate = ktime_set(0, 6000 * 1000); 253 data->al_scale = 120000; 254 break; 255 } 256 mutex_init(&data->vcnl4200_al.lock); 257 mutex_init(&data->vcnl4200_ps.lock); 258 259 ret = data->chip_spec->set_power_state(data, true); 260 if (ret < 0) 261 return ret; 262 263 return 0; 264 }; 265 266 static int vcnl4000_read_data(struct vcnl4000_data *data, u8 data_reg, int *val) 267 { 268 s32 ret; 269 270 ret = i2c_smbus_read_word_swapped(data->client, data_reg); 271 if (ret < 0) 272 return ret; 273 274 *val = ret; 275 return 0; 276 } 277 278 static int vcnl4000_write_data(struct vcnl4000_data *data, u8 data_reg, int val) 279 { 280 if (val > U16_MAX) 281 return -ERANGE; 282 283 return i2c_smbus_write_word_swapped(data->client, data_reg, val); 284 } 285 286 287 static int vcnl4000_measure(struct vcnl4000_data *data, u8 req_mask, 288 u8 rdy_mask, u8 data_reg, int *val) 289 { 290 int tries = 20; 291 int ret; 292 293 mutex_lock(&data->vcnl4000_lock); 294 295 ret = i2c_smbus_write_byte_data(data->client, VCNL4000_COMMAND, 296 req_mask); 297 if (ret < 0) 298 goto fail; 299 300 /* wait for data to become ready */ 301 while (tries--) { 302 ret = i2c_smbus_read_byte_data(data->client, VCNL4000_COMMAND); 303 if (ret < 0) 304 goto fail; 305 if (ret & rdy_mask) 306 break; 307 msleep(20); /* measurement takes up to 100 ms */ 308 } 309 310 if (tries < 0) { 311 dev_err(&data->client->dev, 312 "vcnl4000_measure() failed, data not ready\n"); 313 ret = -EIO; 314 goto fail; 315 } 316 317 ret = vcnl4000_read_data(data, data_reg, val); 318 if (ret < 0) 319 goto fail; 320 321 mutex_unlock(&data->vcnl4000_lock); 322 323 return 0; 324 325 fail: 326 mutex_unlock(&data->vcnl4000_lock); 327 return ret; 328 } 329 330 static int vcnl4200_measure(struct vcnl4000_data *data, 331 struct vcnl4200_channel *chan, int *val) 332 { 333 int ret; 334 s64 delta; 335 ktime_t next_measurement; 336 337 mutex_lock(&chan->lock); 338 339 next_measurement = ktime_add(chan->last_measurement, 340 chan->sampling_rate); 341 delta = ktime_us_delta(next_measurement, ktime_get()); 342 if (delta > 0) 343 usleep_range(delta, delta + 500); 344 chan->last_measurement = ktime_get(); 345 346 mutex_unlock(&chan->lock); 347 348 ret = i2c_smbus_read_word_data(data->client, chan->reg); 349 if (ret < 0) 350 return ret; 351 352 *val = ret; 353 354 return 0; 355 } 356 357 static int vcnl4000_measure_light(struct vcnl4000_data *data, int *val) 358 { 359 return vcnl4000_measure(data, 360 VCNL4000_AL_OD, VCNL4000_AL_RDY, 361 VCNL4000_AL_RESULT_HI, val); 362 } 363 364 static int vcnl4200_measure_light(struct vcnl4000_data *data, int *val) 365 { 366 return vcnl4200_measure(data, &data->vcnl4200_al, val); 367 } 368 369 static int vcnl4000_measure_proximity(struct vcnl4000_data *data, int *val) 370 { 371 return vcnl4000_measure(data, 372 VCNL4000_PS_OD, VCNL4000_PS_RDY, 373 VCNL4000_PS_RESULT_HI, val); 374 } 375 376 static int vcnl4200_measure_proximity(struct vcnl4000_data *data, int *val) 377 { 378 return vcnl4200_measure(data, &data->vcnl4200_ps, val); 379 } 380 381 static int vcnl4010_read_proxy_samp_freq(struct vcnl4000_data *data, int *val, 382 int *val2) 383 { 384 int ret; 385 386 ret = i2c_smbus_read_byte_data(data->client, VCNL4010_PROX_RATE); 387 if (ret < 0) 388 return ret; 389 390 if (ret >= ARRAY_SIZE(vcnl4010_prox_sampling_frequency)) 391 return -EINVAL; 392 393 *val = vcnl4010_prox_sampling_frequency[ret][0]; 394 *val2 = vcnl4010_prox_sampling_frequency[ret][1]; 395 396 return 0; 397 } 398 399 static bool vcnl4010_is_in_periodic_mode(struct vcnl4000_data *data) 400 { 401 int ret; 402 403 ret = i2c_smbus_read_byte_data(data->client, VCNL4000_COMMAND); 404 if (ret < 0) 405 return false; 406 407 return !!(ret & VCNL4000_SELF_TIMED_EN); 408 } 409 410 static int vcnl4000_set_pm_runtime_state(struct vcnl4000_data *data, bool on) 411 { 412 struct device *dev = &data->client->dev; 413 int ret; 414 415 if (on) { 416 ret = pm_runtime_get_sync(dev); 417 if (ret < 0) 418 pm_runtime_put_noidle(dev); 419 } else { 420 pm_runtime_mark_last_busy(dev); 421 ret = pm_runtime_put_autosuspend(dev); 422 } 423 424 return ret; 425 } 426 427 static int vcnl4000_read_raw(struct iio_dev *indio_dev, 428 struct iio_chan_spec const *chan, 429 int *val, int *val2, long mask) 430 { 431 int ret; 432 struct vcnl4000_data *data = iio_priv(indio_dev); 433 434 switch (mask) { 435 case IIO_CHAN_INFO_RAW: 436 ret = vcnl4000_set_pm_runtime_state(data, true); 437 if (ret < 0) 438 return ret; 439 440 switch (chan->type) { 441 case IIO_LIGHT: 442 ret = data->chip_spec->measure_light(data, val); 443 if (!ret) 444 ret = IIO_VAL_INT; 445 break; 446 case IIO_PROXIMITY: 447 ret = data->chip_spec->measure_proximity(data, val); 448 if (!ret) 449 ret = IIO_VAL_INT; 450 break; 451 default: 452 ret = -EINVAL; 453 } 454 vcnl4000_set_pm_runtime_state(data, false); 455 return ret; 456 case IIO_CHAN_INFO_SCALE: 457 if (chan->type != IIO_LIGHT) 458 return -EINVAL; 459 460 *val = 0; 461 *val2 = data->al_scale; 462 return IIO_VAL_INT_PLUS_MICRO; 463 default: 464 return -EINVAL; 465 } 466 } 467 468 static int vcnl4010_read_raw(struct iio_dev *indio_dev, 469 struct iio_chan_spec const *chan, 470 int *val, int *val2, long mask) 471 { 472 int ret; 473 struct vcnl4000_data *data = iio_priv(indio_dev); 474 475 switch (mask) { 476 case IIO_CHAN_INFO_RAW: 477 case IIO_CHAN_INFO_SCALE: 478 ret = iio_device_claim_direct_mode(indio_dev); 479 if (ret) 480 return ret; 481 482 /* Protect against event capture. */ 483 if (vcnl4010_is_in_periodic_mode(data)) { 484 ret = -EBUSY; 485 } else { 486 ret = vcnl4000_read_raw(indio_dev, chan, val, val2, 487 mask); 488 } 489 490 iio_device_release_direct_mode(indio_dev); 491 return ret; 492 case IIO_CHAN_INFO_SAMP_FREQ: 493 switch (chan->type) { 494 case IIO_PROXIMITY: 495 ret = vcnl4010_read_proxy_samp_freq(data, val, val2); 496 if (ret < 0) 497 return ret; 498 return IIO_VAL_INT_PLUS_MICRO; 499 default: 500 return -EINVAL; 501 } 502 default: 503 return -EINVAL; 504 } 505 } 506 507 static int vcnl4010_read_avail(struct iio_dev *indio_dev, 508 struct iio_chan_spec const *chan, 509 const int **vals, int *type, int *length, 510 long mask) 511 { 512 switch (mask) { 513 case IIO_CHAN_INFO_SAMP_FREQ: 514 *vals = (int *)vcnl4010_prox_sampling_frequency; 515 *type = IIO_VAL_INT_PLUS_MICRO; 516 *length = 2 * ARRAY_SIZE(vcnl4010_prox_sampling_frequency); 517 return IIO_AVAIL_LIST; 518 default: 519 return -EINVAL; 520 } 521 } 522 523 static int vcnl4010_write_proxy_samp_freq(struct vcnl4000_data *data, int val, 524 int val2) 525 { 526 unsigned int i; 527 int index = -1; 528 529 for (i = 0; i < ARRAY_SIZE(vcnl4010_prox_sampling_frequency); i++) { 530 if (val == vcnl4010_prox_sampling_frequency[i][0] && 531 val2 == vcnl4010_prox_sampling_frequency[i][1]) { 532 index = i; 533 break; 534 } 535 } 536 537 if (index < 0) 538 return -EINVAL; 539 540 return i2c_smbus_write_byte_data(data->client, VCNL4010_PROX_RATE, 541 index); 542 } 543 544 static int vcnl4010_write_raw(struct iio_dev *indio_dev, 545 struct iio_chan_spec const *chan, 546 int val, int val2, long mask) 547 { 548 int ret; 549 struct vcnl4000_data *data = iio_priv(indio_dev); 550 551 ret = iio_device_claim_direct_mode(indio_dev); 552 if (ret) 553 return ret; 554 555 /* Protect against event capture. */ 556 if (vcnl4010_is_in_periodic_mode(data)) { 557 ret = -EBUSY; 558 goto end; 559 } 560 561 switch (mask) { 562 case IIO_CHAN_INFO_SAMP_FREQ: 563 switch (chan->type) { 564 case IIO_PROXIMITY: 565 ret = vcnl4010_write_proxy_samp_freq(data, val, val2); 566 goto end; 567 default: 568 ret = -EINVAL; 569 goto end; 570 } 571 default: 572 ret = -EINVAL; 573 goto end; 574 } 575 576 end: 577 iio_device_release_direct_mode(indio_dev); 578 return ret; 579 } 580 581 static int vcnl4010_read_event(struct iio_dev *indio_dev, 582 const struct iio_chan_spec *chan, 583 enum iio_event_type type, 584 enum iio_event_direction dir, 585 enum iio_event_info info, 586 int *val, int *val2) 587 { 588 int ret; 589 struct vcnl4000_data *data = iio_priv(indio_dev); 590 591 switch (info) { 592 case IIO_EV_INFO_VALUE: 593 switch (dir) { 594 case IIO_EV_DIR_RISING: 595 ret = vcnl4000_read_data(data, VCNL4010_HIGH_THR_HI, 596 val); 597 if (ret < 0) 598 return ret; 599 return IIO_VAL_INT; 600 case IIO_EV_DIR_FALLING: 601 ret = vcnl4000_read_data(data, VCNL4010_LOW_THR_HI, 602 val); 603 if (ret < 0) 604 return ret; 605 return IIO_VAL_INT; 606 default: 607 return -EINVAL; 608 } 609 default: 610 return -EINVAL; 611 } 612 } 613 614 static int vcnl4010_write_event(struct iio_dev *indio_dev, 615 const struct iio_chan_spec *chan, 616 enum iio_event_type type, 617 enum iio_event_direction dir, 618 enum iio_event_info info, 619 int val, int val2) 620 { 621 int ret; 622 struct vcnl4000_data *data = iio_priv(indio_dev); 623 624 switch (info) { 625 case IIO_EV_INFO_VALUE: 626 switch (dir) { 627 case IIO_EV_DIR_RISING: 628 ret = vcnl4000_write_data(data, VCNL4010_HIGH_THR_HI, 629 val); 630 if (ret < 0) 631 return ret; 632 return IIO_VAL_INT; 633 case IIO_EV_DIR_FALLING: 634 ret = vcnl4000_write_data(data, VCNL4010_LOW_THR_HI, 635 val); 636 if (ret < 0) 637 return ret; 638 return IIO_VAL_INT; 639 default: 640 return -EINVAL; 641 } 642 default: 643 return -EINVAL; 644 } 645 } 646 647 static bool vcnl4010_is_thr_enabled(struct vcnl4000_data *data) 648 { 649 int ret; 650 651 ret = i2c_smbus_read_byte_data(data->client, VCNL4010_INT_CTRL); 652 if (ret < 0) 653 return false; 654 655 return !!(ret & VCNL4010_INT_THR_EN); 656 } 657 658 static int vcnl4010_read_event_config(struct iio_dev *indio_dev, 659 const struct iio_chan_spec *chan, 660 enum iio_event_type type, 661 enum iio_event_direction dir) 662 { 663 struct vcnl4000_data *data = iio_priv(indio_dev); 664 665 switch (chan->type) { 666 case IIO_PROXIMITY: 667 return vcnl4010_is_thr_enabled(data); 668 default: 669 return -EINVAL; 670 } 671 } 672 673 static int vcnl4010_config_threshold(struct iio_dev *indio_dev, bool state) 674 { 675 struct vcnl4000_data *data = iio_priv(indio_dev); 676 int ret; 677 int icr; 678 int command; 679 680 if (state) { 681 ret = iio_device_claim_direct_mode(indio_dev); 682 if (ret) 683 return ret; 684 685 /* Enable periodic measurement of proximity data. */ 686 command = VCNL4000_SELF_TIMED_EN | VCNL4000_PROX_EN; 687 688 /* 689 * Enable interrupts on threshold, for proximity data by 690 * default. 691 */ 692 icr = VCNL4010_INT_THR_EN; 693 } else { 694 if (!vcnl4010_is_thr_enabled(data)) 695 return 0; 696 697 command = 0; 698 icr = 0; 699 } 700 701 ret = i2c_smbus_write_byte_data(data->client, VCNL4000_COMMAND, 702 command); 703 if (ret < 0) 704 goto end; 705 706 ret = i2c_smbus_write_byte_data(data->client, VCNL4010_INT_CTRL, icr); 707 708 end: 709 if (state) 710 iio_device_release_direct_mode(indio_dev); 711 712 return ret; 713 } 714 715 static int vcnl4010_write_event_config(struct iio_dev *indio_dev, 716 const struct iio_chan_spec *chan, 717 enum iio_event_type type, 718 enum iio_event_direction dir, 719 int state) 720 { 721 switch (chan->type) { 722 case IIO_PROXIMITY: 723 return vcnl4010_config_threshold(indio_dev, state); 724 default: 725 return -EINVAL; 726 } 727 } 728 729 static ssize_t vcnl4000_read_near_level(struct iio_dev *indio_dev, 730 uintptr_t priv, 731 const struct iio_chan_spec *chan, 732 char *buf) 733 { 734 struct vcnl4000_data *data = iio_priv(indio_dev); 735 736 return sprintf(buf, "%u\n", data->near_level); 737 } 738 739 static const struct iio_chan_spec_ext_info vcnl4000_ext_info[] = { 740 { 741 .name = "nearlevel", 742 .shared = IIO_SEPARATE, 743 .read = vcnl4000_read_near_level, 744 }, 745 { /* sentinel */ } 746 }; 747 748 static const struct iio_event_spec vcnl4000_event_spec[] = { 749 { 750 .type = IIO_EV_TYPE_THRESH, 751 .dir = IIO_EV_DIR_RISING, 752 .mask_separate = BIT(IIO_EV_INFO_VALUE), 753 }, { 754 .type = IIO_EV_TYPE_THRESH, 755 .dir = IIO_EV_DIR_FALLING, 756 .mask_separate = BIT(IIO_EV_INFO_VALUE), 757 }, { 758 .type = IIO_EV_TYPE_THRESH, 759 .dir = IIO_EV_DIR_EITHER, 760 .mask_separate = BIT(IIO_EV_INFO_ENABLE), 761 } 762 }; 763 764 static const struct iio_chan_spec vcnl4000_channels[] = { 765 { 766 .type = IIO_LIGHT, 767 .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | 768 BIT(IIO_CHAN_INFO_SCALE), 769 }, { 770 .type = IIO_PROXIMITY, 771 .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), 772 .ext_info = vcnl4000_ext_info, 773 } 774 }; 775 776 static const struct iio_chan_spec vcnl4010_channels[] = { 777 { 778 .type = IIO_LIGHT, 779 .scan_index = -1, 780 .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | 781 BIT(IIO_CHAN_INFO_SCALE), 782 }, { 783 .type = IIO_PROXIMITY, 784 .scan_index = 0, 785 .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | 786 BIT(IIO_CHAN_INFO_SAMP_FREQ), 787 .info_mask_separate_available = BIT(IIO_CHAN_INFO_SAMP_FREQ), 788 .event_spec = vcnl4000_event_spec, 789 .num_event_specs = ARRAY_SIZE(vcnl4000_event_spec), 790 .ext_info = vcnl4000_ext_info, 791 .scan_type = { 792 .sign = 'u', 793 .realbits = 16, 794 .storagebits = 16, 795 .endianness = IIO_CPU, 796 }, 797 }, 798 IIO_CHAN_SOFT_TIMESTAMP(1), 799 }; 800 801 static const struct iio_info vcnl4000_info = { 802 .read_raw = vcnl4000_read_raw, 803 }; 804 805 static const struct iio_info vcnl4010_info = { 806 .read_raw = vcnl4010_read_raw, 807 .read_avail = vcnl4010_read_avail, 808 .write_raw = vcnl4010_write_raw, 809 .read_event_value = vcnl4010_read_event, 810 .write_event_value = vcnl4010_write_event, 811 .read_event_config = vcnl4010_read_event_config, 812 .write_event_config = vcnl4010_write_event_config, 813 }; 814 815 static const struct vcnl4000_chip_spec vcnl4000_chip_spec_cfg[] = { 816 [VCNL4000] = { 817 .prod = "VCNL4000", 818 .init = vcnl4000_init, 819 .measure_light = vcnl4000_measure_light, 820 .measure_proximity = vcnl4000_measure_proximity, 821 .set_power_state = vcnl4000_set_power_state, 822 .channels = vcnl4000_channels, 823 .num_channels = ARRAY_SIZE(vcnl4000_channels), 824 .info = &vcnl4000_info, 825 .irq_support = false, 826 }, 827 [VCNL4010] = { 828 .prod = "VCNL4010/4020", 829 .init = vcnl4000_init, 830 .measure_light = vcnl4000_measure_light, 831 .measure_proximity = vcnl4000_measure_proximity, 832 .set_power_state = vcnl4000_set_power_state, 833 .channels = vcnl4010_channels, 834 .num_channels = ARRAY_SIZE(vcnl4010_channels), 835 .info = &vcnl4010_info, 836 .irq_support = true, 837 }, 838 [VCNL4040] = { 839 .prod = "VCNL4040", 840 .init = vcnl4200_init, 841 .measure_light = vcnl4200_measure_light, 842 .measure_proximity = vcnl4200_measure_proximity, 843 .set_power_state = vcnl4200_set_power_state, 844 .channels = vcnl4000_channels, 845 .num_channels = ARRAY_SIZE(vcnl4000_channels), 846 .info = &vcnl4000_info, 847 .irq_support = false, 848 }, 849 [VCNL4200] = { 850 .prod = "VCNL4200", 851 .init = vcnl4200_init, 852 .measure_light = vcnl4200_measure_light, 853 .measure_proximity = vcnl4200_measure_proximity, 854 .set_power_state = vcnl4200_set_power_state, 855 .channels = vcnl4000_channels, 856 .num_channels = ARRAY_SIZE(vcnl4000_channels), 857 .info = &vcnl4000_info, 858 .irq_support = false, 859 }, 860 }; 861 862 static irqreturn_t vcnl4010_irq_thread(int irq, void *p) 863 { 864 struct iio_dev *indio_dev = p; 865 struct vcnl4000_data *data = iio_priv(indio_dev); 866 unsigned long isr; 867 int ret; 868 869 ret = i2c_smbus_read_byte_data(data->client, VCNL4010_ISR); 870 if (ret < 0) 871 goto end; 872 873 isr = ret; 874 875 if (isr & VCNL4010_INT_THR) { 876 if (test_bit(VCNL4010_INT_THR_LOW, &isr)) { 877 iio_push_event(indio_dev, 878 IIO_UNMOD_EVENT_CODE( 879 IIO_PROXIMITY, 880 1, 881 IIO_EV_TYPE_THRESH, 882 IIO_EV_DIR_FALLING), 883 iio_get_time_ns(indio_dev)); 884 } 885 886 if (test_bit(VCNL4010_INT_THR_HIGH, &isr)) { 887 iio_push_event(indio_dev, 888 IIO_UNMOD_EVENT_CODE( 889 IIO_PROXIMITY, 890 1, 891 IIO_EV_TYPE_THRESH, 892 IIO_EV_DIR_RISING), 893 iio_get_time_ns(indio_dev)); 894 } 895 896 i2c_smbus_write_byte_data(data->client, VCNL4010_ISR, 897 isr & VCNL4010_INT_THR); 898 } 899 900 if (isr & VCNL4010_INT_DRDY && iio_buffer_enabled(indio_dev)) 901 iio_trigger_poll_chained(indio_dev->trig); 902 903 end: 904 return IRQ_HANDLED; 905 } 906 907 static irqreturn_t vcnl4010_trigger_handler(int irq, void *p) 908 { 909 struct iio_poll_func *pf = p; 910 struct iio_dev *indio_dev = pf->indio_dev; 911 struct vcnl4000_data *data = iio_priv(indio_dev); 912 const unsigned long *active_scan_mask = indio_dev->active_scan_mask; 913 u16 buffer[8] = {0}; /* 1x16-bit + ts */ 914 bool data_read = false; 915 unsigned long isr; 916 int val = 0; 917 int ret; 918 919 ret = i2c_smbus_read_byte_data(data->client, VCNL4010_ISR); 920 if (ret < 0) 921 goto end; 922 923 isr = ret; 924 925 if (test_bit(0, active_scan_mask)) { 926 if (test_bit(VCNL4010_INT_PROXIMITY, &isr)) { 927 ret = vcnl4000_read_data(data, 928 VCNL4000_PS_RESULT_HI, 929 &val); 930 if (ret < 0) 931 goto end; 932 933 buffer[0] = val; 934 data_read = true; 935 } 936 } 937 938 ret = i2c_smbus_write_byte_data(data->client, VCNL4010_ISR, 939 isr & VCNL4010_INT_DRDY); 940 if (ret < 0) 941 goto end; 942 943 if (!data_read) 944 goto end; 945 946 iio_push_to_buffers_with_timestamp(indio_dev, buffer, 947 iio_get_time_ns(indio_dev)); 948 949 end: 950 iio_trigger_notify_done(indio_dev->trig); 951 return IRQ_HANDLED; 952 } 953 954 static int vcnl4010_buffer_postenable(struct iio_dev *indio_dev) 955 { 956 struct vcnl4000_data *data = iio_priv(indio_dev); 957 int ret; 958 int cmd; 959 960 ret = iio_triggered_buffer_postenable(indio_dev); 961 if (ret) 962 return ret; 963 964 /* Do not enable the buffer if we are already capturing events. */ 965 if (vcnl4010_is_in_periodic_mode(data)) { 966 ret = -EBUSY; 967 goto end; 968 } 969 970 ret = i2c_smbus_write_byte_data(data->client, VCNL4010_INT_CTRL, 971 VCNL4010_INT_PROX_EN); 972 if (ret < 0) 973 goto end; 974 975 cmd = VCNL4000_SELF_TIMED_EN | VCNL4000_PROX_EN; 976 ret = i2c_smbus_write_byte_data(data->client, VCNL4000_COMMAND, cmd); 977 if (ret < 0) 978 goto end; 979 980 return 0; 981 end: 982 iio_triggered_buffer_predisable(indio_dev); 983 984 return ret; 985 } 986 987 static int vcnl4010_buffer_predisable(struct iio_dev *indio_dev) 988 { 989 struct vcnl4000_data *data = iio_priv(indio_dev); 990 int ret, ret_disable; 991 992 ret = i2c_smbus_write_byte_data(data->client, VCNL4010_INT_CTRL, 0); 993 if (ret < 0) 994 goto end; 995 996 ret = i2c_smbus_write_byte_data(data->client, VCNL4000_COMMAND, 0); 997 998 end: 999 ret_disable = iio_triggered_buffer_predisable(indio_dev); 1000 if (ret == 0) 1001 ret = ret_disable; 1002 1003 return ret; 1004 } 1005 1006 static const struct iio_buffer_setup_ops vcnl4010_buffer_ops = { 1007 .postenable = &vcnl4010_buffer_postenable, 1008 .predisable = &vcnl4010_buffer_predisable, 1009 }; 1010 1011 static const struct iio_trigger_ops vcnl4010_trigger_ops = { 1012 .validate_device = iio_trigger_validate_own_device, 1013 }; 1014 1015 static int vcnl4010_probe_trigger(struct iio_dev *indio_dev) 1016 { 1017 struct vcnl4000_data *data = iio_priv(indio_dev); 1018 struct i2c_client *client = data->client; 1019 struct iio_trigger *trigger; 1020 1021 trigger = devm_iio_trigger_alloc(&client->dev, "%s-dev%d", 1022 indio_dev->name, indio_dev->id); 1023 if (!trigger) 1024 return -ENOMEM; 1025 1026 trigger->dev.parent = &client->dev; 1027 trigger->ops = &vcnl4010_trigger_ops; 1028 iio_trigger_set_drvdata(trigger, indio_dev); 1029 1030 return devm_iio_trigger_register(&client->dev, trigger); 1031 } 1032 1033 static int vcnl4000_probe(struct i2c_client *client, 1034 const struct i2c_device_id *id) 1035 { 1036 struct vcnl4000_data *data; 1037 struct iio_dev *indio_dev; 1038 int ret; 1039 1040 indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*data)); 1041 if (!indio_dev) 1042 return -ENOMEM; 1043 1044 data = iio_priv(indio_dev); 1045 i2c_set_clientdata(client, indio_dev); 1046 data->client = client; 1047 data->id = id->driver_data; 1048 data->chip_spec = &vcnl4000_chip_spec_cfg[data->id]; 1049 1050 ret = data->chip_spec->init(data); 1051 if (ret < 0) 1052 return ret; 1053 1054 dev_dbg(&client->dev, "%s Ambient light/proximity sensor, Rev: %02x\n", 1055 data->chip_spec->prod, data->rev); 1056 1057 if (device_property_read_u32(&client->dev, "proximity-near-level", 1058 &data->near_level)) 1059 data->near_level = 0; 1060 1061 indio_dev->dev.parent = &client->dev; 1062 indio_dev->info = data->chip_spec->info; 1063 indio_dev->channels = data->chip_spec->channels; 1064 indio_dev->num_channels = data->chip_spec->num_channels; 1065 indio_dev->name = VCNL4000_DRV_NAME; 1066 indio_dev->modes = INDIO_DIRECT_MODE; 1067 1068 if (client->irq && data->chip_spec->irq_support) { 1069 ret = devm_iio_triggered_buffer_setup(&client->dev, indio_dev, 1070 NULL, 1071 vcnl4010_trigger_handler, 1072 &vcnl4010_buffer_ops); 1073 if (ret < 0) { 1074 dev_err(&client->dev, 1075 "unable to setup iio triggered buffer\n"); 1076 return ret; 1077 } 1078 1079 ret = devm_request_threaded_irq(&client->dev, client->irq, 1080 NULL, vcnl4010_irq_thread, 1081 IRQF_TRIGGER_FALLING | 1082 IRQF_ONESHOT, 1083 "vcnl4010_irq", 1084 indio_dev); 1085 if (ret < 0) { 1086 dev_err(&client->dev, "irq request failed\n"); 1087 return ret; 1088 } 1089 1090 ret = vcnl4010_probe_trigger(indio_dev); 1091 if (ret < 0) 1092 return ret; 1093 } 1094 1095 ret = pm_runtime_set_active(&client->dev); 1096 if (ret < 0) 1097 goto fail_poweroff; 1098 1099 ret = iio_device_register(indio_dev); 1100 if (ret < 0) 1101 goto fail_poweroff; 1102 1103 pm_runtime_enable(&client->dev); 1104 pm_runtime_set_autosuspend_delay(&client->dev, VCNL4000_SLEEP_DELAY_MS); 1105 pm_runtime_use_autosuspend(&client->dev); 1106 1107 return 0; 1108 fail_poweroff: 1109 data->chip_spec->set_power_state(data, false); 1110 return ret; 1111 } 1112 1113 static const struct of_device_id vcnl_4000_of_match[] = { 1114 { 1115 .compatible = "vishay,vcnl4000", 1116 .data = (void *)VCNL4000, 1117 }, 1118 { 1119 .compatible = "vishay,vcnl4010", 1120 .data = (void *)VCNL4010, 1121 }, 1122 { 1123 .compatible = "vishay,vcnl4020", 1124 .data = (void *)VCNL4010, 1125 }, 1126 { 1127 .compatible = "vishay,vcnl4040", 1128 .data = (void *)VCNL4040, 1129 }, 1130 { 1131 .compatible = "vishay,vcnl4200", 1132 .data = (void *)VCNL4200, 1133 }, 1134 {}, 1135 }; 1136 MODULE_DEVICE_TABLE(of, vcnl_4000_of_match); 1137 1138 static int vcnl4000_remove(struct i2c_client *client) 1139 { 1140 struct iio_dev *indio_dev = i2c_get_clientdata(client); 1141 struct vcnl4000_data *data = iio_priv(indio_dev); 1142 1143 pm_runtime_dont_use_autosuspend(&client->dev); 1144 pm_runtime_disable(&client->dev); 1145 iio_device_unregister(indio_dev); 1146 pm_runtime_set_suspended(&client->dev); 1147 1148 return data->chip_spec->set_power_state(data, false); 1149 } 1150 1151 static int __maybe_unused vcnl4000_runtime_suspend(struct device *dev) 1152 { 1153 struct iio_dev *indio_dev = i2c_get_clientdata(to_i2c_client(dev)); 1154 struct vcnl4000_data *data = iio_priv(indio_dev); 1155 1156 return data->chip_spec->set_power_state(data, false); 1157 } 1158 1159 static int __maybe_unused vcnl4000_runtime_resume(struct device *dev) 1160 { 1161 struct iio_dev *indio_dev = i2c_get_clientdata(to_i2c_client(dev)); 1162 struct vcnl4000_data *data = iio_priv(indio_dev); 1163 1164 return data->chip_spec->set_power_state(data, true); 1165 } 1166 1167 static const struct dev_pm_ops vcnl4000_pm_ops = { 1168 SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend, 1169 pm_runtime_force_resume) 1170 SET_RUNTIME_PM_OPS(vcnl4000_runtime_suspend, 1171 vcnl4000_runtime_resume, NULL) 1172 }; 1173 1174 static struct i2c_driver vcnl4000_driver = { 1175 .driver = { 1176 .name = VCNL4000_DRV_NAME, 1177 .pm = &vcnl4000_pm_ops, 1178 .of_match_table = vcnl_4000_of_match, 1179 }, 1180 .probe = vcnl4000_probe, 1181 .id_table = vcnl4000_id, 1182 .remove = vcnl4000_remove, 1183 }; 1184 1185 module_i2c_driver(vcnl4000_driver); 1186 1187 MODULE_AUTHOR("Peter Meerwald <pmeerw@pmeerw.net>"); 1188 MODULE_AUTHOR("Mathieu Othacehe <m.othacehe@gmail.com>"); 1189 MODULE_DESCRIPTION("Vishay VCNL4000 proximity/ambient light sensor driver"); 1190 MODULE_LICENSE("GPL"); 1191