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