linux/drivers/iio/light/isl29018.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0-or-later
   2/*
   3 * A iio driver for the light sensor ISL 29018/29023/29035.
   4 *
   5 * IIO driver for monitoring ambient light intensity in luxi, proximity
   6 * sensing and infrared sensing.
   7 *
   8 * Copyright (c) 2010, NVIDIA Corporation.
   9 */
  10
  11#include <linux/module.h>
  12#include <linux/i2c.h>
  13#include <linux/err.h>
  14#include <linux/mutex.h>
  15#include <linux/delay.h>
  16#include <linux/regmap.h>
  17#include <linux/regulator/consumer.h>
  18#include <linux/slab.h>
  19#include <linux/iio/iio.h>
  20#include <linux/iio/sysfs.h>
  21#include <linux/acpi.h>
  22
  23#define ISL29018_CONV_TIME_MS           100
  24
  25#define ISL29018_REG_ADD_COMMAND1       0x00
  26#define ISL29018_CMD1_OPMODE_SHIFT      5
  27#define ISL29018_CMD1_OPMODE_MASK       (7 << ISL29018_CMD1_OPMODE_SHIFT)
  28#define ISL29018_CMD1_OPMODE_POWER_DOWN 0
  29#define ISL29018_CMD1_OPMODE_ALS_ONCE   1
  30#define ISL29018_CMD1_OPMODE_IR_ONCE    2
  31#define ISL29018_CMD1_OPMODE_PROX_ONCE  3
  32
  33#define ISL29018_REG_ADD_COMMAND2       0x01
  34#define ISL29018_CMD2_RESOLUTION_SHIFT  2
  35#define ISL29018_CMD2_RESOLUTION_MASK   (0x3 << ISL29018_CMD2_RESOLUTION_SHIFT)
  36
  37#define ISL29018_CMD2_RANGE_SHIFT       0
  38#define ISL29018_CMD2_RANGE_MASK        (0x3 << ISL29018_CMD2_RANGE_SHIFT)
  39
  40#define ISL29018_CMD2_SCHEME_SHIFT      7
  41#define ISL29018_CMD2_SCHEME_MASK       (0x1 << ISL29018_CMD2_SCHEME_SHIFT)
  42
  43#define ISL29018_REG_ADD_DATA_LSB       0x02
  44#define ISL29018_REG_ADD_DATA_MSB       0x03
  45
  46#define ISL29018_REG_TEST               0x08
  47#define ISL29018_TEST_SHIFT             0
  48#define ISL29018_TEST_MASK              (0xFF << ISL29018_TEST_SHIFT)
  49
  50#define ISL29035_REG_DEVICE_ID          0x0F
  51#define ISL29035_DEVICE_ID_SHIFT        0x03
  52#define ISL29035_DEVICE_ID_MASK         (0x7 << ISL29035_DEVICE_ID_SHIFT)
  53#define ISL29035_DEVICE_ID              0x5
  54#define ISL29035_BOUT_SHIFT             0x07
  55#define ISL29035_BOUT_MASK              (0x01 << ISL29035_BOUT_SHIFT)
  56
  57enum isl29018_int_time {
  58        ISL29018_INT_TIME_16,
  59        ISL29018_INT_TIME_12,
  60        ISL29018_INT_TIME_8,
  61        ISL29018_INT_TIME_4,
  62};
  63
  64static const unsigned int isl29018_int_utimes[3][4] = {
  65        {90000, 5630, 351, 21},
  66        {90000, 5600, 352, 22},
  67        {105000, 6500, 410, 25},
  68};
  69
  70static const struct isl29018_scale {
  71        unsigned int scale;
  72        unsigned int uscale;
  73} isl29018_scales[4][4] = {
  74        { {0, 15258}, {0, 61035}, {0, 244140}, {0, 976562} },
  75        { {0, 244140}, {0, 976562}, {3, 906250}, {15, 625000} },
  76        { {3, 906250}, {15, 625000}, {62, 500000}, {250, 0} },
  77        { {62, 500000}, {250, 0}, {1000, 0}, {4000, 0} }
  78};
  79
  80struct isl29018_chip {
  81        struct regmap           *regmap;
  82        struct mutex            lock;
  83        int                     type;
  84        unsigned int            calibscale;
  85        unsigned int            ucalibscale;
  86        unsigned int            int_time;
  87        struct isl29018_scale   scale;
  88        int                     prox_scheme;
  89        bool                    suspended;
  90        struct regulator        *vcc_reg;
  91};
  92
  93static int isl29018_set_integration_time(struct isl29018_chip *chip,
  94                                         unsigned int utime)
  95{
  96        unsigned int i;
  97        int ret;
  98        unsigned int int_time, new_int_time;
  99
 100        for (i = 0; i < ARRAY_SIZE(isl29018_int_utimes[chip->type]); ++i) {
 101                if (utime == isl29018_int_utimes[chip->type][i]) {
 102                        new_int_time = i;
 103                        break;
 104                }
 105        }
 106
 107        if (i >= ARRAY_SIZE(isl29018_int_utimes[chip->type]))
 108                return -EINVAL;
 109
 110        ret = regmap_update_bits(chip->regmap, ISL29018_REG_ADD_COMMAND2,
 111                                 ISL29018_CMD2_RESOLUTION_MASK,
 112                                 i << ISL29018_CMD2_RESOLUTION_SHIFT);
 113        if (ret < 0)
 114                return ret;
 115
 116        /* Keep the same range when integration time changes */
 117        int_time = chip->int_time;
 118        for (i = 0; i < ARRAY_SIZE(isl29018_scales[int_time]); ++i) {
 119                if (chip->scale.scale == isl29018_scales[int_time][i].scale &&
 120                    chip->scale.uscale == isl29018_scales[int_time][i].uscale) {
 121                        chip->scale = isl29018_scales[new_int_time][i];
 122                        break;
 123                }
 124        }
 125        chip->int_time = new_int_time;
 126
 127        return 0;
 128}
 129
 130static int isl29018_set_scale(struct isl29018_chip *chip, int scale, int uscale)
 131{
 132        unsigned int i;
 133        int ret;
 134        struct isl29018_scale new_scale;
 135
 136        for (i = 0; i < ARRAY_SIZE(isl29018_scales[chip->int_time]); ++i) {
 137                if (scale == isl29018_scales[chip->int_time][i].scale &&
 138                    uscale == isl29018_scales[chip->int_time][i].uscale) {
 139                        new_scale = isl29018_scales[chip->int_time][i];
 140                        break;
 141                }
 142        }
 143
 144        if (i >= ARRAY_SIZE(isl29018_scales[chip->int_time]))
 145                return -EINVAL;
 146
 147        ret = regmap_update_bits(chip->regmap, ISL29018_REG_ADD_COMMAND2,
 148                                 ISL29018_CMD2_RANGE_MASK,
 149                                 i << ISL29018_CMD2_RANGE_SHIFT);
 150        if (ret < 0)
 151                return ret;
 152
 153        chip->scale = new_scale;
 154
 155        return 0;
 156}
 157
 158static int isl29018_read_sensor_input(struct isl29018_chip *chip, int mode)
 159{
 160        int status;
 161        unsigned int lsb;
 162        unsigned int msb;
 163        struct device *dev = regmap_get_device(chip->regmap);
 164
 165        /* Set mode */
 166        status = regmap_write(chip->regmap, ISL29018_REG_ADD_COMMAND1,
 167                              mode << ISL29018_CMD1_OPMODE_SHIFT);
 168        if (status) {
 169                dev_err(dev,
 170                        "Error in setting operating mode err %d\n", status);
 171                return status;
 172        }
 173        msleep(ISL29018_CONV_TIME_MS);
 174        status = regmap_read(chip->regmap, ISL29018_REG_ADD_DATA_LSB, &lsb);
 175        if (status < 0) {
 176                dev_err(dev,
 177                        "Error in reading LSB DATA with err %d\n", status);
 178                return status;
 179        }
 180
 181        status = regmap_read(chip->regmap, ISL29018_REG_ADD_DATA_MSB, &msb);
 182        if (status < 0) {
 183                dev_err(dev,
 184                        "Error in reading MSB DATA with error %d\n", status);
 185                return status;
 186        }
 187        dev_vdbg(dev, "MSB 0x%x and LSB 0x%x\n", msb, lsb);
 188
 189        return (msb << 8) | lsb;
 190}
 191
 192static int isl29018_read_lux(struct isl29018_chip *chip, int *lux)
 193{
 194        int lux_data;
 195        unsigned int data_x_range;
 196
 197        lux_data = isl29018_read_sensor_input(chip,
 198                                              ISL29018_CMD1_OPMODE_ALS_ONCE);
 199        if (lux_data < 0)
 200                return lux_data;
 201
 202        data_x_range = lux_data * chip->scale.scale +
 203                       lux_data * chip->scale.uscale / 1000000;
 204        *lux = data_x_range * chip->calibscale +
 205               data_x_range * chip->ucalibscale / 1000000;
 206
 207        return 0;
 208}
 209
 210static int isl29018_read_ir(struct isl29018_chip *chip, int *ir)
 211{
 212        int ir_data;
 213
 214        ir_data = isl29018_read_sensor_input(chip,
 215                                             ISL29018_CMD1_OPMODE_IR_ONCE);
 216        if (ir_data < 0)
 217                return ir_data;
 218
 219        *ir = ir_data;
 220
 221        return 0;
 222}
 223
 224static int isl29018_read_proximity_ir(struct isl29018_chip *chip, int scheme,
 225                                      int *near_ir)
 226{
 227        int status;
 228        int prox_data = -1;
 229        int ir_data = -1;
 230        struct device *dev = regmap_get_device(chip->regmap);
 231
 232        /* Do proximity sensing with required scheme */
 233        status = regmap_update_bits(chip->regmap, ISL29018_REG_ADD_COMMAND2,
 234                                    ISL29018_CMD2_SCHEME_MASK,
 235                                    scheme << ISL29018_CMD2_SCHEME_SHIFT);
 236        if (status) {
 237                dev_err(dev, "Error in setting operating mode\n");
 238                return status;
 239        }
 240
 241        prox_data = isl29018_read_sensor_input(chip,
 242                                               ISL29018_CMD1_OPMODE_PROX_ONCE);
 243        if (prox_data < 0)
 244                return prox_data;
 245
 246        if (scheme == 1) {
 247                *near_ir = prox_data;
 248                return 0;
 249        }
 250
 251        ir_data = isl29018_read_sensor_input(chip,
 252                                             ISL29018_CMD1_OPMODE_IR_ONCE);
 253        if (ir_data < 0)
 254                return ir_data;
 255
 256        if (prox_data >= ir_data)
 257                *near_ir = prox_data - ir_data;
 258        else
 259                *near_ir = 0;
 260
 261        return 0;
 262}
 263
 264static ssize_t in_illuminance_scale_available_show
 265                        (struct device *dev, struct device_attribute *attr,
 266                         char *buf)
 267{
 268        struct iio_dev *indio_dev = dev_to_iio_dev(dev);
 269        struct isl29018_chip *chip = iio_priv(indio_dev);
 270        unsigned int i;
 271        int len = 0;
 272
 273        mutex_lock(&chip->lock);
 274        for (i = 0; i < ARRAY_SIZE(isl29018_scales[chip->int_time]); ++i)
 275                len += sprintf(buf + len, "%d.%06d ",
 276                               isl29018_scales[chip->int_time][i].scale,
 277                               isl29018_scales[chip->int_time][i].uscale);
 278        mutex_unlock(&chip->lock);
 279
 280        buf[len - 1] = '\n';
 281
 282        return len;
 283}
 284
 285static ssize_t in_illuminance_integration_time_available_show
 286                        (struct device *dev, struct device_attribute *attr,
 287                         char *buf)
 288{
 289        struct iio_dev *indio_dev = dev_to_iio_dev(dev);
 290        struct isl29018_chip *chip = iio_priv(indio_dev);
 291        unsigned int i;
 292        int len = 0;
 293
 294        for (i = 0; i < ARRAY_SIZE(isl29018_int_utimes[chip->type]); ++i)
 295                len += sprintf(buf + len, "0.%06d ",
 296                               isl29018_int_utimes[chip->type][i]);
 297
 298        buf[len - 1] = '\n';
 299
 300        return len;
 301}
 302
 303/*
 304 * From ISL29018 Data Sheet (FN6619.4, Oct 8, 2012) regarding the
 305 * infrared suppression:
 306 *
 307 *   Proximity Sensing Scheme: Bit 7. This bit programs the function
 308 * of the proximity detection. Logic 0 of this bit, Scheme 0, makes
 309 * full n (4, 8, 12, 16) bits (unsigned) proximity detection. The range
 310 * of Scheme 0 proximity count is from 0 to 2^n. Logic 1 of this bit,
 311 * Scheme 1, makes n-1 (3, 7, 11, 15) bits (2's complementary)
 312 * proximity_less_ambient detection. The range of Scheme 1
 313 * proximity count is from -2^(n-1) to 2^(n-1) . The sign bit is extended
 314 * for resolutions less than 16. While Scheme 0 has wider dynamic
 315 * range, Scheme 1 proximity detection is less affected by the
 316 * ambient IR noise variation.
 317 *
 318 * 0 Sensing IR from LED and ambient
 319 * 1 Sensing IR from LED with ambient IR rejection
 320 */
 321static ssize_t proximity_on_chip_ambient_infrared_suppression_show
 322                        (struct device *dev, struct device_attribute *attr,
 323                         char *buf)
 324{
 325        struct iio_dev *indio_dev = dev_to_iio_dev(dev);
 326        struct isl29018_chip *chip = iio_priv(indio_dev);
 327
 328        /*
 329         * Return the "proximity scheme" i.e. if the chip does on chip
 330         * infrared suppression (1 means perform on chip suppression)
 331         */
 332        return sprintf(buf, "%d\n", chip->prox_scheme);
 333}
 334
 335static ssize_t proximity_on_chip_ambient_infrared_suppression_store
 336                        (struct device *dev, struct device_attribute *attr,
 337                         const char *buf, size_t count)
 338{
 339        struct iio_dev *indio_dev = dev_to_iio_dev(dev);
 340        struct isl29018_chip *chip = iio_priv(indio_dev);
 341        int val;
 342
 343        if (kstrtoint(buf, 10, &val))
 344                return -EINVAL;
 345        if (!(val == 0 || val == 1))
 346                return -EINVAL;
 347
 348        /*
 349         * Get the "proximity scheme" i.e. if the chip does on chip
 350         * infrared suppression (1 means perform on chip suppression)
 351         */
 352        mutex_lock(&chip->lock);
 353        chip->prox_scheme = val;
 354        mutex_unlock(&chip->lock);
 355
 356        return count;
 357}
 358
 359static int isl29018_write_raw(struct iio_dev *indio_dev,
 360                              struct iio_chan_spec const *chan,
 361                              int val,
 362                              int val2,
 363                              long mask)
 364{
 365        struct isl29018_chip *chip = iio_priv(indio_dev);
 366        int ret = -EINVAL;
 367
 368        mutex_lock(&chip->lock);
 369        if (chip->suspended) {
 370                ret = -EBUSY;
 371                goto write_done;
 372        }
 373        switch (mask) {
 374        case IIO_CHAN_INFO_CALIBSCALE:
 375                if (chan->type == IIO_LIGHT) {
 376                        chip->calibscale = val;
 377                        chip->ucalibscale = val2;
 378                        ret = 0;
 379                }
 380                break;
 381        case IIO_CHAN_INFO_INT_TIME:
 382                if (chan->type == IIO_LIGHT && !val)
 383                        ret = isl29018_set_integration_time(chip, val2);
 384                break;
 385        case IIO_CHAN_INFO_SCALE:
 386                if (chan->type == IIO_LIGHT)
 387                        ret = isl29018_set_scale(chip, val, val2);
 388                break;
 389        default:
 390                break;
 391        }
 392
 393write_done:
 394        mutex_unlock(&chip->lock);
 395
 396        return ret;
 397}
 398
 399static int isl29018_read_raw(struct iio_dev *indio_dev,
 400                             struct iio_chan_spec const *chan,
 401                             int *val,
 402                             int *val2,
 403                             long mask)
 404{
 405        int ret = -EINVAL;
 406        struct isl29018_chip *chip = iio_priv(indio_dev);
 407
 408        mutex_lock(&chip->lock);
 409        if (chip->suspended) {
 410                ret = -EBUSY;
 411                goto read_done;
 412        }
 413        switch (mask) {
 414        case IIO_CHAN_INFO_RAW:
 415        case IIO_CHAN_INFO_PROCESSED:
 416                switch (chan->type) {
 417                case IIO_LIGHT:
 418                        ret = isl29018_read_lux(chip, val);
 419                        break;
 420                case IIO_INTENSITY:
 421                        ret = isl29018_read_ir(chip, val);
 422                        break;
 423                case IIO_PROXIMITY:
 424                        ret = isl29018_read_proximity_ir(chip,
 425                                                         chip->prox_scheme,
 426                                                         val);
 427                        break;
 428                default:
 429                        break;
 430                }
 431                if (!ret)
 432                        ret = IIO_VAL_INT;
 433                break;
 434        case IIO_CHAN_INFO_INT_TIME:
 435                if (chan->type == IIO_LIGHT) {
 436                        *val = 0;
 437                        *val2 = isl29018_int_utimes[chip->type][chip->int_time];
 438                        ret = IIO_VAL_INT_PLUS_MICRO;
 439                }
 440                break;
 441        case IIO_CHAN_INFO_SCALE:
 442                if (chan->type == IIO_LIGHT) {
 443                        *val = chip->scale.scale;
 444                        *val2 = chip->scale.uscale;
 445                        ret = IIO_VAL_INT_PLUS_MICRO;
 446                }
 447                break;
 448        case IIO_CHAN_INFO_CALIBSCALE:
 449                if (chan->type == IIO_LIGHT) {
 450                        *val = chip->calibscale;
 451                        *val2 = chip->ucalibscale;
 452                        ret = IIO_VAL_INT_PLUS_MICRO;
 453                }
 454                break;
 455        default:
 456                break;
 457        }
 458
 459read_done:
 460        mutex_unlock(&chip->lock);
 461
 462        return ret;
 463}
 464
 465#define ISL29018_LIGHT_CHANNEL {                                        \
 466        .type = IIO_LIGHT,                                              \
 467        .indexed = 1,                                                   \
 468        .channel = 0,                                                   \
 469        .info_mask_separate = BIT(IIO_CHAN_INFO_PROCESSED) |            \
 470        BIT(IIO_CHAN_INFO_CALIBSCALE) |                                 \
 471        BIT(IIO_CHAN_INFO_SCALE) |                                      \
 472        BIT(IIO_CHAN_INFO_INT_TIME),                                    \
 473}
 474
 475#define ISL29018_IR_CHANNEL {                                           \
 476        .type = IIO_INTENSITY,                                          \
 477        .modified = 1,                                                  \
 478        .info_mask_separate = BIT(IIO_CHAN_INFO_RAW),                   \
 479        .channel2 = IIO_MOD_LIGHT_IR,                                   \
 480}
 481
 482#define ISL29018_PROXIMITY_CHANNEL {                                    \
 483        .type = IIO_PROXIMITY,                                          \
 484        .info_mask_separate = BIT(IIO_CHAN_INFO_RAW),                   \
 485}
 486
 487static const struct iio_chan_spec isl29018_channels[] = {
 488        ISL29018_LIGHT_CHANNEL,
 489        ISL29018_IR_CHANNEL,
 490        ISL29018_PROXIMITY_CHANNEL,
 491};
 492
 493static const struct iio_chan_spec isl29023_channels[] = {
 494        ISL29018_LIGHT_CHANNEL,
 495        ISL29018_IR_CHANNEL,
 496};
 497
 498static IIO_DEVICE_ATTR_RO(in_illuminance_integration_time_available, 0);
 499static IIO_DEVICE_ATTR_RO(in_illuminance_scale_available, 0);
 500static IIO_DEVICE_ATTR_RW(proximity_on_chip_ambient_infrared_suppression, 0);
 501
 502#define ISL29018_DEV_ATTR(name) (&iio_dev_attr_##name.dev_attr.attr)
 503
 504static struct attribute *isl29018_attributes[] = {
 505        ISL29018_DEV_ATTR(in_illuminance_scale_available),
 506        ISL29018_DEV_ATTR(in_illuminance_integration_time_available),
 507        ISL29018_DEV_ATTR(proximity_on_chip_ambient_infrared_suppression),
 508        NULL
 509};
 510
 511static struct attribute *isl29023_attributes[] = {
 512        ISL29018_DEV_ATTR(in_illuminance_scale_available),
 513        ISL29018_DEV_ATTR(in_illuminance_integration_time_available),
 514        NULL
 515};
 516
 517static const struct attribute_group isl29018_group = {
 518        .attrs = isl29018_attributes,
 519};
 520
 521static const struct attribute_group isl29023_group = {
 522        .attrs = isl29023_attributes,
 523};
 524
 525enum {
 526        isl29018,
 527        isl29023,
 528        isl29035,
 529};
 530
 531static int isl29018_chip_init(struct isl29018_chip *chip)
 532{
 533        int status;
 534        struct device *dev = regmap_get_device(chip->regmap);
 535
 536        if (chip->type == isl29035) {
 537                unsigned int id;
 538
 539                status = regmap_read(chip->regmap, ISL29035_REG_DEVICE_ID, &id);
 540                if (status < 0) {
 541                        dev_err(dev,
 542                                "Error reading ID register with error %d\n",
 543                                status);
 544                        return status;
 545                }
 546
 547                id = (id & ISL29035_DEVICE_ID_MASK) >> ISL29035_DEVICE_ID_SHIFT;
 548
 549                if (id != ISL29035_DEVICE_ID)
 550                        return -ENODEV;
 551
 552                /* Clear brownout bit */
 553                status = regmap_update_bits(chip->regmap,
 554                                            ISL29035_REG_DEVICE_ID,
 555                                            ISL29035_BOUT_MASK, 0);
 556                if (status < 0)
 557                        return status;
 558        }
 559
 560        /*
 561         * Code added per Intersil Application Note 1534:
 562         *     When VDD sinks to approximately 1.8V or below, some of
 563         * the part's registers may change their state. When VDD
 564         * recovers to 2.25V (or greater), the part may thus be in an
 565         * unknown mode of operation. The user can return the part to
 566         * a known mode of operation either by (a) setting VDD = 0V for
 567         * 1 second or more and then powering back up with a slew rate
 568         * of 0.5V/ms or greater, or (b) via I2C disable all ALS/PROX
 569         * conversions, clear the test registers, and then rewrite all
 570         * registers to the desired values.
 571         * ...
 572         * For ISL29011, ISL29018, ISL29021, ISL29023
 573         * 1. Write 0x00 to register 0x08 (TEST)
 574         * 2. Write 0x00 to register 0x00 (CMD1)
 575         * 3. Rewrite all registers to the desired values
 576         *
 577         * ISL29018 Data Sheet (FN6619.1, Feb 11, 2010) essentially says
 578         * the same thing EXCEPT the data sheet asks for a 1ms delay after
 579         * writing the CMD1 register.
 580         */
 581        status = regmap_write(chip->regmap, ISL29018_REG_TEST, 0x0);
 582        if (status < 0) {
 583                dev_err(dev, "Failed to clear isl29018 TEST reg.(%d)\n",
 584                        status);
 585                return status;
 586        }
 587
 588        /*
 589         * See Intersil AN1534 comments above.
 590         * "Operating Mode" (COMMAND1) register is reprogrammed when
 591         * data is read from the device.
 592         */
 593        status = regmap_write(chip->regmap, ISL29018_REG_ADD_COMMAND1, 0);
 594        if (status < 0) {
 595                dev_err(dev, "Failed to clear isl29018 CMD1 reg.(%d)\n",
 596                        status);
 597                return status;
 598        }
 599
 600        usleep_range(1000, 2000);       /* per data sheet, page 10 */
 601
 602        /* Set defaults */
 603        status = isl29018_set_scale(chip, chip->scale.scale,
 604                                    chip->scale.uscale);
 605        if (status < 0) {
 606                dev_err(dev, "Init of isl29018 fails\n");
 607                return status;
 608        }
 609
 610        status = isl29018_set_integration_time(chip,
 611                        isl29018_int_utimes[chip->type][chip->int_time]);
 612        if (status < 0)
 613                dev_err(dev, "Init of isl29018 fails\n");
 614
 615        return status;
 616}
 617
 618static const struct iio_info isl29018_info = {
 619        .attrs = &isl29018_group,
 620        .read_raw = isl29018_read_raw,
 621        .write_raw = isl29018_write_raw,
 622};
 623
 624static const struct iio_info isl29023_info = {
 625        .attrs = &isl29023_group,
 626        .read_raw = isl29018_read_raw,
 627        .write_raw = isl29018_write_raw,
 628};
 629
 630static bool isl29018_is_volatile_reg(struct device *dev, unsigned int reg)
 631{
 632        switch (reg) {
 633        case ISL29018_REG_ADD_DATA_LSB:
 634        case ISL29018_REG_ADD_DATA_MSB:
 635        case ISL29018_REG_ADD_COMMAND1:
 636        case ISL29018_REG_TEST:
 637        case ISL29035_REG_DEVICE_ID:
 638                return true;
 639        default:
 640                return false;
 641        }
 642}
 643
 644static const struct regmap_config isl29018_regmap_config = {
 645        .reg_bits = 8,
 646        .val_bits = 8,
 647        .volatile_reg = isl29018_is_volatile_reg,
 648        .max_register = ISL29018_REG_TEST,
 649        .num_reg_defaults_raw = ISL29018_REG_TEST + 1,
 650        .cache_type = REGCACHE_RBTREE,
 651};
 652
 653static const struct regmap_config isl29035_regmap_config = {
 654        .reg_bits = 8,
 655        .val_bits = 8,
 656        .volatile_reg = isl29018_is_volatile_reg,
 657        .max_register = ISL29035_REG_DEVICE_ID,
 658        .num_reg_defaults_raw = ISL29035_REG_DEVICE_ID + 1,
 659        .cache_type = REGCACHE_RBTREE,
 660};
 661
 662struct isl29018_chip_info {
 663        const struct iio_chan_spec *channels;
 664        int num_channels;
 665        const struct iio_info *indio_info;
 666        const struct regmap_config *regmap_cfg;
 667};
 668
 669static const struct isl29018_chip_info isl29018_chip_info_tbl[] = {
 670        [isl29018] = {
 671                .channels = isl29018_channels,
 672                .num_channels = ARRAY_SIZE(isl29018_channels),
 673                .indio_info = &isl29018_info,
 674                .regmap_cfg = &isl29018_regmap_config,
 675        },
 676        [isl29023] = {
 677                .channels = isl29023_channels,
 678                .num_channels = ARRAY_SIZE(isl29023_channels),
 679                .indio_info = &isl29023_info,
 680                .regmap_cfg = &isl29018_regmap_config,
 681        },
 682        [isl29035] = {
 683                .channels = isl29023_channels,
 684                .num_channels = ARRAY_SIZE(isl29023_channels),
 685                .indio_info = &isl29023_info,
 686                .regmap_cfg = &isl29035_regmap_config,
 687        },
 688};
 689
 690static const char *isl29018_match_acpi_device(struct device *dev, int *data)
 691{
 692        const struct acpi_device_id *id;
 693
 694        id = acpi_match_device(dev->driver->acpi_match_table, dev);
 695
 696        if (!id)
 697                return NULL;
 698
 699        *data = (int)id->driver_data;
 700
 701        return dev_name(dev);
 702}
 703
 704static void isl29018_disable_regulator_action(void *_data)
 705{
 706        struct isl29018_chip *chip = _data;
 707        int err;
 708
 709        err = regulator_disable(chip->vcc_reg);
 710        if (err)
 711                pr_err("failed to disable isl29018's VCC regulator!\n");
 712}
 713
 714static int isl29018_probe(struct i2c_client *client,
 715                          const struct i2c_device_id *id)
 716{
 717        struct isl29018_chip *chip;
 718        struct iio_dev *indio_dev;
 719        int err;
 720        const char *name = NULL;
 721        int dev_id = 0;
 722
 723        indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*chip));
 724        if (!indio_dev)
 725                return -ENOMEM;
 726
 727        chip = iio_priv(indio_dev);
 728
 729        i2c_set_clientdata(client, indio_dev);
 730
 731        if (id) {
 732                name = id->name;
 733                dev_id = id->driver_data;
 734        }
 735
 736        if (ACPI_HANDLE(&client->dev))
 737                name = isl29018_match_acpi_device(&client->dev, &dev_id);
 738
 739        mutex_init(&chip->lock);
 740
 741        chip->type = dev_id;
 742        chip->calibscale = 1;
 743        chip->ucalibscale = 0;
 744        chip->int_time = ISL29018_INT_TIME_16;
 745        chip->scale = isl29018_scales[chip->int_time][0];
 746        chip->suspended = false;
 747
 748        chip->vcc_reg = devm_regulator_get(&client->dev, "vcc");
 749        if (IS_ERR(chip->vcc_reg))
 750                return dev_err_probe(&client->dev, PTR_ERR(chip->vcc_reg),
 751                                     "failed to get VCC regulator!\n");
 752
 753        err = regulator_enable(chip->vcc_reg);
 754        if (err) {
 755                dev_err(&client->dev, "failed to enable VCC regulator!\n");
 756                return err;
 757        }
 758
 759        err = devm_add_action_or_reset(&client->dev, isl29018_disable_regulator_action,
 760                                 chip);
 761        if (err) {
 762                dev_err(&client->dev, "failed to setup regulator cleanup action!\n");
 763                return err;
 764        }
 765
 766        chip->regmap = devm_regmap_init_i2c(client,
 767                                isl29018_chip_info_tbl[dev_id].regmap_cfg);
 768        if (IS_ERR(chip->regmap)) {
 769                err = PTR_ERR(chip->regmap);
 770                dev_err(&client->dev, "regmap initialization fails: %d\n", err);
 771                return err;
 772        }
 773
 774        err = isl29018_chip_init(chip);
 775        if (err)
 776                return err;
 777
 778        indio_dev->info = isl29018_chip_info_tbl[dev_id].indio_info;
 779        indio_dev->channels = isl29018_chip_info_tbl[dev_id].channels;
 780        indio_dev->num_channels = isl29018_chip_info_tbl[dev_id].num_channels;
 781        indio_dev->name = name;
 782        indio_dev->modes = INDIO_DIRECT_MODE;
 783
 784        return devm_iio_device_register(&client->dev, indio_dev);
 785}
 786
 787#ifdef CONFIG_PM_SLEEP
 788static int isl29018_suspend(struct device *dev)
 789{
 790        struct isl29018_chip *chip = iio_priv(dev_get_drvdata(dev));
 791        int ret;
 792
 793        mutex_lock(&chip->lock);
 794
 795        /*
 796         * Since this driver uses only polling commands, we are by default in
 797         * auto shutdown (ie, power-down) mode.
 798         * So we do not have much to do here.
 799         */
 800        chip->suspended = true;
 801        ret = regulator_disable(chip->vcc_reg);
 802        if (ret)
 803                dev_err(dev, "failed to disable VCC regulator\n");
 804
 805        mutex_unlock(&chip->lock);
 806
 807        return ret;
 808}
 809
 810static int isl29018_resume(struct device *dev)
 811{
 812        struct isl29018_chip *chip = iio_priv(dev_get_drvdata(dev));
 813        int err;
 814
 815        mutex_lock(&chip->lock);
 816
 817        err = regulator_enable(chip->vcc_reg);
 818        if (err) {
 819                dev_err(dev, "failed to enable VCC regulator\n");
 820                mutex_unlock(&chip->lock);
 821                return err;
 822        }
 823
 824        err = isl29018_chip_init(chip);
 825        if (!err)
 826                chip->suspended = false;
 827
 828        mutex_unlock(&chip->lock);
 829
 830        return err;
 831}
 832
 833static SIMPLE_DEV_PM_OPS(isl29018_pm_ops, isl29018_suspend, isl29018_resume);
 834#define ISL29018_PM_OPS (&isl29018_pm_ops)
 835#else
 836#define ISL29018_PM_OPS NULL
 837#endif
 838
 839#ifdef CONFIG_ACPI
 840static const struct acpi_device_id isl29018_acpi_match[] = {
 841        {"ISL29018", isl29018},
 842        {"ISL29023", isl29023},
 843        {"ISL29035", isl29035},
 844        {},
 845};
 846MODULE_DEVICE_TABLE(acpi, isl29018_acpi_match);
 847#endif
 848
 849static const struct i2c_device_id isl29018_id[] = {
 850        {"isl29018", isl29018},
 851        {"isl29023", isl29023},
 852        {"isl29035", isl29035},
 853        {}
 854};
 855MODULE_DEVICE_TABLE(i2c, isl29018_id);
 856
 857static const struct of_device_id isl29018_of_match[] = {
 858        { .compatible = "isil,isl29018", },
 859        { .compatible = "isil,isl29023", },
 860        { .compatible = "isil,isl29035", },
 861        { },
 862};
 863MODULE_DEVICE_TABLE(of, isl29018_of_match);
 864
 865static struct i2c_driver isl29018_driver = {
 866        .driver  = {
 867                        .name = "isl29018",
 868                        .acpi_match_table = ACPI_PTR(isl29018_acpi_match),
 869                        .pm = ISL29018_PM_OPS,
 870                        .of_match_table = isl29018_of_match,
 871                    },
 872        .probe   = isl29018_probe,
 873        .id_table = isl29018_id,
 874};
 875module_i2c_driver(isl29018_driver);
 876
 877MODULE_DESCRIPTION("ISL29018 Ambient Light Sensor driver");
 878MODULE_LICENSE("GPL");
 879