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