Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

iio: cm36651: Add CM36651 proximity/light sensor

This patch adds a new driver for Capella CM36651 proximity and RGB sensor.

Signed-off-by: Beomho Seo <beomho.seo@samsung.com>
Signed-off-by: Jonathan Cameron <jic23@kernel.org>

authored by

Beomho Seo and committed by
Jonathan Cameron
e590d451 a47f6e08

+720
+11
drivers/iio/light/Kconfig
··· 27 27 To compile this driver as a module, choose M here: the 28 28 module will be called apds9300. 29 29 30 + config CM36651 31 + depends on I2C 32 + tristate "CM36651 driver" 33 + help 34 + Say Y here if you use cm36651. 35 + This option enables proximity & RGB sensor using 36 + Capella cm36651 device driver. 37 + 38 + To compile this driver as a module, choose M here: 39 + the module will be called cm36651. 40 + 30 41 config GP2AP020A00F 31 42 tristate "Sharp GP2AP020A00F Proximity/ALS sensor" 32 43 depends on I2C
+1
drivers/iio/light/Makefile
··· 5 5 # When adding new entries keep the list in alphabetical order 6 6 obj-$(CONFIG_ADJD_S311) += adjd_s311.o 7 7 obj-$(CONFIG_APDS9300) += apds9300.o 8 + obj-$(CONFIG_CM36651) += cm36651.o 8 9 obj-$(CONFIG_GP2AP020A00F) += gp2ap020a00f.o 9 10 obj-$(CONFIG_HID_SENSOR_ALS) += hid-sensor-als.o 10 11 obj-$(CONFIG_SENSORS_LM3533) += lm3533-als.o
+708
drivers/iio/light/cm36651.c
··· 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 80000 usec */ 54 + #define CM36651_CS_IT2 0x40 /* Integration time 160000 usec */ 55 + #define CM36651_CS_IT3 0x80 /* Integration time 320000 usec */ 56 + #define CM36651_CS_IT4 0xC0 /* Integration time 640000 usec */ 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 320 usec */ 68 + #define CM36651_PS_IT2 0x10 /* Integration time 420 usec */ 69 + #define CM36651_PS_IT3 0x20 /* Integration time 520 usec */ 70 + #define CM36651_PS_IT4 0x30 /* Integration time 640 usec */ 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 "80000 160000 320000 640000" 97 + #define CM36651_PS_INT_TIME_AVAIL "320 420 520 640" 98 + 99 + enum cm36651_operation_mode { 100 + CM36651_LIGHT_EN, 101 + CM36651_PROXIMITY_EN, 102 + CM36651_PROXIMITY_EV_EN, 103 + }; 104 + 105 + enum 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 + 112 + enum 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 + 119 + static const u8 cm36651_cs_reg[CM36651_CS_CONF_REG_NUM] = { 120 + CM36651_CS_CONF1, 121 + CM36651_CS_CONF2, 122 + }; 123 + 124 + static 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 + 131 + struct 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 + 146 + static 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 + 193 + static 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 + 233 + static 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 + 276 + static 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 + 329 + static 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 + 358 + static int cm36651_read_int_time(struct cm36651_data *cm36651, 359 + struct iio_chan_spec const *chan, int *val) 360 + { 361 + switch (chan->type) { 362 + case IIO_LIGHT: 363 + if (cm36651->cs_int_time[chan->address] == CM36651_CS_IT1) 364 + *val = 80000; 365 + else if (cm36651->cs_int_time[chan->address] == CM36651_CS_IT2) 366 + *val = 160000; 367 + else if (cm36651->cs_int_time[chan->address] == CM36651_CS_IT3) 368 + *val = 320000; 369 + else if (cm36651->cs_int_time[chan->address] == CM36651_CS_IT4) 370 + *val = 640000; 371 + else 372 + return -EINVAL; 373 + break; 374 + case IIO_PROXIMITY: 375 + if (cm36651->ps_int_time == CM36651_PS_IT1) 376 + *val = 320; 377 + else if (cm36651->ps_int_time == CM36651_PS_IT2) 378 + *val = 420; 379 + else if (cm36651->ps_int_time == CM36651_PS_IT3) 380 + *val = 520; 381 + else if (cm36651->ps_int_time == CM36651_PS_IT4) 382 + *val = 640; 383 + else 384 + return -EINVAL; 385 + break; 386 + default: 387 + return -EINVAL; 388 + } 389 + 390 + return IIO_VAL_INT_PLUS_MICRO; 391 + } 392 + 393 + static 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 + 448 + static 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 + ret = cm36651_read_int_time(cm36651, chan, val); 463 + break; 464 + default: 465 + ret = -EINVAL; 466 + } 467 + 468 + mutex_unlock(&cm36651->lock); 469 + 470 + return ret; 471 + } 472 + 473 + static int cm36651_write_raw(struct iio_dev *indio_dev, 474 + struct iio_chan_spec const *chan, 475 + int val, int val2, long mask) 476 + { 477 + struct cm36651_data *cm36651 = iio_priv(indio_dev); 478 + struct i2c_client *client = cm36651->client; 479 + int ret = -EINVAL; 480 + 481 + if (mask == IIO_CHAN_INFO_INT_TIME) { 482 + ret = cm36651_write_int_time(cm36651, chan, val); 483 + if (ret < 0) 484 + dev_err(&client->dev, "Integration time write failed\n"); 485 + } 486 + 487 + return ret; 488 + } 489 + 490 + static int cm36651_read_prox_thresh(struct iio_dev *indio_dev, 491 + u64 event_code, int *val) 492 + { 493 + struct cm36651_data *cm36651 = iio_priv(indio_dev); 494 + 495 + *val = cm36651->ps_ctrl_regs[CM36651_PS_THD]; 496 + 497 + return 0; 498 + } 499 + 500 + static int cm36651_write_prox_thresh(struct iio_dev *indio_dev, 501 + u64 event_code, int val) 502 + { 503 + struct cm36651_data *cm36651 = iio_priv(indio_dev); 504 + struct i2c_client *client = cm36651->client; 505 + int ret; 506 + 507 + if (val < 3 || val > 255) 508 + return -EINVAL; 509 + 510 + cm36651->ps_ctrl_regs[CM36651_PS_THD] = val; 511 + ret = i2c_smbus_write_byte_data(cm36651->ps_client, CM36651_PS_THD, 512 + cm36651->ps_ctrl_regs[CM36651_PS_THD]); 513 + 514 + if (ret < 0) { 515 + dev_err(&client->dev, "PS threshold write failed: %d\n", ret); 516 + return ret; 517 + } 518 + 519 + return 0; 520 + } 521 + 522 + static int cm36651_write_prox_event_config(struct iio_dev *indio_dev, 523 + u64 event_code, int state) 524 + { 525 + struct cm36651_data *cm36651 = iio_priv(indio_dev); 526 + int cmd, ret = -EINVAL; 527 + 528 + mutex_lock(&cm36651->lock); 529 + 530 + cmd = state ? CM36651_CMD_PROX_EV_EN : CM36651_CMD_PROX_EV_DIS; 531 + ret = cm36651_set_operation_mode(cm36651, cmd); 532 + 533 + mutex_unlock(&cm36651->lock); 534 + 535 + return ret; 536 + } 537 + 538 + static int cm36651_read_prox_event_config(struct iio_dev *indio_dev, 539 + u64 event_code) 540 + { 541 + struct cm36651_data *cm36651 = iio_priv(indio_dev); 542 + int event_en; 543 + 544 + mutex_lock(&cm36651->lock); 545 + 546 + event_en = test_bit(CM36651_PROXIMITY_EV_EN, &cm36651->flags); 547 + 548 + mutex_unlock(&cm36651->lock); 549 + 550 + return event_en; 551 + } 552 + 553 + #define CM36651_LIGHT_CHANNEL(_color, _idx) { \ 554 + .type = IIO_LIGHT, \ 555 + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | \ 556 + BIT(IIO_CHAN_INFO_INT_TIME), \ 557 + .address = _idx, \ 558 + .modified = 1, \ 559 + .channel2 = IIO_MOD_LIGHT_##_color, \ 560 + } \ 561 + 562 + static const struct iio_chan_spec cm36651_channels[] = { 563 + { 564 + .type = IIO_PROXIMITY, 565 + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | 566 + BIT(IIO_CHAN_INFO_INT_TIME), 567 + .event_mask = IIO_EV_BIT(IIO_EV_TYPE_THRESH, IIO_EV_DIR_EITHER) 568 + }, 569 + CM36651_LIGHT_CHANNEL(RED, CM36651_LIGHT_CHANNEL_IDX_RED), 570 + CM36651_LIGHT_CHANNEL(GREEN, CM36651_LIGHT_CHANNEL_IDX_GREEN), 571 + CM36651_LIGHT_CHANNEL(BLUE, CM36651_LIGHT_CHANNEL_IDX_BLUE), 572 + CM36651_LIGHT_CHANNEL(CLEAR, CM36651_LIGHT_CHANNEL_IDX_CLEAR), 573 + }; 574 + 575 + static IIO_CONST_ATTR(in_illuminance_integration_time_available, 576 + CM36651_CS_INT_TIME_AVAIL); 577 + static IIO_CONST_ATTR(in_proximity_integration_time_available, 578 + CM36651_PS_INT_TIME_AVAIL); 579 + 580 + static struct attribute *cm36651_attributes[] = { 581 + &iio_const_attr_in_illuminance_integration_time_available.dev_attr.attr, 582 + &iio_const_attr_in_proximity_integration_time_available.dev_attr.attr, 583 + NULL, 584 + }; 585 + 586 + static const struct attribute_group cm36651_attribute_group = { 587 + .attrs = cm36651_attributes 588 + }; 589 + 590 + static const struct iio_info cm36651_info = { 591 + .driver_module = THIS_MODULE, 592 + .read_raw = &cm36651_read_raw, 593 + .write_raw = &cm36651_write_raw, 594 + .read_event_value = &cm36651_read_prox_thresh, 595 + .write_event_value = &cm36651_write_prox_thresh, 596 + .read_event_config = &cm36651_read_prox_event_config, 597 + .write_event_config = &cm36651_write_prox_event_config, 598 + .attrs = &cm36651_attribute_group, 599 + }; 600 + 601 + static int cm36651_probe(struct i2c_client *client, 602 + const struct i2c_device_id *id) 603 + { 604 + struct cm36651_data *cm36651; 605 + struct iio_dev *indio_dev; 606 + int ret; 607 + 608 + indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*cm36651)); 609 + if (!indio_dev) 610 + return -ENOMEM; 611 + 612 + cm36651 = iio_priv(indio_dev); 613 + 614 + cm36651->vled_reg = devm_regulator_get(&client->dev, "vled"); 615 + if (IS_ERR(cm36651->vled_reg)) { 616 + dev_err(&client->dev, "get regulator vled failed\n"); 617 + return PTR_ERR(cm36651->vled_reg); 618 + } 619 + 620 + ret = regulator_enable(cm36651->vled_reg); 621 + if (ret) { 622 + dev_err(&client->dev, "enable regulator vled failed\n"); 623 + return ret; 624 + } 625 + 626 + i2c_set_clientdata(client, indio_dev); 627 + 628 + cm36651->client = client; 629 + cm36651->ps_client = i2c_new_dummy(client->adapter, 630 + CM36651_I2C_ADDR_PS); 631 + cm36651->ara_client = i2c_new_dummy(client->adapter, CM36651_ARA); 632 + mutex_init(&cm36651->lock); 633 + indio_dev->dev.parent = &client->dev; 634 + indio_dev->channels = cm36651_channels; 635 + indio_dev->num_channels = ARRAY_SIZE(cm36651_channels); 636 + indio_dev->info = &cm36651_info; 637 + indio_dev->name = id->name; 638 + indio_dev->modes = INDIO_DIRECT_MODE; 639 + 640 + ret = cm36651_setup_reg(cm36651); 641 + if (ret) { 642 + dev_err(&client->dev, "%s: register setup failed\n", __func__); 643 + goto error_disable_reg; 644 + } 645 + 646 + ret = request_threaded_irq(client->irq, NULL, cm36651_irq_handler, 647 + IRQF_TRIGGER_FALLING | IRQF_ONESHOT, 648 + "cm36651", indio_dev); 649 + if (ret) { 650 + dev_err(&client->dev, "%s: request irq failed\n", __func__); 651 + goto error_disable_reg; 652 + } 653 + 654 + ret = iio_device_register(indio_dev); 655 + if (ret) { 656 + dev_err(&client->dev, "%s: regist device failed\n", __func__); 657 + goto error_free_irq; 658 + } 659 + 660 + return 0; 661 + 662 + error_free_irq: 663 + free_irq(client->irq, indio_dev); 664 + error_disable_reg: 665 + regulator_disable(cm36651->vled_reg); 666 + return ret; 667 + } 668 + 669 + static int cm36651_remove(struct i2c_client *client) 670 + { 671 + struct iio_dev *indio_dev = i2c_get_clientdata(client); 672 + struct cm36651_data *cm36651 = iio_priv(indio_dev); 673 + 674 + iio_device_unregister(indio_dev); 675 + regulator_disable(cm36651->vled_reg); 676 + free_irq(client->irq, indio_dev); 677 + 678 + return 0; 679 + } 680 + 681 + static const struct i2c_device_id cm36651_id[] = { 682 + { "cm36651", 0 }, 683 + { } 684 + }; 685 + 686 + MODULE_DEVICE_TABLE(i2c, cm36651_id); 687 + 688 + static const struct of_device_id cm36651_of_match[] = { 689 + { .compatible = "capella,cm36651" }, 690 + { } 691 + }; 692 + 693 + static struct i2c_driver cm36651_driver = { 694 + .driver = { 695 + .name = "cm36651", 696 + .of_match_table = of_match_ptr(cm36651_of_match), 697 + .owner = THIS_MODULE, 698 + }, 699 + .probe = cm36651_probe, 700 + .remove = cm36651_remove, 701 + .id_table = cm36651_id, 702 + }; 703 + 704 + module_i2c_driver(cm36651_driver); 705 + 706 + MODULE_AUTHOR("Beomho Seo <beomho.seo@samsung.com>"); 707 + MODULE_DESCRIPTION("CM36651 proximity/ambient light sensor driver"); 708 + MODULE_LICENSE("GPL v2");