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