linux/drivers/iio/light/tsl2772.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0+
   2/*
   3 * Device driver for monitoring ambient light intensity in (lux) and proximity
   4 * detection (prox) within the TAOS TSL2571, TSL2671, TMD2671, TSL2771, TMD2771,
   5 * TSL2572, TSL2672, TMD2672, TSL2772, and TMD2772 devices.
   6 *
   7 * Copyright (c) 2012, TAOS Corporation.
   8 * Copyright (c) 2017-2018 Brian Masney <masneyb@onstation.org>
   9 */
  10
  11#include <linux/delay.h>
  12#include <linux/errno.h>
  13#include <linux/i2c.h>
  14#include <linux/interrupt.h>
  15#include <linux/kernel.h>
  16#include <linux/module.h>
  17#include <linux/mutex.h>
  18#include <linux/slab.h>
  19#include <linux/iio/events.h>
  20#include <linux/iio/iio.h>
  21#include <linux/iio/sysfs.h>
  22#include <linux/platform_data/tsl2772.h>
  23#include <linux/regulator/consumer.h>
  24
  25/* Cal defs */
  26#define PROX_STAT_CAL                   0
  27#define PROX_STAT_SAMP                  1
  28#define MAX_SAMPLES_CAL                 200
  29
  30/* TSL2772 Device ID */
  31#define TRITON_ID                       0x00
  32#define SWORDFISH_ID                    0x30
  33#define HALIBUT_ID                      0x20
  34
  35/* Lux calculation constants */
  36#define TSL2772_LUX_CALC_OVER_FLOW      65535
  37
  38/*
  39 * TAOS Register definitions - Note: depending on device, some of these register
  40 * are not used and the register address is benign.
  41 */
  42
  43/* Register offsets */
  44#define TSL2772_MAX_CONFIG_REG          16
  45
  46/* Device Registers and Masks */
  47#define TSL2772_CNTRL                   0x00
  48#define TSL2772_ALS_TIME                0X01
  49#define TSL2772_PRX_TIME                0x02
  50#define TSL2772_WAIT_TIME               0x03
  51#define TSL2772_ALS_MINTHRESHLO         0X04
  52#define TSL2772_ALS_MINTHRESHHI         0X05
  53#define TSL2772_ALS_MAXTHRESHLO         0X06
  54#define TSL2772_ALS_MAXTHRESHHI         0X07
  55#define TSL2772_PRX_MINTHRESHLO         0X08
  56#define TSL2772_PRX_MINTHRESHHI         0X09
  57#define TSL2772_PRX_MAXTHRESHLO         0X0A
  58#define TSL2772_PRX_MAXTHRESHHI         0X0B
  59#define TSL2772_PERSISTENCE             0x0C
  60#define TSL2772_ALS_PRX_CONFIG          0x0D
  61#define TSL2772_PRX_COUNT               0x0E
  62#define TSL2772_GAIN                    0x0F
  63#define TSL2772_NOTUSED                 0x10
  64#define TSL2772_REVID                   0x11
  65#define TSL2772_CHIPID                  0x12
  66#define TSL2772_STATUS                  0x13
  67#define TSL2772_ALS_CHAN0LO             0x14
  68#define TSL2772_ALS_CHAN0HI             0x15
  69#define TSL2772_ALS_CHAN1LO             0x16
  70#define TSL2772_ALS_CHAN1HI             0x17
  71#define TSL2772_PRX_LO                  0x18
  72#define TSL2772_PRX_HI                  0x19
  73
  74/* tsl2772 cmd reg masks */
  75#define TSL2772_CMD_REG                 0x80
  76#define TSL2772_CMD_SPL_FN              0x60
  77#define TSL2772_CMD_REPEAT_PROTO        0x00
  78#define TSL2772_CMD_AUTOINC_PROTO       0x20
  79
  80#define TSL2772_CMD_PROX_INT_CLR        0X05
  81#define TSL2772_CMD_ALS_INT_CLR         0x06
  82#define TSL2772_CMD_PROXALS_INT_CLR     0X07
  83
  84/* tsl2772 cntrl reg masks */
  85#define TSL2772_CNTL_ADC_ENBL           0x02
  86#define TSL2772_CNTL_PWR_ON             0x01
  87
  88/* tsl2772 status reg masks */
  89#define TSL2772_STA_ADC_VALID           0x01
  90#define TSL2772_STA_PRX_VALID           0x02
  91#define TSL2772_STA_ADC_PRX_VALID       (TSL2772_STA_ADC_VALID | \
  92                                         TSL2772_STA_PRX_VALID)
  93#define TSL2772_STA_ALS_INTR            0x10
  94#define TSL2772_STA_PRX_INTR            0x20
  95
  96/* tsl2772 cntrl reg masks */
  97#define TSL2772_CNTL_REG_CLEAR          0x00
  98#define TSL2772_CNTL_PROX_INT_ENBL      0X20
  99#define TSL2772_CNTL_ALS_INT_ENBL       0X10
 100#define TSL2772_CNTL_WAIT_TMR_ENBL      0X08
 101#define TSL2772_CNTL_PROX_DET_ENBL      0X04
 102#define TSL2772_CNTL_PWRON              0x01
 103#define TSL2772_CNTL_ALSPON_ENBL        0x03
 104#define TSL2772_CNTL_INTALSPON_ENBL     0x13
 105#define TSL2772_CNTL_PROXPON_ENBL       0x0F
 106#define TSL2772_CNTL_INTPROXPON_ENBL    0x2F
 107
 108#define TSL2772_ALS_GAIN_TRIM_MIN       250
 109#define TSL2772_ALS_GAIN_TRIM_MAX       4000
 110
 111#define TSL2772_MAX_PROX_LEDS           2
 112
 113#define TSL2772_BOOT_MIN_SLEEP_TIME     10000
 114#define TSL2772_BOOT_MAX_SLEEP_TIME     28000
 115
 116/* Device family members */
 117enum {
 118        tsl2571,
 119        tsl2671,
 120        tmd2671,
 121        tsl2771,
 122        tmd2771,
 123        tsl2572,
 124        tsl2672,
 125        tmd2672,
 126        tsl2772,
 127        tmd2772,
 128        apds9930,
 129};
 130
 131enum {
 132        TSL2772_CHIP_UNKNOWN = 0,
 133        TSL2772_CHIP_WORKING = 1,
 134        TSL2772_CHIP_SUSPENDED = 2
 135};
 136
 137/* Per-device data */
 138struct tsl2772_als_info {
 139        u16 als_ch0;
 140        u16 als_ch1;
 141        u16 lux;
 142};
 143
 144struct tsl2772_chip_info {
 145        int chan_table_elements;
 146        struct iio_chan_spec channel_with_events[4];
 147        struct iio_chan_spec channel_without_events[4];
 148        const struct iio_info *info;
 149};
 150
 151static const int tsl2772_led_currents[][2] = {
 152        { 100000, TSL2772_100_mA },
 153        {  50000, TSL2772_50_mA },
 154        {  25000, TSL2772_25_mA },
 155        {  13000, TSL2772_13_mA },
 156        {      0, 0 }
 157};
 158
 159struct tsl2772_chip {
 160        kernel_ulong_t id;
 161        struct mutex prox_mutex;
 162        struct mutex als_mutex;
 163        struct i2c_client *client;
 164        struct regulator *vdd_supply;
 165        struct regulator *vddio_supply;
 166        u16 prox_data;
 167        struct tsl2772_als_info als_cur_info;
 168        struct tsl2772_settings settings;
 169        struct tsl2772_platform_data *pdata;
 170        int als_gain_time_scale;
 171        int als_saturation;
 172        int tsl2772_chip_status;
 173        u8 tsl2772_config[TSL2772_MAX_CONFIG_REG];
 174        const struct tsl2772_chip_info  *chip_info;
 175        const struct iio_info *info;
 176        s64 event_timestamp;
 177        /*
 178         * This structure is intentionally large to accommodate
 179         * updates via sysfs.
 180         * Sized to 9 = max 8 segments + 1 termination segment
 181         */
 182        struct tsl2772_lux tsl2772_device_lux[TSL2772_MAX_LUX_TABLE_SIZE];
 183};
 184
 185/*
 186 * Different devices require different coefficents, and these numbers were
 187 * derived from the 'Lux Equation' section of the various device datasheets.
 188 * All of these coefficients assume a Glass Attenuation (GA) factor of 1.
 189 * The coefficients are multiplied by 1000 to avoid floating point operations.
 190 * The two rows in each table correspond to the Lux1 and Lux2 equations from
 191 * the datasheets.
 192 */
 193static const struct tsl2772_lux tsl2x71_lux_table[TSL2772_DEF_LUX_TABLE_SZ] = {
 194        { 53000, 106000 },
 195        { 31800,  53000 },
 196        { 0,          0 },
 197};
 198
 199static const struct tsl2772_lux tmd2x71_lux_table[TSL2772_DEF_LUX_TABLE_SZ] = {
 200        { 24000,  48000 },
 201        { 14400,  24000 },
 202        { 0,          0 },
 203};
 204
 205static const struct tsl2772_lux tsl2x72_lux_table[TSL2772_DEF_LUX_TABLE_SZ] = {
 206        { 60000, 112200 },
 207        { 37800,  60000 },
 208        {     0,      0 },
 209};
 210
 211static const struct tsl2772_lux tmd2x72_lux_table[TSL2772_DEF_LUX_TABLE_SZ] = {
 212        { 20000,  35000 },
 213        { 12600,  20000 },
 214        {     0,      0 },
 215};
 216
 217static const struct tsl2772_lux apds9930_lux_table[TSL2772_DEF_LUX_TABLE_SZ] = {
 218        { 52000,  96824 },
 219        { 38792,  67132 },
 220        {     0,      0 },
 221};
 222
 223static const struct tsl2772_lux *tsl2772_default_lux_table_group[] = {
 224        [tsl2571] = tsl2x71_lux_table,
 225        [tsl2671] = tsl2x71_lux_table,
 226        [tmd2671] = tmd2x71_lux_table,
 227        [tsl2771] = tsl2x71_lux_table,
 228        [tmd2771] = tmd2x71_lux_table,
 229        [tsl2572] = tsl2x72_lux_table,
 230        [tsl2672] = tsl2x72_lux_table,
 231        [tmd2672] = tmd2x72_lux_table,
 232        [tsl2772] = tsl2x72_lux_table,
 233        [tmd2772] = tmd2x72_lux_table,
 234        [apds9930] = apds9930_lux_table,
 235};
 236
 237static const struct tsl2772_settings tsl2772_default_settings = {
 238        .als_time = 255, /* 2.72 / 2.73 ms */
 239        .als_gain = 0,
 240        .prox_time = 255, /* 2.72 / 2.73 ms */
 241        .prox_gain = 0,
 242        .wait_time = 255,
 243        .als_prox_config = 0,
 244        .als_gain_trim = 1000,
 245        .als_cal_target = 150,
 246        .als_persistence = 1,
 247        .als_interrupt_en = false,
 248        .als_thresh_low = 200,
 249        .als_thresh_high = 256,
 250        .prox_persistence = 1,
 251        .prox_interrupt_en = false,
 252        .prox_thres_low  = 0,
 253        .prox_thres_high = 512,
 254        .prox_max_samples_cal = 30,
 255        .prox_pulse_count = 8,
 256        .prox_diode = TSL2772_DIODE1,
 257        .prox_power = TSL2772_100_mA
 258};
 259
 260static const s16 tsl2772_als_gain[] = {
 261        1,
 262        8,
 263        16,
 264        120
 265};
 266
 267static const s16 tsl2772_prox_gain[] = {
 268        1,
 269        2,
 270        4,
 271        8
 272};
 273
 274static const int tsl2772_int_time_avail[][6] = {
 275        [tsl2571] = { 0, 2720, 0, 2720, 0, 696000 },
 276        [tsl2671] = { 0, 2720, 0, 2720, 0, 696000 },
 277        [tmd2671] = { 0, 2720, 0, 2720, 0, 696000 },
 278        [tsl2771] = { 0, 2720, 0, 2720, 0, 696000 },
 279        [tmd2771] = { 0, 2720, 0, 2720, 0, 696000 },
 280        [tsl2572] = { 0, 2730, 0, 2730, 0, 699000 },
 281        [tsl2672] = { 0, 2730, 0, 2730, 0, 699000 },
 282        [tmd2672] = { 0, 2730, 0, 2730, 0, 699000 },
 283        [tsl2772] = { 0, 2730, 0, 2730, 0, 699000 },
 284        [tmd2772] = { 0, 2730, 0, 2730, 0, 699000 },
 285        [apds9930] = { 0, 2730, 0, 2730, 0, 699000 },
 286};
 287
 288static int tsl2772_int_calibscale_avail[] = { 1, 8, 16, 120 };
 289
 290static int tsl2772_prox_calibscale_avail[] = { 1, 2, 4, 8 };
 291
 292/* Channel variations */
 293enum {
 294        ALS,
 295        PRX,
 296        ALSPRX,
 297        PRX2,
 298        ALSPRX2,
 299};
 300
 301static const u8 device_channel_config[] = {
 302        [tsl2571] = ALS,
 303        [tsl2671] = PRX,
 304        [tmd2671] = PRX,
 305        [tsl2771] = ALSPRX,
 306        [tmd2771] = ALSPRX,
 307        [tsl2572] = ALS,
 308        [tsl2672] = PRX2,
 309        [tmd2672] = PRX2,
 310        [tsl2772] = ALSPRX2,
 311        [tmd2772] = ALSPRX2,
 312        [apds9930] = ALSPRX2,
 313};
 314
 315static int tsl2772_read_status(struct tsl2772_chip *chip)
 316{
 317        int ret;
 318
 319        ret = i2c_smbus_read_byte_data(chip->client,
 320                                       TSL2772_CMD_REG | TSL2772_STATUS);
 321        if (ret < 0)
 322                dev_err(&chip->client->dev,
 323                        "%s: failed to read STATUS register: %d\n", __func__,
 324                        ret);
 325
 326        return ret;
 327}
 328
 329static int tsl2772_write_control_reg(struct tsl2772_chip *chip, u8 data)
 330{
 331        int ret;
 332
 333        ret = i2c_smbus_write_byte_data(chip->client,
 334                                        TSL2772_CMD_REG | TSL2772_CNTRL, data);
 335        if (ret < 0) {
 336                dev_err(&chip->client->dev,
 337                        "%s: failed to write to control register %x: %d\n",
 338                        __func__, data, ret);
 339        }
 340
 341        return ret;
 342}
 343
 344static int tsl2772_read_autoinc_regs(struct tsl2772_chip *chip, int lower_reg,
 345                                     int upper_reg)
 346{
 347        u8 buf[2];
 348        int ret;
 349
 350        ret = i2c_smbus_write_byte(chip->client,
 351                                   TSL2772_CMD_REG | TSL2772_CMD_AUTOINC_PROTO |
 352                                   lower_reg);
 353        if (ret < 0) {
 354                dev_err(&chip->client->dev,
 355                        "%s: failed to enable auto increment protocol: %d\n",
 356                        __func__, ret);
 357                return ret;
 358        }
 359
 360        ret = i2c_smbus_read_byte_data(chip->client,
 361                                       TSL2772_CMD_REG | lower_reg);
 362        if (ret < 0) {
 363                dev_err(&chip->client->dev,
 364                        "%s: failed to read from register %x: %d\n", __func__,
 365                        lower_reg, ret);
 366                return ret;
 367        }
 368        buf[0] = ret;
 369
 370        ret = i2c_smbus_read_byte_data(chip->client,
 371                                       TSL2772_CMD_REG | upper_reg);
 372        if (ret < 0) {
 373                dev_err(&chip->client->dev,
 374                        "%s: failed to read from register %x: %d\n", __func__,
 375                        upper_reg, ret);
 376                return ret;
 377        }
 378        buf[1] = ret;
 379
 380        ret = i2c_smbus_write_byte(chip->client,
 381                                   TSL2772_CMD_REG | TSL2772_CMD_REPEAT_PROTO |
 382                                   lower_reg);
 383        if (ret < 0) {
 384                dev_err(&chip->client->dev,
 385                        "%s: failed to enable repeated byte protocol: %d\n",
 386                        __func__, ret);
 387                return ret;
 388        }
 389
 390        return le16_to_cpup((const __le16 *)&buf[0]);
 391}
 392
 393/**
 394 * tsl2772_get_lux() - Reads and calculates current lux value.
 395 * @indio_dev:  pointer to IIO device
 396 *
 397 * The raw ch0 and ch1 values of the ambient light sensed in the last
 398 * integration cycle are read from the device. The raw values are multiplied
 399 * by a device-specific scale factor, and divided by the integration time and
 400 * device gain. The code supports multiple lux equations through the lux table
 401 * coefficients. A lux gain trim is applied to each lux equation, and then the
 402 * maximum lux within the interval 0..65535 is selected.
 403 */
 404static int tsl2772_get_lux(struct iio_dev *indio_dev)
 405{
 406        struct tsl2772_chip *chip = iio_priv(indio_dev);
 407        struct tsl2772_lux *p;
 408        int max_lux, ret;
 409        bool overflow;
 410
 411        mutex_lock(&chip->als_mutex);
 412
 413        if (chip->tsl2772_chip_status != TSL2772_CHIP_WORKING) {
 414                dev_err(&chip->client->dev, "%s: device is not enabled\n",
 415                        __func__);
 416                ret = -EBUSY;
 417                goto out_unlock;
 418        }
 419
 420        ret = tsl2772_read_status(chip);
 421        if (ret < 0)
 422                goto out_unlock;
 423
 424        if (!(ret & TSL2772_STA_ADC_VALID)) {
 425                dev_err(&chip->client->dev,
 426                        "%s: data not valid yet\n", __func__);
 427                ret = chip->als_cur_info.lux; /* return LAST VALUE */
 428                goto out_unlock;
 429        }
 430
 431        ret = tsl2772_read_autoinc_regs(chip, TSL2772_ALS_CHAN0LO,
 432                                        TSL2772_ALS_CHAN0HI);
 433        if (ret < 0)
 434                goto out_unlock;
 435        chip->als_cur_info.als_ch0 = ret;
 436
 437        ret = tsl2772_read_autoinc_regs(chip, TSL2772_ALS_CHAN1LO,
 438                                        TSL2772_ALS_CHAN1HI);
 439        if (ret < 0)
 440                goto out_unlock;
 441        chip->als_cur_info.als_ch1 = ret;
 442
 443        if (chip->als_cur_info.als_ch0 >= chip->als_saturation) {
 444                max_lux = TSL2772_LUX_CALC_OVER_FLOW;
 445                goto update_struct_with_max_lux;
 446        }
 447
 448        if (!chip->als_cur_info.als_ch0) {
 449                /* have no data, so return LAST VALUE */
 450                ret = chip->als_cur_info.lux;
 451                goto out_unlock;
 452        }
 453
 454        max_lux = 0;
 455        overflow = false;
 456        for (p = (struct tsl2772_lux *)chip->tsl2772_device_lux; p->ch0 != 0;
 457             p++) {
 458                int lux;
 459
 460                lux = ((chip->als_cur_info.als_ch0 * p->ch0) -
 461                       (chip->als_cur_info.als_ch1 * p->ch1)) /
 462                        chip->als_gain_time_scale;
 463
 464                /*
 465                 * The als_gain_trim can have a value within the range 250..4000
 466                 * and is a multiplier for the lux. A trim of 1000 makes no
 467                 * changes to the lux, less than 1000 scales it down, and
 468                 * greater than 1000 scales it up.
 469                 */
 470                lux = (lux * chip->settings.als_gain_trim) / 1000;
 471
 472                if (lux > TSL2772_LUX_CALC_OVER_FLOW) {
 473                        overflow = true;
 474                        continue;
 475                }
 476
 477                max_lux = max(max_lux, lux);
 478        }
 479
 480        if (overflow && max_lux == 0)
 481                max_lux = TSL2772_LUX_CALC_OVER_FLOW;
 482
 483update_struct_with_max_lux:
 484        chip->als_cur_info.lux = max_lux;
 485        ret = max_lux;
 486
 487out_unlock:
 488        mutex_unlock(&chip->als_mutex);
 489
 490        return ret;
 491}
 492
 493/**
 494 * tsl2772_get_prox() - Reads proximity data registers and updates
 495 *                      chip->prox_data.
 496 *
 497 * @indio_dev:  pointer to IIO device
 498 */
 499static int tsl2772_get_prox(struct iio_dev *indio_dev)
 500{
 501        struct tsl2772_chip *chip = iio_priv(indio_dev);
 502        int ret;
 503
 504        mutex_lock(&chip->prox_mutex);
 505
 506        ret = tsl2772_read_status(chip);
 507        if (ret < 0)
 508                goto prox_poll_err;
 509
 510        switch (chip->id) {
 511        case tsl2571:
 512        case tsl2671:
 513        case tmd2671:
 514        case tsl2771:
 515        case tmd2771:
 516                if (!(ret & TSL2772_STA_ADC_VALID)) {
 517                        ret = -EINVAL;
 518                        goto prox_poll_err;
 519                }
 520                break;
 521        case tsl2572:
 522        case tsl2672:
 523        case tmd2672:
 524        case tsl2772:
 525        case tmd2772:
 526        case apds9930:
 527                if (!(ret & TSL2772_STA_PRX_VALID)) {
 528                        ret = -EINVAL;
 529                        goto prox_poll_err;
 530                }
 531                break;
 532        }
 533
 534        ret = tsl2772_read_autoinc_regs(chip, TSL2772_PRX_LO, TSL2772_PRX_HI);
 535        if (ret < 0)
 536                goto prox_poll_err;
 537        chip->prox_data = ret;
 538
 539prox_poll_err:
 540        mutex_unlock(&chip->prox_mutex);
 541
 542        return ret;
 543}
 544
 545static int tsl2772_read_prox_led_current(struct tsl2772_chip *chip)
 546{
 547        struct device_node *of_node = chip->client->dev.of_node;
 548        int ret, tmp, i;
 549
 550        ret = of_property_read_u32(of_node, "led-max-microamp", &tmp);
 551        if (ret < 0)
 552                return ret;
 553
 554        for (i = 0; tsl2772_led_currents[i][0] != 0; i++) {
 555                if (tmp == tsl2772_led_currents[i][0]) {
 556                        chip->settings.prox_power = tsl2772_led_currents[i][1];
 557                        return 0;
 558                }
 559        }
 560
 561        dev_err(&chip->client->dev, "Invalid value %d for led-max-microamp\n",
 562                tmp);
 563
 564        return -EINVAL;
 565
 566}
 567
 568static int tsl2772_read_prox_diodes(struct tsl2772_chip *chip)
 569{
 570        struct device_node *of_node = chip->client->dev.of_node;
 571        int i, ret, num_leds, prox_diode_mask;
 572        u32 leds[TSL2772_MAX_PROX_LEDS];
 573
 574        ret = of_property_count_u32_elems(of_node, "amstaos,proximity-diodes");
 575        if (ret < 0)
 576                return ret;
 577
 578        num_leds = ret;
 579        if (num_leds > TSL2772_MAX_PROX_LEDS)
 580                num_leds = TSL2772_MAX_PROX_LEDS;
 581
 582        ret = of_property_read_u32_array(of_node, "amstaos,proximity-diodes",
 583                                         leds, num_leds);
 584        if (ret < 0) {
 585                dev_err(&chip->client->dev,
 586                        "Invalid value for amstaos,proximity-diodes: %d.\n",
 587                        ret);
 588                return ret;
 589        }
 590
 591        prox_diode_mask = 0;
 592        for (i = 0; i < num_leds; i++) {
 593                if (leds[i] == 0)
 594                        prox_diode_mask |= TSL2772_DIODE0;
 595                else if (leds[i] == 1)
 596                        prox_diode_mask |= TSL2772_DIODE1;
 597                else {
 598                        dev_err(&chip->client->dev,
 599                                "Invalid value %d in amstaos,proximity-diodes.\n",
 600                                leds[i]);
 601                        return -EINVAL;
 602                }
 603        }
 604
 605        return 0;
 606}
 607
 608static void tsl2772_parse_dt(struct tsl2772_chip *chip)
 609{
 610        tsl2772_read_prox_led_current(chip);
 611        tsl2772_read_prox_diodes(chip);
 612}
 613
 614/**
 615 * tsl2772_defaults() - Populates the device nominal operating parameters
 616 *                      with those provided by a 'platform' data struct or
 617 *                      with prefined defaults.
 618 *
 619 * @chip:               pointer to device structure.
 620 */
 621static void tsl2772_defaults(struct tsl2772_chip *chip)
 622{
 623        /* If Operational settings defined elsewhere.. */
 624        if (chip->pdata && chip->pdata->platform_default_settings)
 625                memcpy(&chip->settings, chip->pdata->platform_default_settings,
 626                       sizeof(tsl2772_default_settings));
 627        else
 628                memcpy(&chip->settings, &tsl2772_default_settings,
 629                       sizeof(tsl2772_default_settings));
 630
 631        /* Load up the proper lux table. */
 632        if (chip->pdata && chip->pdata->platform_lux_table[0].ch0 != 0)
 633                memcpy(chip->tsl2772_device_lux,
 634                       chip->pdata->platform_lux_table,
 635                       sizeof(chip->pdata->platform_lux_table));
 636        else
 637                memcpy(chip->tsl2772_device_lux,
 638                       tsl2772_default_lux_table_group[chip->id],
 639                       TSL2772_DEFAULT_TABLE_BYTES);
 640
 641        tsl2772_parse_dt(chip);
 642}
 643
 644/**
 645 * tsl2772_als_calibrate() -    Obtain single reading and calculate
 646 *                              the als_gain_trim.
 647 *
 648 * @indio_dev:  pointer to IIO device
 649 */
 650static int tsl2772_als_calibrate(struct iio_dev *indio_dev)
 651{
 652        struct tsl2772_chip *chip = iio_priv(indio_dev);
 653        int ret, lux_val;
 654
 655        ret = i2c_smbus_read_byte_data(chip->client,
 656                                       TSL2772_CMD_REG | TSL2772_CNTRL);
 657        if (ret < 0) {
 658                dev_err(&chip->client->dev,
 659                        "%s: failed to read from the CNTRL register\n",
 660                        __func__);
 661                return ret;
 662        }
 663
 664        if ((ret & (TSL2772_CNTL_ADC_ENBL | TSL2772_CNTL_PWR_ON))
 665                        != (TSL2772_CNTL_ADC_ENBL | TSL2772_CNTL_PWR_ON)) {
 666                dev_err(&chip->client->dev,
 667                        "%s: Device is not powered on and/or ADC is not enabled\n",
 668                        __func__);
 669                return -EINVAL;
 670        } else if ((ret & TSL2772_STA_ADC_VALID) != TSL2772_STA_ADC_VALID) {
 671                dev_err(&chip->client->dev,
 672                        "%s: The two ADC channels have not completed an integration cycle\n",
 673                        __func__);
 674                return -ENODATA;
 675        }
 676
 677        lux_val = tsl2772_get_lux(indio_dev);
 678        if (lux_val < 0) {
 679                dev_err(&chip->client->dev,
 680                        "%s: failed to get lux\n", __func__);
 681                return lux_val;
 682        }
 683        if (lux_val == 0)
 684                return -ERANGE;
 685
 686        ret = (chip->settings.als_cal_target * chip->settings.als_gain_trim) /
 687                        lux_val;
 688        if (ret < TSL2772_ALS_GAIN_TRIM_MIN || ret > TSL2772_ALS_GAIN_TRIM_MAX)
 689                return -ERANGE;
 690
 691        chip->settings.als_gain_trim = ret;
 692
 693        return ret;
 694}
 695
 696static void tsl2772_disable_regulators_action(void *_data)
 697{
 698        struct tsl2772_chip *chip = _data;
 699
 700        regulator_disable(chip->vdd_supply);
 701        regulator_disable(chip->vddio_supply);
 702}
 703
 704static int tsl2772_enable_regulator(struct tsl2772_chip *chip,
 705                                    struct regulator *regulator)
 706{
 707        int ret;
 708
 709        ret = regulator_enable(regulator);
 710        if (ret < 0) {
 711                dev_err(&chip->client->dev, "Failed to enable regulator: %d\n",
 712                        ret);
 713                return ret;
 714        }
 715
 716        return 0;
 717}
 718
 719static struct regulator *tsl2772_get_regulator(struct tsl2772_chip *chip,
 720                                               char *name)
 721{
 722        struct regulator *regulator;
 723        int ret;
 724
 725        regulator = devm_regulator_get(&chip->client->dev, name);
 726        if (IS_ERR(regulator)) {
 727                if (PTR_ERR(regulator) != -EPROBE_DEFER)
 728                        dev_err(&chip->client->dev,
 729                                "Failed to get %s regulator %d\n",
 730                                name, (int)PTR_ERR(regulator));
 731
 732                return regulator;
 733        }
 734
 735        ret = tsl2772_enable_regulator(chip, regulator);
 736        if (ret < 0)
 737                return ERR_PTR(ret);
 738
 739        return regulator;
 740}
 741
 742static int tsl2772_chip_on(struct iio_dev *indio_dev)
 743{
 744        struct tsl2772_chip *chip = iio_priv(indio_dev);
 745        int ret, i, als_count, als_time_us;
 746        u8 *dev_reg, reg_val;
 747
 748        /* Non calculated parameters */
 749        chip->tsl2772_config[TSL2772_ALS_TIME] = chip->settings.als_time;
 750        chip->tsl2772_config[TSL2772_PRX_TIME] = chip->settings.prox_time;
 751        chip->tsl2772_config[TSL2772_WAIT_TIME] = chip->settings.wait_time;
 752        chip->tsl2772_config[TSL2772_ALS_PRX_CONFIG] =
 753                chip->settings.als_prox_config;
 754
 755        chip->tsl2772_config[TSL2772_ALS_MINTHRESHLO] =
 756                (chip->settings.als_thresh_low) & 0xFF;
 757        chip->tsl2772_config[TSL2772_ALS_MINTHRESHHI] =
 758                (chip->settings.als_thresh_low >> 8) & 0xFF;
 759        chip->tsl2772_config[TSL2772_ALS_MAXTHRESHLO] =
 760                (chip->settings.als_thresh_high) & 0xFF;
 761        chip->tsl2772_config[TSL2772_ALS_MAXTHRESHHI] =
 762                (chip->settings.als_thresh_high >> 8) & 0xFF;
 763        chip->tsl2772_config[TSL2772_PERSISTENCE] =
 764                (chip->settings.prox_persistence & 0xFF) << 4 |
 765                (chip->settings.als_persistence & 0xFF);
 766
 767        chip->tsl2772_config[TSL2772_PRX_COUNT] =
 768                        chip->settings.prox_pulse_count;
 769        chip->tsl2772_config[TSL2772_PRX_MINTHRESHLO] =
 770                        (chip->settings.prox_thres_low) & 0xFF;
 771        chip->tsl2772_config[TSL2772_PRX_MINTHRESHHI] =
 772                        (chip->settings.prox_thres_low >> 8) & 0xFF;
 773        chip->tsl2772_config[TSL2772_PRX_MAXTHRESHLO] =
 774                        (chip->settings.prox_thres_high) & 0xFF;
 775        chip->tsl2772_config[TSL2772_PRX_MAXTHRESHHI] =
 776                        (chip->settings.prox_thres_high >> 8) & 0xFF;
 777
 778        /* and make sure we're not already on */
 779        if (chip->tsl2772_chip_status == TSL2772_CHIP_WORKING) {
 780                /* if forcing a register update - turn off, then on */
 781                dev_info(&chip->client->dev, "device is already enabled\n");
 782                return -EINVAL;
 783        }
 784
 785        /* Set the gain based on tsl2772_settings struct */
 786        chip->tsl2772_config[TSL2772_GAIN] =
 787                (chip->settings.als_gain & 0xFF) |
 788                ((chip->settings.prox_gain & 0xFF) << 2) |
 789                (chip->settings.prox_diode << 4) |
 790                (chip->settings.prox_power << 6);
 791
 792        /* set chip time scaling and saturation */
 793        als_count = 256 - chip->settings.als_time;
 794        als_time_us = als_count * tsl2772_int_time_avail[chip->id][3];
 795        chip->als_saturation = als_count * 768; /* 75% of full scale */
 796        chip->als_gain_time_scale = als_time_us *
 797                tsl2772_als_gain[chip->settings.als_gain];
 798
 799        /*
 800         * TSL2772 Specific power-on / adc enable sequence
 801         * Power on the device 1st.
 802         */
 803        ret = tsl2772_write_control_reg(chip, TSL2772_CNTL_PWR_ON);
 804        if (ret < 0)
 805                return ret;
 806
 807        /*
 808         * Use the following shadow copy for our delay before enabling ADC.
 809         * Write all the registers.
 810         */
 811        for (i = 0, dev_reg = chip->tsl2772_config;
 812                        i < TSL2772_MAX_CONFIG_REG; i++) {
 813                int reg = TSL2772_CMD_REG + i;
 814
 815                ret = i2c_smbus_write_byte_data(chip->client, reg,
 816                                                *dev_reg++);
 817                if (ret < 0) {
 818                        dev_err(&chip->client->dev,
 819                                "%s: failed to write to register %x: %d\n",
 820                                __func__, reg, ret);
 821                        return ret;
 822                }
 823        }
 824
 825        /* Power-on settling time */
 826        usleep_range(3000, 3500);
 827
 828        reg_val = TSL2772_CNTL_PWR_ON | TSL2772_CNTL_ADC_ENBL |
 829                  TSL2772_CNTL_PROX_DET_ENBL;
 830        if (chip->settings.als_interrupt_en)
 831                reg_val |= TSL2772_CNTL_ALS_INT_ENBL;
 832        if (chip->settings.prox_interrupt_en)
 833                reg_val |= TSL2772_CNTL_PROX_INT_ENBL;
 834
 835        ret = tsl2772_write_control_reg(chip, reg_val);
 836        if (ret < 0)
 837                return ret;
 838
 839        ret = i2c_smbus_write_byte(chip->client,
 840                                   TSL2772_CMD_REG | TSL2772_CMD_SPL_FN |
 841                                   TSL2772_CMD_PROXALS_INT_CLR);
 842        if (ret < 0) {
 843                dev_err(&chip->client->dev,
 844                        "%s: failed to clear interrupt status: %d\n",
 845                        __func__, ret);
 846                return ret;
 847        }
 848
 849        chip->tsl2772_chip_status = TSL2772_CHIP_WORKING;
 850
 851        return ret;
 852}
 853
 854static int tsl2772_chip_off(struct iio_dev *indio_dev)
 855{
 856        struct tsl2772_chip *chip = iio_priv(indio_dev);
 857
 858        /* turn device off */
 859        chip->tsl2772_chip_status = TSL2772_CHIP_SUSPENDED;
 860        return tsl2772_write_control_reg(chip, 0x00);
 861}
 862
 863/**
 864 * tsl2772_invoke_change - power cycle the device to implement the user
 865 *                         parameters
 866 * @indio_dev:  pointer to IIO device
 867 *
 868 * Obtain and lock both ALS and PROX resources, determine and save device state
 869 * (On/Off), cycle device to implement updated parameter, put device back into
 870 * proper state, and unlock resource.
 871 */
 872static int tsl2772_invoke_change(struct iio_dev *indio_dev)
 873{
 874        struct tsl2772_chip *chip = iio_priv(indio_dev);
 875        int device_status = chip->tsl2772_chip_status;
 876        int ret;
 877
 878        mutex_lock(&chip->als_mutex);
 879        mutex_lock(&chip->prox_mutex);
 880
 881        if (device_status == TSL2772_CHIP_WORKING) {
 882                ret = tsl2772_chip_off(indio_dev);
 883                if (ret < 0)
 884                        goto unlock;
 885        }
 886
 887        ret = tsl2772_chip_on(indio_dev);
 888
 889unlock:
 890        mutex_unlock(&chip->prox_mutex);
 891        mutex_unlock(&chip->als_mutex);
 892
 893        return ret;
 894}
 895
 896static int tsl2772_prox_cal(struct iio_dev *indio_dev)
 897{
 898        struct tsl2772_chip *chip = iio_priv(indio_dev);
 899        int prox_history[MAX_SAMPLES_CAL + 1];
 900        int i, ret, mean, max, sample_sum;
 901
 902        if (chip->settings.prox_max_samples_cal < 1 ||
 903            chip->settings.prox_max_samples_cal > MAX_SAMPLES_CAL)
 904                return -EINVAL;
 905
 906        for (i = 0; i < chip->settings.prox_max_samples_cal; i++) {
 907                usleep_range(15000, 17500);
 908                ret = tsl2772_get_prox(indio_dev);
 909                if (ret < 0)
 910                        return ret;
 911
 912                prox_history[i] = chip->prox_data;
 913        }
 914
 915        sample_sum = 0;
 916        max = INT_MIN;
 917        for (i = 0; i < chip->settings.prox_max_samples_cal; i++) {
 918                sample_sum += prox_history[i];
 919                max = max(max, prox_history[i]);
 920        }
 921        mean = sample_sum / chip->settings.prox_max_samples_cal;
 922
 923        chip->settings.prox_thres_high = (max << 1) - mean;
 924
 925        return tsl2772_invoke_change(indio_dev);
 926}
 927
 928static int tsl2772_read_avail(struct iio_dev *indio_dev,
 929                              struct iio_chan_spec const *chan,
 930                              const int **vals, int *type, int *length,
 931                              long mask)
 932{
 933        struct tsl2772_chip *chip = iio_priv(indio_dev);
 934
 935        switch (mask) {
 936        case IIO_CHAN_INFO_CALIBSCALE:
 937                if (chan->type == IIO_INTENSITY) {
 938                        *length = ARRAY_SIZE(tsl2772_int_calibscale_avail);
 939                        *vals = tsl2772_int_calibscale_avail;
 940                } else {
 941                        *length = ARRAY_SIZE(tsl2772_prox_calibscale_avail);
 942                        *vals = tsl2772_prox_calibscale_avail;
 943                }
 944                *type = IIO_VAL_INT;
 945                return IIO_AVAIL_LIST;
 946        case IIO_CHAN_INFO_INT_TIME:
 947                *length = ARRAY_SIZE(tsl2772_int_time_avail[chip->id]);
 948                *vals = tsl2772_int_time_avail[chip->id];
 949                *type = IIO_VAL_INT_PLUS_MICRO;
 950                return IIO_AVAIL_RANGE;
 951        }
 952
 953        return -EINVAL;
 954}
 955
 956static ssize_t in_illuminance0_target_input_show(struct device *dev,
 957                                                 struct device_attribute *attr,
 958                                                 char *buf)
 959{
 960        struct tsl2772_chip *chip = iio_priv(dev_to_iio_dev(dev));
 961
 962        return snprintf(buf, PAGE_SIZE, "%d\n", chip->settings.als_cal_target);
 963}
 964
 965static ssize_t in_illuminance0_target_input_store(struct device *dev,
 966                                                  struct device_attribute *attr,
 967                                                  const char *buf, size_t len)
 968{
 969        struct iio_dev *indio_dev = dev_to_iio_dev(dev);
 970        struct tsl2772_chip *chip = iio_priv(indio_dev);
 971        u16 value;
 972        int ret;
 973
 974        if (kstrtou16(buf, 0, &value))
 975                return -EINVAL;
 976
 977        chip->settings.als_cal_target = value;
 978        ret = tsl2772_invoke_change(indio_dev);
 979        if (ret < 0)
 980                return ret;
 981
 982        return len;
 983}
 984
 985static ssize_t in_illuminance0_calibrate_store(struct device *dev,
 986                                               struct device_attribute *attr,
 987                                               const char *buf, size_t len)
 988{
 989        struct iio_dev *indio_dev = dev_to_iio_dev(dev);
 990        bool value;
 991        int ret;
 992
 993        if (kstrtobool(buf, &value) || !value)
 994                return -EINVAL;
 995
 996        ret = tsl2772_als_calibrate(indio_dev);
 997        if (ret < 0)
 998                return ret;
 999
1000        ret = tsl2772_invoke_change(indio_dev);
1001        if (ret < 0)
1002                return ret;
1003
1004        return len;
1005}
1006
1007static ssize_t in_illuminance0_lux_table_show(struct device *dev,
1008                                              struct device_attribute *attr,
1009                                              char *buf)
1010{
1011        struct tsl2772_chip *chip = iio_priv(dev_to_iio_dev(dev));
1012        int i = 0;
1013        int offset = 0;
1014
1015        while (i < TSL2772_MAX_LUX_TABLE_SIZE) {
1016                offset += snprintf(buf + offset, PAGE_SIZE, "%u,%u,",
1017                        chip->tsl2772_device_lux[i].ch0,
1018                        chip->tsl2772_device_lux[i].ch1);
1019                if (chip->tsl2772_device_lux[i].ch0 == 0) {
1020                        /*
1021                         * We just printed the first "0" entry.
1022                         * Now get rid of the extra "," and break.
1023                         */
1024                        offset--;
1025                        break;
1026                }
1027                i++;
1028        }
1029
1030        offset += snprintf(buf + offset, PAGE_SIZE, "\n");
1031        return offset;
1032}
1033
1034static ssize_t in_illuminance0_lux_table_store(struct device *dev,
1035                                               struct device_attribute *attr,
1036                                               const char *buf, size_t len)
1037{
1038        struct iio_dev *indio_dev = dev_to_iio_dev(dev);
1039        struct tsl2772_chip *chip = iio_priv(indio_dev);
1040        int value[ARRAY_SIZE(chip->tsl2772_device_lux) * 2 + 1];
1041        int n, ret;
1042
1043        get_options(buf, ARRAY_SIZE(value), value);
1044
1045        /*
1046         * We now have an array of ints starting at value[1], and
1047         * enumerated by value[0].
1048         * We expect each group of two ints to be one table entry,
1049         * and the last table entry is all 0.
1050         */
1051        n = value[0];
1052        if ((n % 2) || n < 4 ||
1053            n > ((ARRAY_SIZE(chip->tsl2772_device_lux) - 1) * 2))
1054                return -EINVAL;
1055
1056        if ((value[(n - 1)] | value[n]) != 0)
1057                return -EINVAL;
1058
1059        if (chip->tsl2772_chip_status == TSL2772_CHIP_WORKING) {
1060                ret = tsl2772_chip_off(indio_dev);
1061                if (ret < 0)
1062                        return ret;
1063        }
1064
1065        /* Zero out the table */
1066        memset(chip->tsl2772_device_lux, 0, sizeof(chip->tsl2772_device_lux));
1067        memcpy(chip->tsl2772_device_lux, &value[1], (value[0] * 4));
1068
1069        ret = tsl2772_invoke_change(indio_dev);
1070        if (ret < 0)
1071                return ret;
1072
1073        return len;
1074}
1075
1076static ssize_t in_proximity0_calibrate_store(struct device *dev,
1077                                             struct device_attribute *attr,
1078                                             const char *buf, size_t len)
1079{
1080        struct iio_dev *indio_dev = dev_to_iio_dev(dev);
1081        bool value;
1082        int ret;
1083
1084        if (kstrtobool(buf, &value) || !value)
1085                return -EINVAL;
1086
1087        ret = tsl2772_prox_cal(indio_dev);
1088        if (ret < 0)
1089                return ret;
1090
1091        ret = tsl2772_invoke_change(indio_dev);
1092        if (ret < 0)
1093                return ret;
1094
1095        return len;
1096}
1097
1098static int tsl2772_read_interrupt_config(struct iio_dev *indio_dev,
1099                                         const struct iio_chan_spec *chan,
1100                                         enum iio_event_type type,
1101                                         enum iio_event_direction dir)
1102{
1103        struct tsl2772_chip *chip = iio_priv(indio_dev);
1104
1105        if (chan->type == IIO_INTENSITY)
1106                return chip->settings.als_interrupt_en;
1107        else
1108                return chip->settings.prox_interrupt_en;
1109}
1110
1111static int tsl2772_write_interrupt_config(struct iio_dev *indio_dev,
1112                                          const struct iio_chan_spec *chan,
1113                                          enum iio_event_type type,
1114                                          enum iio_event_direction dir,
1115                                          int val)
1116{
1117        struct tsl2772_chip *chip = iio_priv(indio_dev);
1118
1119        if (chan->type == IIO_INTENSITY)
1120                chip->settings.als_interrupt_en = val ? true : false;
1121        else
1122                chip->settings.prox_interrupt_en = val ? true : false;
1123
1124        return tsl2772_invoke_change(indio_dev);
1125}
1126
1127static int tsl2772_write_event_value(struct iio_dev *indio_dev,
1128                                     const struct iio_chan_spec *chan,
1129                                     enum iio_event_type type,
1130                                     enum iio_event_direction dir,
1131                                     enum iio_event_info info,
1132                                     int val, int val2)
1133{
1134        struct tsl2772_chip *chip = iio_priv(indio_dev);
1135        int ret = -EINVAL, count, persistence;
1136        u8 time;
1137
1138        switch (info) {
1139        case IIO_EV_INFO_VALUE:
1140                if (chan->type == IIO_INTENSITY) {
1141                        switch (dir) {
1142                        case IIO_EV_DIR_RISING:
1143                                chip->settings.als_thresh_high = val;
1144                                ret = 0;
1145                                break;
1146                        case IIO_EV_DIR_FALLING:
1147                                chip->settings.als_thresh_low = val;
1148                                ret = 0;
1149                                break;
1150                        default:
1151                                break;
1152                        }
1153                } else {
1154                        switch (dir) {
1155                        case IIO_EV_DIR_RISING:
1156                                chip->settings.prox_thres_high = val;
1157                                ret = 0;
1158                                break;
1159                        case IIO_EV_DIR_FALLING:
1160                                chip->settings.prox_thres_low = val;
1161                                ret = 0;
1162                                break;
1163                        default:
1164                                break;
1165                        }
1166                }
1167                break;
1168        case IIO_EV_INFO_PERIOD:
1169                if (chan->type == IIO_INTENSITY)
1170                        time = chip->settings.als_time;
1171                else
1172                        time = chip->settings.prox_time;
1173
1174                count = 256 - time;
1175                persistence = ((val * 1000000) + val2) /
1176                        (count * tsl2772_int_time_avail[chip->id][3]);
1177
1178                if (chan->type == IIO_INTENSITY) {
1179                        /* ALS filter values are 1, 2, 3, 5, 10, 15, ..., 60 */
1180                        if (persistence > 3)
1181                                persistence = (persistence / 5) + 3;
1182
1183                        chip->settings.als_persistence = persistence;
1184                } else {
1185                        chip->settings.prox_persistence = persistence;
1186                }
1187
1188                ret = 0;
1189                break;
1190        default:
1191                break;
1192        }
1193
1194        if (ret < 0)
1195                return ret;
1196
1197        return tsl2772_invoke_change(indio_dev);
1198}
1199
1200static int tsl2772_read_event_value(struct iio_dev *indio_dev,
1201                                    const struct iio_chan_spec *chan,
1202                                    enum iio_event_type type,
1203                                    enum iio_event_direction dir,
1204                                    enum iio_event_info info,
1205                                    int *val, int *val2)
1206{
1207        struct tsl2772_chip *chip = iio_priv(indio_dev);
1208        int filter_delay, persistence;
1209        u8 time;
1210
1211        switch (info) {
1212        case IIO_EV_INFO_VALUE:
1213                if (chan->type == IIO_INTENSITY) {
1214                        switch (dir) {
1215                        case IIO_EV_DIR_RISING:
1216                                *val = chip->settings.als_thresh_high;
1217                                return IIO_VAL_INT;
1218                        case IIO_EV_DIR_FALLING:
1219                                *val = chip->settings.als_thresh_low;
1220                                return IIO_VAL_INT;
1221                        default:
1222                                return -EINVAL;
1223                        }
1224                } else {
1225                        switch (dir) {
1226                        case IIO_EV_DIR_RISING:
1227                                *val = chip->settings.prox_thres_high;
1228                                return IIO_VAL_INT;
1229                        case IIO_EV_DIR_FALLING:
1230                                *val = chip->settings.prox_thres_low;
1231                                return IIO_VAL_INT;
1232                        default:
1233                                return -EINVAL;
1234                        }
1235                }
1236                break;
1237        case IIO_EV_INFO_PERIOD:
1238                if (chan->type == IIO_INTENSITY) {
1239                        time = chip->settings.als_time;
1240                        persistence = chip->settings.als_persistence;
1241
1242                        /* ALS filter values are 1, 2, 3, 5, 10, 15, ..., 60 */
1243                        if (persistence > 3)
1244                                persistence = (persistence - 3) * 5;
1245                } else {
1246                        time = chip->settings.prox_time;
1247                        persistence = chip->settings.prox_persistence;
1248                }
1249
1250                filter_delay = persistence * (256 - time) *
1251                        tsl2772_int_time_avail[chip->id][3];
1252
1253                *val = filter_delay / 1000000;
1254                *val2 = filter_delay % 1000000;
1255                return IIO_VAL_INT_PLUS_MICRO;
1256        default:
1257                return -EINVAL;
1258        }
1259}
1260
1261static int tsl2772_read_raw(struct iio_dev *indio_dev,
1262                            struct iio_chan_spec const *chan,
1263                            int *val,
1264                            int *val2,
1265                            long mask)
1266{
1267        struct tsl2772_chip *chip = iio_priv(indio_dev);
1268
1269        switch (mask) {
1270        case IIO_CHAN_INFO_PROCESSED:
1271                switch (chan->type) {
1272                case IIO_LIGHT:
1273                        tsl2772_get_lux(indio_dev);
1274                        *val = chip->als_cur_info.lux;
1275                        return IIO_VAL_INT;
1276                default:
1277                        return -EINVAL;
1278                }
1279        case IIO_CHAN_INFO_RAW:
1280                switch (chan->type) {
1281                case IIO_INTENSITY:
1282                        tsl2772_get_lux(indio_dev);
1283                        if (chan->channel == 0)
1284                                *val = chip->als_cur_info.als_ch0;
1285                        else
1286                                *val = chip->als_cur_info.als_ch1;
1287                        return IIO_VAL_INT;
1288                case IIO_PROXIMITY:
1289                        tsl2772_get_prox(indio_dev);
1290                        *val = chip->prox_data;
1291                        return IIO_VAL_INT;
1292                default:
1293                        return -EINVAL;
1294                }
1295                break;
1296        case IIO_CHAN_INFO_CALIBSCALE:
1297                if (chan->type == IIO_LIGHT)
1298                        *val = tsl2772_als_gain[chip->settings.als_gain];
1299                else
1300                        *val = tsl2772_prox_gain[chip->settings.prox_gain];
1301                return IIO_VAL_INT;
1302        case IIO_CHAN_INFO_CALIBBIAS:
1303                *val = chip->settings.als_gain_trim;
1304                return IIO_VAL_INT;
1305        case IIO_CHAN_INFO_INT_TIME:
1306                *val = 0;
1307                *val2 = (256 - chip->settings.als_time) *
1308                        tsl2772_int_time_avail[chip->id][3];
1309                return IIO_VAL_INT_PLUS_MICRO;
1310        default:
1311                return -EINVAL;
1312        }
1313}
1314
1315static int tsl2772_write_raw(struct iio_dev *indio_dev,
1316                             struct iio_chan_spec const *chan,
1317                             int val,
1318                             int val2,
1319                             long mask)
1320{
1321        struct tsl2772_chip *chip = iio_priv(indio_dev);
1322
1323        switch (mask) {
1324        case IIO_CHAN_INFO_CALIBSCALE:
1325                if (chan->type == IIO_INTENSITY) {
1326                        switch (val) {
1327                        case 1:
1328                                chip->settings.als_gain = 0;
1329                                break;
1330                        case 8:
1331                                chip->settings.als_gain = 1;
1332                                break;
1333                        case 16:
1334                                chip->settings.als_gain = 2;
1335                                break;
1336                        case 120:
1337                                chip->settings.als_gain = 3;
1338                                break;
1339                        default:
1340                                return -EINVAL;
1341                        }
1342                } else {
1343                        switch (val) {
1344                        case 1:
1345                                chip->settings.prox_gain = 0;
1346                                break;
1347                        case 2:
1348                                chip->settings.prox_gain = 1;
1349                                break;
1350                        case 4:
1351                                chip->settings.prox_gain = 2;
1352                                break;
1353                        case 8:
1354                                chip->settings.prox_gain = 3;
1355                                break;
1356                        default:
1357                                return -EINVAL;
1358                        }
1359                }
1360                break;
1361        case IIO_CHAN_INFO_CALIBBIAS:
1362                if (val < TSL2772_ALS_GAIN_TRIM_MIN ||
1363                    val > TSL2772_ALS_GAIN_TRIM_MAX)
1364                        return -EINVAL;
1365
1366                chip->settings.als_gain_trim = val;
1367                break;
1368        case IIO_CHAN_INFO_INT_TIME:
1369                if (val != 0 || val2 < tsl2772_int_time_avail[chip->id][1] ||
1370                    val2 > tsl2772_int_time_avail[chip->id][5])
1371                        return -EINVAL;
1372
1373                chip->settings.als_time = 256 -
1374                        (val2 / tsl2772_int_time_avail[chip->id][3]);
1375                break;
1376        default:
1377                return -EINVAL;
1378        }
1379
1380        return tsl2772_invoke_change(indio_dev);
1381}
1382
1383static DEVICE_ATTR_RW(in_illuminance0_target_input);
1384
1385static DEVICE_ATTR_WO(in_illuminance0_calibrate);
1386
1387static DEVICE_ATTR_WO(in_proximity0_calibrate);
1388
1389static DEVICE_ATTR_RW(in_illuminance0_lux_table);
1390
1391/* Use the default register values to identify the Taos device */
1392static int tsl2772_device_id_verif(int id, int target)
1393{
1394        switch (target) {
1395        case tsl2571:
1396        case tsl2671:
1397        case tsl2771:
1398                return (id & 0xf0) == TRITON_ID;
1399        case tmd2671:
1400        case tmd2771:
1401                return (id & 0xf0) == HALIBUT_ID;
1402        case tsl2572:
1403        case tsl2672:
1404        case tmd2672:
1405        case tsl2772:
1406        case tmd2772:
1407        case apds9930:
1408                return (id & 0xf0) == SWORDFISH_ID;
1409        }
1410
1411        return -EINVAL;
1412}
1413
1414static irqreturn_t tsl2772_event_handler(int irq, void *private)
1415{
1416        struct iio_dev *indio_dev = private;
1417        struct tsl2772_chip *chip = iio_priv(indio_dev);
1418        s64 timestamp = iio_get_time_ns(indio_dev);
1419        int ret;
1420
1421        ret = tsl2772_read_status(chip);
1422        if (ret < 0)
1423                return IRQ_HANDLED;
1424
1425        /* What type of interrupt do we need to process */
1426        if (ret & TSL2772_STA_PRX_INTR) {
1427                iio_push_event(indio_dev,
1428                               IIO_UNMOD_EVENT_CODE(IIO_PROXIMITY,
1429                                                    0,
1430                                                    IIO_EV_TYPE_THRESH,
1431                                                    IIO_EV_DIR_EITHER),
1432                               timestamp);
1433        }
1434
1435        if (ret & TSL2772_STA_ALS_INTR) {
1436                iio_push_event(indio_dev,
1437                               IIO_UNMOD_EVENT_CODE(IIO_LIGHT,
1438                                                    0,
1439                                                    IIO_EV_TYPE_THRESH,
1440                                                    IIO_EV_DIR_EITHER),
1441                               timestamp);
1442        }
1443
1444        ret = i2c_smbus_write_byte(chip->client,
1445                                   TSL2772_CMD_REG | TSL2772_CMD_SPL_FN |
1446                                   TSL2772_CMD_PROXALS_INT_CLR);
1447        if (ret < 0)
1448                dev_err(&chip->client->dev,
1449                        "%s: failed to clear interrupt status: %d\n",
1450                        __func__, ret);
1451
1452        return IRQ_HANDLED;
1453}
1454
1455static struct attribute *tsl2772_ALS_device_attrs[] = {
1456        &dev_attr_in_illuminance0_target_input.attr,
1457        &dev_attr_in_illuminance0_calibrate.attr,
1458        &dev_attr_in_illuminance0_lux_table.attr,
1459        NULL
1460};
1461
1462static struct attribute *tsl2772_PRX_device_attrs[] = {
1463        &dev_attr_in_proximity0_calibrate.attr,
1464        NULL
1465};
1466
1467static struct attribute *tsl2772_ALSPRX_device_attrs[] = {
1468        &dev_attr_in_illuminance0_target_input.attr,
1469        &dev_attr_in_illuminance0_calibrate.attr,
1470        &dev_attr_in_illuminance0_lux_table.attr,
1471        NULL
1472};
1473
1474static struct attribute *tsl2772_PRX2_device_attrs[] = {
1475        &dev_attr_in_proximity0_calibrate.attr,
1476        NULL
1477};
1478
1479static struct attribute *tsl2772_ALSPRX2_device_attrs[] = {
1480        &dev_attr_in_illuminance0_target_input.attr,
1481        &dev_attr_in_illuminance0_calibrate.attr,
1482        &dev_attr_in_illuminance0_lux_table.attr,
1483        &dev_attr_in_proximity0_calibrate.attr,
1484        NULL
1485};
1486
1487static const struct attribute_group tsl2772_device_attr_group_tbl[] = {
1488        [ALS] = {
1489                .attrs = tsl2772_ALS_device_attrs,
1490        },
1491        [PRX] = {
1492                .attrs = tsl2772_PRX_device_attrs,
1493        },
1494        [ALSPRX] = {
1495                .attrs = tsl2772_ALSPRX_device_attrs,
1496        },
1497        [PRX2] = {
1498                .attrs = tsl2772_PRX2_device_attrs,
1499        },
1500        [ALSPRX2] = {
1501                .attrs = tsl2772_ALSPRX2_device_attrs,
1502        },
1503};
1504
1505#define TSL2772_DEVICE_INFO(type)[type] = \
1506        { \
1507                .attrs = &tsl2772_device_attr_group_tbl[type], \
1508                .read_raw = &tsl2772_read_raw, \
1509                .read_avail = &tsl2772_read_avail, \
1510                .write_raw = &tsl2772_write_raw, \
1511                .read_event_value = &tsl2772_read_event_value, \
1512                .write_event_value = &tsl2772_write_event_value, \
1513                .read_event_config = &tsl2772_read_interrupt_config, \
1514                .write_event_config = &tsl2772_write_interrupt_config, \
1515        }
1516
1517static const struct iio_info tsl2772_device_info[] = {
1518        TSL2772_DEVICE_INFO(ALS),
1519        TSL2772_DEVICE_INFO(PRX),
1520        TSL2772_DEVICE_INFO(ALSPRX),
1521        TSL2772_DEVICE_INFO(PRX2),
1522        TSL2772_DEVICE_INFO(ALSPRX2),
1523};
1524
1525static const struct iio_event_spec tsl2772_events[] = {
1526        {
1527                .type = IIO_EV_TYPE_THRESH,
1528                .dir = IIO_EV_DIR_RISING,
1529                .mask_separate = BIT(IIO_EV_INFO_VALUE),
1530        }, {
1531                .type = IIO_EV_TYPE_THRESH,
1532                .dir = IIO_EV_DIR_FALLING,
1533                .mask_separate = BIT(IIO_EV_INFO_VALUE),
1534        }, {
1535                .type = IIO_EV_TYPE_THRESH,
1536                .dir = IIO_EV_DIR_EITHER,
1537                .mask_separate = BIT(IIO_EV_INFO_PERIOD) |
1538                        BIT(IIO_EV_INFO_ENABLE),
1539        },
1540};
1541
1542static const struct tsl2772_chip_info tsl2772_chip_info_tbl[] = {
1543        [ALS] = {
1544                .channel_with_events = {
1545                        {
1546                        .type = IIO_LIGHT,
1547                        .indexed = 1,
1548                        .channel = 0,
1549                        .info_mask_separate = BIT(IIO_CHAN_INFO_PROCESSED),
1550                        }, {
1551                        .type = IIO_INTENSITY,
1552                        .indexed = 1,
1553                        .channel = 0,
1554                        .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
1555                                BIT(IIO_CHAN_INFO_INT_TIME) |
1556                                BIT(IIO_CHAN_INFO_CALIBSCALE) |
1557                                BIT(IIO_CHAN_INFO_CALIBBIAS),
1558                        .info_mask_separate_available =
1559                                BIT(IIO_CHAN_INFO_INT_TIME) |
1560                                BIT(IIO_CHAN_INFO_CALIBSCALE),
1561                        .event_spec = tsl2772_events,
1562                        .num_event_specs = ARRAY_SIZE(tsl2772_events),
1563                        }, {
1564                        .type = IIO_INTENSITY,
1565                        .indexed = 1,
1566                        .channel = 1,
1567                        },
1568                },
1569                .channel_without_events = {
1570                        {
1571                        .type = IIO_LIGHT,
1572                        .indexed = 1,
1573                        .channel = 0,
1574                        .info_mask_separate = BIT(IIO_CHAN_INFO_PROCESSED),
1575                        }, {
1576                        .type = IIO_INTENSITY,
1577                        .indexed = 1,
1578                        .channel = 0,
1579                        .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
1580                                BIT(IIO_CHAN_INFO_INT_TIME) |
1581                                BIT(IIO_CHAN_INFO_CALIBSCALE) |
1582                                BIT(IIO_CHAN_INFO_CALIBBIAS),
1583                        .info_mask_separate_available =
1584                                BIT(IIO_CHAN_INFO_INT_TIME) |
1585                                BIT(IIO_CHAN_INFO_CALIBSCALE),
1586                        }, {
1587                        .type = IIO_INTENSITY,
1588                        .indexed = 1,
1589                        .channel = 1,
1590                        },
1591                },
1592                .chan_table_elements = 3,
1593                .info = &tsl2772_device_info[ALS],
1594        },
1595        [PRX] = {
1596                .channel_with_events = {
1597                        {
1598                        .type = IIO_PROXIMITY,
1599                        .indexed = 1,
1600                        .channel = 0,
1601                        .info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
1602                        .event_spec = tsl2772_events,
1603                        .num_event_specs = ARRAY_SIZE(tsl2772_events),
1604                        },
1605                },
1606                .channel_without_events = {
1607                        {
1608                        .type = IIO_PROXIMITY,
1609                        .indexed = 1,
1610                        .channel = 0,
1611                        .info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
1612                        },
1613                },
1614                .chan_table_elements = 1,
1615                .info = &tsl2772_device_info[PRX],
1616        },
1617        [ALSPRX] = {
1618                .channel_with_events = {
1619                        {
1620                        .type = IIO_LIGHT,
1621                        .indexed = 1,
1622                        .channel = 0,
1623                        .info_mask_separate = BIT(IIO_CHAN_INFO_PROCESSED),
1624                        }, {
1625                        .type = IIO_INTENSITY,
1626                        .indexed = 1,
1627                        .channel = 0,
1628                        .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
1629                                BIT(IIO_CHAN_INFO_INT_TIME) |
1630                                BIT(IIO_CHAN_INFO_CALIBSCALE) |
1631                                BIT(IIO_CHAN_INFO_CALIBBIAS),
1632                        .info_mask_separate_available =
1633                                BIT(IIO_CHAN_INFO_INT_TIME) |
1634                                BIT(IIO_CHAN_INFO_CALIBSCALE),
1635                        .event_spec = tsl2772_events,
1636                        .num_event_specs = ARRAY_SIZE(tsl2772_events),
1637                        }, {
1638                        .type = IIO_INTENSITY,
1639                        .indexed = 1,
1640                        .channel = 1,
1641                        .info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
1642                        }, {
1643                        .type = IIO_PROXIMITY,
1644                        .indexed = 1,
1645                        .channel = 0,
1646                        .info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
1647                        .event_spec = tsl2772_events,
1648                        .num_event_specs = ARRAY_SIZE(tsl2772_events),
1649                        },
1650                },
1651                .channel_without_events = {
1652                        {
1653                        .type = IIO_LIGHT,
1654                        .indexed = 1,
1655                        .channel = 0,
1656                        .info_mask_separate = BIT(IIO_CHAN_INFO_PROCESSED),
1657                        }, {
1658                        .type = IIO_INTENSITY,
1659                        .indexed = 1,
1660                        .channel = 0,
1661                        .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
1662                                BIT(IIO_CHAN_INFO_INT_TIME) |
1663                                BIT(IIO_CHAN_INFO_CALIBSCALE) |
1664                                BIT(IIO_CHAN_INFO_CALIBBIAS),
1665                        .info_mask_separate_available =
1666                                BIT(IIO_CHAN_INFO_INT_TIME) |
1667                                BIT(IIO_CHAN_INFO_CALIBSCALE),
1668                        }, {
1669                        .type = IIO_INTENSITY,
1670                        .indexed = 1,
1671                        .channel = 1,
1672                        .info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
1673                        }, {
1674                        .type = IIO_PROXIMITY,
1675                        .indexed = 1,
1676                        .channel = 0,
1677                        .info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
1678                        },
1679                },
1680                .chan_table_elements = 4,
1681                .info = &tsl2772_device_info[ALSPRX],
1682        },
1683        [PRX2] = {
1684                .channel_with_events = {
1685                        {
1686                        .type = IIO_PROXIMITY,
1687                        .indexed = 1,
1688                        .channel = 0,
1689                        .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
1690                                BIT(IIO_CHAN_INFO_CALIBSCALE),
1691                        .info_mask_separate_available =
1692                                BIT(IIO_CHAN_INFO_CALIBSCALE),
1693                        .event_spec = tsl2772_events,
1694                        .num_event_specs = ARRAY_SIZE(tsl2772_events),
1695                        },
1696                },
1697                .channel_without_events = {
1698                        {
1699                        .type = IIO_PROXIMITY,
1700                        .indexed = 1,
1701                        .channel = 0,
1702                        .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
1703                                BIT(IIO_CHAN_INFO_CALIBSCALE),
1704                        .info_mask_separate_available =
1705                                BIT(IIO_CHAN_INFO_CALIBSCALE),
1706                        },
1707                },
1708                .chan_table_elements = 1,
1709                .info = &tsl2772_device_info[PRX2],
1710        },
1711        [ALSPRX2] = {
1712                .channel_with_events = {
1713                        {
1714                        .type = IIO_LIGHT,
1715                        .indexed = 1,
1716                        .channel = 0,
1717                        .info_mask_separate = BIT(IIO_CHAN_INFO_PROCESSED),
1718                        }, {
1719                        .type = IIO_INTENSITY,
1720                        .indexed = 1,
1721                        .channel = 0,
1722                        .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
1723                                BIT(IIO_CHAN_INFO_INT_TIME) |
1724                                BIT(IIO_CHAN_INFO_CALIBSCALE) |
1725                                BIT(IIO_CHAN_INFO_CALIBBIAS),
1726                        .info_mask_separate_available =
1727                                BIT(IIO_CHAN_INFO_INT_TIME) |
1728                                BIT(IIO_CHAN_INFO_CALIBSCALE),
1729                        .event_spec = tsl2772_events,
1730                        .num_event_specs = ARRAY_SIZE(tsl2772_events),
1731                        }, {
1732                        .type = IIO_INTENSITY,
1733                        .indexed = 1,
1734                        .channel = 1,
1735                        .info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
1736                        }, {
1737                        .type = IIO_PROXIMITY,
1738                        .indexed = 1,
1739                        .channel = 0,
1740                        .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
1741                                BIT(IIO_CHAN_INFO_CALIBSCALE),
1742                        .info_mask_separate_available =
1743                                BIT(IIO_CHAN_INFO_CALIBSCALE),
1744                        .event_spec = tsl2772_events,
1745                        .num_event_specs = ARRAY_SIZE(tsl2772_events),
1746                        },
1747                },
1748                .channel_without_events = {
1749                        {
1750                        .type = IIO_LIGHT,
1751                        .indexed = 1,
1752                        .channel = 0,
1753                        .info_mask_separate = BIT(IIO_CHAN_INFO_PROCESSED),
1754                        }, {
1755                        .type = IIO_INTENSITY,
1756                        .indexed = 1,
1757                        .channel = 0,
1758                        .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
1759                                BIT(IIO_CHAN_INFO_INT_TIME) |
1760                                BIT(IIO_CHAN_INFO_CALIBSCALE) |
1761                                BIT(IIO_CHAN_INFO_CALIBBIAS),
1762                        .info_mask_separate_available =
1763                                BIT(IIO_CHAN_INFO_INT_TIME) |
1764                                BIT(IIO_CHAN_INFO_CALIBSCALE),
1765                        }, {
1766                        .type = IIO_INTENSITY,
1767                        .indexed = 1,
1768                        .channel = 1,
1769                        .info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
1770                        }, {
1771                        .type = IIO_PROXIMITY,
1772                        .indexed = 1,
1773                        .channel = 0,
1774                        .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
1775                                BIT(IIO_CHAN_INFO_CALIBSCALE),
1776                        .info_mask_separate_available =
1777                                BIT(IIO_CHAN_INFO_CALIBSCALE),
1778                        },
1779                },
1780                .chan_table_elements = 4,
1781                .info = &tsl2772_device_info[ALSPRX2],
1782        },
1783};
1784
1785static int tsl2772_probe(struct i2c_client *clientp,
1786                         const struct i2c_device_id *id)
1787{
1788        struct iio_dev *indio_dev;
1789        struct tsl2772_chip *chip;
1790        int ret;
1791
1792        indio_dev = devm_iio_device_alloc(&clientp->dev, sizeof(*chip));
1793        if (!indio_dev)
1794                return -ENOMEM;
1795
1796        chip = iio_priv(indio_dev);
1797        chip->client = clientp;
1798        i2c_set_clientdata(clientp, indio_dev);
1799
1800        chip->vddio_supply = tsl2772_get_regulator(chip, "vddio");
1801        if (IS_ERR(chip->vddio_supply))
1802                return PTR_ERR(chip->vddio_supply);
1803
1804        chip->vdd_supply = tsl2772_get_regulator(chip, "vdd");
1805        if (IS_ERR(chip->vdd_supply)) {
1806                regulator_disable(chip->vddio_supply);
1807                return PTR_ERR(chip->vdd_supply);
1808        }
1809
1810        ret = devm_add_action(&clientp->dev, tsl2772_disable_regulators_action,
1811                              chip);
1812        if (ret < 0) {
1813                tsl2772_disable_regulators_action(chip);
1814                dev_err(&clientp->dev, "Failed to setup regulator cleanup action %d\n",
1815                        ret);
1816                return ret;
1817        }
1818
1819        usleep_range(TSL2772_BOOT_MIN_SLEEP_TIME, TSL2772_BOOT_MAX_SLEEP_TIME);
1820
1821        ret = i2c_smbus_read_byte_data(chip->client,
1822                                       TSL2772_CMD_REG | TSL2772_CHIPID);
1823        if (ret < 0)
1824                return ret;
1825
1826        if (tsl2772_device_id_verif(ret, id->driver_data) <= 0) {
1827                dev_info(&chip->client->dev,
1828                         "%s: i2c device found does not match expected id\n",
1829                                __func__);
1830                return -EINVAL;
1831        }
1832
1833        ret = i2c_smbus_write_byte(clientp, TSL2772_CMD_REG | TSL2772_CNTRL);
1834        if (ret < 0) {
1835                dev_err(&clientp->dev,
1836                        "%s: Failed to write to CMD register: %d\n",
1837                        __func__, ret);
1838                return ret;
1839        }
1840
1841        mutex_init(&chip->als_mutex);
1842        mutex_init(&chip->prox_mutex);
1843
1844        chip->tsl2772_chip_status = TSL2772_CHIP_UNKNOWN;
1845        chip->pdata = dev_get_platdata(&clientp->dev);
1846        chip->id = id->driver_data;
1847        chip->chip_info =
1848                &tsl2772_chip_info_tbl[device_channel_config[id->driver_data]];
1849
1850        indio_dev->info = chip->chip_info->info;
1851        indio_dev->dev.parent = &clientp->dev;
1852        indio_dev->modes = INDIO_DIRECT_MODE;
1853        indio_dev->name = chip->client->name;
1854        indio_dev->num_channels = chip->chip_info->chan_table_elements;
1855
1856        if (clientp->irq) {
1857                indio_dev->channels = chip->chip_info->channel_with_events;
1858
1859                ret = devm_request_threaded_irq(&clientp->dev, clientp->irq,
1860                                                NULL,
1861                                                &tsl2772_event_handler,
1862                                                IRQF_TRIGGER_FALLING |
1863                                                IRQF_ONESHOT,
1864                                                "TSL2772_event",
1865                                                indio_dev);
1866                if (ret) {
1867                        dev_err(&clientp->dev,
1868                                "%s: irq request failed\n", __func__);
1869                        return ret;
1870                }
1871        } else {
1872                indio_dev->channels = chip->chip_info->channel_without_events;
1873        }
1874
1875        tsl2772_defaults(chip);
1876        ret = tsl2772_chip_on(indio_dev);
1877        if (ret < 0)
1878                return ret;
1879
1880        ret = iio_device_register(indio_dev);
1881        if (ret) {
1882                tsl2772_chip_off(indio_dev);
1883                dev_err(&clientp->dev,
1884                        "%s: iio registration failed\n", __func__);
1885                return ret;
1886        }
1887
1888        return 0;
1889}
1890
1891static int tsl2772_suspend(struct device *dev)
1892{
1893        struct iio_dev *indio_dev = dev_get_drvdata(dev);
1894        struct tsl2772_chip *chip = iio_priv(indio_dev);
1895        int ret;
1896
1897        ret = tsl2772_chip_off(indio_dev);
1898        regulator_disable(chip->vdd_supply);
1899        regulator_disable(chip->vddio_supply);
1900
1901        return ret;
1902}
1903
1904static int tsl2772_resume(struct device *dev)
1905{
1906        struct iio_dev *indio_dev = dev_get_drvdata(dev);
1907        struct tsl2772_chip *chip = iio_priv(indio_dev);
1908        int ret;
1909
1910        ret = tsl2772_enable_regulator(chip, chip->vddio_supply);
1911        if (ret < 0)
1912                return ret;
1913
1914        ret = tsl2772_enable_regulator(chip, chip->vdd_supply);
1915        if (ret < 0) {
1916                regulator_disable(chip->vddio_supply);
1917                return ret;
1918        }
1919
1920        usleep_range(TSL2772_BOOT_MIN_SLEEP_TIME, TSL2772_BOOT_MAX_SLEEP_TIME);
1921
1922        return tsl2772_chip_on(indio_dev);
1923}
1924
1925static int tsl2772_remove(struct i2c_client *client)
1926{
1927        struct iio_dev *indio_dev = i2c_get_clientdata(client);
1928
1929        tsl2772_chip_off(indio_dev);
1930
1931        iio_device_unregister(indio_dev);
1932
1933        return 0;
1934}
1935
1936static const struct i2c_device_id tsl2772_idtable[] = {
1937        { "tsl2571", tsl2571 },
1938        { "tsl2671", tsl2671 },
1939        { "tmd2671", tmd2671 },
1940        { "tsl2771", tsl2771 },
1941        { "tmd2771", tmd2771 },
1942        { "tsl2572", tsl2572 },
1943        { "tsl2672", tsl2672 },
1944        { "tmd2672", tmd2672 },
1945        { "tsl2772", tsl2772 },
1946        { "tmd2772", tmd2772 },
1947        { "apds9930", apds9930},
1948        {}
1949};
1950
1951MODULE_DEVICE_TABLE(i2c, tsl2772_idtable);
1952
1953static const struct of_device_id tsl2772_of_match[] = {
1954        { .compatible = "amstaos,tsl2571" },
1955        { .compatible = "amstaos,tsl2671" },
1956        { .compatible = "amstaos,tmd2671" },
1957        { .compatible = "amstaos,tsl2771" },
1958        { .compatible = "amstaos,tmd2771" },
1959        { .compatible = "amstaos,tsl2572" },
1960        { .compatible = "amstaos,tsl2672" },
1961        { .compatible = "amstaos,tmd2672" },
1962        { .compatible = "amstaos,tsl2772" },
1963        { .compatible = "amstaos,tmd2772" },
1964        { .compatible = "avago,apds9930" },
1965        {}
1966};
1967MODULE_DEVICE_TABLE(of, tsl2772_of_match);
1968
1969static const struct dev_pm_ops tsl2772_pm_ops = {
1970        .suspend = tsl2772_suspend,
1971        .resume  = tsl2772_resume,
1972};
1973
1974static struct i2c_driver tsl2772_driver = {
1975        .driver = {
1976                .name = "tsl2772",
1977                .of_match_table = tsl2772_of_match,
1978                .pm = &tsl2772_pm_ops,
1979        },
1980        .id_table = tsl2772_idtable,
1981        .probe = tsl2772_probe,
1982        .remove = tsl2772_remove,
1983};
1984
1985module_i2c_driver(tsl2772_driver);
1986
1987MODULE_AUTHOR("J. August Brenner <Jon.Brenner@ams.com>");
1988MODULE_AUTHOR("Brian Masney <masneyb@onstation.org>");
1989MODULE_DESCRIPTION("TAOS tsl2772 ambient and proximity light sensor driver");
1990MODULE_LICENSE("GPL");
1991