1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * isl29501.c: ISL29501 Time of Flight sensor driver. 4 * 5 * Copyright (C) 2018 6 * Author: Mathieu Othacehe <m.othacehe@gmail.com> 7 * 8 * 7-bit I2C slave address: 0x57 9 */ 10 11 #include <linux/kernel.h> 12 #include <linux/module.h> 13 #include <linux/i2c.h> 14 #include <linux/err.h> 15 #include <linux/iio/iio.h> 16 #include <linux/iio/sysfs.h> 17 18 #include <linux/iio/trigger_consumer.h> 19 #include <linux/iio/buffer.h> 20 #include <linux/iio/triggered_buffer.h> 21 22 /* Control, setting and status registers */ 23 #define ISL29501_DEVICE_ID 0x00 24 #define ISL29501_ID 0x0A 25 26 /* Sampling control registers */ 27 #define ISL29501_INTEGRATION_PERIOD 0x10 28 #define ISL29501_SAMPLE_PERIOD 0x11 29 30 /* Closed loop calibration registers */ 31 #define ISL29501_CROSSTALK_I_MSB 0x24 32 #define ISL29501_CROSSTALK_I_LSB 0x25 33 #define ISL29501_CROSSTALK_I_EXPONENT 0x26 34 #define ISL29501_CROSSTALK_Q_MSB 0x27 35 #define ISL29501_CROSSTALK_Q_LSB 0x28 36 #define ISL29501_CROSSTALK_Q_EXPONENT 0x29 37 #define ISL29501_CROSSTALK_GAIN_MSB 0x2A 38 #define ISL29501_CROSSTALK_GAIN_LSB 0x2B 39 #define ISL29501_MAGNITUDE_REF_EXP 0x2C 40 #define ISL29501_MAGNITUDE_REF_MSB 0x2D 41 #define ISL29501_MAGNITUDE_REF_LSB 0x2E 42 #define ISL29501_PHASE_OFFSET_MSB 0x2F 43 #define ISL29501_PHASE_OFFSET_LSB 0x30 44 45 /* Analog control registers */ 46 #define ISL29501_DRIVER_RANGE 0x90 47 #define ISL29501_EMITTER_DAC 0x91 48 49 #define ISL29501_COMMAND_REGISTER 0xB0 50 51 /* Commands */ 52 #define ISL29501_EMUL_SAMPLE_START_PIN 0x49 53 #define ISL29501_RESET_ALL_REGISTERS 0xD7 54 #define ISL29501_RESET_INT_SM 0xD1 55 56 /* Ambiant light and temperature corrections */ 57 #define ISL29501_TEMP_REFERENCE 0x31 58 #define ISL29501_PHASE_EXPONENT 0x33 59 #define ISL29501_TEMP_COEFF_A 0x34 60 #define ISL29501_TEMP_COEFF_B 0x39 61 #define ISL29501_AMBIANT_COEFF_A 0x36 62 #define ISL29501_AMBIANT_COEFF_B 0x3B 63 64 /* Data output registers */ 65 #define ISL29501_DISTANCE_MSB_DATA 0xD1 66 #define ISL29501_DISTANCE_LSB_DATA 0xD2 67 #define ISL29501_PRECISION_MSB 0xD3 68 #define ISL29501_PRECISION_LSB 0xD4 69 #define ISL29501_MAGNITUDE_EXPONENT 0xD5 70 #define ISL29501_MAGNITUDE_MSB 0xD6 71 #define ISL29501_MAGNITUDE_LSB 0xD7 72 #define ISL29501_PHASE_MSB 0xD8 73 #define ISL29501_PHASE_LSB 0xD9 74 #define ISL29501_I_RAW_EXPONENT 0xDA 75 #define ISL29501_I_RAW_MSB 0xDB 76 #define ISL29501_I_RAW_LSB 0xDC 77 #define ISL29501_Q_RAW_EXPONENT 0xDD 78 #define ISL29501_Q_RAW_MSB 0xDE 79 #define ISL29501_Q_RAW_LSB 0xDF 80 #define ISL29501_DIE_TEMPERATURE 0xE2 81 #define ISL29501_AMBIENT_LIGHT 0xE3 82 #define ISL29501_GAIN_MSB 0xE6 83 #define ISL29501_GAIN_LSB 0xE7 84 85 #define ISL29501_MAX_EXP_VAL 15 86 87 #define ISL29501_INT_TIME_AVAILABLE \ 88 "0.00007 0.00014 0.00028 0.00057 0.00114 " \ 89 "0.00228 0.00455 0.00910 0.01820 0.03640 " \ 90 "0.07281 0.14561" 91 92 #define ISL29501_CURRENT_SCALE_AVAILABLE \ 93 "0.0039 0.0078 0.0118 0.0157 0.0196 " \ 94 "0.0235 0.0275 0.0314 0.0352 0.0392 " \ 95 "0.0431 0.0471 0.0510 0.0549 0.0588" 96 97 enum isl29501_correction_coeff { 98 COEFF_TEMP_A, 99 COEFF_TEMP_B, 100 COEFF_LIGHT_A, 101 COEFF_LIGHT_B, 102 COEFF_MAX, 103 }; 104 105 struct isl29501_private { 106 struct i2c_client *client; 107 struct mutex lock; 108 /* Exact representation of correction coefficients. */ 109 unsigned int shadow_coeffs[COEFF_MAX]; 110 }; 111 112 enum isl29501_register_name { 113 REG_DISTANCE, 114 REG_PHASE, 115 REG_TEMPERATURE, 116 REG_AMBIENT_LIGHT, 117 REG_GAIN, 118 REG_GAIN_BIAS, 119 REG_PHASE_EXP, 120 REG_CALIB_PHASE_TEMP_A, 121 REG_CALIB_PHASE_TEMP_B, 122 REG_CALIB_PHASE_LIGHT_A, 123 REG_CALIB_PHASE_LIGHT_B, 124 REG_DISTANCE_BIAS, 125 REG_TEMPERATURE_BIAS, 126 REG_INT_TIME, 127 REG_SAMPLE_TIME, 128 REG_DRIVER_RANGE, 129 REG_EMITTER_DAC, 130 }; 131 132 struct isl29501_register_desc { 133 u8 msb; 134 u8 lsb; 135 }; 136 137 static const struct isl29501_register_desc isl29501_registers[] = { 138 [REG_DISTANCE] = { 139 .msb = ISL29501_DISTANCE_MSB_DATA, 140 .lsb = ISL29501_DISTANCE_LSB_DATA, 141 }, 142 [REG_PHASE] = { 143 .msb = ISL29501_PHASE_MSB, 144 .lsb = ISL29501_PHASE_LSB, 145 }, 146 [REG_TEMPERATURE] = { 147 .lsb = ISL29501_DIE_TEMPERATURE, 148 }, 149 [REG_AMBIENT_LIGHT] = { 150 .lsb = ISL29501_AMBIENT_LIGHT, 151 }, 152 [REG_GAIN] = { 153 .msb = ISL29501_GAIN_MSB, 154 .lsb = ISL29501_GAIN_LSB, 155 }, 156 [REG_GAIN_BIAS] = { 157 .msb = ISL29501_CROSSTALK_GAIN_MSB, 158 .lsb = ISL29501_CROSSTALK_GAIN_LSB, 159 }, 160 [REG_PHASE_EXP] = { 161 .lsb = ISL29501_PHASE_EXPONENT, 162 }, 163 [REG_CALIB_PHASE_TEMP_A] = { 164 .lsb = ISL29501_TEMP_COEFF_A, 165 }, 166 [REG_CALIB_PHASE_TEMP_B] = { 167 .lsb = ISL29501_TEMP_COEFF_B, 168 }, 169 [REG_CALIB_PHASE_LIGHT_A] = { 170 .lsb = ISL29501_AMBIANT_COEFF_A, 171 }, 172 [REG_CALIB_PHASE_LIGHT_B] = { 173 .lsb = ISL29501_AMBIANT_COEFF_B, 174 }, 175 [REG_DISTANCE_BIAS] = { 176 .msb = ISL29501_PHASE_OFFSET_MSB, 177 .lsb = ISL29501_PHASE_OFFSET_LSB, 178 }, 179 [REG_TEMPERATURE_BIAS] = { 180 .lsb = ISL29501_TEMP_REFERENCE, 181 }, 182 [REG_INT_TIME] = { 183 .lsb = ISL29501_INTEGRATION_PERIOD, 184 }, 185 [REG_SAMPLE_TIME] = { 186 .lsb = ISL29501_SAMPLE_PERIOD, 187 }, 188 [REG_DRIVER_RANGE] = { 189 .lsb = ISL29501_DRIVER_RANGE, 190 }, 191 [REG_EMITTER_DAC] = { 192 .lsb = ISL29501_EMITTER_DAC, 193 }, 194 }; 195 196 static int isl29501_register_read(struct isl29501_private *isl29501, 197 enum isl29501_register_name name, 198 u32 *val) 199 { 200 const struct isl29501_register_desc *reg = &isl29501_registers[name]; 201 u8 msb = 0, lsb = 0; 202 s32 ret; 203 204 mutex_lock(&isl29501->lock); 205 if (reg->msb) { 206 ret = i2c_smbus_read_byte_data(isl29501->client, reg->msb); 207 if (ret < 0) 208 goto err; 209 msb = ret; 210 } 211 212 if (reg->lsb) { 213 ret = i2c_smbus_read_byte_data(isl29501->client, reg->lsb); 214 if (ret < 0) 215 goto err; 216 lsb = ret; 217 } 218 mutex_unlock(&isl29501->lock); 219 220 *val = (msb << 8) + lsb; 221 222 return 0; 223 err: 224 mutex_unlock(&isl29501->lock); 225 226 return ret; 227 } 228 229 static int isl29501_register_write(struct isl29501_private *isl29501, 230 enum isl29501_register_name name, 231 u32 value) 232 { 233 const struct isl29501_register_desc *reg = &isl29501_registers[name]; 234 int ret; 235 236 if (!reg->msb && value > U8_MAX) 237 return -ERANGE; 238 239 if (value > U16_MAX) 240 return -ERANGE; 241 242 mutex_lock(&isl29501->lock); 243 if (reg->msb) { 244 ret = i2c_smbus_write_byte_data(isl29501->client, 245 reg->msb, value >> 8); 246 if (ret < 0) 247 goto err; 248 } 249 250 ret = i2c_smbus_write_byte_data(isl29501->client, reg->lsb, value); 251 252 err: 253 mutex_unlock(&isl29501->lock); 254 return ret; 255 } 256 257 static ssize_t isl29501_read_ext(struct iio_dev *indio_dev, 258 uintptr_t private, 259 const struct iio_chan_spec *chan, 260 char *buf) 261 { 262 struct isl29501_private *isl29501 = iio_priv(indio_dev); 263 enum isl29501_register_name reg = private; 264 int ret; 265 u32 value, gain, coeff, exp; 266 267 switch (reg) { 268 case REG_GAIN: 269 case REG_GAIN_BIAS: 270 ret = isl29501_register_read(isl29501, reg, &gain); 271 if (ret < 0) 272 return ret; 273 274 value = gain; 275 break; 276 case REG_CALIB_PHASE_TEMP_A: 277 case REG_CALIB_PHASE_TEMP_B: 278 case REG_CALIB_PHASE_LIGHT_A: 279 case REG_CALIB_PHASE_LIGHT_B: 280 ret = isl29501_register_read(isl29501, REG_PHASE_EXP, &exp); 281 if (ret < 0) 282 return ret; 283 284 ret = isl29501_register_read(isl29501, reg, &coeff); 285 if (ret < 0) 286 return ret; 287 288 value = coeff << exp; 289 break; 290 default: 291 return -EINVAL; 292 } 293 294 return sprintf(buf, "%u\n", value); 295 } 296 297 static int isl29501_set_shadow_coeff(struct isl29501_private *isl29501, 298 enum isl29501_register_name reg, 299 unsigned int val) 300 { 301 enum isl29501_correction_coeff coeff; 302 303 switch (reg) { 304 case REG_CALIB_PHASE_TEMP_A: 305 coeff = COEFF_TEMP_A; 306 break; 307 case REG_CALIB_PHASE_TEMP_B: 308 coeff = COEFF_TEMP_B; 309 break; 310 case REG_CALIB_PHASE_LIGHT_A: 311 coeff = COEFF_LIGHT_A; 312 break; 313 case REG_CALIB_PHASE_LIGHT_B: 314 coeff = COEFF_LIGHT_B; 315 break; 316 default: 317 return -EINVAL; 318 } 319 isl29501->shadow_coeffs[coeff] = val; 320 321 return 0; 322 } 323 324 static int isl29501_write_coeff(struct isl29501_private *isl29501, 325 enum isl29501_correction_coeff coeff, 326 int val) 327 { 328 enum isl29501_register_name reg; 329 330 switch (coeff) { 331 case COEFF_TEMP_A: 332 reg = REG_CALIB_PHASE_TEMP_A; 333 break; 334 case COEFF_TEMP_B: 335 reg = REG_CALIB_PHASE_TEMP_B; 336 break; 337 case COEFF_LIGHT_A: 338 reg = REG_CALIB_PHASE_LIGHT_A; 339 break; 340 case COEFF_LIGHT_B: 341 reg = REG_CALIB_PHASE_LIGHT_B; 342 break; 343 default: 344 return -EINVAL; 345 } 346 347 return isl29501_register_write(isl29501, reg, val); 348 } 349 350 static unsigned int isl29501_find_corr_exp(unsigned int val, 351 unsigned int max_exp, 352 unsigned int max_mantissa) 353 { 354 unsigned int exp = 1; 355 356 /* 357 * Correction coefficients are represented under 358 * mantissa * 2^exponent form, where mantissa and exponent 359 * are stored in two separate registers of the sensor. 360 * 361 * Compute and return the lowest exponent such as: 362 * mantissa = value / 2^exponent 363 * 364 * where mantissa < max_mantissa. 365 */ 366 if (val <= max_mantissa) 367 return 0; 368 369 while ((val >> exp) > max_mantissa) { 370 exp++; 371 372 if (exp > max_exp) 373 return max_exp; 374 } 375 376 return exp; 377 } 378 379 static ssize_t isl29501_write_ext(struct iio_dev *indio_dev, 380 uintptr_t private, 381 const struct iio_chan_spec *chan, 382 const char *buf, size_t len) 383 { 384 struct isl29501_private *isl29501 = iio_priv(indio_dev); 385 enum isl29501_register_name reg = private; 386 unsigned int val; 387 int max_exp = 0; 388 int ret; 389 int i; 390 391 ret = kstrtouint(buf, 10, &val); 392 if (ret) 393 return ret; 394 395 switch (reg) { 396 case REG_GAIN_BIAS: 397 if (val > U16_MAX) 398 return -ERANGE; 399 400 ret = isl29501_register_write(isl29501, reg, val); 401 if (ret < 0) 402 return ret; 403 404 break; 405 case REG_CALIB_PHASE_TEMP_A: 406 case REG_CALIB_PHASE_TEMP_B: 407 case REG_CALIB_PHASE_LIGHT_A: 408 case REG_CALIB_PHASE_LIGHT_B: 409 410 if (val > (U8_MAX << ISL29501_MAX_EXP_VAL)) 411 return -ERANGE; 412 413 /* Store the correction coefficient under its exact form. */ 414 ret = isl29501_set_shadow_coeff(isl29501, reg, val); 415 if (ret < 0) 416 return ret; 417 418 /* 419 * Find the highest exponent needed to represent 420 * correction coefficients. 421 */ 422 for (i = 0; i < COEFF_MAX; i++) { 423 int corr; 424 int corr_exp; 425 426 corr = isl29501->shadow_coeffs[i]; 427 corr_exp = isl29501_find_corr_exp(corr, 428 ISL29501_MAX_EXP_VAL, 429 U8_MAX / 2); 430 dev_dbg(&isl29501->client->dev, 431 "found exp of corr(%d) = %d\n", corr, corr_exp); 432 433 max_exp = max(max_exp, corr_exp); 434 } 435 436 /* 437 * Represent every correction coefficient under 438 * mantissa * 2^max_exponent form and force the 439 * writing of those coefficients on the sensor. 440 */ 441 for (i = 0; i < COEFF_MAX; i++) { 442 int corr; 443 int mantissa; 444 445 corr = isl29501->shadow_coeffs[i]; 446 if (!corr) 447 continue; 448 449 mantissa = corr >> max_exp; 450 451 ret = isl29501_write_coeff(isl29501, i, mantissa); 452 if (ret < 0) 453 return ret; 454 } 455 456 ret = isl29501_register_write(isl29501, REG_PHASE_EXP, max_exp); 457 if (ret < 0) 458 return ret; 459 460 break; 461 default: 462 return -EINVAL; 463 } 464 465 return len; 466 } 467 468 #define _ISL29501_EXT_INFO(_name, _ident) { \ 469 .name = _name, \ 470 .read = isl29501_read_ext, \ 471 .write = isl29501_write_ext, \ 472 .private = _ident, \ 473 .shared = IIO_SEPARATE, \ 474 } 475 476 static const struct iio_chan_spec_ext_info isl29501_ext_info[] = { 477 _ISL29501_EXT_INFO("agc_gain", REG_GAIN), 478 _ISL29501_EXT_INFO("agc_gain_bias", REG_GAIN_BIAS), 479 _ISL29501_EXT_INFO("calib_phase_temp_a", REG_CALIB_PHASE_TEMP_A), 480 _ISL29501_EXT_INFO("calib_phase_temp_b", REG_CALIB_PHASE_TEMP_B), 481 _ISL29501_EXT_INFO("calib_phase_light_a", REG_CALIB_PHASE_LIGHT_A), 482 _ISL29501_EXT_INFO("calib_phase_light_b", REG_CALIB_PHASE_LIGHT_B), 483 { } 484 }; 485 486 #define ISL29501_DISTANCE_SCAN_INDEX 0 487 #define ISL29501_TIMESTAMP_SCAN_INDEX 1 488 489 static const struct iio_chan_spec isl29501_channels[] = { 490 { 491 .type = IIO_PROXIMITY, 492 .scan_index = ISL29501_DISTANCE_SCAN_INDEX, 493 .info_mask_separate = 494 BIT(IIO_CHAN_INFO_RAW) | 495 BIT(IIO_CHAN_INFO_SCALE) | 496 BIT(IIO_CHAN_INFO_CALIBBIAS), 497 .scan_type = { 498 .sign = 'u', 499 .realbits = 16, 500 .storagebits = 16, 501 .endianness = IIO_CPU, 502 }, 503 .info_mask_shared_by_all = BIT(IIO_CHAN_INFO_INT_TIME) | 504 BIT(IIO_CHAN_INFO_SAMP_FREQ), 505 .ext_info = isl29501_ext_info, 506 }, 507 { 508 .type = IIO_PHASE, 509 .scan_index = -1, 510 .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | 511 BIT(IIO_CHAN_INFO_SCALE), 512 }, 513 { 514 .type = IIO_CURRENT, 515 .scan_index = -1, 516 .output = 1, 517 .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | 518 BIT(IIO_CHAN_INFO_SCALE), 519 }, 520 { 521 .type = IIO_TEMP, 522 .scan_index = -1, 523 .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | 524 BIT(IIO_CHAN_INFO_SCALE) | 525 BIT(IIO_CHAN_INFO_CALIBBIAS), 526 }, 527 { 528 .type = IIO_INTENSITY, 529 .scan_index = -1, 530 .modified = 1, 531 .channel2 = IIO_MOD_LIGHT_CLEAR, 532 .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | 533 BIT(IIO_CHAN_INFO_SCALE), 534 }, 535 IIO_CHAN_SOFT_TIMESTAMP(ISL29501_TIMESTAMP_SCAN_INDEX), 536 }; 537 538 static int isl29501_reset_registers(struct isl29501_private *isl29501) 539 { 540 int ret; 541 542 ret = i2c_smbus_write_byte_data(isl29501->client, 543 ISL29501_COMMAND_REGISTER, 544 ISL29501_RESET_ALL_REGISTERS); 545 if (ret < 0) { 546 dev_err(&isl29501->client->dev, 547 "cannot reset registers %d\n", ret); 548 return ret; 549 } 550 551 ret = i2c_smbus_write_byte_data(isl29501->client, 552 ISL29501_COMMAND_REGISTER, 553 ISL29501_RESET_INT_SM); 554 if (ret < 0) 555 dev_err(&isl29501->client->dev, 556 "cannot reset state machine %d\n", ret); 557 558 return ret; 559 } 560 561 static int isl29501_begin_acquisition(struct isl29501_private *isl29501) 562 { 563 int ret; 564 565 ret = i2c_smbus_write_byte_data(isl29501->client, 566 ISL29501_COMMAND_REGISTER, 567 ISL29501_EMUL_SAMPLE_START_PIN); 568 if (ret < 0) 569 dev_err(&isl29501->client->dev, 570 "cannot begin acquisition %d\n", ret); 571 572 return ret; 573 } 574 575 static IIO_CONST_ATTR_INT_TIME_AVAIL(ISL29501_INT_TIME_AVAILABLE); 576 static IIO_CONST_ATTR(out_current_scale_available, 577 ISL29501_CURRENT_SCALE_AVAILABLE); 578 579 static struct attribute *isl29501_attributes[] = { 580 &iio_const_attr_integration_time_available.dev_attr.attr, 581 &iio_const_attr_out_current_scale_available.dev_attr.attr, 582 NULL 583 }; 584 585 static const struct attribute_group isl29501_attribute_group = { 586 .attrs = isl29501_attributes, 587 }; 588 589 static const int isl29501_current_scale_table[][2] = { 590 {0, 3900}, {0, 7800}, {0, 11800}, {0, 15700}, 591 {0, 19600}, {0, 23500}, {0, 27500}, {0, 31400}, 592 {0, 35200}, {0, 39200}, {0, 43100}, {0, 47100}, 593 {0, 51000}, {0, 54900}, {0, 58800}, 594 }; 595 596 static const int isl29501_int_time[][2] = { 597 {0, 70}, /* 0.07 ms */ 598 {0, 140}, /* 0.14 ms */ 599 {0, 280}, /* 0.28 ms */ 600 {0, 570}, /* 0.57 ms */ 601 {0, 1140}, /* 1.14 ms */ 602 {0, 2280}, /* 2.28 ms */ 603 {0, 4550}, /* 4.55 ms */ 604 {0, 9100}, /* 9.11 ms */ 605 {0, 18200}, /* 18.2 ms */ 606 {0, 36400}, /* 36.4 ms */ 607 {0, 72810}, /* 72.81 ms */ 608 {0, 145610} /* 145.28 ms */ 609 }; 610 611 static int isl29501_get_raw(struct isl29501_private *isl29501, 612 const struct iio_chan_spec *chan, 613 int *raw) 614 { 615 int ret; 616 617 switch (chan->type) { 618 case IIO_PROXIMITY: 619 ret = isl29501_register_read(isl29501, REG_DISTANCE, raw); 620 if (ret < 0) 621 return ret; 622 623 return IIO_VAL_INT; 624 case IIO_INTENSITY: 625 ret = isl29501_register_read(isl29501, 626 REG_AMBIENT_LIGHT, 627 raw); 628 if (ret < 0) 629 return ret; 630 631 return IIO_VAL_INT; 632 case IIO_PHASE: 633 ret = isl29501_register_read(isl29501, REG_PHASE, raw); 634 if (ret < 0) 635 return ret; 636 637 return IIO_VAL_INT; 638 case IIO_CURRENT: 639 ret = isl29501_register_read(isl29501, REG_EMITTER_DAC, raw); 640 if (ret < 0) 641 return ret; 642 643 return IIO_VAL_INT; 644 case IIO_TEMP: 645 ret = isl29501_register_read(isl29501, REG_TEMPERATURE, raw); 646 if (ret < 0) 647 return ret; 648 649 return IIO_VAL_INT; 650 default: 651 return -EINVAL; 652 } 653 } 654 655 static int isl29501_get_scale(struct isl29501_private *isl29501, 656 const struct iio_chan_spec *chan, 657 int *val, int *val2) 658 { 659 int ret; 660 u32 current_scale; 661 662 switch (chan->type) { 663 case IIO_PROXIMITY: 664 /* distance = raw_distance * 33.31 / 65536 (m) */ 665 *val = 3331; 666 *val2 = 6553600; 667 668 return IIO_VAL_FRACTIONAL; 669 case IIO_PHASE: 670 /* phase = raw_phase * 2pi / 65536 (rad) */ 671 *val = 0; 672 *val2 = 95874; 673 674 return IIO_VAL_INT_PLUS_NANO; 675 case IIO_INTENSITY: 676 /* light = raw_light * 35 / 10000 (mA) */ 677 *val = 35; 678 *val2 = 10000; 679 680 return IIO_VAL_FRACTIONAL; 681 case IIO_CURRENT: 682 ret = isl29501_register_read(isl29501, 683 REG_DRIVER_RANGE, 684 ¤t_scale); 685 if (ret < 0) 686 return ret; 687 688 if (current_scale > ARRAY_SIZE(isl29501_current_scale_table)) 689 return -EINVAL; 690 691 if (!current_scale) { 692 *val = 0; 693 *val2 = 0; 694 return IIO_VAL_INT; 695 } 696 697 *val = isl29501_current_scale_table[current_scale - 1][0]; 698 *val2 = isl29501_current_scale_table[current_scale - 1][1]; 699 700 return IIO_VAL_INT_PLUS_MICRO; 701 case IIO_TEMP: 702 /* temperature = raw_temperature * 125 / 100000 (milli °C) */ 703 *val = 125; 704 *val2 = 100000; 705 706 return IIO_VAL_FRACTIONAL; 707 default: 708 return -EINVAL; 709 } 710 } 711 712 static int isl29501_get_calibbias(struct isl29501_private *isl29501, 713 const struct iio_chan_spec *chan, 714 int *bias) 715 { 716 switch (chan->type) { 717 case IIO_PROXIMITY: 718 return isl29501_register_read(isl29501, 719 REG_DISTANCE_BIAS, 720 bias); 721 case IIO_TEMP: 722 return isl29501_register_read(isl29501, 723 REG_TEMPERATURE_BIAS, 724 bias); 725 default: 726 return -EINVAL; 727 } 728 } 729 730 static int isl29501_get_inttime(struct isl29501_private *isl29501, 731 int *val, int *val2) 732 { 733 int ret; 734 u32 inttime; 735 736 ret = isl29501_register_read(isl29501, REG_INT_TIME, &inttime); 737 if (ret < 0) 738 return ret; 739 740 if (inttime >= ARRAY_SIZE(isl29501_int_time)) 741 return -EINVAL; 742 743 *val = isl29501_int_time[inttime][0]; 744 *val2 = isl29501_int_time[inttime][1]; 745 746 return IIO_VAL_INT_PLUS_MICRO; 747 } 748 749 static int isl29501_get_freq(struct isl29501_private *isl29501, 750 int *val, int *val2) 751 { 752 int ret; 753 int sample_time; 754 unsigned long long freq; 755 u32 temp; 756 757 ret = isl29501_register_read(isl29501, REG_SAMPLE_TIME, &sample_time); 758 if (ret < 0) 759 return ret; 760 761 /* freq = 1 / (0.000450 * (sample_time + 1) * 10^-6) */ 762 freq = 1000000ULL * 1000000ULL; 763 764 do_div(freq, 450 * (sample_time + 1)); 765 766 temp = do_div(freq, 1000000); 767 *val = freq; 768 *val2 = temp; 769 770 return IIO_VAL_INT_PLUS_MICRO; 771 } 772 773 static int isl29501_read_raw(struct iio_dev *indio_dev, 774 struct iio_chan_spec const *chan, int *val, 775 int *val2, long mask) 776 { 777 struct isl29501_private *isl29501 = iio_priv(indio_dev); 778 779 switch (mask) { 780 case IIO_CHAN_INFO_RAW: 781 return isl29501_get_raw(isl29501, chan, val); 782 case IIO_CHAN_INFO_SCALE: 783 return isl29501_get_scale(isl29501, chan, val, val2); 784 case IIO_CHAN_INFO_INT_TIME: 785 return isl29501_get_inttime(isl29501, val, val2); 786 case IIO_CHAN_INFO_SAMP_FREQ: 787 return isl29501_get_freq(isl29501, val, val2); 788 case IIO_CHAN_INFO_CALIBBIAS: 789 return isl29501_get_calibbias(isl29501, chan, val); 790 default: 791 return -EINVAL; 792 } 793 } 794 795 static int isl29501_set_raw(struct isl29501_private *isl29501, 796 const struct iio_chan_spec *chan, 797 int raw) 798 { 799 switch (chan->type) { 800 case IIO_CURRENT: 801 return isl29501_register_write(isl29501, REG_EMITTER_DAC, raw); 802 default: 803 return -EINVAL; 804 } 805 } 806 807 static int isl29501_set_inttime(struct isl29501_private *isl29501, 808 int val, int val2) 809 { 810 int i; 811 812 for (i = 0; i < ARRAY_SIZE(isl29501_int_time); i++) { 813 if (isl29501_int_time[i][0] == val && 814 isl29501_int_time[i][1] == val2) { 815 return isl29501_register_write(isl29501, 816 REG_INT_TIME, 817 i); 818 } 819 } 820 821 return -EINVAL; 822 } 823 824 static int isl29501_set_scale(struct isl29501_private *isl29501, 825 const struct iio_chan_spec *chan, 826 int val, int val2) 827 { 828 int i; 829 830 if (chan->type != IIO_CURRENT) 831 return -EINVAL; 832 833 for (i = 0; i < ARRAY_SIZE(isl29501_current_scale_table); i++) { 834 if (isl29501_current_scale_table[i][0] == val && 835 isl29501_current_scale_table[i][1] == val2) { 836 return isl29501_register_write(isl29501, 837 REG_DRIVER_RANGE, 838 i + 1); 839 } 840 } 841 842 return -EINVAL; 843 } 844 845 static int isl29501_set_calibbias(struct isl29501_private *isl29501, 846 const struct iio_chan_spec *chan, 847 int bias) 848 { 849 switch (chan->type) { 850 case IIO_PROXIMITY: 851 return isl29501_register_write(isl29501, 852 REG_DISTANCE_BIAS, 853 bias); 854 case IIO_TEMP: 855 return isl29501_register_write(isl29501, 856 REG_TEMPERATURE_BIAS, 857 bias); 858 default: 859 return -EINVAL; 860 } 861 } 862 863 static int isl29501_set_freq(struct isl29501_private *isl29501, 864 int val, int val2) 865 { 866 int freq; 867 unsigned long long sample_time; 868 869 /* sample_freq = 1 / (0.000450 * (sample_time + 1) * 10^-6) */ 870 freq = val * 1000000 + val2 % 1000000; 871 sample_time = 2222ULL * 1000000ULL; 872 do_div(sample_time, freq); 873 874 sample_time -= 1; 875 876 if (sample_time > 255) 877 return -ERANGE; 878 879 return isl29501_register_write(isl29501, REG_SAMPLE_TIME, sample_time); 880 } 881 882 static int isl29501_write_raw(struct iio_dev *indio_dev, 883 struct iio_chan_spec const *chan, 884 int val, int val2, long mask) 885 { 886 struct isl29501_private *isl29501 = iio_priv(indio_dev); 887 888 switch (mask) { 889 case IIO_CHAN_INFO_RAW: 890 return isl29501_set_raw(isl29501, chan, val); 891 case IIO_CHAN_INFO_INT_TIME: 892 return isl29501_set_inttime(isl29501, val, val2); 893 case IIO_CHAN_INFO_SAMP_FREQ: 894 return isl29501_set_freq(isl29501, val, val2); 895 case IIO_CHAN_INFO_SCALE: 896 return isl29501_set_scale(isl29501, chan, val, val2); 897 case IIO_CHAN_INFO_CALIBBIAS: 898 return isl29501_set_calibbias(isl29501, chan, val); 899 default: 900 return -EINVAL; 901 } 902 } 903 904 static const struct iio_info isl29501_info = { 905 .read_raw = &isl29501_read_raw, 906 .write_raw = &isl29501_write_raw, 907 .attrs = &isl29501_attribute_group, 908 }; 909 910 static int isl29501_init_chip(struct isl29501_private *isl29501) 911 { 912 int ret; 913 914 ret = i2c_smbus_read_byte_data(isl29501->client, ISL29501_DEVICE_ID); 915 if (ret < 0) { 916 dev_err(&isl29501->client->dev, "Error reading device id\n"); 917 return ret; 918 } 919 920 if (ret != ISL29501_ID) { 921 dev_err(&isl29501->client->dev, 922 "Wrong chip id, got %x expected %x\n", 923 ret, ISL29501_DEVICE_ID); 924 return -ENODEV; 925 } 926 927 ret = isl29501_reset_registers(isl29501); 928 if (ret < 0) 929 return ret; 930 931 return isl29501_begin_acquisition(isl29501); 932 } 933 934 static irqreturn_t isl29501_trigger_handler(int irq, void *p) 935 { 936 struct iio_poll_func *pf = p; 937 struct iio_dev *indio_dev = pf->indio_dev; 938 struct isl29501_private *isl29501 = iio_priv(indio_dev); 939 const unsigned long *active_mask = indio_dev->active_scan_mask; 940 u32 value; 941 struct { 942 u16 data; 943 aligned_s64 ts; 944 } scan = { }; 945 946 if (test_bit(ISL29501_DISTANCE_SCAN_INDEX, active_mask)) { 947 isl29501_register_read(isl29501, REG_DISTANCE, &value); 948 scan.data = value; 949 } 950 951 iio_push_to_buffers_with_timestamp(indio_dev, &scan, pf->timestamp); 952 iio_trigger_notify_done(indio_dev->trig); 953 954 return IRQ_HANDLED; 955 } 956 957 static int isl29501_probe(struct i2c_client *client) 958 { 959 struct iio_dev *indio_dev; 960 struct isl29501_private *isl29501; 961 int ret; 962 963 indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*isl29501)); 964 if (!indio_dev) 965 return -ENOMEM; 966 967 isl29501 = iio_priv(indio_dev); 968 969 i2c_set_clientdata(client, indio_dev); 970 isl29501->client = client; 971 972 mutex_init(&isl29501->lock); 973 974 ret = isl29501_init_chip(isl29501); 975 if (ret < 0) 976 return ret; 977 978 indio_dev->modes = INDIO_DIRECT_MODE; 979 indio_dev->channels = isl29501_channels; 980 indio_dev->num_channels = ARRAY_SIZE(isl29501_channels); 981 indio_dev->name = client->name; 982 indio_dev->info = &isl29501_info; 983 984 ret = devm_iio_triggered_buffer_setup(&client->dev, indio_dev, 985 iio_pollfunc_store_time, 986 isl29501_trigger_handler, 987 NULL); 988 if (ret < 0) { 989 dev_err(&client->dev, "unable to setup iio triggered buffer\n"); 990 return ret; 991 } 992 993 return devm_iio_device_register(&client->dev, indio_dev); 994 } 995 996 static const struct i2c_device_id isl29501_id[] = { 997 { .name = "isl29501" }, 998 { } 999 }; 1000 1001 MODULE_DEVICE_TABLE(i2c, isl29501_id); 1002 1003 static const struct of_device_id isl29501_i2c_matches[] = { 1004 { .compatible = "renesas,isl29501" }, 1005 { } 1006 }; 1007 MODULE_DEVICE_TABLE(of, isl29501_i2c_matches); 1008 1009 static struct i2c_driver isl29501_driver = { 1010 .driver = { 1011 .name = "isl29501", 1012 .of_match_table = isl29501_i2c_matches, 1013 }, 1014 .id_table = isl29501_id, 1015 .probe = isl29501_probe, 1016 }; 1017 module_i2c_driver(isl29501_driver); 1018 1019 MODULE_AUTHOR("Mathieu Othacehe <m.othacehe@gmail.com>"); 1020 MODULE_DESCRIPTION("ISL29501 Time of Flight sensor driver"); 1021 MODULE_LICENSE("GPL v2"); 1022