linux/drivers/staging/iio/light/tsl2x7x_core.c
<<
>>
Prefs
   1/*
   2 * Device driver for monitoring ambient light intensity in (lux)
   3 * and proximity detection (prox) within the TAOS TSL2X7X family of devices.
   4 *
   5 * Copyright (c) 2012, TAOS Corporation.
   6 *
   7 * This program is free software; you can redistribute it and/or modify
   8 * it under the terms of the GNU General Public License as published by
   9 * the Free Software Foundation; either version 2 of the License, or
  10 * (at your option) any later version.
  11 *
  12 * This program is distributed in the hope that it will be useful, but WITHOUT
  13 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  14 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
  15 * more details.
  16 *
  17 * You should have received a copy of the GNU General Public License along
  18 * with this program; if not, write to the Free Software Foundation, Inc.,
  19 * 51 Franklin Street, Fifth Floor, Boston, MA        02110-1301, USA.
  20 */
  21
  22#include <linux/kernel.h>
  23#include <linux/i2c.h>
  24#include <linux/errno.h>
  25#include <linux/delay.h>
  26#include <linux/mutex.h>
  27#include <linux/interrupt.h>
  28#include <linux/slab.h>
  29#include <linux/module.h>
  30#include <linux/iio/events.h>
  31#include <linux/iio/iio.h>
  32#include <linux/iio/sysfs.h>
  33#include "tsl2x7x.h"
  34
  35/* Cal defs*/
  36#define PROX_STAT_CAL        0
  37#define PROX_STAT_SAMP       1
  38#define MAX_SAMPLES_CAL      200
  39
  40/* TSL2X7X Device ID */
  41#define TRITON_ID    0x00
  42#define SWORDFISH_ID 0x30
  43#define HALIBUT_ID   0x20
  44
  45/* Lux calculation constants */
  46#define TSL2X7X_LUX_CALC_OVER_FLOW     65535
  47
  48/* TAOS Register definitions - note:
  49 * depending on device, some of these register are not used and the
  50 * register address is benign.
  51 */
  52/* 2X7X register offsets */
  53#define TSL2X7X_MAX_CONFIG_REG         16
  54
  55/* Device Registers and Masks */
  56#define TSL2X7X_CNTRL                  0x00
  57#define TSL2X7X_ALS_TIME               0X01
  58#define TSL2X7X_PRX_TIME               0x02
  59#define TSL2X7X_WAIT_TIME              0x03
  60#define TSL2X7X_ALS_MINTHRESHLO        0X04
  61#define TSL2X7X_ALS_MINTHRESHHI        0X05
  62#define TSL2X7X_ALS_MAXTHRESHLO        0X06
  63#define TSL2X7X_ALS_MAXTHRESHHI        0X07
  64#define TSL2X7X_PRX_MINTHRESHLO        0X08
  65#define TSL2X7X_PRX_MINTHRESHHI        0X09
  66#define TSL2X7X_PRX_MAXTHRESHLO        0X0A
  67#define TSL2X7X_PRX_MAXTHRESHHI        0X0B
  68#define TSL2X7X_PERSISTENCE            0x0C
  69#define TSL2X7X_PRX_CONFIG             0x0D
  70#define TSL2X7X_PRX_COUNT              0x0E
  71#define TSL2X7X_GAIN                   0x0F
  72#define TSL2X7X_NOTUSED                0x10
  73#define TSL2X7X_REVID                  0x11
  74#define TSL2X7X_CHIPID                 0x12
  75#define TSL2X7X_STATUS                 0x13
  76#define TSL2X7X_ALS_CHAN0LO            0x14
  77#define TSL2X7X_ALS_CHAN0HI            0x15
  78#define TSL2X7X_ALS_CHAN1LO            0x16
  79#define TSL2X7X_ALS_CHAN1HI            0x17
  80#define TSL2X7X_PRX_LO                 0x18
  81#define TSL2X7X_PRX_HI                 0x19
  82
  83/* tsl2X7X cmd reg masks */
  84#define TSL2X7X_CMD_REG                0x80
  85#define TSL2X7X_CMD_SPL_FN             0x60
  86
  87#define TSL2X7X_CMD_PROX_INT_CLR       0X05
  88#define TSL2X7X_CMD_ALS_INT_CLR        0x06
  89#define TSL2X7X_CMD_PROXALS_INT_CLR    0X07
  90
  91/* tsl2X7X cntrl reg masks */
  92#define TSL2X7X_CNTL_ADC_ENBL          0x02
  93#define TSL2X7X_CNTL_PWR_ON            0x01
  94
  95/* tsl2X7X status reg masks */
  96#define TSL2X7X_STA_ADC_VALID          0x01
  97#define TSL2X7X_STA_PRX_VALID          0x02
  98#define TSL2X7X_STA_ADC_PRX_VALID      (TSL2X7X_STA_ADC_VALID |\
  99                                        TSL2X7X_STA_PRX_VALID)
 100#define TSL2X7X_STA_ALS_INTR           0x10
 101#define TSL2X7X_STA_PRX_INTR           0x20
 102
 103/* tsl2X7X cntrl reg masks */
 104#define TSL2X7X_CNTL_REG_CLEAR         0x00
 105#define TSL2X7X_CNTL_PROX_INT_ENBL     0X20
 106#define TSL2X7X_CNTL_ALS_INT_ENBL      0X10
 107#define TSL2X7X_CNTL_WAIT_TMR_ENBL     0X08
 108#define TSL2X7X_CNTL_PROX_DET_ENBL     0X04
 109#define TSL2X7X_CNTL_PWRON             0x01
 110#define TSL2X7X_CNTL_ALSPON_ENBL       0x03
 111#define TSL2X7X_CNTL_INTALSPON_ENBL    0x13
 112#define TSL2X7X_CNTL_PROXPON_ENBL      0x0F
 113#define TSL2X7X_CNTL_INTPROXPON_ENBL   0x2F
 114
 115/*Prox diode to use */
 116#define TSL2X7X_DIODE0                 0x10
 117#define TSL2X7X_DIODE1                 0x20
 118#define TSL2X7X_DIODE_BOTH             0x30
 119
 120/* LED Power */
 121#define TSL2X7X_mA100                  0x00
 122#define TSL2X7X_mA50                   0x40
 123#define TSL2X7X_mA25                   0x80
 124#define TSL2X7X_mA13                   0xD0
 125#define TSL2X7X_MAX_TIMER_CNT          (0xFF)
 126
 127/*Common device IIO EventMask */
 128#define TSL2X7X_EVENT_MASK \
 129                (IIO_EV_BIT(IIO_EV_TYPE_THRESH, IIO_EV_DIR_RISING) | \
 130                IIO_EV_BIT(IIO_EV_TYPE_THRESH, IIO_EV_DIR_FALLING)),
 131
 132#define TSL2X7X_MIN_ITIME 3
 133
 134/* TAOS txx2x7x Device family members */
 135enum {
 136        tsl2571,
 137        tsl2671,
 138        tmd2671,
 139        tsl2771,
 140        tmd2771,
 141        tsl2572,
 142        tsl2672,
 143        tmd2672,
 144        tsl2772,
 145        tmd2772
 146};
 147
 148enum {
 149        TSL2X7X_CHIP_UNKNOWN = 0,
 150        TSL2X7X_CHIP_WORKING = 1,
 151        TSL2X7X_CHIP_SUSPENDED = 2
 152};
 153
 154struct tsl2x7x_parse_result {
 155        int integer;
 156        int fract;
 157};
 158
 159/* Per-device data */
 160struct tsl2x7x_als_info {
 161        u16 als_ch0;
 162        u16 als_ch1;
 163        u16 lux;
 164};
 165
 166struct tsl2x7x_prox_stat {
 167        int min;
 168        int max;
 169        int mean;
 170        unsigned long stddev;
 171};
 172
 173struct tsl2x7x_chip_info {
 174        int chan_table_elements;
 175        struct iio_chan_spec            channel[4];
 176        const struct iio_info           *info;
 177};
 178
 179struct tsl2X7X_chip {
 180        kernel_ulong_t id;
 181        struct mutex prox_mutex;
 182        struct mutex als_mutex;
 183        struct i2c_client *client;
 184        u16 prox_data;
 185        struct tsl2x7x_als_info als_cur_info;
 186        struct tsl2x7x_settings tsl2x7x_settings;
 187        struct tsl2X7X_platform_data *pdata;
 188        int als_time_scale;
 189        int als_saturation;
 190        int tsl2x7x_chip_status;
 191        u8 tsl2x7x_config[TSL2X7X_MAX_CONFIG_REG];
 192        const struct tsl2x7x_chip_info  *chip_info;
 193        const struct iio_info *info;
 194        s64 event_timestamp;
 195        /* This structure is intentionally large to accommodate
 196         * updates via sysfs. */
 197        /* Sized to 9 = max 8 segments + 1 termination segment */
 198        struct tsl2x7x_lux tsl2x7x_device_lux[TSL2X7X_MAX_LUX_TABLE_SIZE];
 199};
 200
 201/* Different devices require different coefficents */
 202static const struct tsl2x7x_lux tsl2x71_lux_table[] = {
 203        { 14461,   611,   1211 },
 204        { 18540,   352,    623 },
 205        {     0,     0,      0 },
 206};
 207
 208static const struct tsl2x7x_lux tmd2x71_lux_table[] = {
 209        { 11635,   115,    256 },
 210        { 15536,    87,    179 },
 211        {     0,     0,      0 },
 212};
 213
 214static const struct tsl2x7x_lux tsl2x72_lux_table[] = {
 215        { 14013,   466,   917 },
 216        { 18222,   310,   552 },
 217        {     0,     0,     0 },
 218};
 219
 220static const struct tsl2x7x_lux tmd2x72_lux_table[] = {
 221        { 13218,   130,   262 },
 222        { 17592,   92,    169 },
 223        {     0,     0,     0 },
 224};
 225
 226static const struct tsl2x7x_lux *tsl2x7x_default_lux_table_group[] = {
 227        [tsl2571] =     tsl2x71_lux_table,
 228        [tsl2671] =     tsl2x71_lux_table,
 229        [tmd2671] =     tmd2x71_lux_table,
 230        [tsl2771] =     tsl2x71_lux_table,
 231        [tmd2771] =     tmd2x71_lux_table,
 232        [tsl2572] =     tsl2x72_lux_table,
 233        [tsl2672] =     tsl2x72_lux_table,
 234        [tmd2672] =     tmd2x72_lux_table,
 235        [tsl2772] =     tsl2x72_lux_table,
 236        [tmd2772] =     tmd2x72_lux_table,
 237};
 238
 239static const struct tsl2x7x_settings tsl2x7x_default_settings = {
 240        .als_time = 219, /* 101 ms */
 241        .als_gain = 0,
 242        .prx_time = 254, /* 5.4 ms */
 243        .prox_gain = 1,
 244        .wait_time = 245,
 245        .prox_config = 0,
 246        .als_gain_trim = 1000,
 247        .als_cal_target = 150,
 248        .als_thresh_low = 200,
 249        .als_thresh_high = 256,
 250        .persistence = 255,
 251        .interrupts_en = 0,
 252        .prox_thres_low  = 0,
 253        .prox_thres_high = 512,
 254        .prox_max_samples_cal = 30,
 255        .prox_pulse_count = 8
 256};
 257
 258static const s16 tsl2X7X_als_gainadj[] = {
 259        1,
 260        8,
 261        16,
 262        120
 263};
 264
 265static const s16 tsl2X7X_prx_gainadj[] = {
 266        1,
 267        2,
 268        4,
 269        8
 270};
 271
 272/* Channel variations */
 273enum {
 274        ALS,
 275        PRX,
 276        ALSPRX,
 277        PRX2,
 278        ALSPRX2,
 279};
 280
 281static const u8 device_channel_config[] = {
 282        ALS,
 283        PRX,
 284        PRX,
 285        ALSPRX,
 286        ALSPRX,
 287        ALS,
 288        PRX2,
 289        PRX2,
 290        ALSPRX2,
 291        ALSPRX2
 292};
 293
 294/**
 295 * tsl2x7x_i2c_read() - Read a byte from a register.
 296 * @client:     i2c client
 297 * @reg:        device register to read from
 298 * @*val:       pointer to location to store register contents.
 299 *
 300 */
 301static int
 302tsl2x7x_i2c_read(struct i2c_client *client, u8 reg, u8 *val)
 303{
 304        int ret = 0;
 305
 306        /* select register to write */
 307        ret = i2c_smbus_write_byte(client, (TSL2X7X_CMD_REG | reg));
 308        if (ret < 0) {
 309                dev_err(&client->dev, "%s: failed to write register %x\n"
 310                                , __func__, reg);
 311                return ret;
 312        }
 313
 314        /* read the data */
 315        ret = i2c_smbus_read_byte(client);
 316        if (ret >= 0)
 317                *val = (u8)ret;
 318        else
 319                dev_err(&client->dev, "%s: failed to read register %x\n"
 320                                                , __func__, reg);
 321
 322        return ret;
 323}
 324
 325/**
 326 * tsl2x7x_get_lux() - Reads and calculates current lux value.
 327 * @indio_dev:  pointer to IIO device
 328 *
 329 * The raw ch0 and ch1 values of the ambient light sensed in the last
 330 * integration cycle are read from the device.
 331 * Time scale factor array values are adjusted based on the integration time.
 332 * The raw values are multiplied by a scale factor, and device gain is obtained
 333 * using gain index. Limit checks are done next, then the ratio of a multiple
 334 * of ch1 value, to the ch0 value, is calculated. Array tsl2x7x_device_lux[]
 335 * is then scanned to find the first ratio value that is just above the ratio
 336 * we just calculated. The ch0 and ch1 multiplier constants in the array are
 337 * then used along with the time scale factor array values, to calculate the
 338 * lux.
 339 */
 340static int tsl2x7x_get_lux(struct iio_dev *indio_dev)
 341{
 342        u16 ch0, ch1; /* separated ch0/ch1 data from device */
 343        u32 lux; /* raw lux calculated from device data */
 344        u64 lux64;
 345        u32 ratio;
 346        u8 buf[4];
 347        struct tsl2x7x_lux *p;
 348        struct tsl2X7X_chip *chip = iio_priv(indio_dev);
 349        int i, ret;
 350        u32 ch0lux = 0;
 351        u32 ch1lux = 0;
 352
 353        if (mutex_trylock(&chip->als_mutex) == 0)
 354                return chip->als_cur_info.lux; /* busy, so return LAST VALUE */
 355
 356        if (chip->tsl2x7x_chip_status != TSL2X7X_CHIP_WORKING) {
 357                /* device is not enabled */
 358                dev_err(&chip->client->dev, "%s: device is not enabled\n",
 359                                __func__);
 360                ret = -EBUSY ;
 361                goto out_unlock;
 362        }
 363
 364        ret = tsl2x7x_i2c_read(chip->client,
 365                (TSL2X7X_CMD_REG | TSL2X7X_STATUS), &buf[0]);
 366        if (ret < 0) {
 367                dev_err(&chip->client->dev,
 368                        "%s: Failed to read STATUS Reg\n", __func__);
 369                goto out_unlock;
 370        }
 371        /* is data new & valid */
 372        if (!(buf[0] & TSL2X7X_STA_ADC_VALID)) {
 373                dev_err(&chip->client->dev,
 374                        "%s: data not valid yet\n", __func__);
 375                ret = chip->als_cur_info.lux; /* return LAST VALUE */
 376                goto out_unlock;
 377        }
 378
 379        for (i = 0; i < 4; i++) {
 380                ret = tsl2x7x_i2c_read(chip->client,
 381                        (TSL2X7X_CMD_REG | (TSL2X7X_ALS_CHAN0LO + i)),
 382                        &buf[i]);
 383                if (ret < 0) {
 384                        dev_err(&chip->client->dev,
 385                                "%s: failed to read. err=%x\n", __func__, ret);
 386                        goto out_unlock;
 387                }
 388        }
 389
 390        /* clear any existing interrupt status */
 391        ret = i2c_smbus_write_byte(chip->client,
 392                (TSL2X7X_CMD_REG |
 393                                TSL2X7X_CMD_SPL_FN |
 394                                TSL2X7X_CMD_ALS_INT_CLR));
 395        if (ret < 0) {
 396                dev_err(&chip->client->dev,
 397                "%s: i2c_write_command failed - err = %d\n",
 398                        __func__, ret);
 399                goto out_unlock; /* have no data, so return failure */
 400        }
 401
 402        /* extract ALS/lux data */
 403        ch0 = le16_to_cpup((const __le16 *)&buf[0]);
 404        ch1 = le16_to_cpup((const __le16 *)&buf[2]);
 405
 406        chip->als_cur_info.als_ch0 = ch0;
 407        chip->als_cur_info.als_ch1 = ch1;
 408
 409        if ((ch0 >= chip->als_saturation) || (ch1 >= chip->als_saturation)) {
 410                lux = TSL2X7X_LUX_CALC_OVER_FLOW;
 411                goto return_max;
 412        }
 413
 414        if (ch0 == 0) {
 415                /* have no data, so return LAST VALUE */
 416                ret = chip->als_cur_info.lux;
 417                goto out_unlock;
 418        }
 419        /* calculate ratio */
 420        ratio = (ch1 << 15) / ch0;
 421        /* convert to unscaled lux using the pointer to the table */
 422        p = (struct tsl2x7x_lux *) chip->tsl2x7x_device_lux;
 423        while (p->ratio != 0 && p->ratio < ratio)
 424                p++;
 425
 426        if (p->ratio == 0) {
 427                lux = 0;
 428        } else {
 429                ch0lux = DIV_ROUND_UP((ch0 * p->ch0),
 430                        tsl2X7X_als_gainadj[chip->tsl2x7x_settings.als_gain]);
 431                ch1lux = DIV_ROUND_UP((ch1 * p->ch1),
 432                        tsl2X7X_als_gainadj[chip->tsl2x7x_settings.als_gain]);
 433                lux = ch0lux - ch1lux;
 434        }
 435
 436        /* note: lux is 31 bit max at this point */
 437        if (ch1lux > ch0lux) {
 438                dev_dbg(&chip->client->dev, "ch1lux > ch0lux-return last value\n");
 439                ret = chip->als_cur_info.lux;
 440                goto out_unlock;
 441        }
 442
 443        /* adjust for active time scale */
 444        if (chip->als_time_scale == 0)
 445                lux = 0;
 446        else
 447                lux = (lux + (chip->als_time_scale >> 1)) /
 448                        chip->als_time_scale;
 449
 450        /* adjust for active gain scale
 451         * The tsl2x7x_device_lux tables have a factor of 256 built-in.
 452         * User-specified gain provides a multiplier.
 453         * Apply user-specified gain before shifting right to retain precision.
 454         * Use 64 bits to avoid overflow on multiplication.
 455         * Then go back to 32 bits before division to avoid using div_u64().
 456         */
 457
 458        lux64 = lux;
 459        lux64 = lux64 * chip->tsl2x7x_settings.als_gain_trim;
 460        lux64 >>= 8;
 461        lux = lux64;
 462        lux = (lux + 500) / 1000;
 463
 464        if (lux > TSL2X7X_LUX_CALC_OVER_FLOW) /* check for overflow */
 465                lux = TSL2X7X_LUX_CALC_OVER_FLOW;
 466
 467        /* Update the structure with the latest lux. */
 468return_max:
 469        chip->als_cur_info.lux = lux;
 470        ret = lux;
 471
 472out_unlock:
 473        mutex_unlock(&chip->als_mutex);
 474
 475        return ret;
 476}
 477
 478/**
 479 * tsl2x7x_get_prox() - Reads proximity data registers and updates
 480 *                      chip->prox_data.
 481 *
 482 * @indio_dev:  pointer to IIO device
 483 */
 484static int tsl2x7x_get_prox(struct iio_dev *indio_dev)
 485{
 486        int i;
 487        int ret;
 488        u8 status;
 489        u8 chdata[2];
 490        struct tsl2X7X_chip *chip = iio_priv(indio_dev);
 491
 492        if (mutex_trylock(&chip->prox_mutex) == 0) {
 493                dev_err(&chip->client->dev,
 494                        "%s: Can't get prox mutex\n", __func__);
 495                return -EBUSY;
 496        }
 497
 498        ret = tsl2x7x_i2c_read(chip->client,
 499                (TSL2X7X_CMD_REG | TSL2X7X_STATUS), &status);
 500        if (ret < 0) {
 501                dev_err(&chip->client->dev,
 502                "%s: i2c err=%d\n", __func__, ret);
 503                goto prox_poll_err;
 504        }
 505
 506        switch (chip->id) {
 507        case tsl2571:
 508        case tsl2671:
 509        case tmd2671:
 510        case tsl2771:
 511        case tmd2771:
 512                if (!(status & TSL2X7X_STA_ADC_VALID))
 513                        goto prox_poll_err;
 514        break;
 515        case tsl2572:
 516        case tsl2672:
 517        case tmd2672:
 518        case tsl2772:
 519        case tmd2772:
 520                if (!(status & TSL2X7X_STA_PRX_VALID))
 521                        goto prox_poll_err;
 522        break;
 523        }
 524
 525        for (i = 0; i < 2; i++) {
 526                ret = tsl2x7x_i2c_read(chip->client,
 527                        (TSL2X7X_CMD_REG |
 528                                        (TSL2X7X_PRX_LO + i)), &chdata[i]);
 529                if (ret < 0)
 530                        goto prox_poll_err;
 531        }
 532
 533        chip->prox_data =
 534                        le16_to_cpup((const __le16 *)&chdata[0]);
 535
 536prox_poll_err:
 537
 538        mutex_unlock(&chip->prox_mutex);
 539
 540        return chip->prox_data;
 541}
 542
 543/**
 544 * tsl2x7x_defaults() - Populates the device nominal operating parameters
 545 *                      with those provided by a 'platform' data struct or
 546 *                      with prefined defaults.
 547 *
 548 * @chip:               pointer to device structure.
 549 */
 550static void tsl2x7x_defaults(struct tsl2X7X_chip *chip)
 551{
 552        /* If Operational settings defined elsewhere.. */
 553        if (chip->pdata && chip->pdata->platform_default_settings != 0)
 554                memcpy(&(chip->tsl2x7x_settings),
 555                        chip->pdata->platform_default_settings,
 556                        sizeof(tsl2x7x_default_settings));
 557        else
 558                memcpy(&(chip->tsl2x7x_settings),
 559                        &tsl2x7x_default_settings,
 560                        sizeof(tsl2x7x_default_settings));
 561
 562        /* Load up the proper lux table. */
 563        if (chip->pdata && chip->pdata->platform_lux_table[0].ratio != 0)
 564                memcpy(chip->tsl2x7x_device_lux,
 565                        chip->pdata->platform_lux_table,
 566                        sizeof(chip->pdata->platform_lux_table));
 567        else
 568                memcpy(chip->tsl2x7x_device_lux,
 569                (struct tsl2x7x_lux *)tsl2x7x_default_lux_table_group[chip->id],
 570                                MAX_DEFAULT_TABLE_BYTES);
 571}
 572
 573/**
 574 * tsl2x7x_als_calibrate() -    Obtain single reading and calculate
 575 *                              the als_gain_trim.
 576 *
 577 * @indio_dev:  pointer to IIO device
 578 */
 579static int tsl2x7x_als_calibrate(struct iio_dev *indio_dev)
 580{
 581        struct tsl2X7X_chip *chip = iio_priv(indio_dev);
 582        u8 reg_val;
 583        int gain_trim_val;
 584        int ret;
 585        int lux_val;
 586
 587        ret = i2c_smbus_write_byte(chip->client,
 588                        (TSL2X7X_CMD_REG | TSL2X7X_CNTRL));
 589        if (ret < 0) {
 590                dev_err(&chip->client->dev,
 591                "%s: failed to write CNTRL register, ret=%d\n",
 592                __func__, ret);
 593                return ret;
 594        }
 595
 596        reg_val = i2c_smbus_read_byte(chip->client);
 597        if ((reg_val & (TSL2X7X_CNTL_ADC_ENBL | TSL2X7X_CNTL_PWR_ON))
 598                != (TSL2X7X_CNTL_ADC_ENBL | TSL2X7X_CNTL_PWR_ON)) {
 599                dev_err(&chip->client->dev,
 600                        "%s: failed: ADC not enabled\n", __func__);
 601                return -1;
 602        }
 603
 604        ret = i2c_smbus_write_byte(chip->client,
 605                        (TSL2X7X_CMD_REG | TSL2X7X_CNTRL));
 606        if (ret < 0) {
 607                dev_err(&chip->client->dev,
 608                        "%s: failed to write ctrl reg: ret=%d\n",
 609                        __func__, ret);
 610                return ret;
 611        }
 612
 613        reg_val = i2c_smbus_read_byte(chip->client);
 614        if ((reg_val & TSL2X7X_STA_ADC_VALID) != TSL2X7X_STA_ADC_VALID) {
 615                dev_err(&chip->client->dev,
 616                        "%s: failed: STATUS - ADC not valid.\n", __func__);
 617                return -ENODATA;
 618        }
 619
 620        lux_val = tsl2x7x_get_lux(indio_dev);
 621        if (lux_val < 0) {
 622                dev_err(&chip->client->dev,
 623                "%s: failed to get lux\n", __func__);
 624                return lux_val;
 625        }
 626
 627        gain_trim_val =  (((chip->tsl2x7x_settings.als_cal_target)
 628                        * chip->tsl2x7x_settings.als_gain_trim) / lux_val);
 629        if ((gain_trim_val < 250) || (gain_trim_val > 4000))
 630                return -ERANGE;
 631
 632        chip->tsl2x7x_settings.als_gain_trim = gain_trim_val;
 633        dev_info(&chip->client->dev,
 634                "%s als_calibrate completed\n", chip->client->name);
 635
 636        return (int) gain_trim_val;
 637}
 638
 639static int tsl2x7x_chip_on(struct iio_dev *indio_dev)
 640{
 641        int i;
 642        int ret = 0;
 643        u8 *dev_reg;
 644        u8 utmp;
 645        int als_count;
 646        int als_time;
 647        struct tsl2X7X_chip *chip = iio_priv(indio_dev);
 648        u8 reg_val = 0;
 649
 650        if (chip->pdata && chip->pdata->power_on)
 651                chip->pdata->power_on(indio_dev);
 652
 653        /* Non calculated parameters */
 654        chip->tsl2x7x_config[TSL2X7X_PRX_TIME] =
 655                        chip->tsl2x7x_settings.prx_time;
 656        chip->tsl2x7x_config[TSL2X7X_WAIT_TIME] =
 657                        chip->tsl2x7x_settings.wait_time;
 658        chip->tsl2x7x_config[TSL2X7X_PRX_CONFIG] =
 659                        chip->tsl2x7x_settings.prox_config;
 660
 661        chip->tsl2x7x_config[TSL2X7X_ALS_MINTHRESHLO] =
 662                (chip->tsl2x7x_settings.als_thresh_low) & 0xFF;
 663        chip->tsl2x7x_config[TSL2X7X_ALS_MINTHRESHHI] =
 664                (chip->tsl2x7x_settings.als_thresh_low >> 8) & 0xFF;
 665        chip->tsl2x7x_config[TSL2X7X_ALS_MAXTHRESHLO] =
 666                (chip->tsl2x7x_settings.als_thresh_high) & 0xFF;
 667        chip->tsl2x7x_config[TSL2X7X_ALS_MAXTHRESHHI] =
 668                (chip->tsl2x7x_settings.als_thresh_high >> 8) & 0xFF;
 669        chip->tsl2x7x_config[TSL2X7X_PERSISTENCE] =
 670                chip->tsl2x7x_settings.persistence;
 671
 672        chip->tsl2x7x_config[TSL2X7X_PRX_COUNT] =
 673                        chip->tsl2x7x_settings.prox_pulse_count;
 674        chip->tsl2x7x_config[TSL2X7X_PRX_MINTHRESHLO] =
 675        chip->tsl2x7x_settings.prox_thres_low;
 676        chip->tsl2x7x_config[TSL2X7X_PRX_MAXTHRESHLO] =
 677                        chip->tsl2x7x_settings.prox_thres_high;
 678
 679        /* and make sure we're not already on */
 680        if (chip->tsl2x7x_chip_status == TSL2X7X_CHIP_WORKING) {
 681                /* if forcing a register update - turn off, then on */
 682                dev_info(&chip->client->dev, "device is already enabled\n");
 683                return -EINVAL;
 684        }
 685
 686        /* determine als integration register */
 687        als_count = (chip->tsl2x7x_settings.als_time * 100 + 135) / 270;
 688        if (als_count == 0)
 689                als_count = 1; /* ensure at least one cycle */
 690
 691        /* convert back to time (encompasses overrides) */
 692        als_time = (als_count * 27 + 5) / 10;
 693        chip->tsl2x7x_config[TSL2X7X_ALS_TIME] = 256 - als_count;
 694
 695        /* Set the gain based on tsl2x7x_settings struct */
 696        chip->tsl2x7x_config[TSL2X7X_GAIN] =
 697                (chip->tsl2x7x_settings.als_gain |
 698                        (TSL2X7X_mA100 | TSL2X7X_DIODE1)
 699                        | ((chip->tsl2x7x_settings.prox_gain) << 2));
 700
 701        /* set chip struct re scaling and saturation */
 702        chip->als_saturation = als_count * 922; /* 90% of full scale */
 703        chip->als_time_scale = (als_time + 25) / 50;
 704
 705        /* TSL2X7X Specific power-on / adc enable sequence
 706         * Power on the device 1st. */
 707        utmp = TSL2X7X_CNTL_PWR_ON;
 708        ret = i2c_smbus_write_byte_data(chip->client,
 709                TSL2X7X_CMD_REG | TSL2X7X_CNTRL, utmp);
 710        if (ret < 0) {
 711                dev_err(&chip->client->dev,
 712                        "%s: failed on CNTRL reg.\n", __func__);
 713                return ret;
 714        }
 715
 716        /* Use the following shadow copy for our delay before enabling ADC.
 717         * Write all the registers. */
 718        for (i = 0, dev_reg = chip->tsl2x7x_config;
 719                        i < TSL2X7X_MAX_CONFIG_REG; i++) {
 720                ret = i2c_smbus_write_byte_data(chip->client,
 721                                TSL2X7X_CMD_REG + i, *dev_reg++);
 722                if (ret < 0) {
 723                        dev_err(&chip->client->dev,
 724                        "%s: failed on write to reg %d.\n", __func__, i);
 725                        return ret;
 726                }
 727        }
 728
 729        mdelay(3);      /* Power-on settling time */
 730
 731        /* NOW enable the ADC
 732         * initialize the desired mode of operation */
 733        utmp = TSL2X7X_CNTL_PWR_ON |
 734                        TSL2X7X_CNTL_ADC_ENBL |
 735                        TSL2X7X_CNTL_PROX_DET_ENBL;
 736        ret = i2c_smbus_write_byte_data(chip->client,
 737                        TSL2X7X_CMD_REG | TSL2X7X_CNTRL, utmp);
 738        if (ret < 0) {
 739                dev_err(&chip->client->dev,
 740                        "%s: failed on 2nd CTRL reg.\n", __func__);
 741                return ret;
 742        }
 743
 744        chip->tsl2x7x_chip_status = TSL2X7X_CHIP_WORKING;
 745
 746        if (chip->tsl2x7x_settings.interrupts_en != 0) {
 747                dev_info(&chip->client->dev, "Setting Up Interrupt(s)\n");
 748
 749                reg_val = TSL2X7X_CNTL_PWR_ON | TSL2X7X_CNTL_ADC_ENBL;
 750                if ((chip->tsl2x7x_settings.interrupts_en == 0x20) ||
 751                        (chip->tsl2x7x_settings.interrupts_en == 0x30))
 752                        reg_val |= TSL2X7X_CNTL_PROX_DET_ENBL;
 753
 754                reg_val |= chip->tsl2x7x_settings.interrupts_en;
 755                ret = i2c_smbus_write_byte_data(chip->client,
 756                        (TSL2X7X_CMD_REG | TSL2X7X_CNTRL), reg_val);
 757                if (ret < 0)
 758                        dev_err(&chip->client->dev,
 759                                "%s: failed in tsl2x7x_IOCTL_INT_SET.\n",
 760                                __func__);
 761
 762                /* Clear out any initial interrupts  */
 763                ret = i2c_smbus_write_byte(chip->client,
 764                        TSL2X7X_CMD_REG | TSL2X7X_CMD_SPL_FN |
 765                        TSL2X7X_CMD_PROXALS_INT_CLR);
 766                if (ret < 0) {
 767                        dev_err(&chip->client->dev,
 768                                "%s: Failed to clear Int status\n",
 769                                __func__);
 770                return ret;
 771                }
 772        }
 773
 774        return ret;
 775}
 776
 777static int tsl2x7x_chip_off(struct iio_dev *indio_dev)
 778{
 779        int ret;
 780        struct tsl2X7X_chip *chip = iio_priv(indio_dev);
 781
 782        /* turn device off */
 783        chip->tsl2x7x_chip_status = TSL2X7X_CHIP_SUSPENDED;
 784
 785        ret = i2c_smbus_write_byte_data(chip->client,
 786                TSL2X7X_CMD_REG | TSL2X7X_CNTRL, 0x00);
 787
 788        if (chip->pdata && chip->pdata->power_off)
 789                chip->pdata->power_off(chip->client);
 790
 791        return ret;
 792}
 793
 794/**
 795 * tsl2x7x_invoke_change
 796 * @indio_dev:  pointer to IIO device
 797 *
 798 * Obtain and lock both ALS and PROX resources,
 799 * determine and save device state (On/Off),
 800 * cycle device to implement updated parameter,
 801 * put device back into proper state, and unlock
 802 * resource.
 803 */
 804static
 805int tsl2x7x_invoke_change(struct iio_dev *indio_dev)
 806{
 807        struct tsl2X7X_chip *chip = iio_priv(indio_dev);
 808        int device_status = chip->tsl2x7x_chip_status;
 809
 810        mutex_lock(&chip->als_mutex);
 811        mutex_lock(&chip->prox_mutex);
 812
 813        if (device_status == TSL2X7X_CHIP_WORKING)
 814                tsl2x7x_chip_off(indio_dev);
 815
 816        tsl2x7x_chip_on(indio_dev);
 817
 818        if (device_status != TSL2X7X_CHIP_WORKING)
 819                tsl2x7x_chip_off(indio_dev);
 820
 821        mutex_unlock(&chip->prox_mutex);
 822        mutex_unlock(&chip->als_mutex);
 823
 824        return 0;
 825}
 826
 827static
 828void tsl2x7x_prox_calculate(int *data, int length,
 829                struct tsl2x7x_prox_stat *statP)
 830{
 831        int i;
 832        int sample_sum;
 833        int tmp;
 834
 835        if (length == 0)
 836                length = 1;
 837
 838        sample_sum = 0;
 839        statP->min = INT_MAX;
 840        statP->max = INT_MIN;
 841        for (i = 0; i < length; i++) {
 842                sample_sum += data[i];
 843                statP->min = min(statP->min, data[i]);
 844                statP->max = max(statP->max, data[i]);
 845        }
 846
 847        statP->mean = sample_sum / length;
 848        sample_sum = 0;
 849        for (i = 0; i < length; i++) {
 850                tmp = data[i] - statP->mean;
 851                sample_sum += tmp * tmp;
 852        }
 853        statP->stddev = int_sqrt((long)sample_sum)/length;
 854}
 855
 856/**
 857 * tsl2x7x_prox_cal() - Calculates std. and sets thresholds.
 858 * @indio_dev:  pointer to IIO device
 859 *
 860 * Calculates a standard deviation based on the samples,
 861 * and sets the threshold accordingly.
 862 */
 863static void tsl2x7x_prox_cal(struct iio_dev *indio_dev)
 864{
 865        int prox_history[MAX_SAMPLES_CAL + 1];
 866        int i;
 867        struct tsl2x7x_prox_stat prox_stat_data[2];
 868        struct tsl2x7x_prox_stat *calP;
 869        struct tsl2X7X_chip *chip = iio_priv(indio_dev);
 870        u8 tmp_irq_settings;
 871        u8 current_state = chip->tsl2x7x_chip_status;
 872
 873        if (chip->tsl2x7x_settings.prox_max_samples_cal > MAX_SAMPLES_CAL) {
 874                dev_err(&chip->client->dev,
 875                        "%s: max prox samples cal is too big: %d\n",
 876                        __func__, chip->tsl2x7x_settings.prox_max_samples_cal);
 877                chip->tsl2x7x_settings.prox_max_samples_cal = MAX_SAMPLES_CAL;
 878        }
 879
 880        /* have to stop to change settings */
 881        tsl2x7x_chip_off(indio_dev);
 882
 883        /* Enable proximity detection save just in case prox not wanted yet*/
 884        tmp_irq_settings = chip->tsl2x7x_settings.interrupts_en;
 885        chip->tsl2x7x_settings.interrupts_en |= TSL2X7X_CNTL_PROX_INT_ENBL;
 886
 887        /*turn on device if not already on*/
 888        tsl2x7x_chip_on(indio_dev);
 889
 890        /*gather the samples*/
 891        for (i = 0; i < chip->tsl2x7x_settings.prox_max_samples_cal; i++) {
 892                mdelay(15);
 893                tsl2x7x_get_prox(indio_dev);
 894                prox_history[i] = chip->prox_data;
 895                dev_info(&chip->client->dev, "2 i=%d prox data= %d\n",
 896                        i, chip->prox_data);
 897        }
 898
 899        tsl2x7x_chip_off(indio_dev);
 900        calP = &prox_stat_data[PROX_STAT_CAL];
 901        tsl2x7x_prox_calculate(prox_history,
 902                chip->tsl2x7x_settings.prox_max_samples_cal, calP);
 903        chip->tsl2x7x_settings.prox_thres_high = (calP->max << 1) - calP->mean;
 904
 905        dev_info(&chip->client->dev, " cal min=%d mean=%d max=%d\n",
 906                calP->min, calP->mean, calP->max);
 907        dev_info(&chip->client->dev,
 908                "%s proximity threshold set to %d\n",
 909                chip->client->name, chip->tsl2x7x_settings.prox_thres_high);
 910
 911        /* back to the way they were */
 912        chip->tsl2x7x_settings.interrupts_en = tmp_irq_settings;
 913        if (current_state == TSL2X7X_CHIP_WORKING)
 914                tsl2x7x_chip_on(indio_dev);
 915}
 916
 917static ssize_t tsl2x7x_power_state_show(struct device *dev,
 918        struct device_attribute *attr, char *buf)
 919{
 920        struct tsl2X7X_chip *chip = iio_priv(dev_to_iio_dev(dev));
 921
 922        return snprintf(buf, PAGE_SIZE, "%d\n", chip->tsl2x7x_chip_status);
 923}
 924
 925static ssize_t tsl2x7x_power_state_store(struct device *dev,
 926        struct device_attribute *attr, const char *buf, size_t len)
 927{
 928        struct iio_dev *indio_dev = dev_to_iio_dev(dev);
 929        bool value;
 930
 931        if (strtobool(buf, &value))
 932                return -EINVAL;
 933
 934        if (value)
 935                tsl2x7x_chip_on(indio_dev);
 936        else
 937                tsl2x7x_chip_off(indio_dev);
 938
 939        return len;
 940}
 941
 942static ssize_t tsl2x7x_gain_available_show(struct device *dev,
 943        struct device_attribute *attr, char *buf)
 944{
 945        struct tsl2X7X_chip *chip = iio_priv(dev_to_iio_dev(dev));
 946
 947        switch (chip->id) {
 948        case tsl2571:
 949        case tsl2671:
 950        case tmd2671:
 951        case tsl2771:
 952        case tmd2771:
 953                return snprintf(buf, PAGE_SIZE, "%s\n", "1 8 16 128");
 954        break;
 955        }
 956
 957        return snprintf(buf, PAGE_SIZE, "%s\n", "1 8 16 120");
 958}
 959
 960static ssize_t tsl2x7x_prox_gain_available_show(struct device *dev,
 961        struct device_attribute *attr, char *buf)
 962{
 963                return snprintf(buf, PAGE_SIZE, "%s\n", "1 2 4 8");
 964}
 965
 966static ssize_t tsl2x7x_als_time_show(struct device *dev,
 967        struct device_attribute *attr, char *buf)
 968{
 969        struct tsl2X7X_chip *chip = iio_priv(dev_to_iio_dev(dev));
 970        int y, z;
 971
 972        y = (TSL2X7X_MAX_TIMER_CNT - (u8)chip->tsl2x7x_settings.als_time) + 1;
 973        z = y * TSL2X7X_MIN_ITIME;
 974        y /= 1000;
 975        z %= 1000;
 976
 977        return snprintf(buf, PAGE_SIZE, "%d.%03d\n", y, z);
 978}
 979
 980static ssize_t tsl2x7x_als_time_store(struct device *dev,
 981        struct device_attribute *attr, const char *buf, size_t len)
 982{
 983        struct iio_dev *indio_dev = dev_to_iio_dev(dev);
 984        struct tsl2X7X_chip *chip = iio_priv(indio_dev);
 985        struct tsl2x7x_parse_result result;
 986        int ret;
 987
 988        ret = iio_str_to_fixpoint(buf, 100, &result.integer, &result.fract);
 989        if (ret)
 990                return ret;
 991
 992        result.fract /= 3;
 993        chip->tsl2x7x_settings.als_time =
 994                        (TSL2X7X_MAX_TIMER_CNT - (u8)result.fract);
 995
 996        dev_info(&chip->client->dev, "%s: als time = %d",
 997                __func__, chip->tsl2x7x_settings.als_time);
 998
 999        tsl2x7x_invoke_change(indio_dev);
1000
1001        return IIO_VAL_INT_PLUS_MICRO;
1002}
1003
1004static IIO_CONST_ATTR(in_illuminance0_integration_time_available,
1005                ".00272 - .696");
1006
1007static ssize_t tsl2x7x_als_cal_target_show(struct device *dev,
1008        struct device_attribute *attr, char *buf)
1009{
1010        struct tsl2X7X_chip *chip = iio_priv(dev_to_iio_dev(dev));
1011
1012        return snprintf(buf, PAGE_SIZE, "%d\n",
1013                        chip->tsl2x7x_settings.als_cal_target);
1014}
1015
1016static ssize_t tsl2x7x_als_cal_target_store(struct device *dev,
1017        struct device_attribute *attr, const char *buf, size_t len)
1018{
1019        struct iio_dev *indio_dev = dev_to_iio_dev(dev);
1020        struct tsl2X7X_chip *chip = iio_priv(indio_dev);
1021        unsigned long value;
1022
1023        if (kstrtoul(buf, 0, &value))
1024                return -EINVAL;
1025
1026        if (value)
1027                chip->tsl2x7x_settings.als_cal_target = value;
1028
1029        tsl2x7x_invoke_change(indio_dev);
1030
1031        return len;
1032}
1033
1034/* persistence settings */
1035static ssize_t tsl2x7x_als_persistence_show(struct device *dev,
1036        struct device_attribute *attr, char *buf)
1037{
1038        struct tsl2X7X_chip *chip = iio_priv(dev_to_iio_dev(dev));
1039        int y, z, filter_delay;
1040
1041        /* Determine integration time */
1042        y = (TSL2X7X_MAX_TIMER_CNT - (u8)chip->tsl2x7x_settings.als_time) + 1;
1043        z = y * TSL2X7X_MIN_ITIME;
1044        filter_delay = z * (chip->tsl2x7x_settings.persistence & 0x0F);
1045        y = (filter_delay / 1000);
1046        z = (filter_delay % 1000);
1047
1048        return snprintf(buf, PAGE_SIZE, "%d.%03d\n", y, z);
1049}
1050
1051static ssize_t tsl2x7x_als_persistence_store(struct device *dev,
1052        struct device_attribute *attr, const char *buf, size_t len)
1053{
1054        struct iio_dev *indio_dev = dev_to_iio_dev(dev);
1055        struct tsl2X7X_chip *chip = iio_priv(indio_dev);
1056        struct tsl2x7x_parse_result result;
1057        int y, z, filter_delay;
1058        int ret;
1059
1060        ret = iio_str_to_fixpoint(buf, 100, &result.integer, &result.fract);
1061        if (ret)
1062                return ret;
1063
1064        y = (TSL2X7X_MAX_TIMER_CNT - (u8)chip->tsl2x7x_settings.als_time) + 1;
1065        z = y * TSL2X7X_MIN_ITIME;
1066
1067        filter_delay =
1068                DIV_ROUND_UP(((result.integer * 1000) + result.fract), z);
1069
1070        chip->tsl2x7x_settings.persistence &= 0xF0;
1071        chip->tsl2x7x_settings.persistence |= (filter_delay & 0x0F);
1072
1073        dev_info(&chip->client->dev, "%s: als persistence = %d",
1074                __func__, filter_delay);
1075
1076        tsl2x7x_invoke_change(indio_dev);
1077
1078        return IIO_VAL_INT_PLUS_MICRO;
1079}
1080
1081static ssize_t tsl2x7x_prox_persistence_show(struct device *dev,
1082        struct device_attribute *attr, char *buf)
1083{
1084        struct tsl2X7X_chip *chip = iio_priv(dev_to_iio_dev(dev));
1085        int y, z, filter_delay;
1086
1087        /* Determine integration time */
1088        y = (TSL2X7X_MAX_TIMER_CNT - (u8)chip->tsl2x7x_settings.prx_time) + 1;
1089        z = y * TSL2X7X_MIN_ITIME;
1090        filter_delay = z * ((chip->tsl2x7x_settings.persistence & 0xF0) >> 4);
1091        y = (filter_delay / 1000);
1092        z = (filter_delay % 1000);
1093
1094        return snprintf(buf, PAGE_SIZE, "%d.%03d\n", y, z);
1095}
1096
1097static ssize_t tsl2x7x_prox_persistence_store(struct device *dev,
1098        struct device_attribute *attr, const char *buf, size_t len)
1099{
1100        struct iio_dev *indio_dev = dev_to_iio_dev(dev);
1101        struct tsl2X7X_chip *chip = iio_priv(indio_dev);
1102        struct tsl2x7x_parse_result result;
1103        int y, z, filter_delay;
1104        int ret;
1105
1106        ret = iio_str_to_fixpoint(buf, 100, &result.integer, &result.fract);
1107        if (ret)
1108                return ret;
1109
1110        y = (TSL2X7X_MAX_TIMER_CNT - (u8)chip->tsl2x7x_settings.prx_time) + 1;
1111        z = y * TSL2X7X_MIN_ITIME;
1112
1113        filter_delay =
1114                DIV_ROUND_UP(((result.integer * 1000) + result.fract), z);
1115
1116        chip->tsl2x7x_settings.persistence &= 0x0F;
1117        chip->tsl2x7x_settings.persistence |= ((filter_delay << 4) & 0xF0);
1118
1119        dev_info(&chip->client->dev, "%s: prox persistence = %d",
1120                __func__, filter_delay);
1121
1122        tsl2x7x_invoke_change(indio_dev);
1123
1124        return IIO_VAL_INT_PLUS_MICRO;
1125}
1126
1127static ssize_t tsl2x7x_do_calibrate(struct device *dev,
1128        struct device_attribute *attr, const char *buf, size_t len)
1129{
1130        struct iio_dev *indio_dev = dev_to_iio_dev(dev);
1131        bool value;
1132
1133        if (strtobool(buf, &value))
1134                return -EINVAL;
1135
1136        if (value)
1137                tsl2x7x_als_calibrate(indio_dev);
1138
1139        tsl2x7x_invoke_change(indio_dev);
1140
1141        return len;
1142}
1143
1144static ssize_t tsl2x7x_luxtable_show(struct device *dev,
1145        struct device_attribute *attr, char *buf)
1146{
1147        struct tsl2X7X_chip *chip = iio_priv(dev_to_iio_dev(dev));
1148        int i = 0;
1149        int offset = 0;
1150
1151        while (i < (TSL2X7X_MAX_LUX_TABLE_SIZE * 3)) {
1152                offset += snprintf(buf + offset, PAGE_SIZE, "%d,%d,%d,",
1153                        chip->tsl2x7x_device_lux[i].ratio,
1154                        chip->tsl2x7x_device_lux[i].ch0,
1155                        chip->tsl2x7x_device_lux[i].ch1);
1156                if (chip->tsl2x7x_device_lux[i].ratio == 0) {
1157                        /* We just printed the first "0" entry.
1158                         * Now get rid of the extra "," and break. */
1159                        offset--;
1160                        break;
1161                }
1162                i++;
1163        }
1164
1165        offset += snprintf(buf + offset, PAGE_SIZE, "\n");
1166        return offset;
1167}
1168
1169static ssize_t tsl2x7x_luxtable_store(struct device *dev,
1170        struct device_attribute *attr, const char *buf, size_t len)
1171{
1172        struct iio_dev *indio_dev = dev_to_iio_dev(dev);
1173        struct tsl2X7X_chip *chip = iio_priv(indio_dev);
1174        int value[ARRAY_SIZE(chip->tsl2x7x_device_lux)*3 + 1];
1175        int n;
1176
1177        get_options(buf, ARRAY_SIZE(value), value);
1178
1179        /* We now have an array of ints starting at value[1], and
1180         * enumerated by value[0].
1181         * We expect each group of three ints is one table entry,
1182         * and the last table entry is all 0.
1183         */
1184        n = value[0];
1185        if ((n % 3) || n < 6 ||
1186                        n > ((ARRAY_SIZE(chip->tsl2x7x_device_lux) - 1) * 3)) {
1187                dev_info(dev, "LUX TABLE INPUT ERROR 1 Value[0]=%d\n", n);
1188                return -EINVAL;
1189        }
1190
1191        if ((value[(n - 2)] | value[(n - 1)] | value[n]) != 0) {
1192                dev_info(dev, "LUX TABLE INPUT ERROR 2 Value[0]=%d\n", n);
1193                return -EINVAL;
1194        }
1195
1196        if (chip->tsl2x7x_chip_status == TSL2X7X_CHIP_WORKING)
1197                tsl2x7x_chip_off(indio_dev);
1198
1199        /* Zero out the table */
1200        memset(chip->tsl2x7x_device_lux, 0, sizeof(chip->tsl2x7x_device_lux));
1201        memcpy(chip->tsl2x7x_device_lux, &value[1], (value[0] * 4));
1202
1203        tsl2x7x_invoke_change(indio_dev);
1204
1205        return len;
1206}
1207
1208static ssize_t tsl2x7x_do_prox_calibrate(struct device *dev,
1209        struct device_attribute *attr, const char *buf, size_t len)
1210{
1211        struct iio_dev *indio_dev = dev_to_iio_dev(dev);
1212        bool value;
1213
1214        if (strtobool(buf, &value))
1215                return -EINVAL;
1216
1217        if (value)
1218                tsl2x7x_prox_cal(indio_dev);
1219
1220        tsl2x7x_invoke_change(indio_dev);
1221
1222        return len;
1223}
1224
1225static int tsl2x7x_read_interrupt_config(struct iio_dev *indio_dev,
1226                                         u64 event_code)
1227{
1228        struct tsl2X7X_chip *chip = iio_priv(indio_dev);
1229        int ret;
1230
1231        if (IIO_EVENT_CODE_EXTRACT_CHAN_TYPE(event_code) == IIO_INTENSITY)
1232                ret = !!(chip->tsl2x7x_settings.interrupts_en & 0x10);
1233        else
1234                ret = !!(chip->tsl2x7x_settings.interrupts_en & 0x20);
1235
1236        return ret;
1237}
1238
1239static int tsl2x7x_write_interrupt_config(struct iio_dev *indio_dev,
1240                                          u64 event_code,
1241                                          int val)
1242{
1243        struct tsl2X7X_chip *chip = iio_priv(indio_dev);
1244
1245        if (IIO_EVENT_CODE_EXTRACT_CHAN_TYPE(event_code) == IIO_INTENSITY) {
1246                if (val)
1247                        chip->tsl2x7x_settings.interrupts_en |= 0x10;
1248                else
1249                        chip->tsl2x7x_settings.interrupts_en &= 0x20;
1250        } else {
1251                if (val)
1252                        chip->tsl2x7x_settings.interrupts_en |= 0x20;
1253                else
1254                        chip->tsl2x7x_settings.interrupts_en &= 0x10;
1255        }
1256
1257        tsl2x7x_invoke_change(indio_dev);
1258
1259        return 0;
1260}
1261
1262static int tsl2x7x_write_thresh(struct iio_dev *indio_dev,
1263                                  u64 event_code,
1264                                  int val)
1265{
1266        struct tsl2X7X_chip *chip = iio_priv(indio_dev);
1267
1268        if (IIO_EVENT_CODE_EXTRACT_CHAN_TYPE(event_code) == IIO_INTENSITY) {
1269                switch (IIO_EVENT_CODE_EXTRACT_DIR(event_code)) {
1270                case IIO_EV_DIR_RISING:
1271                        chip->tsl2x7x_settings.als_thresh_high = val;
1272                        break;
1273                case IIO_EV_DIR_FALLING:
1274                        chip->tsl2x7x_settings.als_thresh_low = val;
1275                        break;
1276                default:
1277                        return -EINVAL;
1278                }
1279        } else {
1280                switch (IIO_EVENT_CODE_EXTRACT_DIR(event_code)) {
1281                case IIO_EV_DIR_RISING:
1282                        chip->tsl2x7x_settings.prox_thres_high = val;
1283                        break;
1284                case IIO_EV_DIR_FALLING:
1285                        chip->tsl2x7x_settings.prox_thres_low = val;
1286                        break;
1287                default:
1288                        return -EINVAL;
1289                }
1290        }
1291
1292        tsl2x7x_invoke_change(indio_dev);
1293
1294        return 0;
1295}
1296
1297static int tsl2x7x_read_thresh(struct iio_dev *indio_dev,
1298                               u64 event_code,
1299                               int *val)
1300{
1301        struct tsl2X7X_chip *chip = iio_priv(indio_dev);
1302
1303        if (IIO_EVENT_CODE_EXTRACT_CHAN_TYPE(event_code) == IIO_INTENSITY) {
1304                switch (IIO_EVENT_CODE_EXTRACT_DIR(event_code)) {
1305                case IIO_EV_DIR_RISING:
1306                        *val = chip->tsl2x7x_settings.als_thresh_high;
1307                        break;
1308                case IIO_EV_DIR_FALLING:
1309                        *val = chip->tsl2x7x_settings.als_thresh_low;
1310                        break;
1311                default:
1312                        return -EINVAL;
1313                }
1314        } else {
1315                switch (IIO_EVENT_CODE_EXTRACT_DIR(event_code)) {
1316                case IIO_EV_DIR_RISING:
1317                        *val = chip->tsl2x7x_settings.prox_thres_high;
1318                        break;
1319                case IIO_EV_DIR_FALLING:
1320                        *val = chip->tsl2x7x_settings.prox_thres_low;
1321                        break;
1322                default:
1323                        return -EINVAL;
1324                }
1325        }
1326
1327        return 0;
1328}
1329
1330static int tsl2x7x_read_raw(struct iio_dev *indio_dev,
1331                            struct iio_chan_spec const *chan,
1332                            int *val,
1333                            int *val2,
1334                            long mask)
1335{
1336        int ret = -EINVAL;
1337        struct tsl2X7X_chip *chip = iio_priv(indio_dev);
1338
1339        switch (mask) {
1340        case IIO_CHAN_INFO_PROCESSED:
1341                switch (chan->type) {
1342                case IIO_LIGHT:
1343                        tsl2x7x_get_lux(indio_dev);
1344                        *val = chip->als_cur_info.lux;
1345                        ret = IIO_VAL_INT;
1346                        break;
1347                default:
1348                        return -EINVAL;
1349                        break;
1350                }
1351                break;
1352        case IIO_CHAN_INFO_RAW:
1353                switch (chan->type) {
1354                case IIO_INTENSITY:
1355                        tsl2x7x_get_lux(indio_dev);
1356                        if (chan->channel == 0)
1357                                *val = chip->als_cur_info.als_ch0;
1358                        else
1359                                *val = chip->als_cur_info.als_ch1;
1360                        ret = IIO_VAL_INT;
1361                        break;
1362                case IIO_PROXIMITY:
1363                        tsl2x7x_get_prox(indio_dev);
1364                        *val = chip->prox_data;
1365                        ret = IIO_VAL_INT;
1366                        break;
1367                default:
1368                        return -EINVAL;
1369                        break;
1370                }
1371                break;
1372        case IIO_CHAN_INFO_CALIBSCALE:
1373                if (chan->type == IIO_LIGHT)
1374                        *val =
1375                        tsl2X7X_als_gainadj[chip->tsl2x7x_settings.als_gain];
1376                else
1377                        *val =
1378                        tsl2X7X_prx_gainadj[chip->tsl2x7x_settings.prox_gain];
1379                ret = IIO_VAL_INT;
1380                break;
1381        case IIO_CHAN_INFO_CALIBBIAS:
1382                *val = chip->tsl2x7x_settings.als_gain_trim;
1383                ret = IIO_VAL_INT;
1384                break;
1385
1386        default:
1387                ret = -EINVAL;
1388        }
1389
1390        return ret;
1391}
1392
1393static int tsl2x7x_write_raw(struct iio_dev *indio_dev,
1394                               struct iio_chan_spec const *chan,
1395                               int val,
1396                               int val2,
1397                               long mask)
1398{
1399        struct tsl2X7X_chip *chip = iio_priv(indio_dev);
1400
1401        switch (mask) {
1402        case IIO_CHAN_INFO_CALIBSCALE:
1403                if (chan->type == IIO_INTENSITY) {
1404                        switch (val) {
1405                        case 1:
1406                                chip->tsl2x7x_settings.als_gain = 0;
1407                                break;
1408                        case 8:
1409                                chip->tsl2x7x_settings.als_gain = 1;
1410                                break;
1411                        case 16:
1412                                chip->tsl2x7x_settings.als_gain = 2;
1413                                break;
1414                        case 120:
1415                                switch (chip->id) {
1416                                case tsl2572:
1417                                case tsl2672:
1418                                case tmd2672:
1419                                case tsl2772:
1420                                case tmd2772:
1421                                        return -EINVAL;
1422                                break;
1423                                }
1424                                chip->tsl2x7x_settings.als_gain = 3;
1425                                break;
1426                        case 128:
1427                                switch (chip->id) {
1428                                case tsl2571:
1429                                case tsl2671:
1430                                case tmd2671:
1431                                case tsl2771:
1432                                case tmd2771:
1433                                        return -EINVAL;
1434                                break;
1435                                }
1436                                chip->tsl2x7x_settings.als_gain = 3;
1437                                break;
1438                        default:
1439                                return -EINVAL;
1440                        }
1441                } else {
1442                        switch (val) {
1443                        case 1:
1444                                chip->tsl2x7x_settings.prox_gain = 0;
1445                                break;
1446                        case 2:
1447                                chip->tsl2x7x_settings.prox_gain = 1;
1448                                break;
1449                        case 4:
1450                                chip->tsl2x7x_settings.prox_gain = 2;
1451                                break;
1452                        case 8:
1453                                chip->tsl2x7x_settings.prox_gain = 3;
1454                                break;
1455                        default:
1456                                return -EINVAL;
1457                        }
1458                }
1459                break;
1460        case IIO_CHAN_INFO_CALIBBIAS:
1461                chip->tsl2x7x_settings.als_gain_trim = val;
1462                break;
1463
1464        default:
1465                return -EINVAL;
1466        }
1467
1468        tsl2x7x_invoke_change(indio_dev);
1469
1470        return 0;
1471}
1472
1473static DEVICE_ATTR(power_state, S_IRUGO | S_IWUSR,
1474                tsl2x7x_power_state_show, tsl2x7x_power_state_store);
1475
1476static DEVICE_ATTR(in_proximity0_calibscale_available, S_IRUGO,
1477                tsl2x7x_prox_gain_available_show, NULL);
1478
1479static DEVICE_ATTR(in_illuminance0_calibscale_available, S_IRUGO,
1480                tsl2x7x_gain_available_show, NULL);
1481
1482static DEVICE_ATTR(in_illuminance0_integration_time, S_IRUGO | S_IWUSR,
1483                tsl2x7x_als_time_show, tsl2x7x_als_time_store);
1484
1485static DEVICE_ATTR(in_illuminance0_target_input, S_IRUGO | S_IWUSR,
1486                tsl2x7x_als_cal_target_show, tsl2x7x_als_cal_target_store);
1487
1488static DEVICE_ATTR(in_illuminance0_calibrate, S_IWUSR, NULL,
1489                tsl2x7x_do_calibrate);
1490
1491static DEVICE_ATTR(in_proximity0_calibrate, S_IWUSR, NULL,
1492                tsl2x7x_do_prox_calibrate);
1493
1494static DEVICE_ATTR(in_illuminance0_lux_table, S_IRUGO | S_IWUSR,
1495                tsl2x7x_luxtable_show, tsl2x7x_luxtable_store);
1496
1497static DEVICE_ATTR(in_intensity0_thresh_period, S_IRUGO | S_IWUSR,
1498                tsl2x7x_als_persistence_show, tsl2x7x_als_persistence_store);
1499
1500static DEVICE_ATTR(in_proximity0_thresh_period, S_IRUGO | S_IWUSR,
1501                tsl2x7x_prox_persistence_show, tsl2x7x_prox_persistence_store);
1502
1503/* Use the default register values to identify the Taos device */
1504static int tsl2x7x_device_id(unsigned char *id, int target)
1505{
1506        switch (target) {
1507        case tsl2571:
1508        case tsl2671:
1509        case tsl2771:
1510                return ((*id & 0xf0) == TRITON_ID);
1511        break;
1512        case tmd2671:
1513        case tmd2771:
1514                return ((*id & 0xf0) == HALIBUT_ID);
1515        break;
1516        case tsl2572:
1517        case tsl2672:
1518        case tmd2672:
1519        case tsl2772:
1520        case tmd2772:
1521                return ((*id & 0xf0) == SWORDFISH_ID);
1522        break;
1523        }
1524
1525        return -EINVAL;
1526}
1527
1528static irqreturn_t tsl2x7x_event_handler(int irq, void *private)
1529{
1530        struct iio_dev *indio_dev = private;
1531        struct tsl2X7X_chip *chip = iio_priv(indio_dev);
1532        s64 timestamp = iio_get_time_ns();
1533        int ret;
1534        u8 value;
1535
1536        value = i2c_smbus_read_byte_data(chip->client,
1537                TSL2X7X_CMD_REG | TSL2X7X_STATUS);
1538
1539        /* What type of interrupt do we need to process */
1540        if (value & TSL2X7X_STA_PRX_INTR) {
1541                tsl2x7x_get_prox(indio_dev); /* freshen data for ABI */
1542                iio_push_event(indio_dev,
1543                               IIO_UNMOD_EVENT_CODE(IIO_PROXIMITY,
1544                                                    0,
1545                                                    IIO_EV_TYPE_THRESH,
1546                                                    IIO_EV_DIR_EITHER),
1547                                                    timestamp);
1548        }
1549
1550        if (value & TSL2X7X_STA_ALS_INTR) {
1551                tsl2x7x_get_lux(indio_dev); /* freshen data for ABI */
1552                iio_push_event(indio_dev,
1553                       IIO_UNMOD_EVENT_CODE(IIO_LIGHT,
1554                                            0,
1555                                            IIO_EV_TYPE_THRESH,
1556                                            IIO_EV_DIR_EITHER),
1557                                            timestamp);
1558        }
1559        /* Clear interrupt now that we have handled it. */
1560        ret = i2c_smbus_write_byte(chip->client,
1561                TSL2X7X_CMD_REG | TSL2X7X_CMD_SPL_FN |
1562                TSL2X7X_CMD_PROXALS_INT_CLR);
1563        if (ret < 0)
1564                dev_err(&chip->client->dev,
1565                        "%s: Failed to clear irq from event handler. err = %d\n",
1566                        __func__, ret);
1567
1568        return IRQ_HANDLED;
1569}
1570
1571static struct attribute *tsl2x7x_ALS_device_attrs[] = {
1572        &dev_attr_power_state.attr,
1573        &dev_attr_in_illuminance0_calibscale_available.attr,
1574        &dev_attr_in_illuminance0_integration_time.attr,
1575        &iio_const_attr_in_illuminance0_integration_time_available\
1576        .dev_attr.attr,
1577        &dev_attr_in_illuminance0_target_input.attr,
1578        &dev_attr_in_illuminance0_calibrate.attr,
1579        &dev_attr_in_illuminance0_lux_table.attr,
1580        NULL
1581};
1582
1583static struct attribute *tsl2x7x_PRX_device_attrs[] = {
1584        &dev_attr_power_state.attr,
1585        &dev_attr_in_proximity0_calibrate.attr,
1586        NULL
1587};
1588
1589static struct attribute *tsl2x7x_ALSPRX_device_attrs[] = {
1590        &dev_attr_power_state.attr,
1591        &dev_attr_in_illuminance0_calibscale_available.attr,
1592        &dev_attr_in_illuminance0_integration_time.attr,
1593        &iio_const_attr_in_illuminance0_integration_time_available\
1594        .dev_attr.attr,
1595        &dev_attr_in_illuminance0_target_input.attr,
1596        &dev_attr_in_illuminance0_calibrate.attr,
1597        &dev_attr_in_illuminance0_lux_table.attr,
1598        &dev_attr_in_proximity0_calibrate.attr,
1599        NULL
1600};
1601
1602static struct attribute *tsl2x7x_PRX2_device_attrs[] = {
1603        &dev_attr_power_state.attr,
1604        &dev_attr_in_proximity0_calibrate.attr,
1605        &dev_attr_in_proximity0_calibscale_available.attr,
1606        NULL
1607};
1608
1609static struct attribute *tsl2x7x_ALSPRX2_device_attrs[] = {
1610        &dev_attr_power_state.attr,
1611        &dev_attr_in_illuminance0_calibscale_available.attr,
1612        &dev_attr_in_illuminance0_integration_time.attr,
1613        &iio_const_attr_in_illuminance0_integration_time_available\
1614        .dev_attr.attr,
1615        &dev_attr_in_illuminance0_target_input.attr,
1616        &dev_attr_in_illuminance0_calibrate.attr,
1617        &dev_attr_in_illuminance0_lux_table.attr,
1618        &dev_attr_in_proximity0_calibrate.attr,
1619        &dev_attr_in_proximity0_calibscale_available.attr,
1620        NULL
1621};
1622
1623static struct attribute *tsl2X7X_ALS_event_attrs[] = {
1624        &dev_attr_in_intensity0_thresh_period.attr,
1625        NULL,
1626};
1627static struct attribute *tsl2X7X_PRX_event_attrs[] = {
1628        &dev_attr_in_proximity0_thresh_period.attr,
1629        NULL,
1630};
1631
1632static struct attribute *tsl2X7X_ALSPRX_event_attrs[] = {
1633        &dev_attr_in_intensity0_thresh_period.attr,
1634        &dev_attr_in_proximity0_thresh_period.attr,
1635        NULL,
1636};
1637
1638static const struct attribute_group tsl2X7X_device_attr_group_tbl[] = {
1639        [ALS] = {
1640                .attrs = tsl2x7x_ALS_device_attrs,
1641        },
1642        [PRX] = {
1643                .attrs = tsl2x7x_PRX_device_attrs,
1644        },
1645        [ALSPRX] = {
1646                .attrs = tsl2x7x_ALSPRX_device_attrs,
1647        },
1648        [PRX2] = {
1649                .attrs = tsl2x7x_PRX2_device_attrs,
1650        },
1651        [ALSPRX2] = {
1652                .attrs = tsl2x7x_ALSPRX2_device_attrs,
1653        },
1654};
1655
1656static struct attribute_group tsl2X7X_event_attr_group_tbl[] = {
1657        [ALS] = {
1658                .attrs = tsl2X7X_ALS_event_attrs,
1659                .name = "events",
1660        },
1661        [PRX] = {
1662                .attrs = tsl2X7X_PRX_event_attrs,
1663                .name = "events",
1664        },
1665        [ALSPRX] = {
1666                .attrs = tsl2X7X_ALSPRX_event_attrs,
1667                .name = "events",
1668        },
1669};
1670
1671static const struct iio_info tsl2X7X_device_info[] = {
1672        [ALS] = {
1673                .attrs = &tsl2X7X_device_attr_group_tbl[ALS],
1674                .event_attrs = &tsl2X7X_event_attr_group_tbl[ALS],
1675                .driver_module = THIS_MODULE,
1676                .read_raw = &tsl2x7x_read_raw,
1677                .write_raw = &tsl2x7x_write_raw,
1678                .read_event_value = &tsl2x7x_read_thresh,
1679                .write_event_value = &tsl2x7x_write_thresh,
1680                .read_event_config = &tsl2x7x_read_interrupt_config,
1681                .write_event_config = &tsl2x7x_write_interrupt_config,
1682        },
1683        [PRX] = {
1684                .attrs = &tsl2X7X_device_attr_group_tbl[PRX],
1685                .event_attrs = &tsl2X7X_event_attr_group_tbl[PRX],
1686                .driver_module = THIS_MODULE,
1687                .read_raw = &tsl2x7x_read_raw,
1688                .write_raw = &tsl2x7x_write_raw,
1689                .read_event_value = &tsl2x7x_read_thresh,
1690                .write_event_value = &tsl2x7x_write_thresh,
1691                .read_event_config = &tsl2x7x_read_interrupt_config,
1692                .write_event_config = &tsl2x7x_write_interrupt_config,
1693        },
1694        [ALSPRX] = {
1695                .attrs = &tsl2X7X_device_attr_group_tbl[ALSPRX],
1696                .event_attrs = &tsl2X7X_event_attr_group_tbl[ALSPRX],
1697                .driver_module = THIS_MODULE,
1698                .read_raw = &tsl2x7x_read_raw,
1699                .write_raw = &tsl2x7x_write_raw,
1700                .read_event_value = &tsl2x7x_read_thresh,
1701                .write_event_value = &tsl2x7x_write_thresh,
1702                .read_event_config = &tsl2x7x_read_interrupt_config,
1703                .write_event_config = &tsl2x7x_write_interrupt_config,
1704        },
1705        [PRX2] = {
1706                .attrs = &tsl2X7X_device_attr_group_tbl[PRX2],
1707                .event_attrs = &tsl2X7X_event_attr_group_tbl[PRX],
1708                .driver_module = THIS_MODULE,
1709                .read_raw = &tsl2x7x_read_raw,
1710                .write_raw = &tsl2x7x_write_raw,
1711                .read_event_value = &tsl2x7x_read_thresh,
1712                .write_event_value = &tsl2x7x_write_thresh,
1713                .read_event_config = &tsl2x7x_read_interrupt_config,
1714                .write_event_config = &tsl2x7x_write_interrupt_config,
1715        },
1716        [ALSPRX2] = {
1717                .attrs = &tsl2X7X_device_attr_group_tbl[ALSPRX2],
1718                .event_attrs = &tsl2X7X_event_attr_group_tbl[ALSPRX],
1719                .driver_module = THIS_MODULE,
1720                .read_raw = &tsl2x7x_read_raw,
1721                .write_raw = &tsl2x7x_write_raw,
1722                .read_event_value = &tsl2x7x_read_thresh,
1723                .write_event_value = &tsl2x7x_write_thresh,
1724                .read_event_config = &tsl2x7x_read_interrupt_config,
1725                .write_event_config = &tsl2x7x_write_interrupt_config,
1726        },
1727};
1728
1729static const struct tsl2x7x_chip_info tsl2x7x_chip_info_tbl[] = {
1730        [ALS] = {
1731                .channel = {
1732                        {
1733                        .type = IIO_LIGHT,
1734                        .indexed = 1,
1735                        .channel = 0,
1736                        .info_mask_separate = BIT(IIO_CHAN_INFO_PROCESSED),
1737                        }, {
1738                        .type = IIO_INTENSITY,
1739                        .indexed = 1,
1740                        .channel = 0,
1741                        .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
1742                                BIT(IIO_CHAN_INFO_CALIBSCALE) |
1743                                BIT(IIO_CHAN_INFO_CALIBBIAS),
1744                        .event_mask = TSL2X7X_EVENT_MASK
1745                        }, {
1746                        .type = IIO_INTENSITY,
1747                        .indexed = 1,
1748                        .channel = 1,
1749                        },
1750                },
1751        .chan_table_elements = 3,
1752        .info = &tsl2X7X_device_info[ALS],
1753        },
1754        [PRX] = {
1755                .channel = {
1756                        {
1757                        .type = IIO_PROXIMITY,
1758                        .indexed = 1,
1759                        .channel = 0,
1760                        .info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
1761                        .event_mask = TSL2X7X_EVENT_MASK
1762                        },
1763                },
1764        .chan_table_elements = 1,
1765        .info = &tsl2X7X_device_info[PRX],
1766        },
1767        [ALSPRX] = {
1768                .channel = {
1769                        {
1770                        .type = IIO_LIGHT,
1771                        .indexed = 1,
1772                        .channel = 0,
1773                        .info_mask_separate = BIT(IIO_CHAN_INFO_PROCESSED)
1774                        }, {
1775                        .type = IIO_INTENSITY,
1776                        .indexed = 1,
1777                        .channel = 0,
1778                        .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
1779                                BIT(IIO_CHAN_INFO_CALIBSCALE) |
1780                                BIT(IIO_CHAN_INFO_CALIBBIAS),
1781                        .event_mask = TSL2X7X_EVENT_MASK
1782                        }, {
1783                        .type = IIO_INTENSITY,
1784                        .indexed = 1,
1785                        .channel = 1,
1786                        .info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
1787                        }, {
1788                        .type = IIO_PROXIMITY,
1789                        .indexed = 1,
1790                        .channel = 0,
1791                        .info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
1792                        .event_mask = TSL2X7X_EVENT_MASK
1793                        },
1794                },
1795        .chan_table_elements = 4,
1796        .info = &tsl2X7X_device_info[ALSPRX],
1797        },
1798        [PRX2] = {
1799                .channel = {
1800                        {
1801                        .type = IIO_PROXIMITY,
1802                        .indexed = 1,
1803                        .channel = 0,
1804                        .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
1805                                BIT(IIO_CHAN_INFO_CALIBSCALE),
1806                        .event_mask = TSL2X7X_EVENT_MASK
1807                        },
1808                },
1809        .chan_table_elements = 1,
1810        .info = &tsl2X7X_device_info[PRX2],
1811        },
1812        [ALSPRX2] = {
1813                .channel = {
1814                        {
1815                        .type = IIO_LIGHT,
1816                        .indexed = 1,
1817                        .channel = 0,
1818                        .info_mask_separate = BIT(IIO_CHAN_INFO_PROCESSED),
1819                        }, {
1820                        .type = IIO_INTENSITY,
1821                        .indexed = 1,
1822                        .channel = 0,
1823                        .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
1824                                BIT(IIO_CHAN_INFO_CALIBSCALE) |
1825                                BIT(IIO_CHAN_INFO_CALIBBIAS),
1826                        .event_mask = TSL2X7X_EVENT_MASK
1827                        }, {
1828                        .type = IIO_INTENSITY,
1829                        .indexed = 1,
1830                        .channel = 1,
1831                        .info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
1832                        }, {
1833                        .type = IIO_PROXIMITY,
1834                        .indexed = 1,
1835                        .channel = 0,
1836                        .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
1837                                BIT(IIO_CHAN_INFO_CALIBSCALE),
1838                        .event_mask = TSL2X7X_EVENT_MASK
1839                        },
1840                },
1841        .chan_table_elements = 4,
1842        .info = &tsl2X7X_device_info[ALSPRX2],
1843        },
1844};
1845
1846static int tsl2x7x_probe(struct i2c_client *clientp,
1847        const struct i2c_device_id *id)
1848{
1849        int ret;
1850        unsigned char device_id;
1851        struct iio_dev *indio_dev;
1852        struct tsl2X7X_chip *chip;
1853
1854        indio_dev = iio_device_alloc(sizeof(*chip));
1855        if (!indio_dev)
1856                return -ENOMEM;
1857
1858        chip = iio_priv(indio_dev);
1859        chip->client = clientp;
1860        i2c_set_clientdata(clientp, indio_dev);
1861
1862        ret = tsl2x7x_i2c_read(chip->client,
1863                TSL2X7X_CHIPID, &device_id);
1864        if (ret < 0)
1865                goto fail1;
1866
1867        if ((!tsl2x7x_device_id(&device_id, id->driver_data)) ||
1868                (tsl2x7x_device_id(&device_id, id->driver_data) == -EINVAL)) {
1869                dev_info(&chip->client->dev,
1870                                "%s: i2c device found does not match expected id\n",
1871                                __func__);
1872                ret = -EINVAL;
1873                goto fail1;
1874        }
1875
1876        ret = i2c_smbus_write_byte(clientp, (TSL2X7X_CMD_REG | TSL2X7X_CNTRL));
1877        if (ret < 0) {
1878                dev_err(&clientp->dev, "%s: write to cmd reg failed. err = %d\n",
1879                                __func__, ret);
1880                goto fail1;
1881        }
1882
1883        /* ALS and PROX functions can be invoked via user space poll
1884         * or H/W interrupt. If busy return last sample. */
1885        mutex_init(&chip->als_mutex);
1886        mutex_init(&chip->prox_mutex);
1887
1888        chip->tsl2x7x_chip_status = TSL2X7X_CHIP_UNKNOWN;
1889        chip->pdata = clientp->dev.platform_data;
1890        chip->id = id->driver_data;
1891        chip->chip_info =
1892                &tsl2x7x_chip_info_tbl[device_channel_config[id->driver_data]];
1893
1894        indio_dev->info = chip->chip_info->info;
1895        indio_dev->dev.parent = &clientp->dev;
1896        indio_dev->modes = INDIO_DIRECT_MODE;
1897        indio_dev->name = chip->client->name;
1898        indio_dev->channels = chip->chip_info->channel;
1899        indio_dev->num_channels = chip->chip_info->chan_table_elements;
1900
1901        if (clientp->irq) {
1902                ret = request_threaded_irq(clientp->irq,
1903                                           NULL,
1904                                           &tsl2x7x_event_handler,
1905                                           IRQF_TRIGGER_RISING | IRQF_ONESHOT,
1906                                           "TSL2X7X_event",
1907                                           indio_dev);
1908                if (ret) {
1909                        dev_err(&clientp->dev,
1910                                "%s: irq request failed", __func__);
1911                        goto fail1;
1912                }
1913        }
1914
1915        /* Load up the defaults */
1916        tsl2x7x_defaults(chip);
1917        /* Make sure the chip is on */
1918        tsl2x7x_chip_on(indio_dev);
1919
1920        ret = iio_device_register(indio_dev);
1921        if (ret) {
1922                dev_err(&clientp->dev,
1923                        "%s: iio registration failed\n", __func__);
1924                goto fail2;
1925        }
1926
1927        dev_info(&clientp->dev, "%s Light sensor found.\n", id->name);
1928
1929        return 0;
1930
1931fail2:
1932        if (clientp->irq)
1933                free_irq(clientp->irq, indio_dev);
1934fail1:
1935        iio_device_free(indio_dev);
1936
1937        return ret;
1938}
1939
1940static int tsl2x7x_suspend(struct device *dev)
1941{
1942        struct iio_dev *indio_dev = dev_get_drvdata(dev);
1943        struct tsl2X7X_chip *chip = iio_priv(indio_dev);
1944        int ret = 0;
1945
1946        if (chip->tsl2x7x_chip_status == TSL2X7X_CHIP_WORKING) {
1947                ret = tsl2x7x_chip_off(indio_dev);
1948                chip->tsl2x7x_chip_status = TSL2X7X_CHIP_SUSPENDED;
1949        }
1950
1951        if (chip->pdata && chip->pdata->platform_power) {
1952                pm_message_t pmm = {PM_EVENT_SUSPEND};
1953                chip->pdata->platform_power(dev, pmm);
1954        }
1955
1956        return ret;
1957}
1958
1959static int tsl2x7x_resume(struct device *dev)
1960{
1961        struct iio_dev *indio_dev = dev_get_drvdata(dev);
1962        struct tsl2X7X_chip *chip = iio_priv(indio_dev);
1963        int ret = 0;
1964
1965        if (chip->pdata && chip->pdata->platform_power) {
1966                pm_message_t pmm = {PM_EVENT_RESUME};
1967                chip->pdata->platform_power(dev, pmm);
1968        }
1969
1970        if (chip->tsl2x7x_chip_status == TSL2X7X_CHIP_SUSPENDED)
1971                ret = tsl2x7x_chip_on(indio_dev);
1972
1973        return ret;
1974}
1975
1976static int tsl2x7x_remove(struct i2c_client *client)
1977{
1978        struct iio_dev *indio_dev = i2c_get_clientdata(client);
1979
1980        tsl2x7x_chip_off(indio_dev);
1981
1982        iio_device_unregister(indio_dev);
1983        if (client->irq)
1984                free_irq(client->irq, indio_dev);
1985
1986        iio_device_free(indio_dev);
1987
1988        return 0;
1989}
1990
1991static struct i2c_device_id tsl2x7x_idtable[] = {
1992        { "tsl2571", tsl2571 },
1993        { "tsl2671", tsl2671 },
1994        { "tmd2671", tmd2671 },
1995        { "tsl2771", tsl2771 },
1996        { "tmd2771", tmd2771 },
1997        { "tsl2572", tsl2572 },
1998        { "tsl2672", tsl2672 },
1999        { "tmd2672", tmd2672 },
2000        { "tsl2772", tsl2772 },
2001        { "tmd2772", tmd2772 },
2002        {}
2003};
2004
2005MODULE_DEVICE_TABLE(i2c, tsl2x7x_idtable);
2006
2007static const struct dev_pm_ops tsl2x7x_pm_ops = {
2008        .suspend = tsl2x7x_suspend,
2009        .resume  = tsl2x7x_resume,
2010};
2011
2012/* Driver definition */
2013static struct i2c_driver tsl2x7x_driver = {
2014        .driver = {
2015                .name = "tsl2x7x",
2016                .pm = &tsl2x7x_pm_ops,
2017        },
2018        .id_table = tsl2x7x_idtable,
2019        .probe = tsl2x7x_probe,
2020        .remove = tsl2x7x_remove,
2021};
2022
2023module_i2c_driver(tsl2x7x_driver);
2024
2025MODULE_AUTHOR("J. August Brenner<jbrenner@taosinc.com>");
2026MODULE_DESCRIPTION("TAOS tsl2x7x ambient and proximity light sensor driver");
2027MODULE_LICENSE("GPL");
2028