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 vcnl4040_read_als_it(struct vcnl4000_data *data, int *val, int *val2) 541 { 542 int ret; 543 544 ret = i2c_smbus_read_word_data(data->client, VCNL4200_AL_CONF); 545 if (ret < 0) 546 return ret; 547 548 ret = FIELD_GET(VCNL4040_ALS_CONF_IT, ret); 549 if (ret >= data->chip_spec->num_als_it_times) 550 return -EINVAL; 551 552 *val = (*data->chip_spec->als_it_times)[ret][0]; 553 *val2 = (*data->chip_spec->als_it_times)[ret][1]; 554 555 return 0; 556 } 557 558 static ssize_t vcnl4040_write_als_it(struct vcnl4000_data *data, int val) 559 { 560 unsigned int i; 561 int ret; 562 u16 regval; 563 564 for (i = 0; i < data->chip_spec->num_als_it_times; i++) { 565 if (val == (*data->chip_spec->als_it_times)[i][1]) 566 break; 567 } 568 569 if (i == data->chip_spec->num_als_it_times) 570 return -EINVAL; 571 572 data->vcnl4200_al.sampling_rate = ktime_set(0, val * 1200); 573 data->al_scale = div_u64(mul_u32_u32(data->chip_spec->ulux_step, 574 (*data->chip_spec->als_it_times)[0][1]), 575 val); 576 577 guard(mutex)(&data->vcnl4000_lock); 578 579 ret = i2c_smbus_read_word_data(data->client, VCNL4200_AL_CONF); 580 if (ret < 0) 581 return ret; 582 583 regval = FIELD_PREP(VCNL4040_ALS_CONF_IT, i); 584 regval |= (ret & ~VCNL4040_ALS_CONF_IT); 585 return i2c_smbus_write_word_data(data->client, VCNL4200_AL_CONF, regval); 586 } 587 588 static int vcnl4040_read_ps_it(struct vcnl4000_data *data, int *val, int *val2) 589 { 590 int ret; 591 592 ret = i2c_smbus_read_word_data(data->client, VCNL4200_PS_CONF1); 593 if (ret < 0) 594 return ret; 595 596 ret = FIELD_GET(VCNL4040_PS_CONF2_PS_IT, ret); 597 598 if (ret >= data->chip_spec->num_ps_it_times) 599 return -EINVAL; 600 601 *val = (*data->chip_spec->ps_it_times)[ret][0]; 602 *val2 = (*data->chip_spec->ps_it_times)[ret][1]; 603 604 return 0; 605 } 606 607 static ssize_t vcnl4040_write_ps_it(struct vcnl4000_data *data, int val) 608 { 609 unsigned int i; 610 int ret, index = -1; 611 u16 regval; 612 613 for (i = 0; i < data->chip_spec->num_ps_it_times; i++) { 614 if (val == (*data->chip_spec->ps_it_times)[i][1]) { 615 index = i; 616 break; 617 } 618 } 619 620 if (index < 0) 621 return -EINVAL; 622 623 data->vcnl4200_ps.sampling_rate = ktime_set(0, val * 60 * NSEC_PER_USEC); 624 625 guard(mutex)(&data->vcnl4000_lock); 626 627 ret = i2c_smbus_read_word_data(data->client, VCNL4200_PS_CONF1); 628 if (ret < 0) 629 return ret; 630 631 regval = (ret & ~VCNL4040_PS_CONF2_PS_IT) | 632 FIELD_PREP(VCNL4040_PS_CONF2_PS_IT, index); 633 return i2c_smbus_write_word_data(data->client, VCNL4200_PS_CONF1, regval); 634 } 635 636 static ssize_t vcnl4040_read_als_period(struct vcnl4000_data *data, int *val, int *val2) 637 { 638 int ret, ret_pers, it; 639 int64_t val_c; 640 641 ret = i2c_smbus_read_word_data(data->client, VCNL4200_AL_CONF); 642 if (ret < 0) 643 return ret; 644 645 ret_pers = FIELD_GET(VCNL4040_ALS_CONF_PERS, ret); 646 if (ret_pers >= ARRAY_SIZE(vcnl4040_als_persistence)) 647 return -EINVAL; 648 649 it = FIELD_GET(VCNL4040_ALS_CONF_IT, ret); 650 if (it >= data->chip_spec->num_als_it_times) 651 return -EINVAL; 652 653 val_c = mul_u32_u32((*data->chip_spec->als_it_times)[it][1], 654 vcnl4040_als_persistence[ret_pers]); 655 *val = div_u64_rem(val_c, MICRO, val2); 656 657 return IIO_VAL_INT_PLUS_MICRO; 658 } 659 660 static ssize_t vcnl4040_write_als_period(struct vcnl4000_data *data, int val, int val2) 661 { 662 unsigned int i; 663 int ret, it; 664 u16 regval; 665 u64 val_n = mul_u32_u32(val, MICRO) + val2; 666 667 ret = i2c_smbus_read_word_data(data->client, VCNL4200_AL_CONF); 668 if (ret < 0) 669 return ret; 670 671 it = FIELD_GET(VCNL4040_ALS_CONF_IT, ret); 672 if (it >= data->chip_spec->num_als_it_times) 673 return -EINVAL; 674 675 for (i = 0; i < ARRAY_SIZE(vcnl4040_als_persistence) - 1; i++) { 676 if (val_n < mul_u32_u32(vcnl4040_als_persistence[i], 677 (*data->chip_spec->als_it_times)[it][1])) 678 break; 679 } 680 681 guard(mutex)(&data->vcnl4000_lock); 682 683 ret = i2c_smbus_read_word_data(data->client, VCNL4200_AL_CONF); 684 if (ret < 0) 685 return ret; 686 687 regval = FIELD_PREP(VCNL4040_ALS_CONF_PERS, i); 688 regval |= (ret & ~VCNL4040_ALS_CONF_PERS); 689 return i2c_smbus_write_word_data(data->client, VCNL4200_AL_CONF, regval); 690 } 691 692 static ssize_t vcnl4040_read_ps_period(struct vcnl4000_data *data, int *val, int *val2) 693 { 694 int ret, ret_pers, it; 695 696 ret = i2c_smbus_read_word_data(data->client, VCNL4200_PS_CONF1); 697 if (ret < 0) 698 return ret; 699 700 ret_pers = FIELD_GET(VCNL4040_CONF1_PS_PERS, ret); 701 if (ret_pers >= ARRAY_SIZE(vcnl4040_ps_persistence)) 702 return -EINVAL; 703 704 it = FIELD_GET(VCNL4040_PS_CONF2_PS_IT, ret); 705 if (it >= data->chip_spec->num_ps_it_times) 706 return -EINVAL; 707 708 *val = (*data->chip_spec->ps_it_times)[it][0]; 709 *val2 = (*data->chip_spec->ps_it_times)[it][1] * 710 vcnl4040_ps_persistence[ret_pers]; 711 712 return IIO_VAL_INT_PLUS_MICRO; 713 } 714 715 static ssize_t vcnl4040_write_ps_period(struct vcnl4000_data *data, int val, int val2) 716 { 717 int ret, it, i; 718 u16 regval; 719 720 ret = i2c_smbus_read_word_data(data->client, VCNL4200_PS_CONF1); 721 if (ret < 0) 722 return ret; 723 724 it = FIELD_GET(VCNL4040_PS_CONF2_PS_IT, ret); 725 if (it >= data->chip_spec->num_ps_it_times) 726 return -EINVAL; 727 728 if (val > 0) 729 i = ARRAY_SIZE(vcnl4040_ps_persistence) - 1; 730 else { 731 for (i = 0; i < ARRAY_SIZE(vcnl4040_ps_persistence) - 1; i++) { 732 if (val2 <= vcnl4040_ps_persistence[i] * 733 (*data->chip_spec->ps_it_times)[it][1]) 734 break; 735 } 736 } 737 738 guard(mutex)(&data->vcnl4000_lock); 739 740 ret = i2c_smbus_read_word_data(data->client, VCNL4200_PS_CONF1); 741 if (ret < 0) 742 return ret; 743 744 regval = FIELD_PREP(VCNL4040_CONF1_PS_PERS, i); 745 regval |= (ret & ~VCNL4040_CONF1_PS_PERS); 746 return i2c_smbus_write_word_data(data->client, VCNL4200_PS_CONF1, regval); 747 } 748 749 static ssize_t vcnl4040_read_ps_oversampling_ratio(struct vcnl4000_data *data, int *val) 750 { 751 int ret; 752 753 ret = i2c_smbus_read_word_data(data->client, VCNL4200_PS_CONF3); 754 if (ret < 0) 755 return ret; 756 757 ret = FIELD_GET(VCNL4040_PS_CONF3_MPS, ret); 758 if (ret >= ARRAY_SIZE(vcnl4040_ps_oversampling_ratio)) 759 return -EINVAL; 760 761 *val = vcnl4040_ps_oversampling_ratio[ret]; 762 763 return ret; 764 } 765 766 static ssize_t vcnl4040_write_ps_oversampling_ratio(struct vcnl4000_data *data, int val) 767 { 768 unsigned int i; 769 int ret; 770 u16 regval; 771 772 for (i = 0; i < ARRAY_SIZE(vcnl4040_ps_oversampling_ratio); i++) { 773 if (val == vcnl4040_ps_oversampling_ratio[i]) 774 break; 775 } 776 777 if (i >= ARRAY_SIZE(vcnl4040_ps_oversampling_ratio)) 778 return -EINVAL; 779 780 guard(mutex)(&data->vcnl4000_lock); 781 782 ret = i2c_smbus_read_word_data(data->client, VCNL4200_PS_CONF3); 783 if (ret < 0) 784 return ret; 785 786 regval = FIELD_PREP(VCNL4040_PS_CONF3_MPS, i); 787 regval |= (ret & ~VCNL4040_PS_CONF3_MPS); 788 return i2c_smbus_write_word_data(data->client, VCNL4200_PS_CONF3, regval); 789 } 790 791 static ssize_t vcnl4040_read_ps_calibbias(struct vcnl4000_data *data, int *val, int *val2) 792 { 793 int ret; 794 795 ret = i2c_smbus_read_word_data(data->client, VCNL4200_PS_CONF3); 796 if (ret < 0) 797 return ret; 798 799 ret = FIELD_GET(VCNL4040_PS_MS_LED_I, ret); 800 if (ret >= ARRAY_SIZE(vcnl4040_ps_calibbias_ua)) 801 return -EINVAL; 802 803 *val = vcnl4040_ps_calibbias_ua[ret][0]; 804 *val2 = vcnl4040_ps_calibbias_ua[ret][1]; 805 806 return ret; 807 } 808 809 static ssize_t vcnl4040_write_ps_calibbias(struct vcnl4000_data *data, int val) 810 { 811 unsigned int i; 812 int ret; 813 u16 regval; 814 815 for (i = 0; i < ARRAY_SIZE(vcnl4040_ps_calibbias_ua); i++) { 816 if (val == vcnl4040_ps_calibbias_ua[i][1]) 817 break; 818 } 819 820 if (i >= ARRAY_SIZE(vcnl4040_ps_calibbias_ua)) 821 return -EINVAL; 822 823 guard(mutex)(&data->vcnl4000_lock); 824 825 ret = i2c_smbus_read_word_data(data->client, VCNL4200_PS_CONF3); 826 if (ret < 0) 827 return ret; 828 829 regval = (ret & ~VCNL4040_PS_MS_LED_I); 830 regval |= FIELD_PREP(VCNL4040_PS_MS_LED_I, i); 831 return i2c_smbus_write_word_data(data->client, VCNL4200_PS_CONF3, regval); 832 } 833 834 static int vcnl4000_read_raw(struct iio_dev *indio_dev, 835 struct iio_chan_spec const *chan, 836 int *val, int *val2, long mask) 837 { 838 int ret; 839 struct vcnl4000_data *data = iio_priv(indio_dev); 840 841 switch (mask) { 842 case IIO_CHAN_INFO_RAW: 843 ret = pm_runtime_resume_and_get(&data->client->dev); 844 if (ret < 0) 845 return ret; 846 847 switch (chan->type) { 848 case IIO_LIGHT: 849 ret = data->chip_spec->measure_light(data, val); 850 if (!ret) 851 ret = IIO_VAL_INT; 852 break; 853 case IIO_PROXIMITY: 854 ret = data->chip_spec->measure_proximity(data, val); 855 *val2 = data->ps_scale; 856 if (!ret) 857 ret = IIO_VAL_FRACTIONAL; 858 break; 859 default: 860 ret = -EINVAL; 861 } 862 pm_runtime_put_autosuspend(&data->client->dev); 863 return ret; 864 case IIO_CHAN_INFO_SCALE: 865 if (chan->type != IIO_LIGHT) 866 return -EINVAL; 867 868 *val = 0; 869 *val2 = data->al_scale; 870 return IIO_VAL_INT_PLUS_MICRO; 871 case IIO_CHAN_INFO_INT_TIME: 872 switch (chan->type) { 873 case IIO_LIGHT: 874 ret = vcnl4040_read_als_it(data, val, val2); 875 break; 876 case IIO_PROXIMITY: 877 ret = vcnl4040_read_ps_it(data, val, val2); 878 break; 879 default: 880 return -EINVAL; 881 } 882 if (ret < 0) 883 return ret; 884 return IIO_VAL_INT_PLUS_MICRO; 885 case IIO_CHAN_INFO_OVERSAMPLING_RATIO: 886 switch (chan->type) { 887 case IIO_PROXIMITY: 888 ret = vcnl4040_read_ps_oversampling_ratio(data, val); 889 if (ret < 0) 890 return ret; 891 return IIO_VAL_INT; 892 default: 893 return -EINVAL; 894 } 895 case IIO_CHAN_INFO_CALIBBIAS: 896 switch (chan->type) { 897 case IIO_PROXIMITY: 898 ret = vcnl4040_read_ps_calibbias(data, val, val2); 899 if (ret < 0) 900 return ret; 901 return IIO_VAL_INT_PLUS_MICRO; 902 default: 903 return -EINVAL; 904 } 905 default: 906 return -EINVAL; 907 } 908 } 909 910 static int vcnl4040_write_raw(struct iio_dev *indio_dev, 911 struct iio_chan_spec const *chan, 912 int val, int val2, long mask) 913 { 914 struct vcnl4000_data *data = iio_priv(indio_dev); 915 916 switch (mask) { 917 case IIO_CHAN_INFO_INT_TIME: 918 if (val != 0) 919 return -EINVAL; 920 switch (chan->type) { 921 case IIO_LIGHT: 922 return vcnl4040_write_als_it(data, val2); 923 case IIO_PROXIMITY: 924 return vcnl4040_write_ps_it(data, val2); 925 default: 926 return -EINVAL; 927 } 928 case IIO_CHAN_INFO_OVERSAMPLING_RATIO: 929 switch (chan->type) { 930 case IIO_PROXIMITY: 931 return vcnl4040_write_ps_oversampling_ratio(data, val); 932 default: 933 return -EINVAL; 934 } 935 case IIO_CHAN_INFO_CALIBBIAS: 936 switch (chan->type) { 937 case IIO_PROXIMITY: 938 return vcnl4040_write_ps_calibbias(data, val2); 939 default: 940 return -EINVAL; 941 } 942 default: 943 return -EINVAL; 944 } 945 } 946 947 static int vcnl4040_read_avail(struct iio_dev *indio_dev, 948 struct iio_chan_spec const *chan, 949 const int **vals, int *type, int *length, 950 long mask) 951 { 952 struct vcnl4000_data *data = iio_priv(indio_dev); 953 954 switch (mask) { 955 case IIO_CHAN_INFO_INT_TIME: 956 switch (chan->type) { 957 case IIO_LIGHT: 958 *vals = (int *)(*data->chip_spec->als_it_times); 959 *length = 2 * data->chip_spec->num_als_it_times; 960 break; 961 case IIO_PROXIMITY: 962 *vals = (int *)(*data->chip_spec->ps_it_times); 963 *length = 2 * data->chip_spec->num_ps_it_times; 964 break; 965 default: 966 return -EINVAL; 967 } 968 *type = IIO_VAL_INT_PLUS_MICRO; 969 return IIO_AVAIL_LIST; 970 case IIO_CHAN_INFO_OVERSAMPLING_RATIO: 971 switch (chan->type) { 972 case IIO_PROXIMITY: 973 *vals = (int *)vcnl4040_ps_oversampling_ratio; 974 *length = ARRAY_SIZE(vcnl4040_ps_oversampling_ratio); 975 *type = IIO_VAL_INT; 976 return IIO_AVAIL_LIST; 977 default: 978 return -EINVAL; 979 } 980 case IIO_CHAN_INFO_CALIBBIAS: 981 switch (chan->type) { 982 case IIO_PROXIMITY: 983 *vals = (int *)vcnl4040_ps_calibbias_ua; 984 *length = 2 * ARRAY_SIZE(vcnl4040_ps_calibbias_ua); 985 *type = IIO_VAL_INT_PLUS_MICRO; 986 return IIO_AVAIL_LIST; 987 default: 988 return -EINVAL; 989 } 990 default: 991 return -EINVAL; 992 } 993 } 994 995 static int vcnl4010_read_raw(struct iio_dev *indio_dev, 996 struct iio_chan_spec const *chan, 997 int *val, int *val2, long mask) 998 { 999 int ret; 1000 struct vcnl4000_data *data = iio_priv(indio_dev); 1001 1002 switch (mask) { 1003 case IIO_CHAN_INFO_RAW: 1004 case IIO_CHAN_INFO_SCALE: { 1005 IIO_DEV_ACQUIRE_DIRECT_MODE(indio_dev, claim); 1006 if (IIO_DEV_ACQUIRE_FAILED(claim)) 1007 return -EBUSY; 1008 1009 /* Protect against event capture. */ 1010 if (vcnl4010_is_in_periodic_mode(data)) 1011 return -EBUSY; 1012 1013 return vcnl4000_read_raw(indio_dev, chan, val, val2, mask); 1014 } 1015 case IIO_CHAN_INFO_SAMP_FREQ: 1016 switch (chan->type) { 1017 case IIO_PROXIMITY: 1018 ret = vcnl4010_read_proxy_samp_freq(data, val, val2); 1019 if (ret < 0) 1020 return ret; 1021 return IIO_VAL_INT_PLUS_MICRO; 1022 default: 1023 return -EINVAL; 1024 } 1025 default: 1026 return -EINVAL; 1027 } 1028 } 1029 1030 static int vcnl4010_read_avail(struct iio_dev *indio_dev, 1031 struct iio_chan_spec const *chan, 1032 const int **vals, int *type, int *length, 1033 long mask) 1034 { 1035 switch (mask) { 1036 case IIO_CHAN_INFO_SAMP_FREQ: 1037 *vals = (int *)vcnl4010_prox_sampling_frequency; 1038 *type = IIO_VAL_INT_PLUS_MICRO; 1039 *length = 2 * ARRAY_SIZE(vcnl4010_prox_sampling_frequency); 1040 return IIO_AVAIL_LIST; 1041 default: 1042 return -EINVAL; 1043 } 1044 } 1045 1046 static int vcnl4010_write_proxy_samp_freq(struct vcnl4000_data *data, int val, 1047 int val2) 1048 { 1049 unsigned int i; 1050 int index = -1; 1051 1052 for (i = 0; i < ARRAY_SIZE(vcnl4010_prox_sampling_frequency); i++) { 1053 if (val == vcnl4010_prox_sampling_frequency[i][0] && 1054 val2 == vcnl4010_prox_sampling_frequency[i][1]) { 1055 index = i; 1056 break; 1057 } 1058 } 1059 1060 if (index < 0) 1061 return -EINVAL; 1062 1063 return i2c_smbus_write_byte_data(data->client, VCNL4010_PROX_RATE, 1064 index); 1065 } 1066 1067 static int vcnl4010_write_raw(struct iio_dev *indio_dev, 1068 struct iio_chan_spec const *chan, 1069 int val, int val2, long mask) 1070 { 1071 struct vcnl4000_data *data = iio_priv(indio_dev); 1072 1073 IIO_DEV_ACQUIRE_DIRECT_MODE(indio_dev, claim); 1074 if (IIO_DEV_ACQUIRE_FAILED(claim)) 1075 return -EBUSY; 1076 1077 /* Protect against event capture. */ 1078 if (vcnl4010_is_in_periodic_mode(data)) 1079 return -EBUSY; 1080 1081 switch (mask) { 1082 case IIO_CHAN_INFO_SAMP_FREQ: 1083 switch (chan->type) { 1084 case IIO_PROXIMITY: 1085 return vcnl4010_write_proxy_samp_freq(data, val, val2); 1086 default: 1087 return -EINVAL; 1088 } 1089 default: 1090 return -EINVAL; 1091 } 1092 } 1093 1094 static int vcnl4010_read_event(struct iio_dev *indio_dev, 1095 const struct iio_chan_spec *chan, 1096 enum iio_event_type type, 1097 enum iio_event_direction dir, 1098 enum iio_event_info info, 1099 int *val, int *val2) 1100 { 1101 int ret; 1102 struct vcnl4000_data *data = iio_priv(indio_dev); 1103 1104 switch (info) { 1105 case IIO_EV_INFO_VALUE: 1106 switch (dir) { 1107 case IIO_EV_DIR_RISING: 1108 ret = vcnl4000_read_data(data, VCNL4010_HIGH_THR_HI, 1109 val); 1110 if (ret < 0) 1111 return ret; 1112 return IIO_VAL_INT; 1113 case IIO_EV_DIR_FALLING: 1114 ret = vcnl4000_read_data(data, VCNL4010_LOW_THR_HI, 1115 val); 1116 if (ret < 0) 1117 return ret; 1118 return IIO_VAL_INT; 1119 default: 1120 return -EINVAL; 1121 } 1122 default: 1123 return -EINVAL; 1124 } 1125 } 1126 1127 static int vcnl4010_write_event(struct iio_dev *indio_dev, 1128 const struct iio_chan_spec *chan, 1129 enum iio_event_type type, 1130 enum iio_event_direction dir, 1131 enum iio_event_info info, 1132 int val, int val2) 1133 { 1134 int ret; 1135 struct vcnl4000_data *data = iio_priv(indio_dev); 1136 1137 switch (info) { 1138 case IIO_EV_INFO_VALUE: 1139 switch (dir) { 1140 case IIO_EV_DIR_RISING: 1141 ret = vcnl4000_write_data(data, VCNL4010_HIGH_THR_HI, 1142 val); 1143 if (ret < 0) 1144 return ret; 1145 return IIO_VAL_INT; 1146 case IIO_EV_DIR_FALLING: 1147 ret = vcnl4000_write_data(data, VCNL4010_LOW_THR_HI, 1148 val); 1149 if (ret < 0) 1150 return ret; 1151 return IIO_VAL_INT; 1152 default: 1153 return -EINVAL; 1154 } 1155 default: 1156 return -EINVAL; 1157 } 1158 } 1159 1160 static int vcnl4040_read_event(struct iio_dev *indio_dev, 1161 const struct iio_chan_spec *chan, 1162 enum iio_event_type type, 1163 enum iio_event_direction dir, 1164 enum iio_event_info info, 1165 int *val, int *val2) 1166 { 1167 int ret; 1168 struct vcnl4000_data *data = iio_priv(indio_dev); 1169 1170 switch (chan->type) { 1171 case IIO_LIGHT: 1172 switch (info) { 1173 case IIO_EV_INFO_PERIOD: 1174 return vcnl4040_read_als_period(data, val, val2); 1175 case IIO_EV_INFO_VALUE: 1176 switch (dir) { 1177 case IIO_EV_DIR_RISING: 1178 ret = i2c_smbus_read_word_data(data->client, 1179 VCNL4040_ALS_THDH_LM); 1180 break; 1181 case IIO_EV_DIR_FALLING: 1182 ret = i2c_smbus_read_word_data(data->client, 1183 VCNL4040_ALS_THDL_LM); 1184 break; 1185 default: 1186 return -EINVAL; 1187 } 1188 break; 1189 default: 1190 return -EINVAL; 1191 } 1192 break; 1193 case IIO_PROXIMITY: 1194 switch (info) { 1195 case IIO_EV_INFO_PERIOD: 1196 return vcnl4040_read_ps_period(data, val, val2); 1197 case IIO_EV_INFO_VALUE: 1198 switch (dir) { 1199 case IIO_EV_DIR_RISING: 1200 ret = i2c_smbus_read_word_data(data->client, 1201 VCNL4040_PS_THDH_LM); 1202 break; 1203 case IIO_EV_DIR_FALLING: 1204 ret = i2c_smbus_read_word_data(data->client, 1205 VCNL4040_PS_THDL_LM); 1206 break; 1207 default: 1208 return -EINVAL; 1209 } 1210 break; 1211 default: 1212 return -EINVAL; 1213 } 1214 break; 1215 default: 1216 return -EINVAL; 1217 } 1218 if (ret < 0) 1219 return ret; 1220 *val = ret; 1221 return IIO_VAL_INT; 1222 } 1223 1224 static int vcnl4040_write_event(struct iio_dev *indio_dev, 1225 const struct iio_chan_spec *chan, 1226 enum iio_event_type type, 1227 enum iio_event_direction dir, 1228 enum iio_event_info info, 1229 int val, int val2) 1230 { 1231 int ret; 1232 struct vcnl4000_data *data = iio_priv(indio_dev); 1233 1234 switch (chan->type) { 1235 case IIO_LIGHT: 1236 switch (info) { 1237 case IIO_EV_INFO_PERIOD: 1238 return vcnl4040_write_als_period(data, val, val2); 1239 case IIO_EV_INFO_VALUE: 1240 switch (dir) { 1241 case IIO_EV_DIR_RISING: 1242 ret = i2c_smbus_write_word_data(data->client, 1243 VCNL4040_ALS_THDH_LM, 1244 val); 1245 break; 1246 case IIO_EV_DIR_FALLING: 1247 ret = i2c_smbus_write_word_data(data->client, 1248 VCNL4040_ALS_THDL_LM, 1249 val); 1250 break; 1251 default: 1252 return -EINVAL; 1253 } 1254 break; 1255 default: 1256 return -EINVAL; 1257 } 1258 break; 1259 case IIO_PROXIMITY: 1260 switch (info) { 1261 case IIO_EV_INFO_PERIOD: 1262 return vcnl4040_write_ps_period(data, val, val2); 1263 case IIO_EV_INFO_VALUE: 1264 switch (dir) { 1265 case IIO_EV_DIR_RISING: 1266 ret = i2c_smbus_write_word_data(data->client, 1267 VCNL4040_PS_THDH_LM, 1268 val); 1269 break; 1270 case IIO_EV_DIR_FALLING: 1271 ret = i2c_smbus_write_word_data(data->client, 1272 VCNL4040_PS_THDL_LM, 1273 val); 1274 break; 1275 default: 1276 return -EINVAL; 1277 } 1278 break; 1279 default: 1280 return -EINVAL; 1281 } 1282 break; 1283 default: 1284 return -EINVAL; 1285 } 1286 if (ret < 0) 1287 return ret; 1288 return IIO_VAL_INT; 1289 } 1290 1291 static bool vcnl4010_is_thr_enabled(struct vcnl4000_data *data) 1292 { 1293 int ret; 1294 1295 ret = i2c_smbus_read_byte_data(data->client, VCNL4010_INT_CTRL); 1296 if (ret < 0) 1297 return false; 1298 1299 return !!(ret & VCNL4010_INT_THR_EN); 1300 } 1301 1302 static int vcnl4010_read_event_config(struct iio_dev *indio_dev, 1303 const struct iio_chan_spec *chan, 1304 enum iio_event_type type, 1305 enum iio_event_direction dir) 1306 { 1307 struct vcnl4000_data *data = iio_priv(indio_dev); 1308 1309 switch (chan->type) { 1310 case IIO_PROXIMITY: 1311 return vcnl4010_is_thr_enabled(data); 1312 default: 1313 return -EINVAL; 1314 } 1315 } 1316 1317 static int vcnl4010_config_threshold_enable(struct vcnl4000_data *data) 1318 { 1319 int ret; 1320 1321 /* Enable periodic measurement of proximity data. */ 1322 ret = i2c_smbus_write_byte_data(data->client, VCNL4000_COMMAND, 1323 VCNL4000_SELF_TIMED_EN | VCNL4000_PROX_EN); 1324 if (ret < 0) 1325 return ret; 1326 1327 /* 1328 * Enable interrupts on threshold, for proximity data by 1329 * default. 1330 */ 1331 return i2c_smbus_write_byte_data(data->client, VCNL4010_INT_CTRL, 1332 VCNL4010_INT_THR_EN); 1333 } 1334 1335 static int vcnl4010_config_threshold_disable(struct vcnl4000_data *data) 1336 { 1337 int ret; 1338 1339 if (!vcnl4010_is_thr_enabled(data)) 1340 return 0; 1341 1342 ret = i2c_smbus_write_byte_data(data->client, VCNL4000_COMMAND, 0); 1343 if (ret < 0) 1344 return ret; 1345 1346 return i2c_smbus_write_byte_data(data->client, VCNL4010_INT_CTRL, 0); 1347 } 1348 1349 static int vcnl4010_config_threshold(struct iio_dev *indio_dev, bool state) 1350 { 1351 struct vcnl4000_data *data = iio_priv(indio_dev); 1352 1353 if (state) { 1354 IIO_DEV_ACQUIRE_DIRECT_MODE(indio_dev, claim); 1355 if (IIO_DEV_ACQUIRE_FAILED(claim)) 1356 return -EBUSY; 1357 1358 return vcnl4010_config_threshold_enable(data); 1359 } else { 1360 return vcnl4010_config_threshold_disable(data); 1361 } 1362 } 1363 1364 static int vcnl4010_write_event_config(struct iio_dev *indio_dev, 1365 const struct iio_chan_spec *chan, 1366 enum iio_event_type type, 1367 enum iio_event_direction dir, 1368 bool state) 1369 { 1370 switch (chan->type) { 1371 case IIO_PROXIMITY: 1372 return vcnl4010_config_threshold(indio_dev, state); 1373 default: 1374 return -EINVAL; 1375 } 1376 } 1377 1378 static int vcnl4040_read_event_config(struct iio_dev *indio_dev, 1379 const struct iio_chan_spec *chan, 1380 enum iio_event_type type, 1381 enum iio_event_direction dir) 1382 { 1383 int ret; 1384 struct vcnl4000_data *data = iio_priv(indio_dev); 1385 1386 switch (chan->type) { 1387 case IIO_LIGHT: 1388 ret = i2c_smbus_read_word_data(data->client, VCNL4200_AL_CONF); 1389 if (ret < 0) 1390 return ret; 1391 1392 data->als_int = FIELD_GET(VCNL4040_ALS_CONF_INT_EN, ret); 1393 1394 return data->als_int; 1395 case IIO_PROXIMITY: 1396 ret = i2c_smbus_read_word_data(data->client, VCNL4200_PS_CONF1); 1397 if (ret < 0) 1398 return ret; 1399 1400 data->ps_int = FIELD_GET(VCNL4040_PS_CONF2_PS_INT, ret); 1401 1402 return (dir == IIO_EV_DIR_RISING) ? 1403 FIELD_GET(VCNL4040_PS_IF_AWAY, ret) : 1404 FIELD_GET(VCNL4040_PS_IF_CLOSE, ret); 1405 default: 1406 return -EINVAL; 1407 } 1408 } 1409 1410 static int vcnl4040_write_event_config(struct iio_dev *indio_dev, 1411 const struct iio_chan_spec *chan, 1412 enum iio_event_type type, 1413 enum iio_event_direction dir, 1414 bool state) 1415 { 1416 int ret; 1417 u16 val, mask; 1418 struct vcnl4000_data *data = iio_priv(indio_dev); 1419 1420 guard(mutex)(&data->vcnl4000_lock); 1421 1422 switch (chan->type) { 1423 case IIO_LIGHT: 1424 ret = i2c_smbus_read_word_data(data->client, VCNL4200_AL_CONF); 1425 if (ret < 0) 1426 return ret; 1427 1428 mask = VCNL4040_ALS_CONF_INT_EN; 1429 if (state) 1430 val = (ret | mask); 1431 else 1432 val = (ret & ~mask); 1433 1434 data->als_int = FIELD_GET(VCNL4040_ALS_CONF_INT_EN, val); 1435 return i2c_smbus_write_word_data(data->client, VCNL4200_AL_CONF, val); 1436 case IIO_PROXIMITY: 1437 ret = i2c_smbus_read_word_data(data->client, VCNL4200_PS_CONF1); 1438 if (ret < 0) 1439 return ret; 1440 1441 if (dir == IIO_EV_DIR_RISING) 1442 mask = VCNL4040_PS_IF_AWAY; 1443 else 1444 mask = VCNL4040_PS_IF_CLOSE; 1445 1446 val = state ? (ret | mask) : (ret & ~mask); 1447 1448 data->ps_int = FIELD_GET(VCNL4040_PS_CONF2_PS_INT, val); 1449 return i2c_smbus_write_word_data(data->client, VCNL4200_PS_CONF1, val); 1450 default: 1451 return -EINVAL; 1452 } 1453 } 1454 1455 static irqreturn_t vcnl4040_irq_thread(int irq, void *p) 1456 { 1457 struct iio_dev *indio_dev = p; 1458 struct vcnl4000_data *data = iio_priv(indio_dev); 1459 int ret; 1460 1461 ret = i2c_smbus_read_word_data(data->client, data->chip_spec->int_reg); 1462 if (ret < 0) 1463 return IRQ_HANDLED; 1464 1465 if (ret & VCNL4040_PS_IF_CLOSE) { 1466 iio_push_event(indio_dev, 1467 IIO_UNMOD_EVENT_CODE(IIO_PROXIMITY, 0, 1468 IIO_EV_TYPE_THRESH, 1469 IIO_EV_DIR_RISING), 1470 iio_get_time_ns(indio_dev)); 1471 } 1472 1473 if (ret & VCNL4040_PS_IF_AWAY) { 1474 iio_push_event(indio_dev, 1475 IIO_UNMOD_EVENT_CODE(IIO_PROXIMITY, 0, 1476 IIO_EV_TYPE_THRESH, 1477 IIO_EV_DIR_FALLING), 1478 iio_get_time_ns(indio_dev)); 1479 } 1480 1481 if (ret & VCNL4040_ALS_FALLING) { 1482 iio_push_event(indio_dev, 1483 IIO_UNMOD_EVENT_CODE(IIO_LIGHT, 0, 1484 IIO_EV_TYPE_THRESH, 1485 IIO_EV_DIR_FALLING), 1486 iio_get_time_ns(indio_dev)); 1487 } 1488 1489 if (ret & VCNL4040_ALS_RISING) { 1490 iio_push_event(indio_dev, 1491 IIO_UNMOD_EVENT_CODE(IIO_LIGHT, 0, 1492 IIO_EV_TYPE_THRESH, 1493 IIO_EV_DIR_RISING), 1494 iio_get_time_ns(indio_dev)); 1495 } 1496 1497 return IRQ_HANDLED; 1498 } 1499 1500 static ssize_t vcnl4000_read_near_level(struct iio_dev *indio_dev, 1501 uintptr_t priv, 1502 const struct iio_chan_spec *chan, 1503 char *buf) 1504 { 1505 struct vcnl4000_data *data = iio_priv(indio_dev); 1506 1507 return sprintf(buf, "%u\n", data->near_level); 1508 } 1509 1510 static irqreturn_t vcnl4010_irq_thread(int irq, void *p) 1511 { 1512 struct iio_dev *indio_dev = p; 1513 struct vcnl4000_data *data = iio_priv(indio_dev); 1514 unsigned long isr; 1515 int ret; 1516 1517 ret = i2c_smbus_read_byte_data(data->client, VCNL4010_ISR); 1518 if (ret < 0) 1519 goto end; 1520 1521 isr = ret; 1522 1523 if (isr & VCNL4010_INT_THR) { 1524 if (test_bit(VCNL4010_INT_THR_LOW, &isr)) { 1525 iio_push_event(indio_dev, 1526 IIO_UNMOD_EVENT_CODE( 1527 IIO_PROXIMITY, 1528 1, 1529 IIO_EV_TYPE_THRESH, 1530 IIO_EV_DIR_FALLING), 1531 iio_get_time_ns(indio_dev)); 1532 } 1533 1534 if (test_bit(VCNL4010_INT_THR_HIGH, &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_RISING), 1541 iio_get_time_ns(indio_dev)); 1542 } 1543 1544 i2c_smbus_write_byte_data(data->client, VCNL4010_ISR, 1545 isr & VCNL4010_INT_THR); 1546 } 1547 1548 if (isr & VCNL4010_INT_DRDY && iio_buffer_enabled(indio_dev)) 1549 iio_trigger_poll_nested(indio_dev->trig); 1550 1551 end: 1552 return IRQ_HANDLED; 1553 } 1554 1555 static irqreturn_t vcnl4010_trigger_handler(int irq, void *p) 1556 { 1557 struct iio_poll_func *pf = p; 1558 struct iio_dev *indio_dev = pf->indio_dev; 1559 struct vcnl4000_data *data = iio_priv(indio_dev); 1560 const unsigned long *active_scan_mask = indio_dev->active_scan_mask; 1561 struct { 1562 u16 chan; 1563 aligned_s64 ts; 1564 } scan = { }; 1565 bool data_read = false; 1566 unsigned long isr; 1567 int val = 0; 1568 int ret; 1569 1570 ret = i2c_smbus_read_byte_data(data->client, VCNL4010_ISR); 1571 if (ret < 0) 1572 goto end; 1573 1574 isr = ret; 1575 1576 if (test_bit(0, active_scan_mask)) { 1577 if (test_bit(VCNL4010_INT_PROXIMITY, &isr)) { 1578 ret = vcnl4000_read_data(data, 1579 VCNL4000_PS_RESULT_HI, 1580 &val); 1581 if (ret < 0) 1582 goto end; 1583 1584 scan.chan = val; 1585 data_read = true; 1586 } 1587 } 1588 1589 ret = i2c_smbus_write_byte_data(data->client, VCNL4010_ISR, 1590 isr & VCNL4010_INT_DRDY); 1591 if (ret < 0) 1592 goto end; 1593 1594 if (!data_read) 1595 goto end; 1596 1597 iio_push_to_buffers_with_ts(indio_dev, &scan, sizeof(scan), 1598 iio_get_time_ns(indio_dev)); 1599 1600 end: 1601 iio_trigger_notify_done(indio_dev->trig); 1602 return IRQ_HANDLED; 1603 } 1604 1605 static int vcnl4010_buffer_postenable(struct iio_dev *indio_dev) 1606 { 1607 struct vcnl4000_data *data = iio_priv(indio_dev); 1608 int ret; 1609 int cmd; 1610 1611 /* Do not enable the buffer if we are already capturing events. */ 1612 if (vcnl4010_is_in_periodic_mode(data)) 1613 return -EBUSY; 1614 1615 ret = i2c_smbus_write_byte_data(data->client, VCNL4010_INT_CTRL, 1616 VCNL4010_INT_PROX_EN); 1617 if (ret < 0) 1618 return ret; 1619 1620 cmd = VCNL4000_SELF_TIMED_EN | VCNL4000_PROX_EN; 1621 return i2c_smbus_write_byte_data(data->client, VCNL4000_COMMAND, cmd); 1622 } 1623 1624 static int vcnl4010_buffer_predisable(struct iio_dev *indio_dev) 1625 { 1626 struct vcnl4000_data *data = iio_priv(indio_dev); 1627 int ret; 1628 1629 ret = i2c_smbus_write_byte_data(data->client, VCNL4010_INT_CTRL, 0); 1630 if (ret < 0) 1631 return ret; 1632 1633 return i2c_smbus_write_byte_data(data->client, VCNL4000_COMMAND, 0); 1634 } 1635 1636 static const struct iio_buffer_setup_ops vcnl4010_buffer_ops = { 1637 .postenable = &vcnl4010_buffer_postenable, 1638 .predisable = &vcnl4010_buffer_predisable, 1639 }; 1640 1641 static const struct iio_chan_spec_ext_info vcnl4000_ext_info[] = { 1642 { 1643 .name = "nearlevel", 1644 .shared = IIO_SEPARATE, 1645 .read = vcnl4000_read_near_level, 1646 }, 1647 { } 1648 }; 1649 1650 static const struct iio_event_spec vcnl4000_event_spec[] = { 1651 { 1652 .type = IIO_EV_TYPE_THRESH, 1653 .dir = IIO_EV_DIR_RISING, 1654 .mask_separate = BIT(IIO_EV_INFO_VALUE), 1655 }, { 1656 .type = IIO_EV_TYPE_THRESH, 1657 .dir = IIO_EV_DIR_FALLING, 1658 .mask_separate = BIT(IIO_EV_INFO_VALUE), 1659 }, { 1660 .type = IIO_EV_TYPE_THRESH, 1661 .dir = IIO_EV_DIR_EITHER, 1662 .mask_separate = BIT(IIO_EV_INFO_ENABLE), 1663 } 1664 }; 1665 1666 static const struct iio_event_spec vcnl4040_als_event_spec[] = { 1667 { 1668 .type = IIO_EV_TYPE_THRESH, 1669 .dir = IIO_EV_DIR_RISING, 1670 .mask_separate = BIT(IIO_EV_INFO_VALUE), 1671 }, { 1672 .type = IIO_EV_TYPE_THRESH, 1673 .dir = IIO_EV_DIR_FALLING, 1674 .mask_separate = BIT(IIO_EV_INFO_VALUE), 1675 }, { 1676 .type = IIO_EV_TYPE_THRESH, 1677 .dir = IIO_EV_DIR_EITHER, 1678 .mask_separate = BIT(IIO_EV_INFO_ENABLE) | BIT(IIO_EV_INFO_PERIOD), 1679 }, 1680 }; 1681 1682 static const struct iio_event_spec vcnl4040_event_spec[] = { 1683 { 1684 .type = IIO_EV_TYPE_THRESH, 1685 .dir = IIO_EV_DIR_RISING, 1686 .mask_separate = BIT(IIO_EV_INFO_VALUE) | BIT(IIO_EV_INFO_ENABLE), 1687 }, { 1688 .type = IIO_EV_TYPE_THRESH, 1689 .dir = IIO_EV_DIR_FALLING, 1690 .mask_separate = BIT(IIO_EV_INFO_VALUE) | BIT(IIO_EV_INFO_ENABLE), 1691 }, { 1692 .type = IIO_EV_TYPE_THRESH, 1693 .dir = IIO_EV_DIR_EITHER, 1694 .mask_separate = BIT(IIO_EV_INFO_PERIOD), 1695 }, 1696 }; 1697 1698 static const struct iio_chan_spec vcnl4000_channels[] = { 1699 { 1700 .type = IIO_LIGHT, 1701 .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | 1702 BIT(IIO_CHAN_INFO_SCALE), 1703 }, { 1704 .type = IIO_PROXIMITY, 1705 .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), 1706 .ext_info = vcnl4000_ext_info, 1707 } 1708 }; 1709 1710 static const struct iio_chan_spec vcnl4010_channels[] = { 1711 { 1712 .type = IIO_LIGHT, 1713 .scan_index = -1, 1714 .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | 1715 BIT(IIO_CHAN_INFO_SCALE), 1716 }, { 1717 .type = IIO_PROXIMITY, 1718 .scan_index = 0, 1719 .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | 1720 BIT(IIO_CHAN_INFO_SAMP_FREQ), 1721 .info_mask_separate_available = BIT(IIO_CHAN_INFO_SAMP_FREQ), 1722 .event_spec = vcnl4000_event_spec, 1723 .num_event_specs = ARRAY_SIZE(vcnl4000_event_spec), 1724 .ext_info = vcnl4000_ext_info, 1725 .scan_type = { 1726 .sign = 'u', 1727 .realbits = 16, 1728 .storagebits = 16, 1729 .endianness = IIO_CPU, 1730 }, 1731 }, 1732 IIO_CHAN_SOFT_TIMESTAMP(1), 1733 }; 1734 1735 static const struct iio_chan_spec vcnl4040_channels[] = { 1736 { 1737 .type = IIO_LIGHT, 1738 .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | 1739 BIT(IIO_CHAN_INFO_SCALE) | 1740 BIT(IIO_CHAN_INFO_INT_TIME), 1741 .info_mask_separate_available = BIT(IIO_CHAN_INFO_INT_TIME), 1742 .event_spec = vcnl4040_als_event_spec, 1743 .num_event_specs = ARRAY_SIZE(vcnl4040_als_event_spec), 1744 }, { 1745 .type = IIO_PROXIMITY, 1746 .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | 1747 BIT(IIO_CHAN_INFO_INT_TIME) | 1748 BIT(IIO_CHAN_INFO_OVERSAMPLING_RATIO) | 1749 BIT(IIO_CHAN_INFO_CALIBBIAS), 1750 .info_mask_separate_available = BIT(IIO_CHAN_INFO_INT_TIME) | 1751 BIT(IIO_CHAN_INFO_OVERSAMPLING_RATIO) | 1752 BIT(IIO_CHAN_INFO_CALIBBIAS), 1753 .ext_info = vcnl4000_ext_info, 1754 .event_spec = vcnl4040_event_spec, 1755 .num_event_specs = ARRAY_SIZE(vcnl4040_event_spec), 1756 } 1757 }; 1758 1759 static const struct iio_chan_spec cm36672p_channels[] = { 1760 { 1761 .type = IIO_PROXIMITY, 1762 .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | 1763 BIT(IIO_CHAN_INFO_INT_TIME) | 1764 BIT(IIO_CHAN_INFO_OVERSAMPLING_RATIO) | 1765 BIT(IIO_CHAN_INFO_CALIBBIAS), 1766 .info_mask_separate_available = BIT(IIO_CHAN_INFO_INT_TIME) | 1767 BIT(IIO_CHAN_INFO_OVERSAMPLING_RATIO) | 1768 BIT(IIO_CHAN_INFO_CALIBBIAS), 1769 .ext_info = vcnl4000_ext_info, 1770 .event_spec = vcnl4040_event_spec, 1771 .num_event_specs = ARRAY_SIZE(vcnl4040_event_spec), 1772 }, 1773 }; 1774 1775 static const struct iio_info vcnl4000_info = { 1776 .read_raw = vcnl4000_read_raw, 1777 }; 1778 1779 static const struct iio_info vcnl4010_info = { 1780 .read_raw = vcnl4010_read_raw, 1781 .read_avail = vcnl4010_read_avail, 1782 .write_raw = vcnl4010_write_raw, 1783 .read_event_value = vcnl4010_read_event, 1784 .write_event_value = vcnl4010_write_event, 1785 .read_event_config = vcnl4010_read_event_config, 1786 .write_event_config = vcnl4010_write_event_config, 1787 }; 1788 1789 static const struct iio_info vcnl4040_info = { 1790 .read_raw = vcnl4000_read_raw, 1791 .write_raw = vcnl4040_write_raw, 1792 .read_event_value = vcnl4040_read_event, 1793 .write_event_value = vcnl4040_write_event, 1794 .read_event_config = vcnl4040_read_event_config, 1795 .write_event_config = vcnl4040_write_event_config, 1796 .read_avail = vcnl4040_read_avail, 1797 }; 1798 1799 static const struct vcnl4000_chip_spec cm36672p_spec = { 1800 .prod = "CM36672P", 1801 .init = vcnl4200_init, 1802 .measure_proximity = vcnl4200_measure_proximity, 1803 .set_power_state = vcnl4200_set_power_state, 1804 .channels = cm36672p_channels, 1805 .num_channels = ARRAY_SIZE(cm36672p_channels), 1806 .info = &vcnl4040_info, 1807 .irq_thread = vcnl4040_irq_thread, 1808 .int_reg = VCNL4040_INT_FLAGS, 1809 .ps_it_times = &vcnl4040_ps_it_times, 1810 .num_ps_it_times = ARRAY_SIZE(vcnl4040_ps_it_times), 1811 .prod_id = VCNL4040_PROD_ID, 1812 }; 1813 1814 static const struct vcnl4000_chip_spec vcnl4000_spec = { 1815 .prod = "VCNL4000", 1816 .init = vcnl4000_init, 1817 .measure_light = vcnl4000_measure_light, 1818 .measure_proximity = vcnl4000_measure_proximity, 1819 .set_power_state = vcnl4000_set_power_state, 1820 .channels = vcnl4000_channels, 1821 .num_channels = ARRAY_SIZE(vcnl4000_channels), 1822 .info = &vcnl4000_info, 1823 .prod_id = VCNL4000_PROD_ID, 1824 }; 1825 1826 static const struct vcnl4000_chip_spec vcnl4010_spec = { 1827 .prod = "VCNL4010/4020", 1828 .init = vcnl4000_init, 1829 .measure_light = vcnl4000_measure_light, 1830 .measure_proximity = vcnl4000_measure_proximity, 1831 .set_power_state = vcnl4000_set_power_state, 1832 .channels = vcnl4010_channels, 1833 .num_channels = ARRAY_SIZE(vcnl4010_channels), 1834 .info = &vcnl4010_info, 1835 .irq_thread = vcnl4010_irq_thread, 1836 .trig_buffer_func = vcnl4010_trigger_handler, 1837 .buffer_setup_ops = &vcnl4010_buffer_ops, 1838 .prod_id = VCNL4010_PROD_ID, 1839 }; 1840 1841 static const struct vcnl4000_chip_spec vcnl4040_spec = { 1842 .prod = "VCNL4040", 1843 .init = vcnl4200_init, 1844 .measure_light = vcnl4200_measure_light, 1845 .measure_proximity = vcnl4200_measure_proximity, 1846 .set_power_state = vcnl4200_set_power_state, 1847 .channels = vcnl4040_channels, 1848 .num_channels = ARRAY_SIZE(vcnl4040_channels), 1849 .info = &vcnl4040_info, 1850 .irq_thread = vcnl4040_irq_thread, 1851 .int_reg = VCNL4040_INT_FLAGS, 1852 .ps_it_times = &vcnl4040_ps_it_times, 1853 .num_ps_it_times = ARRAY_SIZE(vcnl4040_ps_it_times), 1854 .als_it_times = &vcnl4040_als_it_times, 1855 .num_als_it_times = ARRAY_SIZE(vcnl4040_als_it_times), 1856 .ulux_step = 100000, 1857 .prod_id = VCNL4040_PROD_ID, 1858 }; 1859 1860 static const struct vcnl4000_chip_spec vcnl4200_spec = { 1861 .prod = "VCNL4200", 1862 .init = vcnl4200_init, 1863 .measure_light = vcnl4200_measure_light, 1864 .measure_proximity = vcnl4200_measure_proximity, 1865 .set_power_state = vcnl4200_set_power_state, 1866 .channels = vcnl4040_channels, 1867 .num_channels = ARRAY_SIZE(vcnl4000_channels), 1868 .info = &vcnl4040_info, 1869 .irq_thread = vcnl4040_irq_thread, 1870 .int_reg = VCNL4200_INT_FLAGS, 1871 .ps_it_times = &vcnl4200_ps_it_times, 1872 .num_ps_it_times = ARRAY_SIZE(vcnl4200_ps_it_times), 1873 .als_it_times = &vcnl4200_als_it_times, 1874 .num_als_it_times = ARRAY_SIZE(vcnl4200_als_it_times), 1875 .ulux_step = 24000, 1876 .prod_id = VCNL4200_PROD_ID, 1877 }; 1878 1879 static const struct iio_trigger_ops vcnl4010_trigger_ops = { 1880 .validate_device = iio_trigger_validate_own_device, 1881 }; 1882 1883 static int vcnl4010_probe_trigger(struct iio_dev *indio_dev) 1884 { 1885 struct vcnl4000_data *data = iio_priv(indio_dev); 1886 struct i2c_client *client = data->client; 1887 struct iio_trigger *trigger; 1888 1889 trigger = devm_iio_trigger_alloc(&client->dev, "%s-dev%d", 1890 indio_dev->name, 1891 iio_device_id(indio_dev)); 1892 if (!trigger) 1893 return -ENOMEM; 1894 1895 trigger->ops = &vcnl4010_trigger_ops; 1896 iio_trigger_set_drvdata(trigger, indio_dev); 1897 1898 return devm_iio_trigger_register(&client->dev, trigger); 1899 } 1900 1901 static void vcnl4000_cleanup(void *data) 1902 { 1903 struct iio_dev *indio_dev = data; 1904 struct vcnl4000_data *chip = iio_priv(indio_dev); 1905 struct device *dev = &chip->client->dev; 1906 int ret; 1907 1908 ret = chip->chip_spec->set_power_state(chip, false); 1909 if (ret) 1910 dev_warn(dev, "Failed to power down (%pe)", ERR_PTR(ret)); 1911 } 1912 1913 static int vcnl4000_probe(struct i2c_client *client) 1914 { 1915 static const char * const regulator_names[] = { "vdd", "vio", "vled" }; 1916 struct device *dev = &client->dev; 1917 struct vcnl4000_data *data; 1918 struct iio_dev *indio_dev; 1919 int ret; 1920 1921 indio_dev = devm_iio_device_alloc(dev, sizeof(*data)); 1922 if (!indio_dev) 1923 return -ENOMEM; 1924 1925 data = iio_priv(indio_dev); 1926 i2c_set_clientdata(client, indio_dev); 1927 data->client = client; 1928 data->chip_spec = i2c_get_match_data(client); 1929 1930 ret = devm_regulator_bulk_get_enable(dev, ARRAY_SIZE(regulator_names), 1931 regulator_names); 1932 if (ret) 1933 return ret; 1934 1935 ret = devm_mutex_init(dev, &data->vcnl4000_lock); 1936 if (ret) 1937 return ret; 1938 1939 ret = data->chip_spec->init(data); 1940 if (ret < 0) 1941 return ret; 1942 1943 ret = data->chip_spec->set_power_state(data, true); 1944 if (ret) 1945 return ret; 1946 1947 ret = devm_add_action_or_reset(dev, vcnl4000_cleanup, indio_dev); 1948 if (ret) 1949 return ret; 1950 1951 dev_dbg(dev, "%s Ambient light/proximity sensor, Rev: %02x\n", 1952 data->chip_spec->prod, data->rev); 1953 1954 device_property_read_u32(dev, "proximity-near-level", &data->near_level); 1955 1956 indio_dev->info = data->chip_spec->info; 1957 indio_dev->channels = data->chip_spec->channels; 1958 indio_dev->num_channels = data->chip_spec->num_channels; 1959 indio_dev->name = VCNL4000_DRV_NAME; 1960 indio_dev->modes = INDIO_DIRECT_MODE; 1961 1962 if (data->chip_spec->trig_buffer_func && 1963 data->chip_spec->buffer_setup_ops) { 1964 ret = devm_iio_triggered_buffer_setup(dev, indio_dev, NULL, 1965 data->chip_spec->trig_buffer_func, 1966 data->chip_spec->buffer_setup_ops); 1967 if (ret < 0) 1968 return ret; 1969 } 1970 1971 if (client->irq && data->chip_spec->irq_thread) { 1972 ret = devm_request_threaded_irq(dev, client->irq, NULL, 1973 data->chip_spec->irq_thread, 1974 IRQF_TRIGGER_FALLING | 1975 IRQF_ONESHOT, 1976 "vcnl4000_irq", 1977 indio_dev); 1978 if (ret < 0) 1979 return ret; 1980 1981 ret = vcnl4010_probe_trigger(indio_dev); 1982 if (ret < 0) 1983 return ret; 1984 } 1985 1986 ret = devm_pm_runtime_set_active_enabled(dev); 1987 if (ret) 1988 return ret; 1989 1990 ret = devm_iio_device_register(dev, indio_dev); 1991 if (ret) 1992 return ret; 1993 1994 pm_runtime_set_autosuspend_delay(dev, VCNL4000_SLEEP_DELAY_MS); 1995 pm_runtime_use_autosuspend(dev); 1996 1997 return 0; 1998 } 1999 2000 static const struct of_device_id vcnl_4000_of_match[] = { 2001 { .compatible = "capella,cm36672p", .data = &cm36672p_spec }, 2002 /* Capella CM36686 is fully compatible with Vishay VCNL4040 */ 2003 { .compatible = "capella,cm36686", .data = &vcnl4040_spec }, 2004 { .compatible = "vishay,vcnl4000", .data = &vcnl4000_spec }, 2005 { .compatible = "vishay,vcnl4010", .data = &vcnl4010_spec }, 2006 { .compatible = "vishay,vcnl4020", .data = &vcnl4010_spec }, 2007 { .compatible = "vishay,vcnl4040", .data = &vcnl4040_spec }, 2008 { .compatible = "vishay,vcnl4200", .data = &vcnl4200_spec }, 2009 { } 2010 }; 2011 MODULE_DEVICE_TABLE(of, vcnl_4000_of_match); 2012 2013 static int vcnl4000_runtime_suspend(struct device *dev) 2014 { 2015 struct iio_dev *indio_dev = i2c_get_clientdata(to_i2c_client(dev)); 2016 struct vcnl4000_data *data = iio_priv(indio_dev); 2017 2018 return data->chip_spec->set_power_state(data, false); 2019 } 2020 2021 static int vcnl4000_runtime_resume(struct device *dev) 2022 { 2023 struct iio_dev *indio_dev = i2c_get_clientdata(to_i2c_client(dev)); 2024 struct vcnl4000_data *data = iio_priv(indio_dev); 2025 2026 return data->chip_spec->set_power_state(data, true); 2027 } 2028 2029 static DEFINE_RUNTIME_DEV_PM_OPS(vcnl4000_pm_ops, vcnl4000_runtime_suspend, 2030 vcnl4000_runtime_resume, NULL); 2031 2032 static const struct i2c_device_id vcnl4000_id[] = { 2033 { .name = "cm36672p", .driver_data = (kernel_ulong_t)&cm36672p_spec }, 2034 { .name = "cm36686", .driver_data = (kernel_ulong_t)&vcnl4040_spec }, 2035 { .name = "vcnl4000", .driver_data = (kernel_ulong_t)&vcnl4000_spec }, 2036 { .name = "vcnl4010", .driver_data = (kernel_ulong_t)&vcnl4010_spec }, 2037 { .name = "vcnl4020", .driver_data = (kernel_ulong_t)&vcnl4010_spec }, 2038 { .name = "vcnl4040", .driver_data = (kernel_ulong_t)&vcnl4040_spec }, 2039 { .name = "vcnl4200", .driver_data = (kernel_ulong_t)&vcnl4200_spec }, 2040 { } 2041 }; 2042 MODULE_DEVICE_TABLE(i2c, vcnl4000_id); 2043 2044 static struct i2c_driver vcnl4000_driver = { 2045 .driver = { 2046 .name = VCNL4000_DRV_NAME, 2047 .pm = pm_ptr(&vcnl4000_pm_ops), 2048 .of_match_table = vcnl_4000_of_match, 2049 }, 2050 .probe = vcnl4000_probe, 2051 .id_table = vcnl4000_id, 2052 }; 2053 2054 module_i2c_driver(vcnl4000_driver); 2055 2056 MODULE_AUTHOR("Peter Meerwald <pmeerw@pmeerw.net>"); 2057 MODULE_AUTHOR("Mathieu Othacehe <m.othacehe@gmail.com>"); 2058 MODULE_DESCRIPTION("Vishay VCNL4000 proximity/ambient light sensor driver"); 2059 MODULE_LICENSE("GPL"); 2060