linux/drivers/iio/proximity/isl29501.c
<<
>>
Prefs
   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
  98enum isl29501_correction_coeff {
  99        COEFF_TEMP_A,
 100        COEFF_TEMP_B,
 101        COEFF_LIGHT_A,
 102        COEFF_LIGHT_B,
 103        COEFF_MAX,
 104};
 105
 106struct 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
 113enum 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
 133struct isl29501_register_desc {
 134        u8 msb;
 135        u8 lsb;
 136};
 137
 138static 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
 197static 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;
 224err:
 225        mutex_unlock(&isl29501->lock);
 226
 227        return ret;
 228}
 229
 230static 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
 253err:
 254        mutex_unlock(&isl29501->lock);
 255        return ret;
 256}
 257
 258static 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
 298static 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
 325static 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
 351static 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
 380static 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
 477static 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
 490static 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
 539static 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
 562static 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
 576static IIO_CONST_ATTR_INT_TIME_AVAIL(ISL29501_INT_TIME_AVAILABLE);
 577static IIO_CONST_ATTR(out_current_scale_available,
 578                      ISL29501_CURRENT_SCALE_AVAILABLE);
 579
 580static 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
 586static const struct attribute_group isl29501_attribute_group = {
 587        .attrs = isl29501_attributes,
 588};
 589
 590static 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
 597static 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
 612static 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
 656static 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                                             &current_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
 713static 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
 731static 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
 750static 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
 774static 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
 796static 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
 808static 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
 825static 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
 846static 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
 864static 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
 883static 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
 905static 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
 911static 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
 935static 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] = {}; /* 1x16-bit + 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
 952static 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->dev.parent = &client->dev;
 976        indio_dev->channels = isl29501_channels;
 977        indio_dev->num_channels = ARRAY_SIZE(isl29501_channels);
 978        indio_dev->name = client->name;
 979        indio_dev->info = &isl29501_info;
 980
 981        ret = devm_iio_triggered_buffer_setup(&client->dev, indio_dev,
 982                                              iio_pollfunc_store_time,
 983                                              isl29501_trigger_handler,
 984                                              NULL);
 985        if (ret < 0) {
 986                dev_err(&client->dev, "unable to setup iio triggered buffer\n");
 987                return ret;
 988        }
 989
 990        return devm_iio_device_register(&client->dev, indio_dev);
 991}
 992
 993static const struct i2c_device_id isl29501_id[] = {
 994        {"isl29501", 0},
 995        {}
 996};
 997
 998MODULE_DEVICE_TABLE(i2c, isl29501_id);
 999
1000#if defined(CONFIG_OF)
1001static const struct of_device_id isl29501_i2c_matches[] = {
1002        { .compatible = "renesas,isl29501" },
1003        { }
1004};
1005MODULE_DEVICE_TABLE(of, isl29501_i2c_matches);
1006#endif
1007
1008static struct i2c_driver isl29501_driver = {
1009        .driver = {
1010                .name   = "isl29501",
1011        },
1012        .id_table       = isl29501_id,
1013        .probe          = isl29501_probe,
1014};
1015module_i2c_driver(isl29501_driver);
1016
1017MODULE_AUTHOR("Mathieu Othacehe <m.othacehe@gmail.com>");
1018MODULE_DESCRIPTION("ISL29501 Time of Flight sensor driver");
1019MODULE_LICENSE("GPL v2");
1020