linux/drivers/iio/light/isl29028.c
<<
>>
Prefs
   1/*
   2 * IIO driver for the light sensor ISL29028.
   3 * ISL29028 is Concurrent Ambient Light and Proximity Sensor
   4 *
   5 * Copyright (c) 2012, NVIDIA CORPORATION.  All rights reserved.
   6 * Copyright (c) 2016-2017 Brian Masney <masneyb@onstation.org>
   7 *
   8 * This program is free software; you can redistribute it and/or modify it
   9 * under the terms and conditions of the GNU General Public License,
  10 * version 2, as published by the Free Software Foundation.
  11 *
  12 * This program is distributed in the hope it will be useful, but WITHOUT
  13 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  14 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
  15 * more details.
  16 *
  17 * You should have received a copy of the GNU General Public License
  18 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  19 *
  20 * Datasheets:
  21 *  - http://www.intersil.com/content/dam/Intersil/documents/isl2/isl29028.pdf
  22 *  - http://www.intersil.com/content/dam/Intersil/documents/isl2/isl29030.pdf
  23 */
  24
  25#include <linux/module.h>
  26#include <linux/i2c.h>
  27#include <linux/err.h>
  28#include <linux/mutex.h>
  29#include <linux/delay.h>
  30#include <linux/slab.h>
  31#include <linux/regmap.h>
  32#include <linux/iio/iio.h>
  33#include <linux/iio/sysfs.h>
  34#include <linux/pm_runtime.h>
  35
  36#define ISL29028_CONV_TIME_MS                   100
  37
  38#define ISL29028_REG_CONFIGURE                  0x01
  39
  40#define ISL29028_CONF_ALS_IR_MODE_ALS           0
  41#define ISL29028_CONF_ALS_IR_MODE_IR            BIT(0)
  42#define ISL29028_CONF_ALS_IR_MODE_MASK          BIT(0)
  43
  44#define ISL29028_CONF_ALS_RANGE_LOW_LUX         0
  45#define ISL29028_CONF_ALS_RANGE_HIGH_LUX        BIT(1)
  46#define ISL29028_CONF_ALS_RANGE_MASK            BIT(1)
  47
  48#define ISL29028_CONF_ALS_DIS                   0
  49#define ISL29028_CONF_ALS_EN                    BIT(2)
  50#define ISL29028_CONF_ALS_EN_MASK               BIT(2)
  51
  52#define ISL29028_CONF_PROX_SLP_SH               4
  53#define ISL29028_CONF_PROX_SLP_MASK             (7 << ISL29028_CONF_PROX_SLP_SH)
  54
  55#define ISL29028_CONF_PROX_EN                   BIT(7)
  56#define ISL29028_CONF_PROX_EN_MASK              BIT(7)
  57
  58#define ISL29028_REG_INTERRUPT                  0x02
  59
  60#define ISL29028_REG_PROX_DATA                  0x08
  61#define ISL29028_REG_ALSIR_L                    0x09
  62#define ISL29028_REG_ALSIR_U                    0x0A
  63
  64#define ISL29028_REG_TEST1_MODE                 0x0E
  65#define ISL29028_REG_TEST2_MODE                 0x0F
  66
  67#define ISL29028_NUM_REGS                       (ISL29028_REG_TEST2_MODE + 1)
  68
  69#define ISL29028_POWER_OFF_DELAY_MS             2000
  70
  71struct isl29028_prox_data {
  72        int sampling_int;
  73        int sampling_fract;
  74        int sleep_time;
  75};
  76
  77static const struct isl29028_prox_data isl29028_prox_data[] = {
  78        {   1, 250000, 800 },
  79        {   2, 500000, 400 },
  80        {   5,      0, 200 },
  81        {  10,      0, 100 },
  82        {  13, 300000,  75 },
  83        {  20,      0,  50 },
  84        {  80,      0,  13 }, /*
  85                               * Note: Data sheet lists 12.5 ms sleep time.
  86                               * Round up a half millisecond for msleep().
  87                               */
  88        { 100,  0,   0 }
  89};
  90
  91enum isl29028_als_ir_mode {
  92        ISL29028_MODE_NONE = 0,
  93        ISL29028_MODE_ALS,
  94        ISL29028_MODE_IR,
  95};
  96
  97struct isl29028_chip {
  98        struct mutex                    lock;
  99        struct regmap                   *regmap;
 100        int                             prox_sampling_int;
 101        int                             prox_sampling_frac;
 102        bool                            enable_prox;
 103        int                             lux_scale;
 104        enum isl29028_als_ir_mode       als_ir_mode;
 105};
 106
 107static int isl29028_find_prox_sleep_index(int sampling_int, int sampling_fract)
 108{
 109        int i;
 110
 111        for (i = 0; i < ARRAY_SIZE(isl29028_prox_data); ++i) {
 112                if (isl29028_prox_data[i].sampling_int == sampling_int &&
 113                    isl29028_prox_data[i].sampling_fract == sampling_fract)
 114                        return i;
 115        }
 116
 117        return -EINVAL;
 118}
 119
 120static int isl29028_set_proxim_sampling(struct isl29028_chip *chip,
 121                                        int sampling_int, int sampling_fract)
 122{
 123        struct device *dev = regmap_get_device(chip->regmap);
 124        int sleep_index, ret;
 125
 126        sleep_index = isl29028_find_prox_sleep_index(sampling_int,
 127                                                     sampling_fract);
 128        if (sleep_index < 0)
 129                return sleep_index;
 130
 131        ret = regmap_update_bits(chip->regmap, ISL29028_REG_CONFIGURE,
 132                                 ISL29028_CONF_PROX_SLP_MASK,
 133                                 sleep_index << ISL29028_CONF_PROX_SLP_SH);
 134
 135        if (ret < 0) {
 136                dev_err(dev, "%s(): Error %d setting the proximity sampling\n",
 137                        __func__, ret);
 138                return ret;
 139        }
 140
 141        chip->prox_sampling_int = sampling_int;
 142        chip->prox_sampling_frac = sampling_fract;
 143
 144        return ret;
 145}
 146
 147static int isl29028_enable_proximity(struct isl29028_chip *chip)
 148{
 149        int prox_index, ret;
 150
 151        ret = isl29028_set_proxim_sampling(chip, chip->prox_sampling_int,
 152                                           chip->prox_sampling_frac);
 153        if (ret < 0)
 154                return ret;
 155
 156        ret = regmap_update_bits(chip->regmap, ISL29028_REG_CONFIGURE,
 157                                 ISL29028_CONF_PROX_EN_MASK,
 158                                 ISL29028_CONF_PROX_EN);
 159        if (ret < 0)
 160                return ret;
 161
 162        /* Wait for conversion to be complete for first sample */
 163        prox_index = isl29028_find_prox_sleep_index(chip->prox_sampling_int,
 164                                                    chip->prox_sampling_frac);
 165        if (prox_index < 0)
 166                return prox_index;
 167
 168        msleep(isl29028_prox_data[prox_index].sleep_time);
 169
 170        return 0;
 171}
 172
 173static int isl29028_set_als_scale(struct isl29028_chip *chip, int lux_scale)
 174{
 175        struct device *dev = regmap_get_device(chip->regmap);
 176        int val = (lux_scale == 2000) ? ISL29028_CONF_ALS_RANGE_HIGH_LUX :
 177                                        ISL29028_CONF_ALS_RANGE_LOW_LUX;
 178        int ret;
 179
 180        ret = regmap_update_bits(chip->regmap, ISL29028_REG_CONFIGURE,
 181                                 ISL29028_CONF_ALS_RANGE_MASK, val);
 182        if (ret < 0) {
 183                dev_err(dev, "%s(): Error %d setting the ALS scale\n", __func__,
 184                        ret);
 185                return ret;
 186        }
 187
 188        chip->lux_scale = lux_scale;
 189
 190        return ret;
 191}
 192
 193static int isl29028_set_als_ir_mode(struct isl29028_chip *chip,
 194                                    enum isl29028_als_ir_mode mode)
 195{
 196        int ret;
 197
 198        if (chip->als_ir_mode == mode)
 199                return 0;
 200
 201        ret = isl29028_set_als_scale(chip, chip->lux_scale);
 202        if (ret < 0)
 203                return ret;
 204
 205        switch (mode) {
 206        case ISL29028_MODE_ALS:
 207                ret = regmap_update_bits(chip->regmap, ISL29028_REG_CONFIGURE,
 208                                         ISL29028_CONF_ALS_IR_MODE_MASK,
 209                                         ISL29028_CONF_ALS_IR_MODE_ALS);
 210                if (ret < 0)
 211                        return ret;
 212
 213                ret = regmap_update_bits(chip->regmap, ISL29028_REG_CONFIGURE,
 214                                         ISL29028_CONF_ALS_RANGE_MASK,
 215                                         ISL29028_CONF_ALS_RANGE_HIGH_LUX);
 216                break;
 217        case ISL29028_MODE_IR:
 218                ret = regmap_update_bits(chip->regmap, ISL29028_REG_CONFIGURE,
 219                                         ISL29028_CONF_ALS_IR_MODE_MASK,
 220                                         ISL29028_CONF_ALS_IR_MODE_IR);
 221                break;
 222        case ISL29028_MODE_NONE:
 223                return regmap_update_bits(chip->regmap, ISL29028_REG_CONFIGURE,
 224                                          ISL29028_CONF_ALS_EN_MASK,
 225                                          ISL29028_CONF_ALS_DIS);
 226        }
 227
 228        if (ret < 0)
 229                return ret;
 230
 231        /* Enable the ALS/IR */
 232        ret = regmap_update_bits(chip->regmap, ISL29028_REG_CONFIGURE,
 233                                 ISL29028_CONF_ALS_EN_MASK,
 234                                 ISL29028_CONF_ALS_EN);
 235        if (ret < 0)
 236                return ret;
 237
 238        /* Need to wait for conversion time if ALS/IR mode enabled */
 239        msleep(ISL29028_CONV_TIME_MS);
 240
 241        chip->als_ir_mode = mode;
 242
 243        return 0;
 244}
 245
 246static int isl29028_read_als_ir(struct isl29028_chip *chip, int *als_ir)
 247{
 248        struct device *dev = regmap_get_device(chip->regmap);
 249        unsigned int lsb;
 250        unsigned int msb;
 251        int ret;
 252
 253        ret = regmap_read(chip->regmap, ISL29028_REG_ALSIR_L, &lsb);
 254        if (ret < 0) {
 255                dev_err(dev,
 256                        "%s(): Error %d reading register ALSIR_L\n",
 257                        __func__, ret);
 258                return ret;
 259        }
 260
 261        ret = regmap_read(chip->regmap, ISL29028_REG_ALSIR_U, &msb);
 262        if (ret < 0) {
 263                dev_err(dev,
 264                        "%s(): Error %d reading register ALSIR_U\n",
 265                        __func__, ret);
 266                return ret;
 267        }
 268
 269        *als_ir = ((msb & 0xF) << 8) | (lsb & 0xFF);
 270
 271        return 0;
 272}
 273
 274static int isl29028_read_proxim(struct isl29028_chip *chip, int *prox)
 275{
 276        struct device *dev = regmap_get_device(chip->regmap);
 277        unsigned int data;
 278        int ret;
 279
 280        if (!chip->enable_prox) {
 281                ret = isl29028_enable_proximity(chip);
 282                if (ret < 0)
 283                        return ret;
 284
 285                chip->enable_prox = true;
 286        }
 287
 288        ret = regmap_read(chip->regmap, ISL29028_REG_PROX_DATA, &data);
 289        if (ret < 0) {
 290                dev_err(dev, "%s(): Error %d reading register PROX_DATA\n",
 291                        __func__, ret);
 292                return ret;
 293        }
 294
 295        *prox = data;
 296
 297        return 0;
 298}
 299
 300static int isl29028_als_get(struct isl29028_chip *chip, int *als_data)
 301{
 302        struct device *dev = regmap_get_device(chip->regmap);
 303        int ret;
 304        int als_ir_data;
 305
 306        ret = isl29028_set_als_ir_mode(chip, ISL29028_MODE_ALS);
 307        if (ret < 0) {
 308                dev_err(dev, "%s(): Error %d enabling ALS mode\n", __func__,
 309                        ret);
 310                return ret;
 311        }
 312
 313        ret = isl29028_read_als_ir(chip, &als_ir_data);
 314        if (ret < 0)
 315                return ret;
 316
 317        /*
 318         * convert als data count to lux.
 319         * if lux_scale = 125,  lux = count * 0.031
 320         * if lux_scale = 2000, lux = count * 0.49
 321         */
 322        if (chip->lux_scale == 125)
 323                als_ir_data = (als_ir_data * 31) / 1000;
 324        else
 325                als_ir_data = (als_ir_data * 49) / 100;
 326
 327        *als_data = als_ir_data;
 328
 329        return 0;
 330}
 331
 332static int isl29028_ir_get(struct isl29028_chip *chip, int *ir_data)
 333{
 334        struct device *dev = regmap_get_device(chip->regmap);
 335        int ret;
 336
 337        ret = isl29028_set_als_ir_mode(chip, ISL29028_MODE_IR);
 338        if (ret < 0) {
 339                dev_err(dev, "%s(): Error %d enabling IR mode\n", __func__,
 340                        ret);
 341                return ret;
 342        }
 343
 344        return isl29028_read_als_ir(chip, ir_data);
 345}
 346
 347static int isl29028_set_pm_runtime_busy(struct isl29028_chip *chip, bool on)
 348{
 349        struct device *dev = regmap_get_device(chip->regmap);
 350        int ret;
 351
 352        if (on) {
 353                ret = pm_runtime_get_sync(dev);
 354                if (ret < 0)
 355                        pm_runtime_put_noidle(dev);
 356        } else {
 357                pm_runtime_mark_last_busy(dev);
 358                ret = pm_runtime_put_autosuspend(dev);
 359        }
 360
 361        return ret;
 362}
 363
 364/* Channel IO */
 365static int isl29028_write_raw(struct iio_dev *indio_dev,
 366                              struct iio_chan_spec const *chan,
 367                              int val, int val2, long mask)
 368{
 369        struct isl29028_chip *chip = iio_priv(indio_dev);
 370        struct device *dev = regmap_get_device(chip->regmap);
 371        int ret;
 372
 373        ret = isl29028_set_pm_runtime_busy(chip, true);
 374        if (ret < 0)
 375                return ret;
 376
 377        mutex_lock(&chip->lock);
 378
 379        ret = -EINVAL;
 380        switch (chan->type) {
 381        case IIO_PROXIMITY:
 382                if (mask != IIO_CHAN_INFO_SAMP_FREQ) {
 383                        dev_err(dev,
 384                                "%s(): proximity: Mask value 0x%08lx is not supported\n",
 385                                __func__, mask);
 386                        break;
 387                }
 388
 389                if (val < 1 || val > 100) {
 390                        dev_err(dev,
 391                                "%s(): proximity: Sampling frequency %d is not in the range [1:100]\n",
 392                                __func__, val);
 393                        break;
 394                }
 395
 396                ret = isl29028_set_proxim_sampling(chip, val, val2);
 397                break;
 398        case IIO_LIGHT:
 399                if (mask != IIO_CHAN_INFO_SCALE) {
 400                        dev_err(dev,
 401                                "%s(): light: Mask value 0x%08lx is not supported\n",
 402                                __func__, mask);
 403                        break;
 404                }
 405
 406                if (val != 125 && val != 2000) {
 407                        dev_err(dev,
 408                                "%s(): light: Lux scale %d is not in the set {125, 2000}\n",
 409                                __func__, val);
 410                        break;
 411                }
 412
 413                ret = isl29028_set_als_scale(chip, val);
 414                break;
 415        default:
 416                dev_err(dev, "%s(): Unsupported channel type %x\n",
 417                        __func__, chan->type);
 418                break;
 419        }
 420
 421        mutex_unlock(&chip->lock);
 422
 423        if (ret < 0)
 424                return ret;
 425
 426        ret = isl29028_set_pm_runtime_busy(chip, false);
 427        if (ret < 0)
 428                return ret;
 429
 430        return ret;
 431}
 432
 433static int isl29028_read_raw(struct iio_dev *indio_dev,
 434                             struct iio_chan_spec const *chan,
 435                             int *val, int *val2, long mask)
 436{
 437        struct isl29028_chip *chip = iio_priv(indio_dev);
 438        struct device *dev = regmap_get_device(chip->regmap);
 439        int ret, pm_ret;
 440
 441        ret = isl29028_set_pm_runtime_busy(chip, true);
 442        if (ret < 0)
 443                return ret;
 444
 445        mutex_lock(&chip->lock);
 446
 447        ret = -EINVAL;
 448        switch (mask) {
 449        case IIO_CHAN_INFO_RAW:
 450        case IIO_CHAN_INFO_PROCESSED:
 451                switch (chan->type) {
 452                case IIO_LIGHT:
 453                        ret = isl29028_als_get(chip, val);
 454                        break;
 455                case IIO_INTENSITY:
 456                        ret = isl29028_ir_get(chip, val);
 457                        break;
 458                case IIO_PROXIMITY:
 459                        ret = isl29028_read_proxim(chip, val);
 460                        break;
 461                default:
 462                        break;
 463                }
 464
 465                if (ret < 0)
 466                        break;
 467
 468                ret = IIO_VAL_INT;
 469                break;
 470        case IIO_CHAN_INFO_SAMP_FREQ:
 471                if (chan->type != IIO_PROXIMITY)
 472                        break;
 473
 474                *val = chip->prox_sampling_int;
 475                *val2 = chip->prox_sampling_frac;
 476                ret = IIO_VAL_INT;
 477                break;
 478        case IIO_CHAN_INFO_SCALE:
 479                if (chan->type != IIO_LIGHT)
 480                        break;
 481                *val = chip->lux_scale;
 482                ret = IIO_VAL_INT;
 483                break;
 484        default:
 485                dev_err(dev, "%s(): mask value 0x%08lx is not supported\n",
 486                        __func__, mask);
 487                break;
 488        }
 489
 490        mutex_unlock(&chip->lock);
 491
 492        if (ret < 0)
 493                return ret;
 494
 495        /**
 496         * Preserve the ret variable if the call to
 497         * isl29028_set_pm_runtime_busy() is successful so the reading
 498         * (if applicable) is returned to user space.
 499         */
 500        pm_ret = isl29028_set_pm_runtime_busy(chip, false);
 501        if (pm_ret < 0)
 502                return pm_ret;
 503
 504        return ret;
 505}
 506
 507static IIO_CONST_ATTR(in_proximity_sampling_frequency_available,
 508                                "1.25 2.5 5 10 13.3 20 80 100");
 509static IIO_CONST_ATTR(in_illuminance_scale_available, "125 2000");
 510
 511#define ISL29028_CONST_ATTR(name) (&iio_const_attr_##name.dev_attr.attr)
 512static struct attribute *isl29028_attributes[] = {
 513        ISL29028_CONST_ATTR(in_proximity_sampling_frequency_available),
 514        ISL29028_CONST_ATTR(in_illuminance_scale_available),
 515        NULL,
 516};
 517
 518static const struct attribute_group isl29108_group = {
 519        .attrs = isl29028_attributes,
 520};
 521
 522static const struct iio_chan_spec isl29028_channels[] = {
 523        {
 524                .type = IIO_LIGHT,
 525                .info_mask_separate = BIT(IIO_CHAN_INFO_PROCESSED) |
 526                BIT(IIO_CHAN_INFO_SCALE),
 527        }, {
 528                .type = IIO_INTENSITY,
 529                .info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
 530        }, {
 531                .type = IIO_PROXIMITY,
 532                .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
 533                BIT(IIO_CHAN_INFO_SAMP_FREQ),
 534        }
 535};
 536
 537static const struct iio_info isl29028_info = {
 538        .attrs = &isl29108_group,
 539        .driver_module = THIS_MODULE,
 540        .read_raw = isl29028_read_raw,
 541        .write_raw = isl29028_write_raw,
 542};
 543
 544static int isl29028_clear_configure_reg(struct isl29028_chip *chip)
 545{
 546        struct device *dev = regmap_get_device(chip->regmap);
 547        int ret;
 548
 549        ret = regmap_write(chip->regmap, ISL29028_REG_CONFIGURE, 0x0);
 550        if (ret < 0)
 551                dev_err(dev, "%s(): Error %d clearing the CONFIGURE register\n",
 552                        __func__, ret);
 553
 554        chip->als_ir_mode = ISL29028_MODE_NONE;
 555        chip->enable_prox = false;
 556
 557        return ret;
 558}
 559
 560static bool isl29028_is_volatile_reg(struct device *dev, unsigned int reg)
 561{
 562        switch (reg) {
 563        case ISL29028_REG_INTERRUPT:
 564        case ISL29028_REG_PROX_DATA:
 565        case ISL29028_REG_ALSIR_L:
 566        case ISL29028_REG_ALSIR_U:
 567                return true;
 568        default:
 569                return false;
 570        }
 571}
 572
 573static const struct regmap_config isl29028_regmap_config = {
 574        .reg_bits = 8,
 575        .val_bits = 8,
 576        .volatile_reg = isl29028_is_volatile_reg,
 577        .max_register = ISL29028_NUM_REGS - 1,
 578        .num_reg_defaults_raw = ISL29028_NUM_REGS,
 579        .cache_type = REGCACHE_RBTREE,
 580};
 581
 582static int isl29028_probe(struct i2c_client *client,
 583                          const struct i2c_device_id *id)
 584{
 585        struct isl29028_chip *chip;
 586        struct iio_dev *indio_dev;
 587        int ret;
 588
 589        indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*chip));
 590        if (!indio_dev)
 591                return -ENOMEM;
 592
 593        chip = iio_priv(indio_dev);
 594
 595        i2c_set_clientdata(client, indio_dev);
 596        mutex_init(&chip->lock);
 597
 598        chip->regmap = devm_regmap_init_i2c(client, &isl29028_regmap_config);
 599        if (IS_ERR(chip->regmap)) {
 600                ret = PTR_ERR(chip->regmap);
 601                dev_err(&client->dev, "%s: Error %d initializing regmap\n",
 602                        __func__, ret);
 603                return ret;
 604        }
 605
 606        chip->enable_prox  = false;
 607        chip->prox_sampling_int = 20;
 608        chip->prox_sampling_frac = 0;
 609        chip->lux_scale = 2000;
 610
 611        ret = regmap_write(chip->regmap, ISL29028_REG_TEST1_MODE, 0x0);
 612        if (ret < 0) {
 613                dev_err(&client->dev,
 614                        "%s(): Error %d writing to TEST1_MODE register\n",
 615                        __func__, ret);
 616                return ret;
 617        }
 618
 619        ret = regmap_write(chip->regmap, ISL29028_REG_TEST2_MODE, 0x0);
 620        if (ret < 0) {
 621                dev_err(&client->dev,
 622                        "%s(): Error %d writing to TEST2_MODE register\n",
 623                        __func__, ret);
 624                return ret;
 625        }
 626
 627        ret = isl29028_clear_configure_reg(chip);
 628        if (ret < 0)
 629                return ret;
 630
 631        indio_dev->info = &isl29028_info;
 632        indio_dev->channels = isl29028_channels;
 633        indio_dev->num_channels = ARRAY_SIZE(isl29028_channels);
 634        indio_dev->name = id->name;
 635        indio_dev->dev.parent = &client->dev;
 636        indio_dev->modes = INDIO_DIRECT_MODE;
 637
 638        pm_runtime_enable(&client->dev);
 639        pm_runtime_set_autosuspend_delay(&client->dev,
 640                                         ISL29028_POWER_OFF_DELAY_MS);
 641        pm_runtime_use_autosuspend(&client->dev);
 642
 643        ret = devm_iio_device_register(indio_dev->dev.parent, indio_dev);
 644        if (ret < 0) {
 645                dev_err(&client->dev,
 646                        "%s(): iio registration failed with error %d\n",
 647                        __func__, ret);
 648                return ret;
 649        }
 650
 651        return 0;
 652}
 653
 654static int isl29028_remove(struct i2c_client *client)
 655{
 656        struct iio_dev *indio_dev = i2c_get_clientdata(client);
 657        struct isl29028_chip *chip = iio_priv(indio_dev);
 658
 659        iio_device_unregister(indio_dev);
 660
 661        pm_runtime_disable(&client->dev);
 662        pm_runtime_set_suspended(&client->dev);
 663        pm_runtime_put_noidle(&client->dev);
 664
 665        return isl29028_clear_configure_reg(chip);
 666}
 667
 668static int __maybe_unused isl29028_suspend(struct device *dev)
 669{
 670        struct iio_dev *indio_dev = i2c_get_clientdata(to_i2c_client(dev));
 671        struct isl29028_chip *chip = iio_priv(indio_dev);
 672        int ret;
 673
 674        mutex_lock(&chip->lock);
 675
 676        ret = isl29028_clear_configure_reg(chip);
 677
 678        mutex_unlock(&chip->lock);
 679
 680        return ret;
 681}
 682
 683static int __maybe_unused isl29028_resume(struct device *dev)
 684{
 685        /**
 686         * The specific component (ALS/IR or proximity) will enable itself as
 687         * needed the next time that the user requests a reading. This is done
 688         * above in isl29028_set_als_ir_mode() and isl29028_enable_proximity().
 689         */
 690        return 0;
 691}
 692
 693static const struct dev_pm_ops isl29028_pm_ops = {
 694        SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend,
 695                                pm_runtime_force_resume)
 696        SET_RUNTIME_PM_OPS(isl29028_suspend, isl29028_resume, NULL)
 697};
 698
 699static const struct i2c_device_id isl29028_id[] = {
 700        {"isl29028", 0},
 701        {"isl29030", 0},
 702        {}
 703};
 704MODULE_DEVICE_TABLE(i2c, isl29028_id);
 705
 706static const struct of_device_id isl29028_of_match[] = {
 707        { .compatible = "isl,isl29028", }, /* for backward compat., don't use */
 708        { .compatible = "isil,isl29028", },
 709        { .compatible = "isil,isl29030", },
 710        { },
 711};
 712MODULE_DEVICE_TABLE(of, isl29028_of_match);
 713
 714static struct i2c_driver isl29028_driver = {
 715        .driver  = {
 716                .name = "isl29028",
 717                .pm = &isl29028_pm_ops,
 718                .of_match_table = isl29028_of_match,
 719        },
 720        .probe   = isl29028_probe,
 721        .remove  = isl29028_remove,
 722        .id_table = isl29028_id,
 723};
 724
 725module_i2c_driver(isl29028_driver);
 726
 727MODULE_DESCRIPTION("ISL29028 Ambient Light and Proximity Sensor driver");
 728MODULE_LICENSE("GPL v2");
 729MODULE_AUTHOR("Laxman Dewangan <ldewangan@nvidia.com>");
 730