linux/drivers/iio/light/apds9960.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0+
   2/*
   3 * apds9960.c - Support for Avago APDS9960 gesture/RGB/ALS/proximity sensor
   4 *
   5 * Copyright (C) 2015, 2018
   6 * Author: Matt Ranostay <matt.ranostay@konsulko.com>
   7 *
   8 * TODO: gesture + proximity calib offsets
   9 */
  10
  11#include <linux/acpi.h>
  12#include <linux/module.h>
  13#include <linux/init.h>
  14#include <linux/interrupt.h>
  15#include <linux/delay.h>
  16#include <linux/mutex.h>
  17#include <linux/err.h>
  18#include <linux/irq.h>
  19#include <linux/i2c.h>
  20#include <linux/pm_runtime.h>
  21#include <linux/regmap.h>
  22#include <linux/iio/iio.h>
  23#include <linux/iio/buffer.h>
  24#include <linux/iio/events.h>
  25#include <linux/iio/kfifo_buf.h>
  26#include <linux/iio/sysfs.h>
  27
  28#define APDS9960_REGMAP_NAME    "apds9960_regmap"
  29#define APDS9960_DRV_NAME       "apds9960"
  30
  31#define APDS9960_REG_RAM_START  0x00
  32#define APDS9960_REG_RAM_END    0x7f
  33
  34#define APDS9960_REG_ENABLE     0x80
  35#define APDS9960_REG_ATIME      0x81
  36#define APDS9960_REG_WTIME      0x83
  37
  38#define APDS9960_REG_AILTL      0x84
  39#define APDS9960_REG_AILTH      0x85
  40#define APDS9960_REG_AIHTL      0x86
  41#define APDS9960_REG_AIHTH      0x87
  42
  43#define APDS9960_REG_PILT       0x89
  44#define APDS9960_REG_PIHT       0x8b
  45#define APDS9960_REG_PERS       0x8c
  46
  47#define APDS9960_REG_CONFIG_1   0x8d
  48#define APDS9960_REG_PPULSE     0x8e
  49
  50#define APDS9960_REG_CONTROL    0x8f
  51#define APDS9960_REG_CONTROL_AGAIN_MASK         0x03
  52#define APDS9960_REG_CONTROL_PGAIN_MASK         0x0c
  53#define APDS9960_REG_CONTROL_AGAIN_MASK_SHIFT   0
  54#define APDS9960_REG_CONTROL_PGAIN_MASK_SHIFT   2
  55
  56#define APDS9960_REG_CONFIG_2   0x90
  57#define APDS9960_REG_CONFIG_2_GGAIN_MASK        0x60
  58#define APDS9960_REG_CONFIG_2_GGAIN_MASK_SHIFT  5
  59
  60#define APDS9960_REG_ID         0x92
  61
  62#define APDS9960_REG_STATUS     0x93
  63#define APDS9960_REG_STATUS_PS_INT      BIT(5)
  64#define APDS9960_REG_STATUS_ALS_INT     BIT(4)
  65#define APDS9960_REG_STATUS_GINT        BIT(2)
  66
  67#define APDS9960_REG_PDATA      0x9c
  68#define APDS9960_REG_POFFSET_UR 0x9d
  69#define APDS9960_REG_POFFSET_DL 0x9e
  70#define APDS9960_REG_CONFIG_3   0x9f
  71
  72#define APDS9960_REG_GPENTH     0xa0
  73#define APDS9960_REG_GEXTH      0xa1
  74
  75#define APDS9960_REG_GCONF_1    0xa2
  76#define APDS9960_REG_GCONF_1_GFIFO_THRES_MASK           0xc0
  77#define APDS9960_REG_GCONF_1_GFIFO_THRES_MASK_SHIFT     6
  78
  79#define APDS9960_REG_GCONF_2    0xa3
  80#define APDS9960_REG_GOFFSET_U  0xa4
  81#define APDS9960_REG_GOFFSET_D  0xa5
  82#define APDS9960_REG_GPULSE     0xa6
  83#define APDS9960_REG_GOFFSET_L  0xa7
  84#define APDS9960_REG_GOFFSET_R  0xa9
  85#define APDS9960_REG_GCONF_3    0xaa
  86
  87#define APDS9960_REG_GCONF_4    0xab
  88#define APDS9960_REG_GFLVL      0xae
  89#define APDS9960_REG_GSTATUS    0xaf
  90
  91#define APDS9960_REG_IFORCE     0xe4
  92#define APDS9960_REG_PICLEAR    0xe5
  93#define APDS9960_REG_CICLEAR    0xe6
  94#define APDS9960_REG_AICLEAR    0xe7
  95
  96#define APDS9960_DEFAULT_PERS   0x33
  97#define APDS9960_DEFAULT_GPENTH 0x50
  98#define APDS9960_DEFAULT_GEXTH  0x40
  99
 100#define APDS9960_MAX_PXS_THRES_VAL      255
 101#define APDS9960_MAX_ALS_THRES_VAL      0xffff
 102#define APDS9960_MAX_INT_TIME_IN_US     1000000
 103
 104enum apds9960_als_channel_idx {
 105        IDX_ALS_CLEAR, IDX_ALS_RED, IDX_ALS_GREEN, IDX_ALS_BLUE,
 106};
 107
 108#define APDS9960_REG_ALS_BASE   0x94
 109#define APDS9960_REG_ALS_CHANNEL(_colour) \
 110        (APDS9960_REG_ALS_BASE + (IDX_ALS_##_colour * 2))
 111
 112enum apds9960_gesture_channel_idx {
 113        IDX_DIR_UP, IDX_DIR_DOWN, IDX_DIR_LEFT, IDX_DIR_RIGHT,
 114};
 115
 116#define APDS9960_REG_GFIFO_BASE 0xfc
 117#define APDS9960_REG_GFIFO_DIR(_dir) \
 118        (APDS9960_REG_GFIFO_BASE + IDX_DIR_##_dir)
 119
 120struct apds9960_data {
 121        struct i2c_client *client;
 122        struct iio_dev *indio_dev;
 123        struct mutex lock;
 124
 125        /* regmap fields */
 126        struct regmap *regmap;
 127        struct regmap_field *reg_int_als;
 128        struct regmap_field *reg_int_ges;
 129        struct regmap_field *reg_int_pxs;
 130
 131        struct regmap_field *reg_enable_als;
 132        struct regmap_field *reg_enable_ges;
 133        struct regmap_field *reg_enable_pxs;
 134
 135        /* state */
 136        int als_int;
 137        int pxs_int;
 138        int gesture_mode_running;
 139
 140        /* gain values */
 141        int als_gain;
 142        int pxs_gain;
 143
 144        /* integration time value in us */
 145        int als_adc_int_us;
 146
 147        /* gesture buffer */
 148        u8 buffer[4]; /* 4 8-bit channels */
 149};
 150
 151static const struct reg_default apds9960_reg_defaults[] = {
 152        /* Default ALS integration time = 2.48ms */
 153        { APDS9960_REG_ATIME, 0xff },
 154};
 155
 156static const struct regmap_range apds9960_volatile_ranges[] = {
 157        regmap_reg_range(APDS9960_REG_STATUS,
 158                                APDS9960_REG_PDATA),
 159        regmap_reg_range(APDS9960_REG_GFLVL,
 160                                APDS9960_REG_GSTATUS),
 161        regmap_reg_range(APDS9960_REG_GFIFO_DIR(UP),
 162                                APDS9960_REG_GFIFO_DIR(RIGHT)),
 163        regmap_reg_range(APDS9960_REG_IFORCE,
 164                                APDS9960_REG_AICLEAR),
 165};
 166
 167static const struct regmap_access_table apds9960_volatile_table = {
 168        .yes_ranges     = apds9960_volatile_ranges,
 169        .n_yes_ranges   = ARRAY_SIZE(apds9960_volatile_ranges),
 170};
 171
 172static const struct regmap_range apds9960_precious_ranges[] = {
 173        regmap_reg_range(APDS9960_REG_RAM_START, APDS9960_REG_RAM_END),
 174};
 175
 176static const struct regmap_access_table apds9960_precious_table = {
 177        .yes_ranges     = apds9960_precious_ranges,
 178        .n_yes_ranges   = ARRAY_SIZE(apds9960_precious_ranges),
 179};
 180
 181static const struct regmap_range apds9960_readable_ranges[] = {
 182        regmap_reg_range(APDS9960_REG_ENABLE,
 183                                APDS9960_REG_GSTATUS),
 184        regmap_reg_range(APDS9960_REG_GFIFO_DIR(UP),
 185                                APDS9960_REG_GFIFO_DIR(RIGHT)),
 186};
 187
 188static const struct regmap_access_table apds9960_readable_table = {
 189        .yes_ranges     = apds9960_readable_ranges,
 190        .n_yes_ranges   = ARRAY_SIZE(apds9960_readable_ranges),
 191};
 192
 193static const struct regmap_range apds9960_writeable_ranges[] = {
 194        regmap_reg_range(APDS9960_REG_ENABLE, APDS9960_REG_CONFIG_2),
 195        regmap_reg_range(APDS9960_REG_POFFSET_UR, APDS9960_REG_GCONF_4),
 196        regmap_reg_range(APDS9960_REG_IFORCE, APDS9960_REG_AICLEAR),
 197};
 198
 199static const struct regmap_access_table apds9960_writeable_table = {
 200        .yes_ranges     = apds9960_writeable_ranges,
 201        .n_yes_ranges   = ARRAY_SIZE(apds9960_writeable_ranges),
 202};
 203
 204static const struct regmap_config apds9960_regmap_config = {
 205        .name = APDS9960_REGMAP_NAME,
 206        .reg_bits = 8,
 207        .val_bits = 8,
 208        .use_single_read = true,
 209        .use_single_write = true,
 210
 211        .volatile_table = &apds9960_volatile_table,
 212        .precious_table = &apds9960_precious_table,
 213        .rd_table = &apds9960_readable_table,
 214        .wr_table = &apds9960_writeable_table,
 215
 216        .reg_defaults = apds9960_reg_defaults,
 217        .num_reg_defaults = ARRAY_SIZE(apds9960_reg_defaults),
 218        .max_register = APDS9960_REG_GFIFO_DIR(RIGHT),
 219        .cache_type = REGCACHE_RBTREE,
 220};
 221
 222static const struct iio_event_spec apds9960_pxs_event_spec[] = {
 223        {
 224                .type = IIO_EV_TYPE_THRESH,
 225                .dir = IIO_EV_DIR_RISING,
 226                .mask_separate = BIT(IIO_EV_INFO_VALUE) |
 227                        BIT(IIO_EV_INFO_ENABLE),
 228        },
 229        {
 230                .type = IIO_EV_TYPE_THRESH,
 231                .dir = IIO_EV_DIR_FALLING,
 232                .mask_separate = BIT(IIO_EV_INFO_VALUE) |
 233                        BIT(IIO_EV_INFO_ENABLE),
 234        },
 235};
 236
 237static const struct iio_event_spec apds9960_als_event_spec[] = {
 238        {
 239                .type = IIO_EV_TYPE_THRESH,
 240                .dir = IIO_EV_DIR_RISING,
 241                .mask_separate = BIT(IIO_EV_INFO_VALUE) |
 242                        BIT(IIO_EV_INFO_ENABLE),
 243        },
 244        {
 245                .type = IIO_EV_TYPE_THRESH,
 246                .dir = IIO_EV_DIR_FALLING,
 247                .mask_separate = BIT(IIO_EV_INFO_VALUE) |
 248                        BIT(IIO_EV_INFO_ENABLE),
 249        },
 250};
 251
 252#define APDS9960_GESTURE_CHANNEL(_dir, _si) { \
 253        .type = IIO_PROXIMITY, \
 254        .channel = _si + 1, \
 255        .scan_index = _si, \
 256        .indexed = 1, \
 257        .scan_type = { \
 258                .sign = 'u', \
 259                .realbits = 8, \
 260                .storagebits = 8, \
 261        }, \
 262}
 263
 264#define APDS9960_INTENSITY_CHANNEL(_colour) { \
 265        .type = IIO_INTENSITY, \
 266        .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \
 267        .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE) | \
 268                        BIT(IIO_CHAN_INFO_INT_TIME), \
 269        .channel2 = IIO_MOD_LIGHT_##_colour, \
 270        .address = APDS9960_REG_ALS_CHANNEL(_colour), \
 271        .modified = 1, \
 272        .scan_index = -1, \
 273}
 274
 275static const unsigned long apds9960_scan_masks[] = {0xf, 0};
 276
 277static const struct iio_chan_spec apds9960_channels[] = {
 278        {
 279                .type = IIO_PROXIMITY,
 280                .address = APDS9960_REG_PDATA,
 281                .info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
 282                .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE),
 283                .channel = 0,
 284                .indexed = 0,
 285                .scan_index = -1,
 286
 287                .event_spec = apds9960_pxs_event_spec,
 288                .num_event_specs = ARRAY_SIZE(apds9960_pxs_event_spec),
 289        },
 290        /* Gesture Sensor */
 291        APDS9960_GESTURE_CHANNEL(UP, 0),
 292        APDS9960_GESTURE_CHANNEL(DOWN, 1),
 293        APDS9960_GESTURE_CHANNEL(LEFT, 2),
 294        APDS9960_GESTURE_CHANNEL(RIGHT, 3),
 295        /* ALS */
 296        {
 297                .type = IIO_INTENSITY,
 298                .info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
 299                .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE) |
 300                        BIT(IIO_CHAN_INFO_INT_TIME),
 301                .channel2 = IIO_MOD_LIGHT_CLEAR,
 302                .address = APDS9960_REG_ALS_CHANNEL(CLEAR),
 303                .modified = 1,
 304                .scan_index = -1,
 305
 306                .event_spec = apds9960_als_event_spec,
 307                .num_event_specs = ARRAY_SIZE(apds9960_als_event_spec),
 308        },
 309        /* RGB Sensor */
 310        APDS9960_INTENSITY_CHANNEL(RED),
 311        APDS9960_INTENSITY_CHANNEL(GREEN),
 312        APDS9960_INTENSITY_CHANNEL(BLUE),
 313};
 314
 315/* integration time in us */
 316static const int apds9960_int_time[][2] = {
 317        { 28000, 246},
 318        {100000, 219},
 319        {200000, 182},
 320        {700000,   0}
 321};
 322
 323/* gain mapping */
 324static const int apds9960_pxs_gain_map[] = {1, 2, 4, 8};
 325static const int apds9960_als_gain_map[] = {1, 4, 16, 64};
 326
 327static IIO_CONST_ATTR(proximity_scale_available, "1 2 4 8");
 328static IIO_CONST_ATTR(intensity_scale_available, "1 4 16 64");
 329static IIO_CONST_ATTR_INT_TIME_AVAIL("0.028 0.1 0.2 0.7");
 330
 331static struct attribute *apds9960_attributes[] = {
 332        &iio_const_attr_proximity_scale_available.dev_attr.attr,
 333        &iio_const_attr_intensity_scale_available.dev_attr.attr,
 334        &iio_const_attr_integration_time_available.dev_attr.attr,
 335        NULL,
 336};
 337
 338static const struct attribute_group apds9960_attribute_group = {
 339        .attrs = apds9960_attributes,
 340};
 341
 342static const struct reg_field apds9960_reg_field_int_als =
 343                                REG_FIELD(APDS9960_REG_ENABLE, 4, 4);
 344
 345static const struct reg_field apds9960_reg_field_int_ges =
 346                                REG_FIELD(APDS9960_REG_GCONF_4, 1, 1);
 347
 348static const struct reg_field apds9960_reg_field_int_pxs =
 349                                REG_FIELD(APDS9960_REG_ENABLE, 5, 5);
 350
 351static const struct reg_field apds9960_reg_field_enable_als =
 352                                REG_FIELD(APDS9960_REG_ENABLE, 1, 1);
 353
 354static const struct reg_field apds9960_reg_field_enable_ges =
 355                                REG_FIELD(APDS9960_REG_ENABLE, 6, 6);
 356
 357static const struct reg_field apds9960_reg_field_enable_pxs =
 358                                REG_FIELD(APDS9960_REG_ENABLE, 2, 2);
 359
 360static int apds9960_set_it_time(struct apds9960_data *data, int val2)
 361{
 362        int ret = -EINVAL;
 363        int idx;
 364
 365        for (idx = 0; idx < ARRAY_SIZE(apds9960_int_time); idx++) {
 366                if (apds9960_int_time[idx][0] == val2) {
 367                        mutex_lock(&data->lock);
 368                        ret = regmap_write(data->regmap, APDS9960_REG_ATIME,
 369                                                 apds9960_int_time[idx][1]);
 370                        if (!ret)
 371                                data->als_adc_int_us = val2;
 372                        mutex_unlock(&data->lock);
 373                        break;
 374                }
 375        }
 376
 377        return ret;
 378}
 379
 380static int apds9960_set_pxs_gain(struct apds9960_data *data, int val)
 381{
 382        int ret = -EINVAL;
 383        int idx;
 384
 385        for (idx = 0; idx < ARRAY_SIZE(apds9960_pxs_gain_map); idx++) {
 386                if (apds9960_pxs_gain_map[idx] == val) {
 387                        /* pxs + gesture gains are mirrored */
 388                        mutex_lock(&data->lock);
 389                        ret = regmap_update_bits(data->regmap,
 390                                APDS9960_REG_CONTROL,
 391                                APDS9960_REG_CONTROL_PGAIN_MASK,
 392                                idx << APDS9960_REG_CONTROL_PGAIN_MASK_SHIFT);
 393                        if (ret) {
 394                                mutex_unlock(&data->lock);
 395                                break;
 396                        }
 397
 398                        ret = regmap_update_bits(data->regmap,
 399                                APDS9960_REG_CONFIG_2,
 400                                APDS9960_REG_CONFIG_2_GGAIN_MASK,
 401                                idx << APDS9960_REG_CONFIG_2_GGAIN_MASK_SHIFT);
 402                        if (!ret)
 403                                data->pxs_gain = idx;
 404                        mutex_unlock(&data->lock);
 405                        break;
 406                }
 407        }
 408
 409        return ret;
 410}
 411
 412static int apds9960_set_als_gain(struct apds9960_data *data, int val)
 413{
 414        int ret = -EINVAL;
 415        int idx;
 416
 417        for (idx = 0; idx < ARRAY_SIZE(apds9960_als_gain_map); idx++) {
 418                if (apds9960_als_gain_map[idx] == val) {
 419                        mutex_lock(&data->lock);
 420                        ret = regmap_update_bits(data->regmap,
 421                                        APDS9960_REG_CONTROL,
 422                                        APDS9960_REG_CONTROL_AGAIN_MASK, idx);
 423                        if (!ret)
 424                                data->als_gain = idx;
 425                        mutex_unlock(&data->lock);
 426                        break;
 427                }
 428        }
 429
 430        return ret;
 431}
 432
 433#ifdef CONFIG_PM
 434static int apds9960_set_power_state(struct apds9960_data *data, bool on)
 435{
 436        struct device *dev = &data->client->dev;
 437        int ret = 0;
 438
 439        mutex_lock(&data->lock);
 440
 441        if (on) {
 442                int suspended;
 443
 444                suspended = pm_runtime_suspended(dev);
 445                ret = pm_runtime_get_sync(dev);
 446
 447                /* Allow one integration cycle before allowing a reading */
 448                if (suspended)
 449                        usleep_range(data->als_adc_int_us,
 450                                     APDS9960_MAX_INT_TIME_IN_US);
 451        } else {
 452                pm_runtime_mark_last_busy(dev);
 453                ret = pm_runtime_put_autosuspend(dev);
 454        }
 455
 456        mutex_unlock(&data->lock);
 457
 458        return ret;
 459}
 460#else
 461static int apds9960_set_power_state(struct apds9960_data *data, bool on)
 462{
 463        return 0;
 464}
 465#endif
 466
 467static int apds9960_read_raw(struct iio_dev *indio_dev,
 468                             struct iio_chan_spec const *chan,
 469                             int *val, int *val2, long mask)
 470{
 471        struct apds9960_data *data = iio_priv(indio_dev);
 472        __le16 buf;
 473        int ret = -EINVAL;
 474
 475        if (data->gesture_mode_running)
 476                return -EBUSY;
 477
 478        switch (mask) {
 479        case IIO_CHAN_INFO_RAW:
 480                apds9960_set_power_state(data, true);
 481                switch (chan->type) {
 482                case IIO_PROXIMITY:
 483                        ret = regmap_read(data->regmap, chan->address, val);
 484                        if (!ret)
 485                                ret = IIO_VAL_INT;
 486                        break;
 487                case IIO_INTENSITY:
 488                        ret = regmap_bulk_read(data->regmap, chan->address,
 489                                               &buf, 2);
 490                        if (!ret) {
 491                                ret = IIO_VAL_INT;
 492                                *val = le16_to_cpu(buf);
 493                        }
 494                        break;
 495                default:
 496                        ret = -EINVAL;
 497                }
 498                apds9960_set_power_state(data, false);
 499                break;
 500        case IIO_CHAN_INFO_INT_TIME:
 501                /* RGB + ALS sensors only have integration time */
 502                mutex_lock(&data->lock);
 503                switch (chan->type) {
 504                case IIO_INTENSITY:
 505                        *val = 0;
 506                        *val2 = data->als_adc_int_us;
 507                        ret = IIO_VAL_INT_PLUS_MICRO;
 508                        break;
 509                default:
 510                        ret = -EINVAL;
 511                }
 512                mutex_unlock(&data->lock);
 513                break;
 514        case IIO_CHAN_INFO_SCALE:
 515                mutex_lock(&data->lock);
 516                switch (chan->type) {
 517                case IIO_PROXIMITY:
 518                        *val = apds9960_pxs_gain_map[data->pxs_gain];
 519                        ret = IIO_VAL_INT;
 520                        break;
 521                case IIO_INTENSITY:
 522                        *val = apds9960_als_gain_map[data->als_gain];
 523                        ret = IIO_VAL_INT;
 524                        break;
 525                default:
 526                        ret = -EINVAL;
 527                }
 528                mutex_unlock(&data->lock);
 529                break;
 530        }
 531
 532        return ret;
 533};
 534
 535static int apds9960_write_raw(struct iio_dev *indio_dev,
 536                             struct iio_chan_spec const *chan,
 537                             int val, int val2, long mask)
 538{
 539        struct apds9960_data *data = iio_priv(indio_dev);
 540
 541        switch (mask) {
 542        case IIO_CHAN_INFO_INT_TIME:
 543                /* RGB + ALS sensors only have int time */
 544                switch (chan->type) {
 545                case IIO_INTENSITY:
 546                        if (val != 0)
 547                                return -EINVAL;
 548                        return apds9960_set_it_time(data, val2);
 549                default:
 550                        return -EINVAL;
 551                }
 552        case IIO_CHAN_INFO_SCALE:
 553                if (val2 != 0)
 554                        return -EINVAL;
 555                switch (chan->type) {
 556                case IIO_PROXIMITY:
 557                        return apds9960_set_pxs_gain(data, val);
 558                case IIO_INTENSITY:
 559                        return apds9960_set_als_gain(data, val);
 560                default:
 561                        return -EINVAL;
 562                }
 563        default:
 564                return -EINVAL;
 565        }
 566
 567        return 0;
 568}
 569
 570static inline int apds9960_get_thres_reg(const struct iio_chan_spec *chan,
 571                                         enum iio_event_direction dir,
 572                                         u8 *reg)
 573{
 574        switch (dir) {
 575        case IIO_EV_DIR_RISING:
 576                switch (chan->type) {
 577                case IIO_PROXIMITY:
 578                        *reg = APDS9960_REG_PIHT;
 579                        break;
 580                case IIO_INTENSITY:
 581                        *reg = APDS9960_REG_AIHTL;
 582                        break;
 583                default:
 584                        return -EINVAL;
 585                }
 586                break;
 587        case IIO_EV_DIR_FALLING:
 588                switch (chan->type) {
 589                case IIO_PROXIMITY:
 590                        *reg = APDS9960_REG_PILT;
 591                        break;
 592                case IIO_INTENSITY:
 593                        *reg = APDS9960_REG_AILTL;
 594                        break;
 595                default:
 596                        return -EINVAL;
 597                }
 598                break;
 599        default:
 600                return -EINVAL;
 601        }
 602
 603        return 0;
 604}
 605
 606static int apds9960_read_event(struct iio_dev *indio_dev,
 607                               const struct iio_chan_spec *chan,
 608                               enum iio_event_type type,
 609                               enum iio_event_direction dir,
 610                               enum iio_event_info info,
 611                               int *val, int *val2)
 612{
 613        u8 reg;
 614        __le16 buf;
 615        int ret = 0;
 616        struct apds9960_data *data = iio_priv(indio_dev);
 617
 618        if (info != IIO_EV_INFO_VALUE)
 619                return -EINVAL;
 620
 621        ret = apds9960_get_thres_reg(chan, dir, &reg);
 622        if (ret < 0)
 623                return ret;
 624
 625        if (chan->type == IIO_PROXIMITY) {
 626                ret = regmap_read(data->regmap, reg, val);
 627                if (ret < 0)
 628                        return ret;
 629        } else if (chan->type == IIO_INTENSITY) {
 630                ret = regmap_bulk_read(data->regmap, reg, &buf, 2);
 631                if (ret < 0)
 632                        return ret;
 633                *val = le16_to_cpu(buf);
 634        } else
 635                return -EINVAL;
 636
 637        *val2 = 0;
 638
 639        return IIO_VAL_INT;
 640}
 641
 642static int apds9960_write_event(struct iio_dev *indio_dev,
 643                                const struct iio_chan_spec *chan,
 644                                enum iio_event_type type,
 645                                enum iio_event_direction dir,
 646                                enum iio_event_info info,
 647                                int val, int val2)
 648{
 649        u8 reg;
 650        __le16 buf;
 651        int ret = 0;
 652        struct apds9960_data *data = iio_priv(indio_dev);
 653
 654        if (info != IIO_EV_INFO_VALUE)
 655                return -EINVAL;
 656
 657        ret = apds9960_get_thres_reg(chan, dir, &reg);
 658        if (ret < 0)
 659                return ret;
 660
 661        if (chan->type == IIO_PROXIMITY) {
 662                if (val < 0 || val > APDS9960_MAX_PXS_THRES_VAL)
 663                        return -EINVAL;
 664                ret = regmap_write(data->regmap, reg, val);
 665                if (ret < 0)
 666                        return ret;
 667        } else if (chan->type == IIO_INTENSITY) {
 668                if (val < 0 || val > APDS9960_MAX_ALS_THRES_VAL)
 669                        return -EINVAL;
 670                buf = cpu_to_le16(val);
 671                ret = regmap_bulk_write(data->regmap, reg, &buf, 2);
 672                if (ret < 0)
 673                        return ret;
 674        } else
 675                return -EINVAL;
 676
 677        return 0;
 678}
 679
 680static int apds9960_read_event_config(struct iio_dev *indio_dev,
 681                                      const struct iio_chan_spec *chan,
 682                                      enum iio_event_type type,
 683                                      enum iio_event_direction dir)
 684{
 685        struct apds9960_data *data = iio_priv(indio_dev);
 686
 687        switch (chan->type) {
 688        case IIO_PROXIMITY:
 689                return data->pxs_int;
 690        case IIO_INTENSITY:
 691                return data->als_int;
 692        default:
 693                return -EINVAL;
 694        }
 695
 696        return 0;
 697}
 698
 699static int apds9960_write_event_config(struct iio_dev *indio_dev,
 700                                       const struct iio_chan_spec *chan,
 701                                       enum iio_event_type type,
 702                                       enum iio_event_direction dir,
 703                                       int state)
 704{
 705        struct apds9960_data *data = iio_priv(indio_dev);
 706        int ret;
 707
 708        state = !!state;
 709
 710        switch (chan->type) {
 711        case IIO_PROXIMITY:
 712                if (data->pxs_int == state)
 713                        return -EINVAL;
 714
 715                ret = regmap_field_write(data->reg_int_pxs, state);
 716                if (ret)
 717                        return ret;
 718                data->pxs_int = state;
 719                apds9960_set_power_state(data, state);
 720                break;
 721        case IIO_INTENSITY:
 722                if (data->als_int == state)
 723                        return -EINVAL;
 724
 725                ret = regmap_field_write(data->reg_int_als, state);
 726                if (ret)
 727                        return ret;
 728                data->als_int = state;
 729                apds9960_set_power_state(data, state);
 730                break;
 731        default:
 732                return -EINVAL;
 733        }
 734
 735        return 0;
 736}
 737
 738static const struct iio_info apds9960_info = {
 739        .attrs = &apds9960_attribute_group,
 740        .read_raw = apds9960_read_raw,
 741        .write_raw = apds9960_write_raw,
 742        .read_event_value = apds9960_read_event,
 743        .write_event_value = apds9960_write_event,
 744        .read_event_config = apds9960_read_event_config,
 745        .write_event_config = apds9960_write_event_config,
 746
 747};
 748
 749static inline int apds9660_fifo_is_empty(struct apds9960_data *data)
 750{
 751        int cnt;
 752        int ret;
 753
 754        ret = regmap_read(data->regmap, APDS9960_REG_GFLVL, &cnt);
 755        if (ret)
 756                return ret;
 757
 758        return cnt;
 759}
 760
 761static void apds9960_read_gesture_fifo(struct apds9960_data *data)
 762{
 763        int ret, cnt = 0;
 764
 765        mutex_lock(&data->lock);
 766        data->gesture_mode_running = 1;
 767
 768        while (cnt || (cnt = apds9660_fifo_is_empty(data) > 0)) {
 769                ret = regmap_bulk_read(data->regmap, APDS9960_REG_GFIFO_BASE,
 770                                      &data->buffer, 4);
 771
 772                if (ret)
 773                        goto err_read;
 774
 775                iio_push_to_buffers(data->indio_dev, data->buffer);
 776                cnt--;
 777        }
 778
 779err_read:
 780        data->gesture_mode_running = 0;
 781        mutex_unlock(&data->lock);
 782}
 783
 784static irqreturn_t apds9960_interrupt_handler(int irq, void *private)
 785{
 786        struct iio_dev *indio_dev = private;
 787        struct apds9960_data *data = iio_priv(indio_dev);
 788        int ret, status;
 789
 790        ret = regmap_read(data->regmap, APDS9960_REG_STATUS, &status);
 791        if (ret < 0) {
 792                dev_err(&data->client->dev, "irq status reg read failed\n");
 793                return IRQ_HANDLED;
 794        }
 795
 796        if ((status & APDS9960_REG_STATUS_ALS_INT) && data->als_int) {
 797                iio_push_event(indio_dev,
 798                               IIO_UNMOD_EVENT_CODE(IIO_INTENSITY, 0,
 799                                                    IIO_EV_TYPE_THRESH,
 800                                                    IIO_EV_DIR_EITHER),
 801                               iio_get_time_ns(indio_dev));
 802                regmap_write(data->regmap, APDS9960_REG_CICLEAR, 1);
 803        }
 804
 805        if ((status & APDS9960_REG_STATUS_PS_INT) && data->pxs_int) {
 806                iio_push_event(indio_dev,
 807                               IIO_UNMOD_EVENT_CODE(IIO_PROXIMITY, 0,
 808                                                    IIO_EV_TYPE_THRESH,
 809                                                    IIO_EV_DIR_EITHER),
 810                               iio_get_time_ns(indio_dev));
 811                regmap_write(data->regmap, APDS9960_REG_PICLEAR, 1);
 812        }
 813
 814        if (status & APDS9960_REG_STATUS_GINT)
 815                apds9960_read_gesture_fifo(data);
 816
 817        return IRQ_HANDLED;
 818}
 819
 820static int apds9960_set_powermode(struct apds9960_data *data, bool state)
 821{
 822        return regmap_update_bits(data->regmap, APDS9960_REG_ENABLE, 1, state);
 823}
 824
 825static int apds9960_buffer_postenable(struct iio_dev *indio_dev)
 826{
 827        struct apds9960_data *data = iio_priv(indio_dev);
 828        int ret;
 829
 830        ret = regmap_field_write(data->reg_int_ges, 1);
 831        if (ret)
 832                return ret;
 833
 834        ret = regmap_field_write(data->reg_enable_ges, 1);
 835        if (ret)
 836                return ret;
 837
 838        pm_runtime_get_sync(&data->client->dev);
 839
 840        return 0;
 841}
 842
 843static int apds9960_buffer_predisable(struct iio_dev *indio_dev)
 844{
 845        struct apds9960_data *data = iio_priv(indio_dev);
 846        int ret;
 847
 848        ret = regmap_field_write(data->reg_enable_ges, 0);
 849        if (ret)
 850                return ret;
 851
 852        ret = regmap_field_write(data->reg_int_ges, 0);
 853        if (ret)
 854                return ret;
 855
 856        pm_runtime_put_autosuspend(&data->client->dev);
 857
 858        return 0;
 859}
 860
 861static const struct iio_buffer_setup_ops apds9960_buffer_setup_ops = {
 862        .postenable = apds9960_buffer_postenable,
 863        .predisable = apds9960_buffer_predisable,
 864};
 865
 866static int apds9960_regfield_init(struct apds9960_data *data)
 867{
 868        struct device *dev = &data->client->dev;
 869        struct regmap *regmap = data->regmap;
 870
 871        data->reg_int_als = devm_regmap_field_alloc(dev, regmap,
 872                                                apds9960_reg_field_int_als);
 873        if (IS_ERR(data->reg_int_als)) {
 874                dev_err(dev, "INT ALS reg field init failed\n");
 875                return PTR_ERR(data->reg_int_als);
 876        }
 877
 878        data->reg_int_ges = devm_regmap_field_alloc(dev, regmap,
 879                                                apds9960_reg_field_int_ges);
 880        if (IS_ERR(data->reg_int_ges)) {
 881                dev_err(dev, "INT gesture reg field init failed\n");
 882                return PTR_ERR(data->reg_int_ges);
 883        }
 884
 885        data->reg_int_pxs = devm_regmap_field_alloc(dev, regmap,
 886                                                apds9960_reg_field_int_pxs);
 887        if (IS_ERR(data->reg_int_pxs)) {
 888                dev_err(dev, "INT pxs reg field init failed\n");
 889                return PTR_ERR(data->reg_int_pxs);
 890        }
 891
 892        data->reg_enable_als = devm_regmap_field_alloc(dev, regmap,
 893                                                apds9960_reg_field_enable_als);
 894        if (IS_ERR(data->reg_enable_als)) {
 895                dev_err(dev, "Enable ALS reg field init failed\n");
 896                return PTR_ERR(data->reg_enable_als);
 897        }
 898
 899        data->reg_enable_ges = devm_regmap_field_alloc(dev, regmap,
 900                                                apds9960_reg_field_enable_ges);
 901        if (IS_ERR(data->reg_enable_ges)) {
 902                dev_err(dev, "Enable gesture reg field init failed\n");
 903                return PTR_ERR(data->reg_enable_ges);
 904        }
 905
 906        data->reg_enable_pxs = devm_regmap_field_alloc(dev, regmap,
 907                                                apds9960_reg_field_enable_pxs);
 908        if (IS_ERR(data->reg_enable_pxs)) {
 909                dev_err(dev, "Enable PXS reg field init failed\n");
 910                return PTR_ERR(data->reg_enable_pxs);
 911        }
 912
 913        return 0;
 914}
 915
 916static int apds9960_chip_init(struct apds9960_data *data)
 917{
 918        int ret;
 919
 920        /* Default IT for ALS of 28 ms */
 921        ret = apds9960_set_it_time(data, 28000);
 922        if (ret)
 923                return ret;
 924
 925        /* Ensure gesture interrupt is OFF */
 926        ret = regmap_field_write(data->reg_int_ges, 0);
 927        if (ret)
 928                return ret;
 929
 930        /* Disable gesture sensor, since polling is useless from user-space */
 931        ret = regmap_field_write(data->reg_enable_ges, 0);
 932        if (ret)
 933                return ret;
 934
 935        /* Ensure proximity interrupt is OFF */
 936        ret = regmap_field_write(data->reg_int_pxs, 0);
 937        if (ret)
 938                return ret;
 939
 940        /* Enable proximity sensor for polling */
 941        ret = regmap_field_write(data->reg_enable_pxs, 1);
 942        if (ret)
 943                return ret;
 944
 945        /* Ensure ALS interrupt is OFF */
 946        ret = regmap_field_write(data->reg_int_als, 0);
 947        if (ret)
 948                return ret;
 949
 950        /* Enable ALS sensor for polling */
 951        ret = regmap_field_write(data->reg_enable_als, 1);
 952        if (ret)
 953                return ret;
 954        /*
 955         * When enabled trigger an interrupt after 3 readings
 956         * outside threshold for ALS + PXS
 957         */
 958        ret = regmap_write(data->regmap, APDS9960_REG_PERS,
 959                           APDS9960_DEFAULT_PERS);
 960        if (ret)
 961                return ret;
 962
 963        /*
 964         * Wait for 4 event outside gesture threshold to prevent interrupt
 965         * flooding.
 966         */
 967        ret = regmap_update_bits(data->regmap, APDS9960_REG_GCONF_1,
 968                        APDS9960_REG_GCONF_1_GFIFO_THRES_MASK,
 969                        BIT(0) << APDS9960_REG_GCONF_1_GFIFO_THRES_MASK_SHIFT);
 970        if (ret)
 971                return ret;
 972
 973        /* Default ENTER and EXIT thresholds for the GESTURE engine. */
 974        ret = regmap_write(data->regmap, APDS9960_REG_GPENTH,
 975                           APDS9960_DEFAULT_GPENTH);
 976        if (ret)
 977                return ret;
 978
 979        ret = regmap_write(data->regmap, APDS9960_REG_GEXTH,
 980                           APDS9960_DEFAULT_GEXTH);
 981        if (ret)
 982                return ret;
 983
 984        return apds9960_set_powermode(data, 1);
 985}
 986
 987static int apds9960_probe(struct i2c_client *client,
 988                          const struct i2c_device_id *id)
 989{
 990        struct apds9960_data *data;
 991        struct iio_dev *indio_dev;
 992        int ret;
 993
 994        indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*data));
 995        if (!indio_dev)
 996                return -ENOMEM;
 997
 998        indio_dev->info = &apds9960_info;
 999        indio_dev->name = APDS9960_DRV_NAME;
