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