linux/drivers/iio/light/adux1020.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0+
   2/*
   3 * adux1020.c - Support for Analog Devices ADUX1020 photometric sensor
   4 *
   5 * Copyright (C) 2019 Linaro Ltd.
   6 * Author: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
   7 *
   8 * TODO: Triggered buffer support
   9 */
  10
  11#include <linux/bitfield.h>
  12#include <linux/delay.h>
  13#include <linux/err.h>
  14#include <linux/i2c.h>
  15#include <linux/init.h>
  16#include <linux/interrupt.h>
  17#include <linux/irq.h>
  18#include <linux/module.h>
  19#include <linux/mutex.h>
  20#include <linux/regmap.h>
  21
  22#include <linux/iio/iio.h>
  23#include <linux/iio/sysfs.h>
  24#include <linux/iio/events.h>
  25
  26#define ADUX1020_REGMAP_NAME            "adux1020_regmap"
  27#define ADUX1020_DRV_NAME               "adux1020"
  28
  29/* System registers */
  30#define ADUX1020_REG_CHIP_ID            0x08
  31#define ADUX1020_REG_SLAVE_ADDRESS      0x09
  32
  33#define ADUX1020_REG_SW_RESET           0x0f
  34#define ADUX1020_REG_INT_ENABLE         0x1c
  35#define ADUX1020_REG_INT_POLARITY       0x1d
  36#define ADUX1020_REG_PROX_TH_ON1        0x2a
  37#define ADUX1020_REG_PROX_TH_OFF1       0x2b
  38#define ADUX1020_REG_PROX_TYPE          0x2f
  39#define ADUX1020_REG_TEST_MODES_3       0x32
  40#define ADUX1020_REG_FORCE_MODE         0x33
  41#define ADUX1020_REG_FREQUENCY          0x40
  42#define ADUX1020_REG_LED_CURRENT        0x41
  43#define ADUX1020_REG_OP_MODE            0x45
  44#define ADUX1020_REG_INT_MASK           0x48
  45#define ADUX1020_REG_INT_STATUS         0x49
  46#define ADUX1020_REG_DATA_BUFFER        0x60
  47
  48/* Chip ID bits */
  49#define ADUX1020_CHIP_ID_MASK           GENMASK(11, 0)
  50#define ADUX1020_CHIP_ID                0x03fc
  51
  52#define ADUX1020_SW_RESET               BIT(1)
  53#define ADUX1020_FIFO_FLUSH             BIT(15)
  54#define ADUX1020_OP_MODE_MASK           GENMASK(3, 0)
  55#define ADUX1020_DATA_OUT_MODE_MASK     GENMASK(7, 4)
  56#define ADUX1020_DATA_OUT_PROX_I        FIELD_PREP(ADUX1020_DATA_OUT_MODE_MASK, 1)
  57
  58#define ADUX1020_MODE_INT_MASK          GENMASK(7, 0)
  59#define ADUX1020_INT_ENABLE             0x2094
  60#define ADUX1020_INT_DISABLE            0x2090
  61#define ADUX1020_PROX_INT_ENABLE        0x00f0
  62#define ADUX1020_PROX_ON1_INT           BIT(0)
  63#define ADUX1020_PROX_OFF1_INT          BIT(1)
  64#define ADUX1020_FIFO_INT_ENABLE        0x7f
  65#define ADUX1020_MODE_INT_DISABLE       0xff
  66#define ADUX1020_MODE_INT_STATUS_MASK   GENMASK(7, 0)
  67#define ADUX1020_FIFO_STATUS_MASK       GENMASK(15, 8)
  68#define ADUX1020_INT_CLEAR              0xff
  69#define ADUX1020_PROX_TYPE              BIT(15)
  70
  71#define ADUX1020_INT_PROX_ON1           BIT(0)
  72#define ADUX1020_INT_PROX_OFF1          BIT(1)
  73
  74#define ADUX1020_FORCE_CLOCK_ON         0x0f4f
  75#define ADUX1020_FORCE_CLOCK_RESET      0x0040
  76#define ADUX1020_ACTIVE_4_STATE         0x0008
  77
  78#define ADUX1020_PROX_FREQ_MASK         GENMASK(7, 4)
  79#define ADUX1020_PROX_FREQ(x)           FIELD_PREP(ADUX1020_PROX_FREQ_MASK, x)
  80
  81#define ADUX1020_LED_CURRENT_MASK       GENMASK(3, 0)
  82#define ADUX1020_LED_PIREF_EN           BIT(12)
  83
  84/* Operating modes */
  85enum adux1020_op_modes {
  86        ADUX1020_MODE_STANDBY,
  87        ADUX1020_MODE_PROX_I,
  88        ADUX1020_MODE_PROX_XY,
  89        ADUX1020_MODE_GEST,
  90        ADUX1020_MODE_SAMPLE,
  91        ADUX1020_MODE_FORCE = 0x0e,
  92        ADUX1020_MODE_IDLE = 0x0f,
  93};
  94
  95struct adux1020_data {
  96        struct i2c_client *client;
  97        struct iio_dev *indio_dev;
  98        struct mutex lock;
  99        struct regmap *regmap;
 100};
 101
 102struct adux1020_mode_data {
 103        u8 bytes;
 104        u8 buf_len;
 105        u16 int_en;
 106};
 107
 108static const struct adux1020_mode_data adux1020_modes[] = {
 109        [ADUX1020_MODE_PROX_I] = {
 110                .bytes = 2,
 111                .buf_len = 1,
 112                .int_en = ADUX1020_PROX_INT_ENABLE,
 113        },
 114};
 115
 116static const struct regmap_config adux1020_regmap_config = {
 117        .name = ADUX1020_REGMAP_NAME,
 118        .reg_bits = 8,
 119        .val_bits = 16,
 120        .max_register = 0x6F,
 121        .cache_type = REGCACHE_NONE,
 122};
 123
 124static const struct reg_sequence adux1020_def_conf[] = {
 125        { 0x000c, 0x000f },
 126        { 0x0010, 0x1010 },
 127        { 0x0011, 0x004c },
 128        { 0x0012, 0x5f0c },
 129        { 0x0013, 0xada5 },
 130        { 0x0014, 0x0080 },
 131        { 0x0015, 0x0000 },
 132        { 0x0016, 0x0600 },
 133        { 0x0017, 0x0000 },
 134        { 0x0018, 0x2693 },
 135        { 0x0019, 0x0004 },
 136        { 0x001a, 0x4280 },
 137        { 0x001b, 0x0060 },
 138        { 0x001c, 0x2094 },
 139        { 0x001d, 0x0020 },
 140        { 0x001e, 0x0001 },
 141        { 0x001f, 0x0100 },
 142        { 0x0020, 0x0320 },
 143        { 0x0021, 0x0A13 },
 144        { 0x0022, 0x0320 },
 145        { 0x0023, 0x0113 },
 146        { 0x0024, 0x0000 },
 147        { 0x0025, 0x2412 },
 148        { 0x0026, 0x2412 },
 149        { 0x0027, 0x0022 },
 150        { 0x0028, 0x0000 },
 151        { 0x0029, 0x0300 },
 152        { 0x002a, 0x0700 },
 153        { 0x002b, 0x0600 },
 154        { 0x002c, 0x6000 },
 155        { 0x002d, 0x4000 },
 156        { 0x002e, 0x0000 },
 157        { 0x002f, 0x0000 },
 158        { 0x0030, 0x0000 },
 159        { 0x0031, 0x0000 },
 160        { 0x0032, 0x0040 },
 161        { 0x0033, 0x0008 },
 162        { 0x0034, 0xE400 },
 163        { 0x0038, 0x8080 },
 164        { 0x0039, 0x8080 },
 165        { 0x003a, 0x2000 },
 166        { 0x003b, 0x1f00 },
 167        { 0x003c, 0x2000 },
 168        { 0x003d, 0x2000 },
 169        { 0x003e, 0x0000 },
 170        { 0x0040, 0x8069 },
 171        { 0x0041, 0x1f2f },
 172        { 0x0042, 0x4000 },
 173        { 0x0043, 0x0000 },
 174        { 0x0044, 0x0008 },
 175        { 0x0046, 0x0000 },
 176        { 0x0048, 0x00ef },
 177        { 0x0049, 0x0000 },
 178        { 0x0045, 0x0000 },
 179};
 180
 181static const int adux1020_rates[][2] = {
 182        { 0, 100000 },
 183        { 0, 200000 },
 184        { 0, 500000 },
 185        { 1, 0 },
 186        { 2, 0 },
 187        { 5, 0 },
 188        { 10, 0 },
 189        { 20, 0 },
 190        { 50, 0 },
 191        { 100, 0 },
 192        { 190, 0 },
 193        { 450, 0 },
 194        { 820, 0 },
 195        { 1400, 0 },
 196};
 197
 198static const int adux1020_led_currents[][2] = {
 199        { 0, 25000 },
 200        { 0, 40000 },
 201        { 0, 55000 },
 202        { 0, 70000 },
 203        { 0, 85000 },
 204        { 0, 100000 },
 205        { 0, 115000 },
 206        { 0, 130000 },
 207        { 0, 145000 },
 208        { 0, 160000 },
 209        { 0, 175000 },
 210        { 0, 190000 },
 211        { 0, 205000 },
 212        { 0, 220000 },
 213        { 0, 235000 },
 214        { 0, 250000 },
 215};
 216
 217static int adux1020_flush_fifo(struct adux1020_data *data)
 218{
 219        int ret;
 220
 221        /* Force Idle mode */
 222        ret = regmap_write(data->regmap, ADUX1020_REG_FORCE_MODE,
 223                           ADUX1020_ACTIVE_4_STATE);
 224        if (ret < 0)
 225                return ret;
 226
 227        ret = regmap_update_bits(data->regmap, ADUX1020_REG_OP_MODE,
 228                                 ADUX1020_OP_MODE_MASK, ADUX1020_MODE_FORCE);
 229        if (ret < 0)
 230                return ret;
 231
 232        ret = regmap_update_bits(data->regmap, ADUX1020_REG_OP_MODE,
 233                                 ADUX1020_OP_MODE_MASK, ADUX1020_MODE_IDLE);
 234        if (ret < 0)
 235                return ret;
 236
 237        /* Flush FIFO */
 238        ret = regmap_write(data->regmap, ADUX1020_REG_TEST_MODES_3,
 239                           ADUX1020_FORCE_CLOCK_ON);
 240        if (ret < 0)
 241                return ret;
 242
 243        ret = regmap_write(data->regmap, ADUX1020_REG_INT_STATUS,
 244                           ADUX1020_FIFO_FLUSH);
 245        if (ret < 0)
 246                return ret;
 247
 248        return regmap_write(data->regmap, ADUX1020_REG_TEST_MODES_3,
 249                            ADUX1020_FORCE_CLOCK_RESET);
 250}
 251
 252static int adux1020_read_fifo(struct adux1020_data *data, u16 *buf, u8 buf_len)
 253{
 254        unsigned int regval;
 255        int i, ret;
 256
 257        /* Enable 32MHz clock */
 258        ret = regmap_write(data->regmap, ADUX1020_REG_TEST_MODES_3,
 259                           ADUX1020_FORCE_CLOCK_ON);
 260        if (ret < 0)
 261                return ret;
 262
 263        for (i = 0; i < buf_len; i++) {
 264                ret = regmap_read(data->regmap, ADUX1020_REG_DATA_BUFFER,
 265                                  &regval);
 266                if (ret < 0)
 267                        return ret;
 268
 269                buf[i] = regval;
 270        }
 271
 272        /* Set 32MHz clock to be controlled by internal state machine */
 273        return regmap_write(data->regmap, ADUX1020_REG_TEST_MODES_3,
 274                            ADUX1020_FORCE_CLOCK_RESET);
 275}
 276
 277static int adux1020_set_mode(struct adux1020_data *data,
 278                             enum adux1020_op_modes mode)
 279{
 280        int ret;
 281
 282        /* Switch to standby mode before changing the mode */
 283        ret = regmap_write(data->regmap, ADUX1020_REG_OP_MODE,
 284                           ADUX1020_MODE_STANDBY);
 285        if (ret < 0)
 286                return ret;
 287
 288        /* Set data out and switch to the desired mode */
 289        switch (mode) {
 290        case ADUX1020_MODE_PROX_I:
 291                ret = regmap_update_bits(data->regmap, ADUX1020_REG_OP_MODE,
 292                                         ADUX1020_DATA_OUT_MODE_MASK,
 293                                         ADUX1020_DATA_OUT_PROX_I);
 294                if (ret < 0)
 295                        return ret;
 296
 297                ret = regmap_update_bits(data->regmap, ADUX1020_REG_OP_MODE,
 298                                         ADUX1020_OP_MODE_MASK,
 299                                         ADUX1020_MODE_PROX_I);
 300                if (ret < 0)
 301                        return ret;
 302                break;
 303        default:
 304                return -EINVAL;
 305        }
 306
 307        return 0;
 308}
 309
 310static int adux1020_measure(struct adux1020_data *data,
 311                            enum adux1020_op_modes mode,
 312                            u16 *val)
 313{
 314        unsigned int status;
 315        int ret, tries = 50;
 316
 317        /* Disable INT pin as polling is going to be used */
 318        ret = regmap_write(data->regmap, ADUX1020_REG_INT_ENABLE,
 319                           ADUX1020_INT_DISABLE);
 320        if (ret < 0)
 321                return ret;
 322
 323        /* Enable mode interrupt */
 324        ret = regmap_update_bits(data->regmap, ADUX1020_REG_INT_MASK,
 325                                 ADUX1020_MODE_INT_MASK,
 326                                 adux1020_modes[mode].int_en);
 327        if (ret < 0)
 328                return ret;
 329
 330        while (tries--) {
 331                ret = regmap_read(data->regmap, ADUX1020_REG_INT_STATUS,
 332                                  &status);
 333                if (ret < 0)
 334                        return ret;
 335
 336                status &= ADUX1020_FIFO_STATUS_MASK;
 337                if (status >= adux1020_modes[mode].bytes)
 338                        break;
 339                msleep(20);
 340        }
 341
 342        if (tries < 0)
 343                return -EIO;
 344
 345        ret = adux1020_read_fifo(data, val, adux1020_modes[mode].buf_len);
 346        if (ret < 0)
 347                return ret;
 348
 349        /* Clear mode interrupt */
 350        ret = regmap_write(data->regmap, ADUX1020_REG_INT_STATUS,
 351                           (~adux1020_modes[mode].int_en));
 352        if (ret < 0)
 353                return ret;
 354
 355        /* Disable mode interrupts */
 356        return regmap_update_bits(data->regmap, ADUX1020_REG_INT_MASK,
 357                                  ADUX1020_MODE_INT_MASK,
 358                                  ADUX1020_MODE_INT_DISABLE);
 359}
 360
 361static int adux1020_read_raw(struct iio_dev *indio_dev,
 362                             struct iio_chan_spec const *chan,
 363                             int *val, int *val2, long mask)
 364{
 365        struct adux1020_data *data = iio_priv(indio_dev);
 366        u16 buf[3];
 367        int ret = -EINVAL;
 368        unsigned int regval;
 369
 370        mutex_lock(&data->lock);
 371
 372        switch (mask) {
 373        case IIO_CHAN_INFO_RAW:
 374                switch (chan->type) {
 375                case IIO_PROXIMITY:
 376                        ret = adux1020_set_mode(data, ADUX1020_MODE_PROX_I);
 377                        if (ret < 0)
 378                                goto fail;
 379
 380                        ret = adux1020_measure(data, ADUX1020_MODE_PROX_I, buf);
 381                        if (ret < 0)
 382                                goto fail;
 383
 384                        *val = buf[0];
 385                        ret = IIO_VAL_INT;
 386                        break;
 387                default:
 388                        break;
 389                }
 390                break;
 391        case IIO_CHAN_INFO_PROCESSED:
 392                switch (chan->type) {
 393                case IIO_CURRENT:
 394                        ret = regmap_read(data->regmap,
 395                                          ADUX1020_REG_LED_CURRENT, &regval);
 396                        if (ret < 0)
 397                                goto fail;
 398
 399                        regval = regval & ADUX1020_LED_CURRENT_MASK;
 400
 401                        *val = adux1020_led_currents[regval][0];
 402                        *val2 = adux1020_led_currents[regval][1];
 403
 404                        ret = IIO_VAL_INT_PLUS_MICRO;
 405                        break;
 406                default:
 407                        break;
 408                }
 409                break;
 410        case IIO_CHAN_INFO_SAMP_FREQ:
 411                switch (chan->type) {
 412                case IIO_PROXIMITY:
 413                        ret = regmap_read(data->regmap, ADUX1020_REG_FREQUENCY,
 414                                          &regval);
 415                        if (ret < 0)
 416                                goto fail;
 417
 418                        regval = FIELD_GET(ADUX1020_PROX_FREQ_MASK, regval);
 419
 420                        *val = adux1020_rates[regval][0];
 421                        *val2 = adux1020_rates[regval][1];
 422
 423                        ret = IIO_VAL_INT_PLUS_MICRO;
 424                        break;
 425                default:
 426                        break;
 427                }
 428                break;
 429        default:
 430                break;
 431        }
 432
 433fail:
 434        mutex_unlock(&data->lock);
 435
 436        return ret;
 437};
 438
 439static inline int adux1020_find_index(const int array[][2], int count, int val,
 440                                      int val2)
 441{
 442        int i;
 443
 444        for (i = 0; i < count; i++)
 445                if (val == array[i][0] && val2 == array[i][1])
 446                        return i;
 447
 448        return -EINVAL;
 449}
 450
 451static int adux1020_write_raw(struct iio_dev *indio_dev,
 452                              struct iio_chan_spec const *chan,
 453                              int val, int val2, long mask)
 454{
 455        struct adux1020_data *data = iio_priv(indio_dev);
 456        int i, ret = -EINVAL;
 457
 458        mutex_lock(&data->lock);
 459
 460        switch (mask) {
 461        case IIO_CHAN_INFO_SAMP_FREQ:
 462                if (chan->type == IIO_PROXIMITY) {
 463                        i = adux1020_find_index(adux1020_rates,
 464                                                ARRAY_SIZE(adux1020_rates),
 465                                                val, val2);
 466                        if (i < 0) {
 467                                ret = i;
 468                                goto fail;
 469                        }
 470
 471                        ret = regmap_update_bits(data->regmap,
 472                                                 ADUX1020_REG_FREQUENCY,
 473                                                 ADUX1020_PROX_FREQ_MASK,
 474                                                 ADUX1020_PROX_FREQ(i));
 475                }
 476                break;
 477        case IIO_CHAN_INFO_PROCESSED:
 478                if (chan->type == IIO_CURRENT) {
 479                        i = adux1020_find_index(adux1020_led_currents,
 480                                        ARRAY_SIZE(adux1020_led_currents),
 481                                        val, val2);
 482                        if (i < 0) {
 483                                ret = i;
 484                                goto fail;
 485                        }
 486
 487                        ret = regmap_update_bits(data->regmap,
 488                                                 ADUX1020_REG_LED_CURRENT,
 489                                                 ADUX1020_LED_CURRENT_MASK, i);
 490                }
 491                break;
 492        default:
 493                break;
 494        }
 495
 496fail:
 497        mutex_unlock(&data->lock);
 498
 499        return ret;
 500}
 501
 502static int adux1020_write_event_config(struct iio_dev *indio_dev,
 503                                       const struct iio_chan_spec *chan,
 504                                       enum iio_event_type type,
 505                                       enum iio_event_direction dir, int state)
 506{
 507        struct adux1020_data *data = iio_priv(indio_dev);
 508        int ret, mask;
 509
 510        mutex_lock(&data->lock);
 511
 512        ret = regmap_write(data->regmap, ADUX1020_REG_INT_ENABLE,
 513                           ADUX1020_INT_ENABLE);
 514        if (ret < 0)
 515                goto fail;
 516
 517        ret = regmap_write(data->regmap, ADUX1020_REG_INT_POLARITY, 0);
 518        if (ret < 0)
 519                goto fail;
 520
 521        switch (chan->type) {
 522        case IIO_PROXIMITY:
 523                if (dir == IIO_EV_DIR_RISING)
 524                        mask = ADUX1020_PROX_ON1_INT;
 525                else
 526                        mask = ADUX1020_PROX_OFF1_INT;
 527
 528                if (state)
 529                        state = 0;
 530                else
 531                        state = mask;
 532
 533                ret = regmap_update_bits(data->regmap, ADUX1020_REG_INT_MASK,
 534                                         mask, state);
 535                if (ret < 0)
 536                        goto fail;
 537
 538                /*
 539                 * Trigger proximity interrupt when the intensity is above
 540                 * or below threshold
 541                 */
 542                ret = regmap_update_bits(data->regmap, ADUX1020_REG_PROX_TYPE,
 543                                         ADUX1020_PROX_TYPE,
 544                                         ADUX1020_PROX_TYPE);
 545                if (ret < 0)
 546                        goto fail;
 547
 548                /* Set proximity mode */
 549                ret = adux1020_set_mode(data, ADUX1020_MODE_PROX_I);
 550                break;
 551        default:
 552                ret = -EINVAL;
 553                break;
 554        }
 555
 556fail:
 557        mutex_unlock(&data->lock);
 558
 559        return ret;
 560}
 561
 562static int adux1020_read_event_config(struct iio_dev *indio_dev,
 563                                      const struct iio_chan_spec *chan,
 564                                      enum iio_event_type type,
 565                                      enum iio_event_direction dir)
 566{
 567        struct adux1020_data *data = iio_priv(indio_dev);
 568        int ret, mask;
 569        unsigned int regval;
 570
 571        switch (chan->type) {
 572        case IIO_PROXIMITY:
 573                if (dir == IIO_EV_DIR_RISING)
 574                        mask = ADUX1020_PROX_ON1_INT;
 575                else
 576                        mask = ADUX1020_PROX_OFF1_INT;
 577                break;
 578        default:
 579                return -EINVAL;
 580        }
 581
 582        ret = regmap_read(data->regmap, ADUX1020_REG_INT_MASK, &regval);
 583        if (ret < 0)
 584                return ret;
 585
 586        return !(regval & mask);
 587}
 588
 589static int adux1020_read_thresh(struct iio_dev *indio_dev,
 590                                const struct iio_chan_spec *chan,
 591                                enum iio_event_type type,
 592                                enum iio_event_direction dir,
 593                                enum iio_event_info info, int *val, int *val2)
 594{
 595        struct adux1020_data *data = iio_priv(indio_dev);
 596        u8 reg;
 597        int ret;
 598        unsigned int regval;
 599
 600        switch (chan->type) {
 601        case IIO_PROXIMITY:
 602                if (dir == IIO_EV_DIR_RISING)
 603                        reg = ADUX1020_REG_PROX_TH_ON1;
 604                else
 605                        reg = ADUX1020_REG_PROX_TH_OFF1;
 606                break;
 607        default:
 608                return -EINVAL;
 609        }
 610
 611        ret = regmap_read(data->regmap, reg, &regval);
 612        if (ret < 0)
 613                return ret;
 614
 615        *val = regval;
 616
 617        return IIO_VAL_INT;
 618}
 619
 620static int adux1020_write_thresh(struct iio_dev *indio_dev,
 621                                 const struct iio_chan_spec *chan,
 622                                 enum iio_event_type type,
 623                                 enum iio_event_direction dir,
 624                                 enum iio_event_info info, int val, int val2)
 625{
 626        struct adux1020_data *data = iio_priv(indio_dev);
 627        u8 reg;
 628
 629        switch (chan->type) {
 630        case IIO_PROXIMITY:
 631                if (dir == IIO_EV_DIR_RISING)
 632                        reg = ADUX1020_REG_PROX_TH_ON1;
 633                else
 634                        reg = ADUX1020_REG_PROX_TH_OFF1;
 635                break;
 636        default:
 637                return -EINVAL;
 638        }
 639
 640        /* Full scale threshold value is 0-65535  */
 641        if (val < 0 || val > 65535)
 642                return -EINVAL;
 643
 644        return regmap_write(data->regmap, reg, val);
 645}
 646
 647static const struct iio_event_spec adux1020_proximity_event[] = {
 648        {
 649                .type = IIO_EV_TYPE_THRESH,
 650                .dir = IIO_EV_DIR_RISING,
 651                .mask_separate = BIT(IIO_EV_INFO_VALUE) |
 652                        BIT(IIO_EV_INFO_ENABLE),
 653        },
 654        {
 655                .type = IIO_EV_TYPE_THRESH,
 656                .dir = IIO_EV_DIR_FALLING,
 657                .mask_separate = BIT(IIO_EV_INFO_VALUE) |
 658                        BIT(IIO_EV_INFO_ENABLE),
 659        },
 660};
 661
 662static const struct iio_chan_spec adux1020_channels[] = {
 663        {
 664                .type = IIO_PROXIMITY,
 665                .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
 666                                      BIT(IIO_CHAN_INFO_SAMP_FREQ),
 667                .event_spec = adux1020_proximity_event,
 668                .num_event_specs = ARRAY_SIZE(adux1020_proximity_event),
 669        },
 670        {
 671                .type = IIO_CURRENT,
 672                .info_mask_separate = BIT(IIO_CHAN_INFO_PROCESSED),
 673                .extend_name = "led",
 674                .output = 1,
 675        },
 676};
 677
 678static IIO_CONST_ATTR_SAMP_FREQ_AVAIL(
 679                      "0.1 0.2 0.5 1 2 5 10 20 50 100 190 450 820 1400");
 680
 681static struct attribute *adux1020_attributes[] = {
 682        &iio_const_attr_sampling_frequency_available.dev_attr.attr,
 683        NULL
 684};
 685
 686static const struct attribute_group adux1020_attribute_group = {
 687        .attrs = adux1020_attributes,
 688};
 689
 690static const struct iio_info adux1020_info = {
 691        .attrs = &adux1020_attribute_group,
 692        .read_raw = adux1020_read_raw,
 693        .write_raw = adux1020_write_raw,
 694        .read_event_config = adux1020_read_event_config,
 695        .write_event_config = adux1020_write_event_config,
 696        .read_event_value = adux1020_read_thresh,
 697        .write_event_value = adux1020_write_thresh,
 698};
 699
 700static irqreturn_t adux1020_interrupt_handler(int irq, void *private)
 701{
 702        struct iio_dev *indio_dev = private;
 703        struct adux1020_data *data = iio_priv(indio_dev);
 704        int ret, status;
 705
 706        ret = regmap_read(data->regmap, ADUX1020_REG_INT_STATUS, &status);
 707        if (ret < 0)
 708                return IRQ_HANDLED;
 709
 710        status &= ADUX1020_MODE_INT_STATUS_MASK;
 711
 712        if (status & ADUX1020_INT_PROX_ON1) {
 713                iio_push_event(indio_dev,
 714                               IIO_UNMOD_EVENT_CODE(IIO_PROXIMITY, 0,
 715                                                    IIO_EV_TYPE_THRESH,
 716                                                    IIO_EV_DIR_RISING),
 717                               iio_get_time_ns(indio_dev));
 718        }
 719
 720        if (status & ADUX1020_INT_PROX_OFF1) {
 721                iio_push_event(indio_dev,
 722                               IIO_UNMOD_EVENT_CODE(IIO_PROXIMITY, 0,
 723                                                    IIO_EV_TYPE_THRESH,
 724                                                    IIO_EV_DIR_FALLING),
 725                               iio_get_time_ns(indio_dev));
 726        }
 727
 728        regmap_update_bits(data->regmap, ADUX1020_REG_INT_STATUS,
 729                           ADUX1020_MODE_INT_MASK, ADUX1020_INT_CLEAR);
 730
 731        return IRQ_HANDLED;
 732}
 733
 734static int adux1020_chip_init(struct adux1020_data *data)
 735{
 736        struct i2c_client *client = data->client;
 737        int ret;
 738        unsigned int val;
 739
 740        ret = regmap_read(data->regmap, ADUX1020_REG_CHIP_ID, &val);
 741        if (ret < 0)
 742                return ret;
 743
 744        if ((val & ADUX1020_CHIP_ID_MASK) != ADUX1020_CHIP_ID) {
 745                dev_err(&client->dev, "invalid chip id 0x%04x\n", val);
 746                return -ENODEV;
 747        }
 748
 749        dev_dbg(&client->dev, "Detected ADUX1020 with chip id: 0x%04x\n", val);
 750
 751        ret = regmap_update_bits(data->regmap, ADUX1020_REG_SW_RESET,
 752                                 ADUX1020_SW_RESET, ADUX1020_SW_RESET);
 753        if (ret < 0)
 754                return ret;
 755
 756        /* Load default configuration */
 757        ret = regmap_multi_reg_write(data->regmap, adux1020_def_conf,
 758                                     ARRAY_SIZE(adux1020_def_conf));
 759        if (ret < 0)
 760                return ret;
 761
 762        ret = adux1020_flush_fifo(data);
 763        if (ret < 0)
 764                return ret;
 765
 766        /* Use LED_IREF for proximity mode */
 767        ret = regmap_update_bits(data->regmap, ADUX1020_REG_LED_CURRENT,
 768                                 ADUX1020_LED_PIREF_EN, 0);
 769        if (ret < 0)
 770                return ret;
 771
 772        /* Mask all interrupts */
 773        return regmap_update_bits(data->regmap, ADUX1020_REG_INT_MASK,
 774                           ADUX1020_MODE_INT_MASK, ADUX1020_MODE_INT_DISABLE);
 775}
 776
 777static int adux1020_probe(struct i2c_client *client,
 778                          const struct i2c_device_id *id)
 779{
 780        struct adux1020_data *data;
 781        struct iio_dev *indio_dev;
 782        int ret;
 783
 784        indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*data));
 785        if (!indio_dev)
 786                return -ENOMEM;
 787
 788        indio_dev->info = &adux1020_info;
 789        indio_dev->name = ADUX1020_DRV_NAME;
 790        indio_dev->channels = adux1020_channels;
 791        indio_dev->num_channels = ARRAY_SIZE(adux1020_channels);
 792        indio_dev->modes = INDIO_DIRECT_MODE;
 793
 794        data = iio_priv(indio_dev);
 795
 796        data->regmap = devm_regmap_init_i2c(client, &adux1020_regmap_config);
 797        if (IS_ERR(data->regmap)) {
 798                dev_err(&client->dev, "regmap initialization failed.\n");
 799                return PTR_ERR(data->regmap);
 800        }
 801
 802        data->client = client;
 803        data->indio_dev = indio_dev;
 804        mutex_init(&data->lock);
 805
 806        ret = adux1020_chip_init(data);
 807        if (ret)
 808                return ret;
 809
 810        if (client->irq) {
 811                ret = devm_request_threaded_irq(&client->dev, client->irq,
 812                                        NULL, adux1020_interrupt_handler,
 813                                        IRQF_TRIGGER_HIGH | IRQF_ONESHOT,
 814                                        ADUX1020_DRV_NAME, indio_dev);
 815                if (ret) {
 816                        dev_err(&client->dev, "irq request error %d\n", -ret);
 817                        return ret;
 818                }
 819        }
 820
 821        return devm_iio_device_register(&client->dev, indio_dev);
 822}
 823
 824static const struct i2c_device_id adux1020_id[] = {
 825        { "adux1020", 0 },
 826        {}
 827};
 828MODULE_DEVICE_TABLE(i2c, adux1020_id);
 829
 830static const struct of_device_id adux1020_of_match[] = {
 831        { .compatible = "adi,adux1020" },
 832        { }
 833};
 834MODULE_DEVICE_TABLE(of, adux1020_of_match);
 835
 836static struct i2c_driver adux1020_driver = {
 837        .driver = {
 838                .name   = ADUX1020_DRV_NAME,
 839                .of_match_table = adux1020_of_match,
 840        },
 841        .probe          = adux1020_probe,
 842        .id_table       = adux1020_id,
 843};
 844module_i2c_driver(adux1020_driver);
 845
 846MODULE_AUTHOR("Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>");
 847MODULE_DESCRIPTION("ADUX1020 photometric sensor");
 848MODULE_LICENSE("GPL");
 849