1000        indio_dev->channels = apds9960_channels;
1001        indio_dev->num_channels = ARRAY_SIZE(apds9960_channels);
1002        indio_dev->available_scan_masks = apds9960_scan_masks;
1003        indio_dev->modes = INDIO_DIRECT_MODE;
1004
1005        ret = devm_iio_kfifo_buffer_setup(&client->dev, indio_dev,
1006                                          INDIO_BUFFER_SOFTWARE,
1007                                          &apds9960_buffer_setup_ops);
1008        if (ret)
1009                return ret;
1010
1011        data = iio_priv(indio_dev);
1012        i2c_set_clientdata(client, indio_dev);
1013
1014        data->regmap = devm_regmap_init_i2c(client, &apds9960_regmap_config);
1015        if (IS_ERR(data->regmap)) {
1016                dev_err(&client->dev, "regmap initialization failed.\n");
1017                return PTR_ERR(data->regmap);
1018        }
1019
1020        data->client = client;
1021        data->indio_dev = indio_dev;
1022        mutex_init(&data->lock);
1023
1024        ret = pm_runtime_set_active(&client->dev);
1025        if (ret)
1026                goto error_power_down;
1027
1028        pm_runtime_enable(&client->dev);
1029        pm_runtime_set_autosuspend_delay(&client->dev, 5000);
1030        pm_runtime_use_autosuspend(&client->dev);
1031
1032        apds9960_set_power_state(data, true);
1033
1034        ret = apds9960_regfield_init(data);
1035        if (ret)
1036                goto error_power_down;
1037
1038        ret = apds9960_chip_init(data);
1039        if (ret)
1040                goto error_power_down;
1041
1042        if (client->irq <= 0) {
1043                dev_err(&client->dev, "no valid irq defined\n");
1044                ret = -EINVAL;
1045                goto error_power_down;
1046        }
1047        ret = devm_request_threaded_irq(&client->dev, client->irq,
1048                                        NULL, apds9960_interrupt_handler,
1049                                        IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
1050                                        "apds9960_event",
1051                                        indio_dev);
1052        if (ret) {
1053                dev_err(&client->dev, "request irq (%d) failed\n", client->irq);
1054                goto error_power_down;
1055        }
1056
1057        ret = iio_device_register(indio_dev);
1058        if (ret)
1059                goto error_power_down;
1060
1061        apds9960_set_power_state(data, false);
1062
1063        return 0;
1064
1065error_power_down:
1066        apds9960_set_power_state(data, false);
1067
1068        return ret;
1069}
1070
1071static int apds9960_remove(struct i2c_client *client)
1072{
1073        struct iio_dev *indio_dev = i2c_get_clientdata(client);
1074        struct apds9960_data *data = iio_priv(indio_dev);
1075
1076        iio_device_unregister(indio_dev);
1077        pm_runtime_disable(&client->dev);
1078        pm_runtime_set_suspended(&client->dev);
1079        apds9960_set_powermode(data, 0);
1080
1081        return 0;
1082}
1083
1084#ifdef CONFIG_PM
1085static int apds9960_runtime_suspend(struct device *dev)
1086{
1087        struct apds9960_data *data =
1088                        iio_priv(i2c_get_clientdata(to_i2c_client(dev)));
1089
1090        return apds9960_set_powermode(data, 0);
1091}
1092
1093static int apds9960_runtime_resume(struct device *dev)
1094{
1095        struct apds9960_data *data =
1096                        iio_priv(i2c_get_clientdata(to_i2c_client(dev)));
1097
1098        return apds9960_set_powermode(data, 1);
1099}
1100#endif
1101
1102static const struct dev_pm_ops apds9960_pm_ops = {
1103        SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend,
1104                                pm_runtime_force_resume)
1105        SET_RUNTIME_PM_OPS(apds9960_runtime_suspend,
1106                           apds9960_runtime_resume, NULL)
1107};
1108
1109static const struct i2c_device_id apds9960_id[] = {
1110        { "apds9960", 0 },
1111        {}
1112};
1113MODULE_DEVICE_TABLE(i2c, apds9960_id);
1114
1115static const struct acpi_device_id apds9960_acpi_match[] = {
1116        { "MSHW0184" },
1117        { }
1118};
1119MODULE_DEVICE_TABLE(acpi, apds9960_acpi_match);
1120
1121static const struct of_device_id apds9960_of_match[] = {
1122        { .compatible = "avago,apds9960" },
1123        { }
1124};
1125MODULE_DEVICE_TABLE(of, apds9960_of_match);
1126
1127static struct i2c_driver apds9960_driver = {
1128        .driver = {
1129                .name   = APDS9960_DRV_NAME,
1130                .of_match_table = apds9960_of_match,
1131                .pm     = &apds9960_pm_ops,
1132                .acpi_match_table = apds9960_acpi_match,
1133        },
1134        .probe          = apds9960_probe,
1135        .remove         = apds9960_remove,
1136        .id_table       = apds9960_id,
1137};
1138module_i2c_driver(apds9960_driver);
1139
1140MODULE_AUTHOR("Matt Ranostay <matt.ranostay@konsulko.com>");
1141MODULE_DESCRIPTION("APDS9960 Gesture/RGB/ALS/Proximity sensor");
1142MODULE_LICENSE("GPL");
1143