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