linux/drivers/iio/light/rpr0521.c
<<
>>
Prefs
   1/*
   2 * RPR-0521 ROHM Ambient Light and Proximity Sensor
   3 *
   4 * Copyright (c) 2015, Intel Corporation.
   5 *
   6 * This file is subject to the terms and conditions of version 2 of
   7 * the GNU General Public License.  See the file COPYING in the main
   8 * directory of this archive for more details.
   9 *
  10 * IIO driver for RPR-0521RS (7-bit I2C slave address 0x38).
  11 *
  12 * TODO: illuminance channel, buffer
  13 */
  14
  15#include <linux/module.h>
  16#include <linux/init.h>
  17#include <linux/i2c.h>
  18#include <linux/regmap.h>
  19#include <linux/delay.h>
  20#include <linux/acpi.h>
  21
  22#include <linux/iio/iio.h>
  23#include <linux/iio/sysfs.h>
  24#include <linux/pm_runtime.h>
  25
  26#define RPR0521_REG_SYSTEM_CTRL         0x40
  27#define RPR0521_REG_MODE_CTRL           0x41
  28#define RPR0521_REG_ALS_CTRL            0x42
  29#define RPR0521_REG_PXS_CTRL            0x43
  30#define RPR0521_REG_PXS_DATA            0x44 /* 16-bit, little endian */
  31#define RPR0521_REG_ALS_DATA0           0x46 /* 16-bit, little endian */
  32#define RPR0521_REG_ALS_DATA1           0x48 /* 16-bit, little endian */
  33#define RPR0521_REG_PS_OFFSET_LSB       0x53
  34#define RPR0521_REG_ID                  0x92
  35
  36#define RPR0521_MODE_ALS_MASK           BIT(7)
  37#define RPR0521_MODE_PXS_MASK           BIT(6)
  38#define RPR0521_MODE_MEAS_TIME_MASK     GENMASK(3, 0)
  39#define RPR0521_ALS_DATA0_GAIN_MASK     GENMASK(5, 4)
  40#define RPR0521_ALS_DATA0_GAIN_SHIFT    4
  41#define RPR0521_ALS_DATA1_GAIN_MASK     GENMASK(3, 2)
  42#define RPR0521_ALS_DATA1_GAIN_SHIFT    2
  43#define RPR0521_PXS_GAIN_MASK           GENMASK(5, 4)
  44#define RPR0521_PXS_GAIN_SHIFT          4
  45
  46#define RPR0521_MODE_ALS_ENABLE         BIT(7)
  47#define RPR0521_MODE_ALS_DISABLE        0x00
  48#define RPR0521_MODE_PXS_ENABLE         BIT(6)
  49#define RPR0521_MODE_PXS_DISABLE        0x00
  50
  51#define RPR0521_MANUFACT_ID             0xE0
  52#define RPR0521_DEFAULT_MEAS_TIME       0x06 /* ALS - 100ms, PXS - 100ms */
  53
  54#define RPR0521_DRV_NAME                "RPR0521"
  55#define RPR0521_REGMAP_NAME             "rpr0521_regmap"
  56
  57#define RPR0521_SLEEP_DELAY_MS  2000
  58
  59#define RPR0521_ALS_SCALE_AVAIL "0.007812 0.015625 0.5 1"
  60#define RPR0521_PXS_SCALE_AVAIL "0.125 0.5 1"
  61
  62struct rpr0521_gain {
  63        int scale;
  64        int uscale;
  65};
  66
  67static const struct rpr0521_gain rpr0521_als_gain[4] = {
  68        {1, 0},         /* x1 */
  69        {0, 500000},    /* x2 */
  70        {0, 15625},     /* x64 */
  71        {0, 7812},      /* x128 */
  72};
  73
  74static const struct rpr0521_gain rpr0521_pxs_gain[3] = {
  75        {1, 0},         /* x1 */
  76        {0, 500000},    /* x2 */
  77        {0, 125000},    /* x4 */
  78};
  79
  80enum rpr0521_channel {
  81        RPR0521_CHAN_PXS,
  82        RPR0521_CHAN_ALS_DATA0,
  83        RPR0521_CHAN_ALS_DATA1,
  84};
  85
  86struct rpr0521_reg_desc {
  87        u8 address;
  88        u8 device_mask;
  89};
  90
  91static const struct rpr0521_reg_desc rpr0521_data_reg[] = {
  92        [RPR0521_CHAN_PXS]      = {
  93                .address        = RPR0521_REG_PXS_DATA,
  94                .device_mask    = RPR0521_MODE_PXS_MASK,
  95        },
  96        [RPR0521_CHAN_ALS_DATA0] = {
  97                .address        = RPR0521_REG_ALS_DATA0,
  98                .device_mask    = RPR0521_MODE_ALS_MASK,
  99        },
 100        [RPR0521_CHAN_ALS_DATA1] = {
 101                .address        = RPR0521_REG_ALS_DATA1,
 102                .device_mask    = RPR0521_MODE_ALS_MASK,
 103        },
 104};
 105
 106static const struct rpr0521_gain_info {
 107        u8 reg;
 108        u8 mask;
 109        u8 shift;
 110        const struct rpr0521_gain *gain;
 111        int size;
 112} rpr0521_gain[] = {
 113        [RPR0521_CHAN_PXS] = {
 114                .reg    = RPR0521_REG_PXS_CTRL,
 115                .mask   = RPR0521_PXS_GAIN_MASK,
 116                .shift  = RPR0521_PXS_GAIN_SHIFT,
 117                .gain   = rpr0521_pxs_gain,
 118                .size   = ARRAY_SIZE(rpr0521_pxs_gain),
 119        },
 120        [RPR0521_CHAN_ALS_DATA0] = {
 121                .reg    = RPR0521_REG_ALS_CTRL,
 122                .mask   = RPR0521_ALS_DATA0_GAIN_MASK,
 123                .shift  = RPR0521_ALS_DATA0_GAIN_SHIFT,
 124                .gain   = rpr0521_als_gain,
 125                .size   = ARRAY_SIZE(rpr0521_als_gain),
 126        },
 127        [RPR0521_CHAN_ALS_DATA1] = {
 128                .reg    = RPR0521_REG_ALS_CTRL,
 129                .mask   = RPR0521_ALS_DATA1_GAIN_MASK,
 130                .shift  = RPR0521_ALS_DATA1_GAIN_SHIFT,
 131                .gain   = rpr0521_als_gain,
 132                .size   = ARRAY_SIZE(rpr0521_als_gain),
 133        },
 134};
 135
 136struct rpr0521_samp_freq {
 137        int     als_hz;
 138        int     als_uhz;
 139        int     pxs_hz;
 140        int     pxs_uhz;
 141};
 142
 143static const struct rpr0521_samp_freq rpr0521_samp_freq_i[13] = {
 144/*      {ALS, PXS},                W==currently writable option */
 145        {0, 0, 0, 0},           /* W0000, 0=standby */
 146        {0, 0, 100, 0},         /*  0001 */
 147        {0, 0, 25, 0},          /*  0010 */
 148        {0, 0, 10, 0},          /*  0011 */
 149        {0, 0, 2, 500000},      /*  0100 */
 150        {10, 0, 20, 0},         /*  0101 */
 151        {10, 0, 10, 0},         /* W0110 */
 152        {10, 0, 2, 500000},     /*  0111 */
 153        {2, 500000, 20, 0},     /*  1000, measurement 100ms, sleep 300ms */
 154        {2, 500000, 10, 0},     /*  1001, measurement 100ms, sleep 300ms */
 155        {2, 500000, 0, 0},      /*  1010, high sensitivity mode */
 156        {2, 500000, 2, 500000}, /* W1011, high sensitivity mode */
 157        {20, 0, 20, 0}  /* 1100, ALS_data x 0.5, see specification P.18 */
 158};
 159
 160struct rpr0521_data {
 161        struct i2c_client *client;
 162
 163        /* protect device params updates (e.g state, gain) */
 164        struct mutex lock;
 165
 166        /* device active status */
 167        bool als_dev_en;
 168        bool pxs_dev_en;
 169
 170        /* optimize runtime pm ops - enable/disable device only if needed */
 171        bool als_ps_need_en;
 172        bool pxs_ps_need_en;
 173        bool als_need_dis;
 174        bool pxs_need_dis;
 175
 176        struct regmap *regmap;
 177};
 178
 179static IIO_CONST_ATTR(in_intensity_scale_available, RPR0521_ALS_SCALE_AVAIL);
 180static IIO_CONST_ATTR(in_proximity_scale_available, RPR0521_PXS_SCALE_AVAIL);
 181
 182/*
 183 * Start with easy freq first, whole table of freq combinations is more
 184 * complicated.
 185 */
 186static IIO_CONST_ATTR_SAMP_FREQ_AVAIL("2.5 10");
 187
 188static struct attribute *rpr0521_attributes[] = {
 189        &iio_const_attr_in_intensity_scale_available.dev_attr.attr,
 190        &iio_const_attr_in_proximity_scale_available.dev_attr.attr,
 191        &iio_const_attr_sampling_frequency_available.dev_attr.attr,
 192        NULL,
 193};
 194
 195static const struct attribute_group rpr0521_attribute_group = {
 196        .attrs = rpr0521_attributes,
 197};
 198
 199static const struct iio_chan_spec rpr0521_channels[] = {
 200        {
 201                .type = IIO_PROXIMITY,
 202                .address = RPR0521_CHAN_PXS,
 203                .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
 204                        BIT(IIO_CHAN_INFO_OFFSET) |
 205                        BIT(IIO_CHAN_INFO_SCALE),
 206                .info_mask_shared_by_all = BIT(IIO_CHAN_INFO_SAMP_FREQ),
 207        },
 208        {
 209                .type = IIO_INTENSITY,
 210                .modified = 1,
 211                .address = RPR0521_CHAN_ALS_DATA0,
 212                .channel2 = IIO_MOD_LIGHT_BOTH,
 213                .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
 214                        BIT(IIO_CHAN_INFO_SCALE),
 215                .info_mask_shared_by_all = BIT(IIO_CHAN_INFO_SAMP_FREQ),
 216        },
 217        {
 218                .type = IIO_INTENSITY,
 219                .modified = 1,
 220                .address = RPR0521_CHAN_ALS_DATA1,
 221                .channel2 = IIO_MOD_LIGHT_IR,
 222                .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
 223                        BIT(IIO_CHAN_INFO_SCALE),
 224                .info_mask_shared_by_all = BIT(IIO_CHAN_INFO_SAMP_FREQ),
 225        },
 226};
 227
 228static int rpr0521_als_enable(struct rpr0521_data *data, u8 status)
 229{
 230        int ret;
 231
 232        ret = regmap_update_bits(data->regmap, RPR0521_REG_MODE_CTRL,
 233                                 RPR0521_MODE_ALS_MASK,
 234                                 status);
 235        if (ret < 0)
 236                return ret;
 237
 238        if (status & RPR0521_MODE_ALS_MASK)
 239                data->als_dev_en = true;
 240        else
 241                data->als_dev_en = false;
 242
 243        return 0;
 244}
 245
 246static int rpr0521_pxs_enable(struct rpr0521_data *data, u8 status)
 247{
 248        int ret;
 249
 250        ret = regmap_update_bits(data->regmap, RPR0521_REG_MODE_CTRL,
 251                                 RPR0521_MODE_PXS_MASK,
 252                                 status);
 253        if (ret < 0)
 254                return ret;
 255
 256        if (status & RPR0521_MODE_PXS_MASK)
 257                data->pxs_dev_en = true;
 258        else
 259                data->pxs_dev_en = false;
 260
 261        return 0;
 262}
 263
 264/**
 265 * rpr0521_set_power_state - handles runtime PM state and sensors enabled status
 266 *
 267 * @data: rpr0521 device private data
 268 * @on: state to be set for devices in @device_mask
 269 * @device_mask: bitmask specifying for which device we need to update @on state
 270 *
 271 * Calls for this function must be balanced so that each ON should have matching
 272 * OFF. Otherwise pm usage_count gets out of sync.
 273 */
 274static int rpr0521_set_power_state(struct rpr0521_data *data, bool on,
 275                                   u8 device_mask)
 276{
 277#ifdef CONFIG_PM
 278        int ret;
 279
 280        if (device_mask & RPR0521_MODE_ALS_MASK) {
 281                data->als_ps_need_en = on;
 282                data->als_need_dis = !on;
 283        }
 284
 285        if (device_mask & RPR0521_MODE_PXS_MASK) {
 286                data->pxs_ps_need_en = on;
 287                data->pxs_need_dis = !on;
 288        }
 289
 290        /*
 291         * On: _resume() is called only when we are suspended
 292         * Off: _suspend() is called after delay if _resume() is not
 293         * called before that.
 294         * Note: If either measurement is re-enabled before _suspend(),
 295         * both stay enabled until _suspend().
 296         */
 297        if (on) {
 298                ret = pm_runtime_get_sync(&data->client->dev);
 299        } else {
 300                pm_runtime_mark_last_busy(&data->client->dev);
 301                ret = pm_runtime_put_autosuspend(&data->client->dev);
 302        }
 303        if (ret < 0) {
 304                dev_err(&data->client->dev,
 305                        "Failed: rpr0521_set_power_state for %d, ret %d\n",
 306                        on, ret);
 307                if (on)
 308                        pm_runtime_put_noidle(&data->client->dev);
 309
 310                return ret;
 311        }
 312
 313        if (on) {
 314                /* If _resume() was not called, enable measurement now. */
 315                if (data->als_ps_need_en) {
 316                        ret = rpr0521_als_enable(data, RPR0521_MODE_ALS_ENABLE);
 317                        if (ret)
 318                                return ret;
 319                        data->als_ps_need_en = false;
 320                }
 321
 322                if (data->pxs_ps_need_en) {
 323                        ret = rpr0521_pxs_enable(data, RPR0521_MODE_PXS_ENABLE);
 324                        if (ret)
 325                                return ret;
 326                        data->pxs_ps_need_en = false;
 327                }
 328        }
 329#endif
 330        return 0;
 331}
 332
 333static int rpr0521_get_gain(struct rpr0521_data *data, int chan,
 334                            int *val, int *val2)
 335{
 336        int ret, reg, idx;
 337
 338        ret = regmap_read(data->regmap, rpr0521_gain[chan].reg, &reg);
 339        if (ret < 0)
 340                return ret;
 341
 342        idx = (rpr0521_gain[chan].mask & reg) >> rpr0521_gain[chan].shift;
 343        *val = rpr0521_gain[chan].gain[idx].scale;
 344        *val2 = rpr0521_gain[chan].gain[idx].uscale;
 345
 346        return 0;
 347}
 348
 349static int rpr0521_set_gain(struct rpr0521_data *data, int chan,
 350                            int val, int val2)
 351{
 352        int i, idx = -EINVAL;
 353
 354        /* get gain index */
 355        for (i = 0; i < rpr0521_gain[chan].size; i++)
 356                if (val == rpr0521_gain[chan].gain[i].scale &&
 357                    val2 == rpr0521_gain[chan].gain[i].uscale) {
 358                        idx = i;
 359                        break;
 360                }
 361
 362        if (idx < 0)
 363                return idx;
 364
 365        return regmap_update_bits(data->regmap, rpr0521_gain[chan].reg,
 366                                  rpr0521_gain[chan].mask,
 367                                  idx << rpr0521_gain[chan].shift);
 368}
 369
 370static int rpr0521_read_samp_freq(struct rpr0521_data *data,
 371                                enum iio_chan_type chan_type,
 372                            int *val, int *val2)
 373{
 374        int reg, ret;
 375
 376        ret = regmap_read(data->regmap, RPR0521_REG_MODE_CTRL, &reg);
 377        if (ret < 0)
 378                return ret;
 379
 380        reg &= RPR0521_MODE_MEAS_TIME_MASK;
 381        if (reg >= ARRAY_SIZE(rpr0521_samp_freq_i))
 382                return -EINVAL;
 383
 384        switch (chan_type) {
 385        case IIO_INTENSITY:
 386                *val = rpr0521_samp_freq_i[reg].als_hz;
 387                *val2 = rpr0521_samp_freq_i[reg].als_uhz;
 388                return 0;
 389
 390        case IIO_PROXIMITY:
 391                *val = rpr0521_samp_freq_i[reg].pxs_hz;
 392                *val2 = rpr0521_samp_freq_i[reg].pxs_uhz;
 393                return 0;
 394
 395        default:
 396                return -EINVAL;
 397        }
 398}
 399
 400static int rpr0521_write_samp_freq_common(struct rpr0521_data *data,
 401                                enum iio_chan_type chan_type,
 402                                int val, int val2)
 403{
 404        int i;
 405
 406        /*
 407         * Ignore channel
 408         * both pxs and als are setup only to same freq because of simplicity
 409         */
 410        switch (val) {
 411        case 0:
 412                i = 0;
 413                break;
 414
 415        case 2:
 416                if (val2 != 500000)
 417                        return -EINVAL;
 418
 419                i = 11;
 420                break;
 421
 422        case 10:
 423                i = 6;
 424                break;
 425
 426        default:
 427                return -EINVAL;
 428        }
 429
 430        return regmap_update_bits(data->regmap,
 431                RPR0521_REG_MODE_CTRL,
 432                RPR0521_MODE_MEAS_TIME_MASK,
 433                i);
 434}
 435
 436static int rpr0521_read_ps_offset(struct rpr0521_data *data, int *offset)
 437{
 438        int ret;
 439        __le16 buffer;
 440
 441        ret = regmap_bulk_read(data->regmap,
 442                RPR0521_REG_PS_OFFSET_LSB, &buffer, sizeof(buffer));
 443
 444        if (ret < 0) {
 445                dev_err(&data->client->dev, "Failed to read PS OFFSET register\n");
 446                return ret;
 447        }
 448        *offset = le16_to_cpu(buffer);
 449
 450        return ret;
 451}
 452
 453static int rpr0521_write_ps_offset(struct rpr0521_data *data, int offset)
 454{
 455        int ret;
 456        __le16 buffer;
 457
 458        buffer = cpu_to_le16(offset & 0x3ff);
 459        ret = regmap_raw_write(data->regmap,
 460                RPR0521_REG_PS_OFFSET_LSB, &buffer, sizeof(buffer));
 461
 462        if (ret < 0) {
 463                dev_err(&data->client->dev, "Failed to write PS OFFSET register\n");
 464                return ret;
 465        }
 466
 467        return ret;
 468}
 469
 470static int rpr0521_read_raw(struct iio_dev *indio_dev,
 471                            struct iio_chan_spec const *chan, int *val,
 472                            int *val2, long mask)
 473{
 474        struct rpr0521_data *data = iio_priv(indio_dev);
 475        int ret;
 476        u8 device_mask;
 477        __le16 raw_data;
 478
 479        switch (mask) {
 480        case IIO_CHAN_INFO_RAW:
 481                if (chan->type != IIO_INTENSITY && chan->type != IIO_PROXIMITY)
 482                        return -EINVAL;
 483
 484                device_mask = rpr0521_data_reg[chan->address].device_mask;
 485
 486                mutex_lock(&data->lock);
 487                ret = rpr0521_set_power_state(data, true, device_mask);
 488                if (ret < 0) {
 489                        mutex_unlock(&data->lock);
 490                        return ret;
 491                }
 492
 493                ret = regmap_bulk_read(data->regmap,
 494                                       rpr0521_data_reg[chan->address].address,
 495                                       &raw_data, sizeof(raw_data));
 496                if (ret < 0) {
 497                        rpr0521_set_power_state(data, false, device_mask);
 498                        mutex_unlock(&data->lock);
 499                        return ret;
 500                }
 501
 502                ret = rpr0521_set_power_state(data, false, device_mask);
 503                mutex_unlock(&data->lock);
 504                if (ret < 0)
 505                        return ret;
 506
 507                *val = le16_to_cpu(raw_data);
 508
 509                return IIO_VAL_INT;
 510
 511        case IIO_CHAN_INFO_SCALE:
 512                mutex_lock(&data->lock);
 513                ret = rpr0521_get_gain(data, chan->address, val, val2);
 514                mutex_unlock(&data->lock);
 515                if (ret < 0)
 516                        return ret;
 517
 518                return IIO_VAL_INT_PLUS_MICRO;
 519
 520        case IIO_CHAN_INFO_SAMP_FREQ:
 521                mutex_lock(&data->lock);
 522                ret = rpr0521_read_samp_freq(data, chan->type, val, val2);
 523                mutex_unlock(&data->lock);
 524                if (ret < 0)
 525                        return ret;
 526
 527                return IIO_VAL_INT_PLUS_MICRO;
 528
 529        case IIO_CHAN_INFO_OFFSET:
 530                mutex_lock(&data->lock);
 531                ret = rpr0521_read_ps_offset(data, val);
 532                mutex_unlock(&data->lock);
 533                if (ret < 0)
 534                        return ret;
 535
 536                return IIO_VAL_INT;
 537
 538        default:
 539                return -EINVAL;
 540        }
 541}
 542
 543static int rpr0521_write_raw(struct iio_dev *indio_dev,
 544                             struct iio_chan_spec const *chan, int val,
 545                             int val2, long mask)
 546{
 547        struct rpr0521_data *data = iio_priv(indio_dev);
 548        int ret;
 549
 550        switch (mask) {
 551        case IIO_CHAN_INFO_SCALE:
 552                mutex_lock(&data->lock);
 553                ret = rpr0521_set_gain(data, chan->address, val, val2);
 554                mutex_unlock(&data->lock);
 555
 556                return ret;
 557
 558        case IIO_CHAN_INFO_SAMP_FREQ:
 559                mutex_lock(&data->lock);
 560                ret = rpr0521_write_samp_freq_common(data, chan->type,
 561                                                     val, val2);
 562                mutex_unlock(&data->lock);
 563
 564                return ret;
 565
 566        case IIO_CHAN_INFO_OFFSET:
 567                mutex_lock(&data->lock);
 568                ret = rpr0521_write_ps_offset(data, val);
 569                mutex_unlock(&data->lock);
 570
 571                return ret;
 572
 573        default:
 574                return -EINVAL;
 575        }
 576}
 577
 578static const struct iio_info rpr0521_info = {
 579        .driver_module  = THIS_MODULE,
 580        .read_raw       = rpr0521_read_raw,
 581        .write_raw      = rpr0521_write_raw,
 582        .attrs          = &rpr0521_attribute_group,
 583};
 584
 585static int rpr0521_init(struct rpr0521_data *data)
 586{
 587        int ret;
 588        int id;
 589
 590        ret = regmap_read(data->regmap, RPR0521_REG_ID, &id);
 591        if (ret < 0) {
 592                dev_err(&data->client->dev, "Failed to read REG_ID register\n");
 593                return ret;
 594        }
 595
 596        if (id != RPR0521_MANUFACT_ID) {
 597                dev_err(&data->client->dev, "Wrong id, got %x, expected %x\n",
 598                        id, RPR0521_MANUFACT_ID);
 599                return -ENODEV;
 600        }
 601
 602        /* set default measurement time - 100 ms for both ALS and PS */
 603        ret = regmap_update_bits(data->regmap, RPR0521_REG_MODE_CTRL,
 604                                 RPR0521_MODE_MEAS_TIME_MASK,
 605                                 RPR0521_DEFAULT_MEAS_TIME);
 606        if (ret) {
 607                pr_err("regmap_update_bits returned %d\n", ret);
 608                return ret;
 609        }
 610
 611#ifndef CONFIG_PM
 612        ret = rpr0521_als_enable(data, RPR0521_MODE_ALS_ENABLE);
 613        if (ret < 0)
 614                return ret;
 615        ret = rpr0521_pxs_enable(data, RPR0521_MODE_PXS_ENABLE);
 616        if (ret < 0)
 617                return ret;
 618#endif
 619
 620        return 0;
 621}
 622
 623static int rpr0521_poweroff(struct rpr0521_data *data)
 624{
 625        int ret;
 626
 627        ret = regmap_update_bits(data->regmap, RPR0521_REG_MODE_CTRL,
 628                                 RPR0521_MODE_ALS_MASK |
 629                                 RPR0521_MODE_PXS_MASK,
 630                                 RPR0521_MODE_ALS_DISABLE |
 631                                 RPR0521_MODE_PXS_DISABLE);
 632        if (ret < 0)
 633                return ret;
 634
 635        data->als_dev_en = false;
 636        data->pxs_dev_en = false;
 637
 638        return 0;
 639}
 640
 641static bool rpr0521_is_volatile_reg(struct device *dev, unsigned int reg)
 642{
 643        switch (reg) {
 644        case RPR0521_REG_MODE_CTRL:
 645        case RPR0521_REG_ALS_CTRL:
 646        case RPR0521_REG_PXS_CTRL:
 647                return false;
 648        default:
 649                return true;
 650        }
 651}
 652
 653static const struct regmap_config rpr0521_regmap_config = {
 654        .name           = RPR0521_REGMAP_NAME,
 655
 656        .reg_bits       = 8,
 657        .val_bits       = 8,
 658
 659        .max_register   = RPR0521_REG_ID,
 660        .cache_type     = REGCACHE_RBTREE,
 661        .volatile_reg   = rpr0521_is_volatile_reg,
 662};
 663
 664static int rpr0521_probe(struct i2c_client *client,
 665                         const struct i2c_device_id *id)
 666{
 667        struct rpr0521_data *data;
 668        struct iio_dev *indio_dev;
 669        struct regmap *regmap;
 670        int ret;
 671
 672        indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*data));
 673        if (!indio_dev)
 674                return -ENOMEM;
 675
 676        regmap = devm_regmap_init_i2c(client, &rpr0521_regmap_config);
 677        if (IS_ERR(regmap)) {
 678                dev_err(&client->dev, "regmap_init failed!\n");
 679                return PTR_ERR(regmap);
 680        }
 681
 682        data = iio_priv(indio_dev);
 683        i2c_set_clientdata(client, indio_dev);
 684        data->client = client;
 685        data->regmap = regmap;
 686
 687        mutex_init(&data->lock);
 688
 689        indio_dev->dev.parent = &client->dev;
 690        indio_dev->info = &rpr0521_info;
 691        indio_dev->name = RPR0521_DRV_NAME;
 692        indio_dev->channels = rpr0521_channels;
 693        indio_dev->num_channels = ARRAY_SIZE(rpr0521_channels);
 694        indio_dev->modes = INDIO_DIRECT_MODE;
 695
 696        ret = rpr0521_init(data);
 697        if (ret < 0) {
 698                dev_err(&client->dev, "rpr0521 chip init failed\n");
 699                return ret;
 700        }
 701
 702        ret = pm_runtime_set_active(&client->dev);
 703        if (ret < 0)
 704                goto err_poweroff;
 705
 706        pm_runtime_enable(&client->dev);
 707        pm_runtime_set_autosuspend_delay(&client->dev, RPR0521_SLEEP_DELAY_MS);
 708        pm_runtime_use_autosuspend(&client->dev);
 709
 710        ret = iio_device_register(indio_dev);
 711        if (ret)
 712                goto err_pm_disable;
 713
 714        return 0;
 715
 716err_pm_disable:
 717        pm_runtime_disable(&client->dev);
 718        pm_runtime_set_suspended(&client->dev);
 719        pm_runtime_put_noidle(&client->dev);
 720err_poweroff:
 721        rpr0521_poweroff(data);
 722
 723        return ret;
 724}
 725
 726static int rpr0521_remove(struct i2c_client *client)
 727{
 728        struct iio_dev *indio_dev = i2c_get_clientdata(client);
 729
 730        iio_device_unregister(indio_dev);
 731
 732        pm_runtime_disable(&client->dev);
 733        pm_runtime_set_suspended(&client->dev);
 734        pm_runtime_put_noidle(&client->dev);
 735
 736        rpr0521_poweroff(iio_priv(indio_dev));
 737
 738        return 0;
 739}
 740
 741#ifdef CONFIG_PM
 742static int rpr0521_runtime_suspend(struct device *dev)
 743{
 744        struct iio_dev *indio_dev = i2c_get_clientdata(to_i2c_client(dev));
 745        struct rpr0521_data *data = iio_priv(indio_dev);
 746        int ret;
 747
 748        mutex_lock(&data->lock);
 749        /* If measurements are enabled, enable them on resume */
 750        if (!data->als_need_dis)
 751                data->als_ps_need_en = data->als_dev_en;
 752        if (!data->pxs_need_dis)
 753                data->pxs_ps_need_en = data->pxs_dev_en;
 754
 755        /* disable channels and sets {als,pxs}_dev_en to false */
 756        ret = rpr0521_poweroff(data);
 757        regcache_mark_dirty(data->regmap);
 758        mutex_unlock(&data->lock);
 759
 760        return ret;
 761}
 762
 763static int rpr0521_runtime_resume(struct device *dev)
 764{
 765        struct iio_dev *indio_dev = i2c_get_clientdata(to_i2c_client(dev));
 766        struct rpr0521_data *data = iio_priv(indio_dev);
 767        int ret;
 768
 769        regcache_sync(data->regmap);
 770        if (data->als_ps_need_en) {
 771                ret = rpr0521_als_enable(data, RPR0521_MODE_ALS_ENABLE);
 772                if (ret < 0)
 773                        return ret;
 774                data->als_ps_need_en = false;
 775        }
 776
 777        if (data->pxs_ps_need_en) {
 778                ret = rpr0521_pxs_enable(data, RPR0521_MODE_PXS_ENABLE);
 779                if (ret < 0)
 780                        return ret;
 781                data->pxs_ps_need_en = false;
 782        }
 783        msleep(100);    //wait for first measurement result
 784
 785        return 0;
 786}
 787#endif
 788
 789static const struct dev_pm_ops rpr0521_pm_ops = {
 790        SET_RUNTIME_PM_OPS(rpr0521_runtime_suspend,
 791                           rpr0521_runtime_resume, NULL)
 792};
 793
 794static const struct acpi_device_id rpr0521_acpi_match[] = {
 795        {"RPR0521", 0},
 796        { }
 797};
 798MODULE_DEVICE_TABLE(acpi, rpr0521_acpi_match);
 799
 800static const struct i2c_device_id rpr0521_id[] = {
 801        {"rpr0521", 0},
 802        { }
 803};
 804
 805MODULE_DEVICE_TABLE(i2c, rpr0521_id);
 806
 807static struct i2c_driver rpr0521_driver = {
 808        .driver = {
 809                .name   = RPR0521_DRV_NAME,
 810                .pm     = &rpr0521_pm_ops,
 811                .acpi_match_table = ACPI_PTR(rpr0521_acpi_match),
 812        },
 813        .probe          = rpr0521_probe,
 814        .remove         = rpr0521_remove,
 815        .id_table       = rpr0521_id,
 816};
 817
 818module_i2c_driver(rpr0521_driver);
 819
 820MODULE_AUTHOR("Daniel Baluta <daniel.baluta@intel.com>");
 821MODULE_DESCRIPTION("RPR0521 ROHM Ambient Light and Proximity Sensor driver");
 822MODULE_LICENSE("GPL v2");
 823