linux/drivers/iio/light/us5182d.c
<<
>>
Prefs
   1/*
   2 * Copyright (c) 2015 Intel Corporation
   3 *
   4 * Driver for UPISEMI us5182d Proximity and Ambient Light Sensor.
   5 *
   6 * This program is free software; you can redistribute it and/or modify it
   7 * under the terms of the GNU General Public License version 2 as published by
   8 * the Free Software Foundation.
   9 *
  10 * This program is distributed in the hope it will be useful, but WITHOUT
  11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  12 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
  13 * more details.
  14 *
  15 * To do: Interrupt support.
  16 */
  17
  18#include <linux/kernel.h>
  19#include <linux/module.h>
  20#include <linux/acpi.h>
  21#include <linux/delay.h>
  22#include <linux/i2c.h>
  23#include <linux/iio/events.h>
  24#include <linux/iio/iio.h>
  25#include <linux/interrupt.h>
  26#include <linux/irq.h>
  27#include <linux/iio/sysfs.h>
  28#include <linux/mutex.h>
  29#include <linux/pm.h>
  30#include <linux/pm_runtime.h>
  31
  32#define US5182D_REG_CFG0                                0x00
  33#define US5182D_CFG0_ONESHOT_EN                         BIT(6)
  34#define US5182D_CFG0_SHUTDOWN_EN                        BIT(7)
  35#define US5182D_CFG0_WORD_ENABLE                        BIT(0)
  36#define US5182D_CFG0_PROX                               BIT(3)
  37#define US5182D_CFG0_PX_IRQ                             BIT(2)
  38
  39#define US5182D_REG_CFG1                                0x01
  40#define US5182D_CFG1_ALS_RES16                          BIT(4)
  41#define US5182D_CFG1_AGAIN_DEFAULT                      0x00
  42
  43#define US5182D_REG_CFG2                                0x02
  44#define US5182D_CFG2_PX_RES16                           BIT(4)
  45#define US5182D_CFG2_PXGAIN_DEFAULT                     BIT(2)
  46
  47#define US5182D_REG_CFG3                                0x03
  48#define US5182D_CFG3_LED_CURRENT100                     (BIT(4) | BIT(5))
  49#define US5182D_CFG3_INT_SOURCE_PX                      BIT(3)
  50
  51#define US5182D_REG_CFG4                                0x10
  52
  53/*
  54 * Registers for tuning the auto dark current cancelling feature.
  55 * DARK_TH(reg 0x27,0x28) - threshold (counts) for auto dark cancelling.
  56 * when ALS  > DARK_TH --> ALS_Code = ALS - Upper(0x2A) * Dark
  57 * when ALS < DARK_TH --> ALS_Code = ALS - Lower(0x29) * Dark
  58 */
  59#define US5182D_REG_UDARK_TH                    0x27
  60#define US5182D_REG_DARK_AUTO_EN                0x2b
  61#define US5182D_REG_AUTO_LDARK_GAIN             0x29
  62#define US5182D_REG_AUTO_HDARK_GAIN             0x2a
  63
  64/* Thresholds for events: px low (0x08-l, 0x09-h), px high (0x0a-l 0x0b-h) */
  65#define US5182D_REG_PXL_TH                      0x08
  66#define US5182D_REG_PXH_TH                      0x0a
  67
  68#define US5182D_REG_PXL_TH_DEFAULT              1000
  69#define US5182D_REG_PXH_TH_DEFAULT              30000
  70
  71#define US5182D_OPMODE_ALS                      0x01
  72#define US5182D_OPMODE_PX                       0x02
  73#define US5182D_OPMODE_SHIFT                    4
  74
  75#define US5182D_REG_DARK_AUTO_EN_DEFAULT        0x80
  76#define US5182D_REG_AUTO_LDARK_GAIN_DEFAULT     0x16
  77#define US5182D_REG_AUTO_HDARK_GAIN_DEFAULT     0x00
  78
  79#define US5182D_REG_ADL                         0x0c
  80#define US5182D_REG_PDL                         0x0e
  81
  82#define US5182D_REG_MODE_STORE                  0x21
  83#define US5182D_STORE_MODE                      0x01
  84
  85#define US5182D_REG_CHIPID                      0xb2
  86
  87#define US5182D_OPMODE_MASK                     GENMASK(5, 4)
  88#define US5182D_AGAIN_MASK                      0x07
  89#define US5182D_RESET_CHIP                      0x01
  90
  91#define US5182D_CHIPID                          0x26
  92#define US5182D_DRV_NAME                        "us5182d"
  93
  94#define US5182D_GA_RESOLUTION                   1000
  95
  96#define US5182D_READ_BYTE                       1
  97#define US5182D_READ_WORD                       2
  98#define US5182D_OPSTORE_SLEEP_TIME              20 /* ms */
  99#define US5182D_SLEEP_MS                        3000 /* ms */
 100#define US5182D_PXH_TH_DISABLE                  0xffff
 101#define US5182D_PXL_TH_DISABLE                  0x0000
 102
 103/* Available ranges: [12354, 7065, 3998, 2202, 1285, 498, 256, 138] lux */
 104static const int us5182d_scales[] = {188500, 107800, 61000, 33600, 19600, 7600,
 105                                     3900, 2100};
 106
 107/*
 108 * Experimental thresholds that work with US5182D sensor on evaluation board
 109 * roughly between 12-32 lux
 110 */
 111static u16 us5182d_dark_ths_vals[] = {170, 200, 512, 512, 800, 2000, 4000,
 112                                      8000};
 113
 114enum mode {
 115        US5182D_ALS_PX,
 116        US5182D_ALS_ONLY,
 117        US5182D_PX_ONLY
 118};
 119
 120enum pmode {
 121        US5182D_CONTINUOUS,
 122        US5182D_ONESHOT
 123};
 124
 125struct us5182d_data {
 126        struct i2c_client *client;
 127        struct mutex lock;
 128
 129        /* Glass attenuation factor */
 130        u32 ga;
 131
 132        /* Dark gain tuning */
 133        u8 lower_dark_gain;
 134        u8 upper_dark_gain;
 135        u16 *us5182d_dark_ths;
 136
 137        u16 px_low_th;
 138        u16 px_high_th;
 139
 140        int rising_en;
 141        int falling_en;
 142
 143        u8 opmode;
 144        u8 power_mode;
 145
 146        bool als_enabled;
 147        bool px_enabled;
 148
 149        bool default_continuous;
 150};
 151
 152static IIO_CONST_ATTR(in_illuminance_scale_available,
 153                      "0.0021 0.0039 0.0076 0.0196 0.0336 0.061 0.1078 0.1885");
 154
 155static struct attribute *us5182d_attrs[] = {
 156        &iio_const_attr_in_illuminance_scale_available.dev_attr.attr,
 157        NULL
 158};
 159
 160static const struct attribute_group us5182d_attr_group = {
 161        .attrs = us5182d_attrs,
 162};
 163
 164static const struct {
 165        u8 reg;
 166        u8 val;
 167} us5182d_regvals[] = {
 168        {US5182D_REG_CFG0, US5182D_CFG0_WORD_ENABLE},
 169        {US5182D_REG_CFG1, US5182D_CFG1_ALS_RES16},
 170        {US5182D_REG_CFG2, (US5182D_CFG2_PX_RES16 |
 171                            US5182D_CFG2_PXGAIN_DEFAULT)},
 172        {US5182D_REG_CFG3, US5182D_CFG3_LED_CURRENT100 |
 173                           US5182D_CFG3_INT_SOURCE_PX},
 174        {US5182D_REG_CFG4, 0x00},
 175};
 176
 177static const struct iio_event_spec us5182d_events[] = {
 178        {
 179                .type = IIO_EV_TYPE_THRESH,
 180                .dir = IIO_EV_DIR_RISING,
 181                .mask_separate = BIT(IIO_EV_INFO_VALUE) |
 182                                BIT(IIO_EV_INFO_ENABLE),
 183        },
 184        {
 185                .type = IIO_EV_TYPE_THRESH,
 186                .dir = IIO_EV_DIR_FALLING,
 187                .mask_separate = BIT(IIO_EV_INFO_VALUE) |
 188                                BIT(IIO_EV_INFO_ENABLE),
 189        },
 190};
 191
 192static const struct iio_chan_spec us5182d_channels[] = {
 193        {
 194                .type = IIO_LIGHT,
 195                .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
 196                                      BIT(IIO_CHAN_INFO_SCALE),
 197        },
 198        {
 199                .type = IIO_PROXIMITY,
 200                .info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
 201                .event_spec = us5182d_events,
 202                .num_event_specs = ARRAY_SIZE(us5182d_events),
 203        }
 204};
 205
 206static int us5182d_oneshot_en(struct us5182d_data *data)
 207{
 208        int ret;
 209
 210        ret = i2c_smbus_read_byte_data(data->client, US5182D_REG_CFG0);
 211        if (ret < 0)
 212                return ret;
 213
 214        /*
 215         * In oneshot mode the chip will power itself down after taking the
 216         * required measurement.
 217         */
 218        ret = ret | US5182D_CFG0_ONESHOT_EN;
 219
 220        return i2c_smbus_write_byte_data(data->client, US5182D_REG_CFG0, ret);
 221}
 222
 223static int us5182d_set_opmode(struct us5182d_data *data, u8 mode)
 224{
 225        int ret;
 226
 227        if (mode == data->opmode)
 228                return 0;
 229
 230        ret = i2c_smbus_read_byte_data(data->client, US5182D_REG_CFG0);
 231        if (ret < 0)
 232                return ret;
 233
 234        /* update mode */
 235        ret = ret & ~US5182D_OPMODE_MASK;
 236        ret = ret | (mode << US5182D_OPMODE_SHIFT);
 237
 238        /*
 239         * After updating the operating mode, the chip requires that
 240         * the operation is stored, by writing 1 in the STORE_MODE
 241         * register (auto-clearing).
 242         */
 243        ret = i2c_smbus_write_byte_data(data->client, US5182D_REG_CFG0, ret);
 244        if (ret < 0)
 245                return ret;
 246
 247        ret = i2c_smbus_write_byte_data(data->client, US5182D_REG_MODE_STORE,
 248                                        US5182D_STORE_MODE);
 249        if (ret < 0)
 250                return ret;
 251
 252        data->opmode = mode;
 253        msleep(US5182D_OPSTORE_SLEEP_TIME);
 254
 255        return 0;
 256}
 257
 258static int us5182d_als_enable(struct us5182d_data *data)
 259{
 260        int ret;
 261        u8 mode;
 262
 263        if (data->power_mode == US5182D_ONESHOT) {
 264                ret = us5182d_set_opmode(data, US5182D_ALS_ONLY);
 265                if (ret < 0)
 266                        return ret;
 267                data->px_enabled = false;
 268        }
 269
 270        if (data->als_enabled)
 271                return 0;
 272
 273        mode = data->px_enabled ? US5182D_ALS_PX : US5182D_ALS_ONLY;
 274
 275        ret = us5182d_set_opmode(data, mode);
 276        if (ret < 0)
 277                return ret;
 278
 279        data->als_enabled = true;
 280
 281        return 0;
 282}
 283
 284static int us5182d_px_enable(struct us5182d_data *data)
 285{
 286        int ret;
 287        u8 mode;
 288
 289        if (data->power_mode == US5182D_ONESHOT) {
 290                ret = us5182d_set_opmode(data, US5182D_PX_ONLY);
 291                if (ret < 0)
 292                        return ret;
 293                data->als_enabled = false;
 294        }
 295
 296        if (data->px_enabled)
 297                return 0;
 298
 299        mode = data->als_enabled ? US5182D_ALS_PX : US5182D_PX_ONLY;
 300
 301        ret = us5182d_set_opmode(data, mode);
 302        if (ret < 0)
 303                return ret;
 304
 305        data->px_enabled = true;
 306
 307        return 0;
 308}
 309
 310static int us5182d_get_als(struct us5182d_data *data)
 311{
 312        int ret;
 313        unsigned long result;
 314
 315        ret = us5182d_als_enable(data);
 316        if (ret < 0)
 317                return ret;
 318
 319        ret = i2c_smbus_read_word_data(data->client,
 320                                       US5182D_REG_ADL);
 321        if (ret < 0)
 322                return ret;
 323
 324        result = ret * data->ga / US5182D_GA_RESOLUTION;
 325        if (result > 0xffff)
 326                result = 0xffff;
 327
 328        return result;
 329}
 330
 331static int us5182d_get_px(struct us5182d_data *data)
 332{
 333        int ret;
 334
 335        ret = us5182d_px_enable(data);
 336        if (ret < 0)
 337                return ret;
 338
 339        return i2c_smbus_read_word_data(data->client,
 340                                        US5182D_REG_PDL);
 341}
 342
 343static int us5182d_shutdown_en(struct us5182d_data *data, u8 state)
 344{
 345        int ret;
 346
 347        if (data->power_mode == US5182D_ONESHOT)
 348                return 0;
 349
 350        ret = i2c_smbus_read_byte_data(data->client, US5182D_REG_CFG0);
 351        if (ret < 0)
 352                return ret;
 353
 354        ret = ret & ~US5182D_CFG0_SHUTDOWN_EN;
 355        ret = ret | state;
 356
 357        ret = i2c_smbus_write_byte_data(data->client, US5182D_REG_CFG0, ret);
 358        if (ret < 0)
 359                return ret;
 360
 361        if (state & US5182D_CFG0_SHUTDOWN_EN) {
 362                data->als_enabled = false;
 363                data->px_enabled = false;
 364        }
 365
 366        return ret;
 367}
 368
 369
 370static int us5182d_set_power_state(struct us5182d_data *data, bool on)
 371{
 372        int ret;
 373
 374        if (data->power_mode == US5182D_ONESHOT)
 375                return 0;
 376
 377        if (on) {
 378                ret = pm_runtime_get_sync(&data->client->dev);
 379                if (ret < 0)
 380                        pm_runtime_put_noidle(&data->client->dev);
 381        } else {
 382                pm_runtime_mark_last_busy(&data->client->dev);
 383                ret = pm_runtime_put_autosuspend(&data->client->dev);
 384        }
 385
 386        return ret;
 387}
 388
 389static int us5182d_read_value(struct us5182d_data *data,
 390                              struct iio_chan_spec const *chan)
 391{
 392        int ret, value;
 393
 394        mutex_lock(&data->lock);
 395
 396        if (data->power_mode == US5182D_ONESHOT) {
 397                ret = us5182d_oneshot_en(data);
 398                if (ret < 0)
 399                        goto out_err;
 400        }
 401
 402        ret = us5182d_set_power_state(data, true);
 403        if (ret < 0)
 404                goto out_err;
 405
 406        if (chan->type == IIO_LIGHT)
 407                ret = us5182d_get_als(data);
 408        else
 409                ret = us5182d_get_px(data);
 410        if (ret < 0)
 411                goto out_poweroff;
 412
 413        value = ret;
 414
 415        ret = us5182d_set_power_state(data, false);
 416        if (ret < 0)
 417                goto out_err;
 418
 419        mutex_unlock(&data->lock);
 420        return value;
 421
 422out_poweroff:
 423        us5182d_set_power_state(data, false);
 424out_err:
 425        mutex_unlock(&data->lock);
 426        return ret;
 427}
 428
 429static int us5182d_read_raw(struct iio_dev *indio_dev,
 430                            struct iio_chan_spec const *chan, int *val,
 431                            int *val2, long mask)
 432{
 433        struct us5182d_data *data = iio_priv(indio_dev);
 434        int ret;
 435
 436        switch (mask) {
 437        case IIO_CHAN_INFO_RAW:
 438                ret = us5182d_read_value(data, chan);
 439                if (ret < 0)
 440                        return ret;
 441                *val = ret;
 442                return IIO_VAL_INT;
 443        case IIO_CHAN_INFO_SCALE:
 444                ret = i2c_smbus_read_byte_data(data->client, US5182D_REG_CFG1);
 445                if (ret < 0)
 446                        return ret;
 447                *val = 0;
 448                *val2 = us5182d_scales[ret & US5182D_AGAIN_MASK];
 449                return IIO_VAL_INT_PLUS_MICRO;
 450        default:
 451                return -EINVAL;
 452        }
 453}
 454
 455/**
 456 * us5182d_update_dark_th - update Darh_Th registers
 457 * @data        us5182d_data structure
 458 * @index       index in us5182d_dark_ths array to use for the updated value
 459 *
 460 * Function needs to be called with a lock held because it needs two i2c write
 461 * byte operations as these registers (0x27 0x28) don't work in word mode
 462 * accessing.
 463 */
 464static int us5182d_update_dark_th(struct us5182d_data *data, int index)
 465{
 466        __be16 dark_th = cpu_to_be16(data->us5182d_dark_ths[index]);
 467        int ret;
 468
 469        ret = i2c_smbus_write_byte_data(data->client, US5182D_REG_UDARK_TH,
 470                                        ((u8 *)&dark_th)[0]);
 471        if (ret < 0)
 472                return ret;
 473
 474        return i2c_smbus_write_byte_data(data->client, US5182D_REG_UDARK_TH + 1,
 475                                        ((u8 *)&dark_th)[1]);
 476}
 477
 478/**
 479 * us5182d_apply_scale - update the ALS scale
 480 * @data        us5182d_data structure
 481 * @index       index in us5182d_scales array to use for the updated value
 482 *
 483 * Function needs to be called with a lock held as we're having more than one
 484 * i2c operation.
 485 */
 486static int us5182d_apply_scale(struct us5182d_data *data, int index)
 487{
 488        int ret;
 489
 490        ret = i2c_smbus_read_byte_data(data->client, US5182D_REG_CFG1);
 491        if (ret < 0)
 492                return ret;
 493
 494        ret = ret & (~US5182D_AGAIN_MASK);
 495        ret |= index;
 496
 497        ret = i2c_smbus_write_byte_data(data->client, US5182D_REG_CFG1, ret);
 498        if (ret < 0)
 499                return ret;
 500
 501        return us5182d_update_dark_th(data, index);
 502}
 503
 504static int us5182d_write_raw(struct iio_dev *indio_dev,
 505                             struct iio_chan_spec const *chan, int val,
 506                             int val2, long mask)
 507{
 508        struct us5182d_data *data = iio_priv(indio_dev);
 509        int ret, i;
 510
 511        switch (mask) {
 512        case IIO_CHAN_INFO_SCALE:
 513                if (val != 0)
 514                        return -EINVAL;
 515                for (i = 0; i < ARRAY_SIZE(us5182d_scales); i++)
 516                        if (val2 == us5182d_scales[i]) {
 517                                mutex_lock(&data->lock);
 518                                ret = us5182d_apply_scale(data, i);
 519                                mutex_unlock(&data->lock);
 520                                return ret;
 521                        }
 522                break;
 523        default:
 524                return -EINVAL;
 525        }
 526
 527        return -EINVAL;
 528}
 529
 530static int us5182d_setup_prox(struct iio_dev *indio_dev,
 531                              enum iio_event_direction dir, u16 val)
 532{
 533        struct us5182d_data *data = iio_priv(indio_dev);
 534
 535        if (dir == IIO_EV_DIR_FALLING)
 536                return i2c_smbus_write_word_data(data->client,
 537                                                 US5182D_REG_PXL_TH, val);
 538        else if (dir == IIO_EV_DIR_RISING)
 539                return i2c_smbus_write_word_data(data->client,
 540                                                 US5182D_REG_PXH_TH, val);
 541
 542        return 0;
 543}
 544
 545static int us5182d_read_thresh(struct iio_dev *indio_dev,
 546        const struct iio_chan_spec *chan, enum iio_event_type type,
 547        enum iio_event_direction dir, enum iio_event_info info, int *val,
 548        int *val2)
 549{
 550        struct us5182d_data *data = iio_priv(indio_dev);
 551
 552        switch (dir) {
 553        case IIO_EV_DIR_RISING:
 554                mutex_lock(&data->lock);
 555                *val = data->px_high_th;
 556                mutex_unlock(&data->lock);
 557                break;
 558        case IIO_EV_DIR_FALLING:
 559                mutex_lock(&data->lock);
 560                *val = data->px_low_th;
 561                mutex_unlock(&data->lock);
 562                break;
 563        default:
 564                return -EINVAL;
 565        }
 566
 567        return IIO_VAL_INT;
 568}
 569
 570static int us5182d_write_thresh(struct iio_dev *indio_dev,
 571        const struct iio_chan_spec *chan, enum iio_event_type type,
 572        enum iio_event_direction dir, enum iio_event_info info, int val,
 573        int val2)
 574{
 575        struct us5182d_data *data = iio_priv(indio_dev);
 576        int ret;
 577
 578        if (val < 0 || val > USHRT_MAX || val2 != 0)
 579                return -EINVAL;
 580
 581        switch (dir) {
 582        case IIO_EV_DIR_RISING:
 583                mutex_lock(&data->lock);
 584                if (data->rising_en) {
 585                        ret = us5182d_setup_prox(indio_dev, dir, val);
 586                        if (ret < 0)
 587                                goto err;
 588                }
 589                data->px_high_th = val;
 590                mutex_unlock(&data->lock);
 591                break;
 592        case IIO_EV_DIR_FALLING:
 593                mutex_lock(&data->lock);
 594                if (data->falling_en) {
 595                        ret = us5182d_setup_prox(indio_dev, dir, val);
 596                        if (ret < 0)
 597                                goto err;
 598                }
 599                data->px_low_th = val;
 600                mutex_unlock(&data->lock);
 601                break;
 602        default:
 603                return -EINVAL;
 604        }
 605
 606        return 0;
 607err:
 608        mutex_unlock(&data->lock);
 609        return ret;
 610}
 611
 612static int us5182d_read_event_config(struct iio_dev *indio_dev,
 613        const struct iio_chan_spec *chan, enum iio_event_type type,
 614        enum iio_event_direction dir)
 615{
 616        struct us5182d_data *data = iio_priv(indio_dev);
 617        int ret;
 618
 619        switch (dir) {
 620        case IIO_EV_DIR_RISING:
 621                mutex_lock(&data->lock);
 622                ret = data->rising_en;
 623                mutex_unlock(&data->lock);
 624                break;
 625        case IIO_EV_DIR_FALLING:
 626                mutex_lock(&data->lock);
 627                ret = data->falling_en;
 628                mutex_unlock(&data->lock);
 629                break;
 630        default:
 631                ret = -EINVAL;
 632                break;
 633        }
 634
 635        return ret;
 636}
 637
 638static int us5182d_write_event_config(struct iio_dev *indio_dev,
 639        const struct iio_chan_spec *chan, enum iio_event_type type,
 640        enum iio_event_direction dir, int state)
 641{
 642        struct us5182d_data *data = iio_priv(indio_dev);
 643        int ret;
 644        u16 new_th;
 645
 646        mutex_lock(&data->lock);
 647
 648        switch (dir) {
 649        case IIO_EV_DIR_RISING:
 650                if (data->rising_en == state) {
 651                        mutex_unlock(&data->lock);
 652                        return 0;
 653                }
 654                new_th = US5182D_PXH_TH_DISABLE;
 655                if (state) {
 656                        data->power_mode = US5182D_CONTINUOUS;
 657                        ret = us5182d_set_power_state(data, true);
 658                        if (ret < 0)
 659                                goto err;
 660                        ret = us5182d_px_enable(data);
 661                        if (ret < 0)
 662                                goto err_poweroff;
 663                        new_th = data->px_high_th;
 664                }
 665                ret = us5182d_setup_prox(indio_dev, dir, new_th);
 666                if (ret < 0)
 667                        goto err_poweroff;
 668                data->rising_en = state;
 669                break;
 670        case IIO_EV_DIR_FALLING:
 671                if (data->falling_en == state) {
 672                        mutex_unlock(&data->lock);
 673                        return 0;
 674                }
 675                new_th =  US5182D_PXL_TH_DISABLE;
 676                if (state) {
 677                        data->power_mode = US5182D_CONTINUOUS;
 678                        ret = us5182d_set_power_state(data, true);
 679                        if (ret < 0)
 680                                goto err;
 681                        ret = us5182d_px_enable(data);
 682                        if (ret < 0)
 683                                goto err_poweroff;
 684                        new_th = data->px_low_th;
 685                }
 686                ret = us5182d_setup_prox(indio_dev, dir, new_th);
 687                if (ret < 0)
 688                        goto err_poweroff;
 689                data->falling_en = state;
 690                break;
 691        default:
 692                ret = -EINVAL;
 693                goto err;
 694        }
 695
 696        if (!state) {
 697                ret = us5182d_set_power_state(data, false);
 698                if (ret < 0)
 699                        goto err;
 700        }
 701
 702        if (!data->falling_en && !data->rising_en && !data->default_continuous)
 703                data->power_mode = US5182D_ONESHOT;
 704
 705        mutex_unlock(&data->lock);
 706        return 0;
 707
 708err_poweroff:
 709        if (state)
 710                us5182d_set_power_state(data, false);
 711err:
 712        mutex_unlock(&data->lock);
 713        return ret;
 714}
 715
 716static const struct iio_info us5182d_info = {
 717        .driver_module  = THIS_MODULE,
 718        .read_raw = us5182d_read_raw,
 719        .write_raw = us5182d_write_raw,
 720        .attrs = &us5182d_attr_group,
 721        .read_event_value = &us5182d_read_thresh,
 722        .write_event_value = &us5182d_write_thresh,
 723        .read_event_config = &us5182d_read_event_config,
 724        .write_event_config = &us5182d_write_event_config,
 725};
 726
 727static int us5182d_reset(struct iio_dev *indio_dev)
 728{
 729        struct us5182d_data *data = iio_priv(indio_dev);
 730
 731        return i2c_smbus_write_byte_data(data->client, US5182D_REG_CFG3,
 732                                         US5182D_RESET_CHIP);
 733}
 734
 735static int us5182d_init(struct iio_dev *indio_dev)
 736{
 737        struct us5182d_data *data = iio_priv(indio_dev);
 738        int i, ret;
 739
 740        ret = us5182d_reset(indio_dev);
 741        if (ret < 0)
 742                return ret;
 743
 744        data->opmode = 0;
 745        data->power_mode = US5182D_CONTINUOUS;
 746        data->px_low_th = US5182D_REG_PXL_TH_DEFAULT;
 747        data->px_high_th = US5182D_REG_PXH_TH_DEFAULT;
 748
 749        for (i = 0; i < ARRAY_SIZE(us5182d_regvals); i++) {
 750                ret = i2c_smbus_write_byte_data(data->client,
 751                                                us5182d_regvals[i].reg,
 752                                                us5182d_regvals[i].val);
 753                if (ret < 0)
 754                        return ret;
 755        }
 756
 757        data->als_enabled = true;
 758        data->px_enabled = true;
 759
 760        if (!data->default_continuous) {
 761                ret = us5182d_shutdown_en(data, US5182D_CFG0_SHUTDOWN_EN);
 762                if (ret < 0)
 763                        return ret;
 764                data->power_mode = US5182D_ONESHOT;
 765        }
 766
 767        return ret;
 768}
 769
 770static void us5182d_get_platform_data(struct iio_dev *indio_dev)
 771{
 772        struct us5182d_data *data = iio_priv(indio_dev);
 773
 774        if (device_property_read_u32(&data->client->dev, "upisemi,glass-coef",
 775                                     &data->ga))
 776                data->ga = US5182D_GA_RESOLUTION;
 777        if (device_property_read_u16_array(&data->client->dev,
 778                                           "upisemi,dark-ths",
 779                                           data->us5182d_dark_ths,
 780                                           ARRAY_SIZE(us5182d_dark_ths_vals)))
 781                data->us5182d_dark_ths = us5182d_dark_ths_vals;
 782        if (device_property_read_u8(&data->client->dev,
 783                                    "upisemi,upper-dark-gain",
 784                                    &data->upper_dark_gain))
 785                data->upper_dark_gain = US5182D_REG_AUTO_HDARK_GAIN_DEFAULT;
 786        if (device_property_read_u8(&data->client->dev,
 787                                    "upisemi,lower-dark-gain",
 788                                    &data->lower_dark_gain))
 789                data->lower_dark_gain = US5182D_REG_AUTO_LDARK_GAIN_DEFAULT;
 790        data->default_continuous = device_property_read_bool(&data->client->dev,
 791                                                             "upisemi,continuous");
 792}
 793
 794static int  us5182d_dark_gain_config(struct iio_dev *indio_dev)
 795{
 796        struct us5182d_data *data = iio_priv(indio_dev);
 797        int ret;
 798
 799        ret = us5182d_update_dark_th(data, US5182D_CFG1_AGAIN_DEFAULT);
 800        if (ret < 0)
 801                return ret;
 802
 803        ret = i2c_smbus_write_byte_data(data->client,
 804                                        US5182D_REG_AUTO_LDARK_GAIN,
 805                                        data->lower_dark_gain);
 806        if (ret < 0)
 807                return ret;
 808
 809        ret = i2c_smbus_write_byte_data(data->client,
 810                                        US5182D_REG_AUTO_HDARK_GAIN,
 811                                        data->upper_dark_gain);
 812        if (ret < 0)
 813                return ret;
 814
 815        return i2c_smbus_write_byte_data(data->client, US5182D_REG_DARK_AUTO_EN,
 816                                         US5182D_REG_DARK_AUTO_EN_DEFAULT);
 817}
 818
 819static irqreturn_t us5182d_irq_thread_handler(int irq, void *private)
 820{
 821        struct iio_dev *indio_dev = private;
 822        struct us5182d_data *data = iio_priv(indio_dev);
 823        enum iio_event_direction dir;
 824        int ret;
 825        u64 ev;
 826
 827        ret = i2c_smbus_read_byte_data(data->client, US5182D_REG_CFG0);
 828        if (ret < 0) {
 829                dev_err(&data->client->dev, "i2c transfer error in irq\n");
 830                return IRQ_HANDLED;
 831        }
 832
 833        dir = ret & US5182D_CFG0_PROX ? IIO_EV_DIR_RISING : IIO_EV_DIR_FALLING;
 834        ev = IIO_UNMOD_EVENT_CODE(IIO_PROXIMITY, 1, IIO_EV_TYPE_THRESH, dir);
 835
 836        iio_push_event(indio_dev, ev, iio_get_time_ns());
 837
 838        ret = i2c_smbus_write_byte_data(data->client, US5182D_REG_CFG0,
 839                                        ret & ~US5182D_CFG0_PX_IRQ);
 840        if (ret < 0)
 841                dev_err(&data->client->dev, "i2c transfer error in irq\n");
 842
 843        return IRQ_HANDLED;
 844}
 845
 846static int us5182d_probe(struct i2c_client *client,
 847                         const struct i2c_device_id *id)
 848{
 849        struct us5182d_data *data;
 850        struct iio_dev *indio_dev;
 851        int ret;
 852
 853        indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*data));
 854        if (!indio_dev)
 855                return -ENOMEM;
 856
 857        data = iio_priv(indio_dev);
 858        i2c_set_clientdata(client, indio_dev);
 859        data->client = client;
 860
 861        mutex_init(&data->lock);
 862
 863        indio_dev->dev.parent = &client->dev;
 864        indio_dev->info = &us5182d_info;
 865        indio_dev->name = US5182D_DRV_NAME;
 866        indio_dev->channels = us5182d_channels;
 867        indio_dev->num_channels = ARRAY_SIZE(us5182d_channels);
 868        indio_dev->modes = INDIO_DIRECT_MODE;
 869
 870        ret = i2c_smbus_read_byte_data(data->client, US5182D_REG_CHIPID);
 871        if (ret != US5182D_CHIPID) {
 872                dev_err(&data->client->dev,
 873                        "Failed to detect US5182 light chip\n");
 874                return (ret < 0) ? ret : -ENODEV;
 875        }
 876
 877        if (client->irq > 0) {
 878                ret = devm_request_threaded_irq(&client->dev, client->irq, NULL,
 879                                                us5182d_irq_thread_handler,
 880                                                IRQF_TRIGGER_LOW | IRQF_ONESHOT,
 881                                                "us5182d-irq", indio_dev);
 882                if (ret < 0)
 883                        return ret;
 884        } else
 885                dev_warn(&client->dev, "no valid irq found\n");
 886
 887        us5182d_get_platform_data(indio_dev);
 888        ret = us5182d_init(indio_dev);
 889        if (ret < 0)
 890                return ret;
 891
 892        ret = us5182d_dark_gain_config(indio_dev);
 893        if (ret < 0)
 894                goto out_err;
 895
 896        if (data->default_continuous) {
 897                pm_runtime_set_active(&client->dev);
 898                if (ret < 0)
 899                        goto out_err;
 900        }
 901
 902        pm_runtime_enable(&client->dev);
 903        pm_runtime_set_autosuspend_delay(&client->dev,
 904                                         US5182D_SLEEP_MS);
 905        pm_runtime_use_autosuspend(&client->dev);
 906
 907        ret = iio_device_register(indio_dev);
 908        if (ret < 0)
 909                goto out_err;
 910
 911        return 0;
 912
 913out_err:
 914        us5182d_shutdown_en(data, US5182D_CFG0_SHUTDOWN_EN);
 915        return ret;
 916
 917}
 918
 919static int us5182d_remove(struct i2c_client *client)
 920{
 921        struct us5182d_data *data = iio_priv(i2c_get_clientdata(client));
 922
 923        iio_device_unregister(i2c_get_clientdata(client));
 924
 925        pm_runtime_disable(&client->dev);
 926        pm_runtime_set_suspended(&client->dev);
 927
 928        return us5182d_shutdown_en(data, US5182D_CFG0_SHUTDOWN_EN);
 929}
 930
 931#if defined(CONFIG_PM_SLEEP) || defined(CONFIG_PM)
 932static int us5182d_suspend(struct device *dev)
 933{
 934        struct iio_dev *indio_dev = i2c_get_clientdata(to_i2c_client(dev));
 935        struct us5182d_data *data = iio_priv(indio_dev);
 936
 937        if (data->power_mode == US5182D_CONTINUOUS)
 938                return us5182d_shutdown_en(data, US5182D_CFG0_SHUTDOWN_EN);
 939
 940        return 0;
 941}
 942
 943static int us5182d_resume(struct device *dev)
 944{
 945        struct iio_dev *indio_dev = i2c_get_clientdata(to_i2c_client(dev));
 946        struct us5182d_data *data = iio_priv(indio_dev);
 947
 948        if (data->power_mode == US5182D_CONTINUOUS)
 949                return us5182d_shutdown_en(data,
 950                                           ~US5182D_CFG0_SHUTDOWN_EN & 0xff);
 951
 952        return 0;
 953}
 954#endif
 955
 956static const struct dev_pm_ops us5182d_pm_ops = {
 957        SET_SYSTEM_SLEEP_PM_OPS(us5182d_suspend, us5182d_resume)
 958        SET_RUNTIME_PM_OPS(us5182d_suspend, us5182d_resume, NULL)
 959};
 960
 961static const struct acpi_device_id us5182d_acpi_match[] = {
 962        { "USD5182", 0},
 963        {}
 964};
 965
 966MODULE_DEVICE_TABLE(acpi, us5182d_acpi_match);
 967
 968static const struct i2c_device_id us5182d_id[] = {
 969                {"usd5182", 0},
 970                {}
 971};
 972
 973MODULE_DEVICE_TABLE(i2c, us5182d_id);
 974
 975static struct i2c_driver us5182d_driver = {
 976        .driver = {
 977                .name = US5182D_DRV_NAME,
 978                .pm = &us5182d_pm_ops,
 979                .acpi_match_table = ACPI_PTR(us5182d_acpi_match),
 980        },
 981        .probe = us5182d_probe,
 982        .remove = us5182d_remove,
 983        .id_table = us5182d_id,
 984
 985};
 986module_i2c_driver(us5182d_driver);
 987
 988MODULE_AUTHOR("Adriana Reus <adriana.reus@intel.com>");
 989MODULE_DESCRIPTION("Driver for us5182d Proximity and Light Sensor");
 990MODULE_LICENSE("GPL v2");
 991