linux/drivers/iio/light/cm36651.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0-only
   2/*
   3 * Copyright (C) 2013 Samsung Electronics Co., Ltd.
   4 * Author: Beomho Seo <beomho.seo@samsung.com>
   5 */
   6
   7#include <linux/delay.h>
   8#include <linux/err.h>
   9#include <linux/i2c.h>
  10#include <linux/mutex.h>
  11#include <linux/module.h>
  12#include <linux/interrupt.h>
  13#include <linux/regulator/consumer.h>
  14#include <linux/iio/iio.h>
  15#include <linux/iio/sysfs.h>
  16#include <linux/iio/events.h>
  17
  18/* Slave address 0x19 for PS of 7 bit addressing protocol for I2C */
  19#define CM36651_I2C_ADDR_PS             0x19
  20/* Alert Response Address */
  21#define CM36651_ARA                     0x0C
  22
  23/* Ambient light sensor */
  24#define CM36651_CS_CONF1                0x00
  25#define CM36651_CS_CONF2                0x01
  26#define CM36651_ALS_WH_M                0x02
  27#define CM36651_ALS_WH_L                0x03
  28#define CM36651_ALS_WL_M                0x04
  29#define CM36651_ALS_WL_L                0x05
  30#define CM36651_CS_CONF3                0x06
  31#define CM36651_CS_CONF_REG_NUM         0x02
  32
  33/* Proximity sensor */
  34#define CM36651_PS_CONF1                0x00
  35#define CM36651_PS_THD                  0x01
  36#define CM36651_PS_CANC                 0x02
  37#define CM36651_PS_CONF2                0x03
  38#define CM36651_PS_REG_NUM              0x04
  39
  40/* CS_CONF1 command code */
  41#define CM36651_ALS_ENABLE              0x00
  42#define CM36651_ALS_DISABLE             0x01
  43#define CM36651_ALS_INT_EN              0x02
  44#define CM36651_ALS_THRES               0x04
  45
  46/* CS_CONF2 command code */
  47#define CM36651_CS_CONF2_DEFAULT_BIT    0x08
  48
  49/* CS_CONF3 channel integration time */
  50#define CM36651_CS_IT1                  0x00 /* Integration time 80 msec */
  51#define CM36651_CS_IT2                  0x40 /* Integration time 160 msec */
  52#define CM36651_CS_IT3                  0x80 /* Integration time 320 msec */
  53#define CM36651_CS_IT4                  0xC0 /* Integration time 640 msec */
  54
  55/* PS_CONF1 command code */
  56#define CM36651_PS_ENABLE               0x00
  57#define CM36651_PS_DISABLE              0x01
  58#define CM36651_PS_INT_EN               0x02
  59#define CM36651_PS_PERS2                0x04
  60#define CM36651_PS_PERS3                0x08
  61#define CM36651_PS_PERS4                0x0C
  62
  63/* PS_CONF1 command code: integration time */
  64#define CM36651_PS_IT1                  0x00 /* Integration time 0.32 msec */
  65#define CM36651_PS_IT2                  0x10 /* Integration time 0.42 msec */
  66#define CM36651_PS_IT3                  0x20 /* Integration time 0.52 msec */
  67#define CM36651_PS_IT4                  0x30 /* Integration time 0.64 msec */
  68
  69/* PS_CONF1 command code: duty ratio */
  70#define CM36651_PS_DR1                  0x00 /* Duty ratio 1/80 */
  71#define CM36651_PS_DR2                  0x40 /* Duty ratio 1/160 */
  72#define CM36651_PS_DR3                  0x80 /* Duty ratio 1/320 */
  73#define CM36651_PS_DR4                  0xC0 /* Duty ratio 1/640 */
  74
  75/* PS_THD command code */
  76#define CM36651_PS_INITIAL_THD          0x05
  77
  78/* PS_CANC command code */
  79#define CM36651_PS_CANC_DEFAULT         0x00
  80
  81/* PS_CONF2 command code */
  82#define CM36651_PS_HYS1                 0x00
  83#define CM36651_PS_HYS2                 0x01
  84#define CM36651_PS_SMART_PERS_EN        0x02
  85#define CM36651_PS_DIR_INT              0x04
  86#define CM36651_PS_MS                   0x10
  87
  88#define CM36651_CS_COLOR_NUM            4
  89
  90#define CM36651_CLOSE_PROXIMITY         0x32
  91#define CM36651_FAR_PROXIMITY                   0x33
  92
  93#define CM36651_CS_INT_TIME_AVAIL       "0.08 0.16 0.32 0.64"
  94#define CM36651_PS_INT_TIME_AVAIL       "0.000320 0.000420 0.000520 0.000640"
  95
  96enum cm36651_operation_mode {
  97        CM36651_LIGHT_EN,
  98        CM36651_PROXIMITY_EN,
  99        CM36651_PROXIMITY_EV_EN,
 100};
 101
 102enum cm36651_light_channel_idx {
 103        CM36651_LIGHT_CHANNEL_IDX_RED,
 104        CM36651_LIGHT_CHANNEL_IDX_GREEN,
 105        CM36651_LIGHT_CHANNEL_IDX_BLUE,
 106        CM36651_LIGHT_CHANNEL_IDX_CLEAR,
 107};
 108
 109enum cm36651_command {
 110        CM36651_CMD_READ_RAW_LIGHT,
 111        CM36651_CMD_READ_RAW_PROXIMITY,
 112        CM36651_CMD_PROX_EV_EN,
 113        CM36651_CMD_PROX_EV_DIS,
 114};
 115
 116static const u8 cm36651_cs_reg[CM36651_CS_CONF_REG_NUM] = {
 117        CM36651_CS_CONF1,
 118        CM36651_CS_CONF2,
 119};
 120
 121static const u8 cm36651_ps_reg[CM36651_PS_REG_NUM] = {
 122        CM36651_PS_CONF1,
 123        CM36651_PS_THD,
 124        CM36651_PS_CANC,
 125        CM36651_PS_CONF2,
 126};
 127
 128struct cm36651_data {
 129        const struct cm36651_platform_data *pdata;
 130        struct i2c_client *client;
 131        struct i2c_client *ps_client;
 132        struct i2c_client *ara_client;
 133        struct mutex lock;
 134        struct regulator *vled_reg;
 135        unsigned long flags;
 136        int cs_int_time[CM36651_CS_COLOR_NUM];
 137        int ps_int_time;
 138        u8 cs_ctrl_regs[CM36651_CS_CONF_REG_NUM];
 139        u8 ps_ctrl_regs[CM36651_PS_REG_NUM];
 140        u16 color[CM36651_CS_COLOR_NUM];
 141};
 142
 143static int cm36651_setup_reg(struct cm36651_data *cm36651)
 144{
 145        struct i2c_client *client = cm36651->client;
 146        struct i2c_client *ps_client = cm36651->ps_client;
 147        int i, ret;
 148
 149        /* CS initialization */
 150        cm36651->cs_ctrl_regs[CM36651_CS_CONF1] = CM36651_ALS_ENABLE |
 151                                                             CM36651_ALS_THRES;
 152        cm36651->cs_ctrl_regs[CM36651_CS_CONF2] = CM36651_CS_CONF2_DEFAULT_BIT;
 153
 154        for (i = 0; i < CM36651_CS_CONF_REG_NUM; i++) {
 155                ret = i2c_smbus_write_byte_data(client, cm36651_cs_reg[i],
 156                                                     cm36651->cs_ctrl_regs[i]);
 157                if (ret < 0)
 158                        return ret;
 159        }
 160
 161        /* PS initialization */
 162        cm36651->ps_ctrl_regs[CM36651_PS_CONF1] = CM36651_PS_ENABLE |
 163                                                                CM36651_PS_IT2;
 164        cm36651->ps_ctrl_regs[CM36651_PS_THD] = CM36651_PS_INITIAL_THD;
 165        cm36651->ps_ctrl_regs[CM36651_PS_CANC] = CM36651_PS_CANC_DEFAULT;
 166        cm36651->ps_ctrl_regs[CM36651_PS_CONF2] = CM36651_PS_HYS2 |
 167                                CM36651_PS_DIR_INT | CM36651_PS_SMART_PERS_EN;
 168
 169        for (i = 0; i < CM36651_PS_REG_NUM; i++) {
 170                ret = i2c_smbus_write_byte_data(ps_client, cm36651_ps_reg[i],
 171                                                     cm36651->ps_ctrl_regs[i]);
 172                if (ret < 0)
 173                        return ret;
 174        }
 175
 176        /* Set shutdown mode */
 177        ret = i2c_smbus_write_byte_data(client, CM36651_CS_CONF1,
 178                                                          CM36651_ALS_DISABLE);
 179        if (ret < 0)
 180                return ret;
 181
 182        ret = i2c_smbus_write_byte_data(cm36651->ps_client,
 183                                         CM36651_PS_CONF1, CM36651_PS_DISABLE);
 184        if (ret < 0)
 185                return ret;
 186
 187        return 0;
 188}
 189
 190static int cm36651_read_output(struct cm36651_data *cm36651,
 191                                struct iio_chan_spec const *chan, int *val)
 192{
 193        struct i2c_client *client = cm36651->client;
 194        int ret = -EINVAL;
 195
 196        switch (chan->type) {
 197        case IIO_LIGHT:
 198                *val = i2c_smbus_read_word_data(client, chan->address);
 199                if (*val < 0)
 200                        return ret;
 201
 202                ret = i2c_smbus_write_byte_data(client, CM36651_CS_CONF1,
 203                                                        CM36651_ALS_DISABLE);
 204                if (ret < 0)
 205                        return ret;
 206
 207                ret = IIO_VAL_INT;
 208                break;
 209        case IIO_PROXIMITY:
 210                *val = i2c_smbus_read_byte(cm36651->ps_client);
 211                if (*val < 0)
 212                        return ret;
 213
 214                if (!test_bit(CM36651_PROXIMITY_EV_EN, &cm36651->flags)) {
 215                        ret = i2c_smbus_write_byte_data(cm36651->ps_client,
 216                                        CM36651_PS_CONF1, CM36651_PS_DISABLE);
 217                        if (ret < 0)
 218                                return ret;
 219                }
 220
 221                ret = IIO_VAL_INT;
 222                break;
 223        default:
 224                break;
 225        }
 226
 227        return ret;
 228}
 229
 230static irqreturn_t cm36651_irq_handler(int irq, void *data)
 231{
 232        struct iio_dev *indio_dev = data;
 233        struct cm36651_data *cm36651 = iio_priv(indio_dev);
 234        struct i2c_client *client = cm36651->client;
 235        int ev_dir, ret;
 236        u64 ev_code;
 237
 238        /*
 239         * The PS INT pin is an active low signal that PS INT move logic low
 240         * when the object is detect. Once the MCU host received the PS INT
 241         * "LOW" signal, the Host needs to read the data at Alert Response
 242         * Address(ARA) to clear the PS INT signal. After clearing the PS
 243         * INT pin, the PS INT signal toggles from low to high.
 244         */
 245        ret = i2c_smbus_read_byte(cm36651->ara_client);
 246        if (ret < 0) {
 247                dev_err(&client->dev,
 248                                "%s: Data read failed: %d\n", __func__, ret);
 249                return IRQ_HANDLED;
 250        }
 251        switch (ret) {
 252        case CM36651_CLOSE_PROXIMITY:
 253                ev_dir = IIO_EV_DIR_RISING;
 254                break;
 255        case CM36651_FAR_PROXIMITY:
 256                ev_dir = IIO_EV_DIR_FALLING;
 257                break;
 258        default:
 259                dev_err(&client->dev,
 260                        "%s: Data read wrong: %d\n", __func__, ret);
 261                return IRQ_HANDLED;
 262        }
 263
 264        ev_code = IIO_UNMOD_EVENT_CODE(IIO_PROXIMITY,
 265                                CM36651_CMD_READ_RAW_PROXIMITY,
 266                                IIO_EV_TYPE_THRESH, ev_dir);
 267
 268        iio_push_event(indio_dev, ev_code, iio_get_time_ns(indio_dev));
 269
 270        return IRQ_HANDLED;
 271}
 272
 273static int cm36651_set_operation_mode(struct cm36651_data *cm36651, int cmd)
 274{
 275        struct i2c_client *client = cm36651->client;
 276        struct i2c_client *ps_client = cm36651->ps_client;
 277        int ret = -EINVAL;
 278
 279        switch (cmd) {
 280        case CM36651_CMD_READ_RAW_LIGHT:
 281                ret = i2c_smbus_write_byte_data(client, CM36651_CS_CONF1,
 282                                cm36651->cs_ctrl_regs[CM36651_CS_CONF1]);
 283                break;
 284        case CM36651_CMD_READ_RAW_PROXIMITY:
 285                if (test_bit(CM36651_PROXIMITY_EV_EN, &cm36651->flags))
 286                        return CM36651_PROXIMITY_EV_EN;
 287
 288                ret = i2c_smbus_write_byte_data(ps_client, CM36651_PS_CONF1,
 289                                cm36651->ps_ctrl_regs[CM36651_PS_CONF1]);
 290                break;
 291        case CM36651_CMD_PROX_EV_EN:
 292                if (test_bit(CM36651_PROXIMITY_EV_EN, &cm36651->flags)) {
 293                        dev_err(&client->dev,
 294                                "Already proximity event enable state\n");
 295                        return ret;
 296                }
 297                set_bit(CM36651_PROXIMITY_EV_EN, &cm36651->flags);
 298
 299                ret = i2c_smbus_write_byte_data(ps_client,
 300                        cm36651_ps_reg[CM36651_PS_CONF1],
 301                        CM36651_PS_INT_EN | CM36651_PS_PERS2 | CM36651_PS_IT2);
 302
 303                if (ret < 0) {
 304                        dev_err(&client->dev, "Proximity enable event failed\n");
 305                        return ret;
 306                }
 307                break;
 308        case CM36651_CMD_PROX_EV_DIS:
 309                if (!test_bit(CM36651_PROXIMITY_EV_EN, &cm36651->flags)) {
 310                        dev_err(&client->dev,
 311                                "Already proximity event disable state\n");
 312                        return ret;
 313                }
 314                clear_bit(CM36651_PROXIMITY_EV_EN, &cm36651->flags);
 315                ret = i2c_smbus_write_byte_data(ps_client,
 316                                        CM36651_PS_CONF1, CM36651_PS_DISABLE);
 317                break;
 318        }
 319
 320        if (ret < 0)
 321                dev_err(&client->dev, "Write register failed\n");
 322
 323        return ret;
 324}
 325
 326static int cm36651_read_channel(struct cm36651_data *cm36651,
 327                                struct iio_chan_spec const *chan, int *val)
 328{
 329        struct i2c_client *client = cm36651->client;
 330        int cmd, ret;
 331
 332        if (chan->type == IIO_LIGHT)
 333                cmd = CM36651_CMD_READ_RAW_LIGHT;
 334        else if (chan->type == IIO_PROXIMITY)
 335                cmd = CM36651_CMD_READ_RAW_PROXIMITY;
 336        else
 337                return -EINVAL;
 338
 339        ret = cm36651_set_operation_mode(cm36651, cmd);
 340        if (ret < 0) {
 341                dev_err(&client->dev, "CM36651 set operation mode failed\n");
 342                return ret;
 343        }
 344        /* Delay for work after enable operation */
 345        msleep(50);
 346        ret = cm36651_read_output(cm36651, chan, val);
 347        if (ret < 0) {
 348                dev_err(&client->dev, "CM36651 read output failed\n");
 349                return ret;
 350        }
 351
 352        return ret;
 353}
 354
 355static int cm36651_read_int_time(struct cm36651_data *cm36651,
 356                                struct iio_chan_spec const *chan, int *val2)
 357{
 358        switch (chan->type) {
 359        case IIO_LIGHT:
 360                if (cm36651->cs_int_time[chan->address] == CM36651_CS_IT1)
 361                        *val2 = 80000;
 362                else if (cm36651->cs_int_time[chan->address] == CM36651_CS_IT2)
 363                        *val2 = 160000;
 364                else if (cm36651->cs_int_time[chan->address] == CM36651_CS_IT3)
 365                        *val2 = 320000;
 366                else if (cm36651->cs_int_time[chan->address] == CM36651_CS_IT4)
 367                        *val2 = 640000;
 368                else
 369                        return -EINVAL;
 370                break;
 371        case IIO_PROXIMITY:
 372                if (cm36651->ps_int_time == CM36651_PS_IT1)
 373                        *val2 = 320;
 374                else if (cm36651->ps_int_time == CM36651_PS_IT2)
 375                        *val2 = 420;
 376                else if (cm36651->ps_int_time == CM36651_PS_IT3)
 377                        *val2 = 520;
 378                else if (cm36651->ps_int_time == CM36651_PS_IT4)
 379                        *val2 = 640;
 380                else
 381                        return -EINVAL;
 382                break;
 383        default:
 384                return -EINVAL;
 385        }
 386
 387        return IIO_VAL_INT_PLUS_MICRO;
 388}
 389
 390static int cm36651_write_int_time(struct cm36651_data *cm36651,
 391                                struct iio_chan_spec const *chan, int val)
 392{
 393        struct i2c_client *client = cm36651->client;
 394        struct i2c_client *ps_client = cm36651->ps_client;
 395        int int_time, ret;
 396
 397        switch (chan->type) {
 398        case IIO_LIGHT:
 399                if (val == 80000)
 400                        int_time = CM36651_CS_IT1;
 401                else if (val == 160000)
 402                        int_time = CM36651_CS_IT2;
 403                else if (val == 320000)
 404                        int_time = CM36651_CS_IT3;
 405                else if (val == 640000)
 406                        int_time = CM36651_CS_IT4;
 407                else
 408                        return -EINVAL;
 409
 410                ret = i2c_smbus_write_byte_data(client, CM36651_CS_CONF3,
 411                                           int_time >> 2 * (chan->address));
 412                if (ret < 0) {
 413                        dev_err(&client->dev, "CS integration time write failed\n");
 414                        return ret;
 415                }
 416                cm36651->cs_int_time[chan->address] = int_time;
 417                break;
 418        case IIO_PROXIMITY:
 419                if (val == 320)
 420                        int_time = CM36651_PS_IT1;
 421                else if (val == 420)
 422                        int_time = CM36651_PS_IT2;
 423                else if (val == 520)
 424                        int_time = CM36651_PS_IT3;
 425                else if (val == 640)
 426                        int_time = CM36651_PS_IT4;
 427                else
 428                        return -EINVAL;
 429
 430                ret = i2c_smbus_write_byte_data(ps_client,
 431                                                CM36651_PS_CONF1, int_time);
 432                if (ret < 0) {
 433                        dev_err(&client->dev, "PS integration time write failed\n");
 434                        return ret;
 435                }
 436                cm36651->ps_int_time = int_time;
 437                break;
 438        default:
 439                return -EINVAL;
 440        }
 441
 442        return ret;
 443}
 444
 445static int cm36651_read_raw(struct iio_dev *indio_dev,
 446                            struct iio_chan_spec const *chan,
 447                            int *val, int *val2, long mask)
 448{
 449        struct cm36651_data *cm36651 = iio_priv(indio_dev);
 450        int ret;
 451
 452        mutex_lock(&cm36651->lock);
 453
 454        switch (mask) {
 455        case IIO_CHAN_INFO_RAW:
 456                ret = cm36651_read_channel(cm36651, chan, val);
 457                break;
 458        case IIO_CHAN_INFO_INT_TIME:
 459                *val = 0;
 460                ret = cm36651_read_int_time(cm36651, chan, val2);
 461                break;
 462        default:
 463                ret = -EINVAL;
 464        }
 465
 466        mutex_unlock(&cm36651->lock);
 467
 468        return ret;
 469}
 470
 471static int cm36651_write_raw(struct iio_dev *indio_dev,
 472                             struct iio_chan_spec const *chan,
 473                             int val, int val2, long mask)
 474{
 475        struct cm36651_data *cm36651 = iio_priv(indio_dev);
 476        struct i2c_client *client = cm36651->client;
 477        int ret = -EINVAL;
 478
 479        if (mask == IIO_CHAN_INFO_INT_TIME) {
 480                ret = cm36651_write_int_time(cm36651, chan, val2);
 481                if (ret < 0)
 482                        dev_err(&client->dev, "Integration time write failed\n");
 483        }
 484
 485        return ret;
 486}
 487
 488static int cm36651_read_prox_thresh(struct iio_dev *indio_dev,
 489                                        const struct iio_chan_spec *chan,
 490                                        enum iio_event_type type,
 491                                        enum iio_event_direction dir,
 492                                        enum iio_event_info info,
 493                                        int *val, int *val2)
 494{
 495        struct cm36651_data *cm36651 = iio_priv(indio_dev);
 496
 497        *val = cm36651->ps_ctrl_regs[CM36651_PS_THD];
 498
 499        return 0;
 500}
 501
 502static int cm36651_write_prox_thresh(struct iio_dev *indio_dev,
 503                                        const struct iio_chan_spec *chan,
 504                                        enum iio_event_type type,
 505                                        enum iio_event_direction dir,
 506                                        enum iio_event_info info,
 507                                        int val, int val2)
 508{
 509        struct cm36651_data *cm36651 = iio_priv(indio_dev);
 510        struct i2c_client *client = cm36651->client;
 511        int ret;
 512
 513        if (val < 3 || val > 255)
 514                return -EINVAL;
 515
 516        cm36651->ps_ctrl_regs[CM36651_PS_THD] = val;
 517        ret = i2c_smbus_write_byte_data(cm36651->ps_client, CM36651_PS_THD,
 518                                        cm36651->ps_ctrl_regs[CM36651_PS_THD]);
 519
 520        if (ret < 0) {
 521                dev_err(&client->dev, "PS threshold write failed: %d\n", ret);
 522                return ret;
 523        }
 524
 525        return 0;
 526}
 527
 528static int cm36651_write_prox_event_config(struct iio_dev *indio_dev,
 529                                        const struct iio_chan_spec *chan,
 530                                        enum iio_event_type type,
 531                                        enum iio_event_direction dir,
 532                                        int state)
 533{
 534        struct cm36651_data *cm36651 = iio_priv(indio_dev);
 535        int cmd, ret = -EINVAL;
 536
 537        mutex_lock(&cm36651->lock);
 538
 539        cmd = state ? CM36651_CMD_PROX_EV_EN : CM36651_CMD_PROX_EV_DIS;
 540        ret = cm36651_set_operation_mode(cm36651, cmd);
 541
 542        mutex_unlock(&cm36651->lock);
 543
 544        return ret;
 545}
 546
 547static int cm36651_read_prox_event_config(struct iio_dev *indio_dev,
 548                                        const struct iio_chan_spec *chan,
 549                                        enum iio_event_type type,
 550                                        enum iio_event_direction dir)
 551{
 552        struct cm36651_data *cm36651 = iio_priv(indio_dev);
 553        int event_en;
 554
 555        mutex_lock(&cm36651->lock);
 556
 557        event_en = test_bit(CM36651_PROXIMITY_EV_EN, &cm36651->flags);
 558
 559        mutex_unlock(&cm36651->lock);
 560
 561        return event_en;
 562}
 563
 564#define CM36651_LIGHT_CHANNEL(_color, _idx) {           \
 565        .type = IIO_LIGHT,                              \
 566        .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |  \
 567                        BIT(IIO_CHAN_INFO_INT_TIME),    \
 568        .address = _idx,                                \
 569        .modified = 1,                                  \
 570        .channel2 = IIO_MOD_LIGHT_##_color,             \
 571}                                                       \
 572
 573static const struct iio_event_spec cm36651_event_spec[] = {
 574        {
 575                .type = IIO_EV_TYPE_THRESH,
 576                .dir = IIO_EV_DIR_EITHER,
 577                .mask_separate = BIT(IIO_EV_INFO_VALUE) |
 578                                BIT(IIO_EV_INFO_ENABLE),
 579        }
 580};
 581
 582static const struct iio_chan_spec cm36651_channels[] = {
 583        {
 584                .type = IIO_PROXIMITY,
 585                .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
 586                                BIT(IIO_CHAN_INFO_INT_TIME),
 587                .event_spec = cm36651_event_spec,
 588                .num_event_specs = ARRAY_SIZE(cm36651_event_spec),
 589        },
 590        CM36651_LIGHT_CHANNEL(RED, CM36651_LIGHT_CHANNEL_IDX_RED),
 591        CM36651_LIGHT_CHANNEL(GREEN, CM36651_LIGHT_CHANNEL_IDX_GREEN),
 592        CM36651_LIGHT_CHANNEL(BLUE, CM36651_LIGHT_CHANNEL_IDX_BLUE),
 593        CM36651_LIGHT_CHANNEL(CLEAR, CM36651_LIGHT_CHANNEL_IDX_CLEAR),
 594};
 595
 596static IIO_CONST_ATTR(in_illuminance_integration_time_available,
 597                                        CM36651_CS_INT_TIME_AVAIL);
 598static IIO_CONST_ATTR(in_proximity_integration_time_available,
 599                                        CM36651_PS_INT_TIME_AVAIL);
 600
 601static struct attribute *cm36651_attributes[] = {
 602        &iio_const_attr_in_illuminance_integration_time_available.dev_attr.attr,
 603        &iio_const_attr_in_proximity_integration_time_available.dev_attr.attr,
 604        NULL,
 605};
 606
 607static const struct attribute_group cm36651_attribute_group = {
 608        .attrs = cm36651_attributes
 609};
 610
 611static const struct iio_info cm36651_info = {
 612        .read_raw               = &cm36651_read_raw,
 613        .write_raw              = &cm36651_write_raw,
 614        .read_event_value       = &cm36651_read_prox_thresh,
 615        .write_event_value      = &cm36651_write_prox_thresh,
 616        .read_event_config      = &cm36651_read_prox_event_config,
 617        .write_event_config     = &cm36651_write_prox_event_config,
 618        .attrs                  = &cm36651_attribute_group,
 619};
 620
 621static int cm36651_probe(struct i2c_client *client,
 622                             const struct i2c_device_id *id)
 623{
 624        struct cm36651_data *cm36651;
 625        struct iio_dev *indio_dev;
 626        int ret;
 627
 628        indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*cm36651));
 629        if (!indio_dev)
 630                return -ENOMEM;
 631
 632        cm36651 = iio_priv(indio_dev);
 633
 634        cm36651->vled_reg = devm_regulator_get(&client->dev, "vled");
 635        if (IS_ERR(cm36651->vled_reg)) {
 636                dev_err(&client->dev, "get regulator vled failed\n");
 637                return PTR_ERR(cm36651->vled_reg);
 638        }
 639
 640        ret = regulator_enable(cm36651->vled_reg);
 641        if (ret) {
 642                dev_err(&client->dev, "enable regulator vled failed\n");
 643                return ret;
 644        }
 645
 646        i2c_set_clientdata(client, indio_dev);
 647
 648        cm36651->client = client;
 649        cm36651->ps_client = i2c_new_dummy(client->adapter,
 650                                                     CM36651_I2C_ADDR_PS);
 651        if (!cm36651->ps_client) {
 652                dev_err(&client->dev, "%s: new i2c device failed\n", __func__);
 653                ret = -ENODEV;
 654                goto error_disable_reg;
 655        }
 656
 657        cm36651->ara_client = i2c_new_dummy(client->adapter, CM36651_ARA);
 658        if (!cm36651->ara_client) {
 659                dev_err(&client->dev, "%s: new i2c device failed\n", __func__);
 660                ret = -ENODEV;
 661                goto error_i2c_unregister_ps;
 662        }
 663
 664        mutex_init(&cm36651->lock);
 665        indio_dev->dev.parent = &client->dev;
 666        indio_dev->channels = cm36651_channels;
 667        indio_dev->num_channels = ARRAY_SIZE(cm36651_channels);
 668        indio_dev->info = &cm36651_info;
 669        indio_dev->name = id->name;
 670        indio_dev->modes = INDIO_DIRECT_MODE;
 671
 672        ret = cm36651_setup_reg(cm36651);
 673        if (ret) {
 674                dev_err(&client->dev, "%s: register setup failed\n", __func__);
 675                goto error_i2c_unregister_ara;
 676        }
 677
 678        ret = request_threaded_irq(client->irq, NULL, cm36651_irq_handler,
 679                                        IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
 680                                                        "cm36651", indio_dev);
 681        if (ret) {
 682                dev_err(&client->dev, "%s: request irq failed\n", __func__);
 683                goto error_i2c_unregister_ara;
 684        }
 685
 686        ret = iio_device_register(indio_dev);
 687        if (ret) {
 688                dev_err(&client->dev, "%s: regist device failed\n", __func__);
 689                goto error_free_irq;
 690        }
 691
 692        return 0;
 693
 694error_free_irq:
 695        free_irq(client->irq, indio_dev);
 696error_i2c_unregister_ara:
 697        i2c_unregister_device(cm36651->ara_client);
 698error_i2c_unregister_ps:
 699        i2c_unregister_device(cm36651->ps_client);
 700error_disable_reg:
 701        regulator_disable(cm36651->vled_reg);
 702        return ret;
 703}
 704
 705static int cm36651_remove(struct i2c_client *client)
 706{
 707        struct iio_dev *indio_dev = i2c_get_clientdata(client);
 708        struct cm36651_data *cm36651 = iio_priv(indio_dev);
 709
 710        iio_device_unregister(indio_dev);
 711        regulator_disable(cm36651->vled_reg);
 712        free_irq(client->irq, indio_dev);
 713        i2c_unregister_device(cm36651->ps_client);
 714        i2c_unregister_device(cm36651->ara_client);
 715
 716        return 0;
 717}
 718
 719static const struct i2c_device_id cm36651_id[] = {
 720        { "cm36651", 0 },
 721        { }
 722};
 723
 724MODULE_DEVICE_TABLE(i2c, cm36651_id);
 725
 726static const struct of_device_id cm36651_of_match[] = {
 727        { .compatible = "capella,cm36651" },
 728        { }
 729};
 730MODULE_DEVICE_TABLE(of, cm36651_of_match);
 731
 732static struct i2c_driver cm36651_driver = {
 733        .driver = {
 734                .name   = "cm36651",
 735                .of_match_table = cm36651_of_match,
 736        },
 737        .probe          = cm36651_probe,
 738        .remove         = cm36651_remove,
 739        .id_table       = cm36651_id,
 740};
 741
 742module_i2c_driver(cm36651_driver);
 743
 744MODULE_AUTHOR("Beomho Seo <beomho.seo@samsung.com>");
 745MODULE_DESCRIPTION("CM36651 proximity/ambient light sensor driver");
 746MODULE_LICENSE("GPL v2");
 747