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