tsl2583.c (24295B)
1// SPDX-License-Identifier: GPL-2.0-or-later 2/* 3 * Device driver for monitoring ambient light intensity (lux) 4 * within the TAOS tsl258x family of devices (tsl2580, tsl2581, tsl2583). 5 * 6 * Copyright (c) 2011, TAOS Corporation. 7 * Copyright (c) 2016-2017 Brian Masney <masneyb@onstation.org> 8 */ 9 10#include <linux/kernel.h> 11#include <linux/i2c.h> 12#include <linux/errno.h> 13#include <linux/delay.h> 14#include <linux/string.h> 15#include <linux/mutex.h> 16#include <linux/unistd.h> 17#include <linux/slab.h> 18#include <linux/module.h> 19#include <linux/iio/iio.h> 20#include <linux/iio/sysfs.h> 21#include <linux/pm_runtime.h> 22 23/* Device Registers and Masks */ 24#define TSL2583_CNTRL 0x00 25#define TSL2583_ALS_TIME 0X01 26#define TSL2583_INTERRUPT 0x02 27#define TSL2583_GAIN 0x07 28#define TSL2583_REVID 0x11 29#define TSL2583_CHIPID 0x12 30#define TSL2583_ALS_CHAN0LO 0x14 31#define TSL2583_ALS_CHAN0HI 0x15 32#define TSL2583_ALS_CHAN1LO 0x16 33#define TSL2583_ALS_CHAN1HI 0x17 34#define TSL2583_TMR_LO 0x18 35#define TSL2583_TMR_HI 0x19 36 37/* tsl2583 cmd reg masks */ 38#define TSL2583_CMD_REG 0x80 39#define TSL2583_CMD_SPL_FN 0x60 40#define TSL2583_CMD_ALS_INT_CLR 0x01 41 42/* tsl2583 cntrl reg masks */ 43#define TSL2583_CNTL_ADC_ENBL 0x02 44#define TSL2583_CNTL_PWR_OFF 0x00 45#define TSL2583_CNTL_PWR_ON 0x01 46 47/* tsl2583 status reg masks */ 48#define TSL2583_STA_ADC_VALID 0x01 49#define TSL2583_STA_ADC_INTR 0x10 50 51/* Lux calculation constants */ 52#define TSL2583_LUX_CALC_OVER_FLOW 65535 53 54#define TSL2583_INTERRUPT_DISABLED 0x00 55 56#define TSL2583_CHIP_ID 0x90 57#define TSL2583_CHIP_ID_MASK 0xf0 58 59#define TSL2583_POWER_OFF_DELAY_MS 2000 60 61/* Per-device data */ 62struct tsl2583_als_info { 63 u16 als_ch0; 64 u16 als_ch1; 65 u16 lux; 66}; 67 68struct tsl2583_lux { 69 unsigned int ratio; 70 unsigned int ch0; 71 unsigned int ch1; 72}; 73 74static const struct tsl2583_lux tsl2583_default_lux[] = { 75 { 9830, 8520, 15729 }, 76 { 12452, 10807, 23344 }, 77 { 14746, 6383, 11705 }, 78 { 17695, 4063, 6554 }, 79 { 0, 0, 0 } /* Termination segment */ 80}; 81 82#define TSL2583_MAX_LUX_TABLE_ENTRIES 11 83 84struct tsl2583_settings { 85 int als_time; 86 int als_gain; 87 int als_gain_trim; 88 int als_cal_target; 89 90 /* 91 * This structure is intentionally large to accommodate updates via 92 * sysfs. Sized to 11 = max 10 segments + 1 termination segment. 93 * Assumption is that one and only one type of glass used. 94 */ 95 struct tsl2583_lux als_device_lux[TSL2583_MAX_LUX_TABLE_ENTRIES]; 96}; 97 98struct tsl2583_chip { 99 struct mutex als_mutex; 100 struct i2c_client *client; 101 struct tsl2583_als_info als_cur_info; 102 struct tsl2583_settings als_settings; 103 int als_time_scale; 104 int als_saturation; 105}; 106 107struct gainadj { 108 s16 ch0; 109 s16 ch1; 110 s16 mean; 111}; 112 113/* Index = (0 - 3) Used to validate the gain selection index */ 114static const struct gainadj gainadj[] = { 115 { 1, 1, 1 }, 116 { 8, 8, 8 }, 117 { 16, 16, 16 }, 118 { 107, 115, 111 } 119}; 120 121/* 122 * Provides initial operational parameter defaults. 123 * These defaults may be changed through the device's sysfs files. 124 */ 125static void tsl2583_defaults(struct tsl2583_chip *chip) 126{ 127 /* 128 * The integration time must be a multiple of 50ms and within the 129 * range [50, 600] ms. 130 */ 131 chip->als_settings.als_time = 100; 132 133 /* 134 * This is an index into the gainadj table. Assume clear glass as the 135 * default. 136 */ 137 chip->als_settings.als_gain = 0; 138 139 /* Default gain trim to account for aperture effects */ 140 chip->als_settings.als_gain_trim = 1000; 141 142 /* Known external ALS reading used for calibration */ 143 chip->als_settings.als_cal_target = 130; 144 145 /* Default lux table. */ 146 memcpy(chip->als_settings.als_device_lux, tsl2583_default_lux, 147 sizeof(tsl2583_default_lux)); 148} 149 150/* 151 * Reads and calculates current lux value. 152 * The raw ch0 and ch1 values of the ambient light sensed in the last 153 * integration cycle are read from the device. 154 * Time scale factor array values are adjusted based on the integration time. 155 * The raw values are multiplied by a scale factor, and device gain is obtained 156 * using gain index. Limit checks are done next, then the ratio of a multiple 157 * of ch1 value, to the ch0 value, is calculated. The array als_device_lux[] 158 * declared above is then scanned to find the first ratio value that is just 159 * above the ratio we just calculated. The ch0 and ch1 multiplier constants in 160 * the array are then used along with the time scale factor array values, to 161 * calculate the lux. 162 */ 163static int tsl2583_get_lux(struct iio_dev *indio_dev) 164{ 165 u16 ch0, ch1; /* separated ch0/ch1 data from device */ 166 u32 lux; /* raw lux calculated from device data */ 167 u64 lux64; 168 u32 ratio; 169 u8 buf[5]; 170 struct tsl2583_lux *p; 171 struct tsl2583_chip *chip = iio_priv(indio_dev); 172 int i, ret; 173 174 ret = i2c_smbus_read_byte_data(chip->client, TSL2583_CMD_REG); 175 if (ret < 0) { 176 dev_err(&chip->client->dev, "%s: failed to read CMD_REG register\n", 177 __func__); 178 goto done; 179 } 180 181 /* is data new & valid */ 182 if (!(ret & TSL2583_STA_ADC_INTR)) { 183 dev_err(&chip->client->dev, "%s: data not valid; returning last value\n", 184 __func__); 185 ret = chip->als_cur_info.lux; /* return LAST VALUE */ 186 goto done; 187 } 188 189 for (i = 0; i < 4; i++) { 190 int reg = TSL2583_CMD_REG | (TSL2583_ALS_CHAN0LO + i); 191 192 ret = i2c_smbus_read_byte_data(chip->client, reg); 193 if (ret < 0) { 194 dev_err(&chip->client->dev, "%s: failed to read register %x\n", 195 __func__, reg); 196 goto done; 197 } 198 buf[i] = ret; 199 } 200 201 /* 202 * Clear the pending interrupt status bit on the chip to allow the next 203 * integration cycle to start. This has to be done even though this 204 * driver currently does not support interrupts. 205 */ 206 ret = i2c_smbus_write_byte(chip->client, 207 (TSL2583_CMD_REG | TSL2583_CMD_SPL_FN | 208 TSL2583_CMD_ALS_INT_CLR)); 209 if (ret < 0) { 210 dev_err(&chip->client->dev, "%s: failed to clear the interrupt bit\n", 211 __func__); 212 goto done; /* have no data, so return failure */ 213 } 214 215 /* extract ALS/lux data */ 216 ch0 = le16_to_cpup((const __le16 *)&buf[0]); 217 ch1 = le16_to_cpup((const __le16 *)&buf[2]); 218 219 chip->als_cur_info.als_ch0 = ch0; 220 chip->als_cur_info.als_ch1 = ch1; 221 222 if ((ch0 >= chip->als_saturation) || (ch1 >= chip->als_saturation)) 223 goto return_max; 224 225 if (!ch0) { 226 /* 227 * The sensor appears to be in total darkness so set the 228 * calculated lux to 0 and return early to avoid a division by 229 * zero below when calculating the ratio. 230 */ 231 ret = 0; 232 chip->als_cur_info.lux = 0; 233 goto done; 234 } 235 236 /* calculate ratio */ 237 ratio = (ch1 << 15) / ch0; 238 239 /* convert to unscaled lux using the pointer to the table */ 240 for (p = (struct tsl2583_lux *)chip->als_settings.als_device_lux; 241 p->ratio != 0 && p->ratio < ratio; p++) 242 ; 243 244 if (p->ratio == 0) { 245 lux = 0; 246 } else { 247 u32 ch0lux, ch1lux; 248 249 ch0lux = ((ch0 * p->ch0) + 250 (gainadj[chip->als_settings.als_gain].ch0 >> 1)) 251 / gainadj[chip->als_settings.als_gain].ch0; 252 ch1lux = ((ch1 * p->ch1) + 253 (gainadj[chip->als_settings.als_gain].ch1 >> 1)) 254 / gainadj[chip->als_settings.als_gain].ch1; 255 256 /* note: lux is 31 bit max at this point */ 257 if (ch1lux > ch0lux) { 258 dev_dbg(&chip->client->dev, "%s: No Data - Returning 0\n", 259 __func__); 260 ret = 0; 261 chip->als_cur_info.lux = 0; 262 goto done; 263 } 264 265 lux = ch0lux - ch1lux; 266 } 267 268 /* adjust for active time scale */ 269 if (chip->als_time_scale == 0) 270 lux = 0; 271 else 272 lux = (lux + (chip->als_time_scale >> 1)) / 273 chip->als_time_scale; 274 275 /* 276 * Adjust for active gain scale. 277 * The tsl2583_default_lux tables above have a factor of 8192 built in, 278 * so we need to shift right. 279 * User-specified gain provides a multiplier. 280 * Apply user-specified gain before shifting right to retain precision. 281 * Use 64 bits to avoid overflow on multiplication. 282 * Then go back to 32 bits before division to avoid using div_u64(). 283 */ 284 lux64 = lux; 285 lux64 = lux64 * chip->als_settings.als_gain_trim; 286 lux64 >>= 13; 287 lux = lux64; 288 lux = DIV_ROUND_CLOSEST(lux, 1000); 289 290 if (lux > TSL2583_LUX_CALC_OVER_FLOW) { /* check for overflow */ 291return_max: 292 lux = TSL2583_LUX_CALC_OVER_FLOW; 293 } 294 295 /* Update the structure with the latest VALID lux. */ 296 chip->als_cur_info.lux = lux; 297 ret = lux; 298 299done: 300 return ret; 301} 302 303/* 304 * Obtain single reading and calculate the als_gain_trim (later used 305 * to derive actual lux). 306 * Return updated gain_trim value. 307 */ 308static int tsl2583_als_calibrate(struct iio_dev *indio_dev) 309{ 310 struct tsl2583_chip *chip = iio_priv(indio_dev); 311 unsigned int gain_trim_val; 312 int ret; 313 int lux_val; 314 315 ret = i2c_smbus_read_byte_data(chip->client, 316 TSL2583_CMD_REG | TSL2583_CNTRL); 317 if (ret < 0) { 318 dev_err(&chip->client->dev, 319 "%s: failed to read from the CNTRL register\n", 320 __func__); 321 return ret; 322 } 323 324 if ((ret & (TSL2583_CNTL_ADC_ENBL | TSL2583_CNTL_PWR_ON)) 325 != (TSL2583_CNTL_ADC_ENBL | TSL2583_CNTL_PWR_ON)) { 326 dev_err(&chip->client->dev, 327 "%s: Device is not powered on and/or ADC is not enabled\n", 328 __func__); 329 return -EINVAL; 330 } else if ((ret & TSL2583_STA_ADC_VALID) != TSL2583_STA_ADC_VALID) { 331 dev_err(&chip->client->dev, 332 "%s: The two ADC channels have not completed an integration cycle\n", 333 __func__); 334 return -ENODATA; 335 } 336 337 lux_val = tsl2583_get_lux(indio_dev); 338 if (lux_val < 0) { 339 dev_err(&chip->client->dev, "%s: failed to get lux\n", 340 __func__); 341 return lux_val; 342 } 343 344 /* Avoid division by zero of lux_value later on */ 345 if (lux_val == 0) { 346 dev_err(&chip->client->dev, 347 "%s: lux_val of 0 will produce out of range trim_value\n", 348 __func__); 349 return -ENODATA; 350 } 351 352 gain_trim_val = (unsigned int)(((chip->als_settings.als_cal_target) 353 * chip->als_settings.als_gain_trim) / lux_val); 354 if ((gain_trim_val < 250) || (gain_trim_val > 4000)) { 355 dev_err(&chip->client->dev, 356 "%s: trim_val of %d is not within the range [250, 4000]\n", 357 __func__, gain_trim_val); 358 return -ENODATA; 359 } 360 361 chip->als_settings.als_gain_trim = (int)gain_trim_val; 362 363 return 0; 364} 365 366static int tsl2583_set_als_time(struct tsl2583_chip *chip) 367{ 368 int als_count, als_time, ret; 369 u8 val; 370 371 /* determine als integration register */ 372 als_count = DIV_ROUND_CLOSEST(chip->als_settings.als_time * 100, 270); 373 if (!als_count) 374 als_count = 1; /* ensure at least one cycle */ 375 376 /* convert back to time (encompasses overrides) */ 377 als_time = DIV_ROUND_CLOSEST(als_count * 27, 10); 378 379 val = 256 - als_count; 380 ret = i2c_smbus_write_byte_data(chip->client, 381 TSL2583_CMD_REG | TSL2583_ALS_TIME, 382 val); 383 if (ret < 0) { 384 dev_err(&chip->client->dev, "%s: failed to set the als time to %d\n", 385 __func__, val); 386 return ret; 387 } 388 389 /* set chip struct re scaling and saturation */ 390 chip->als_saturation = als_count * 922; /* 90% of full scale */ 391 chip->als_time_scale = DIV_ROUND_CLOSEST(als_time, 50); 392 393 return ret; 394} 395 396static int tsl2583_set_als_gain(struct tsl2583_chip *chip) 397{ 398 int ret; 399 400 /* Set the gain based on als_settings struct */ 401 ret = i2c_smbus_write_byte_data(chip->client, 402 TSL2583_CMD_REG | TSL2583_GAIN, 403 chip->als_settings.als_gain); 404 if (ret < 0) 405 dev_err(&chip->client->dev, 406 "%s: failed to set the gain to %d\n", __func__, 407 chip->als_settings.als_gain); 408 409 return ret; 410} 411 412static int tsl2583_set_power_state(struct tsl2583_chip *chip, u8 state) 413{ 414 int ret; 415 416 ret = i2c_smbus_write_byte_data(chip->client, 417 TSL2583_CMD_REG | TSL2583_CNTRL, state); 418 if (ret < 0) 419 dev_err(&chip->client->dev, 420 "%s: failed to set the power state to %d\n", __func__, 421 state); 422 423 return ret; 424} 425 426/* 427 * Turn the device on. 428 * Configuration must be set before calling this function. 429 */ 430static int tsl2583_chip_init_and_power_on(struct iio_dev *indio_dev) 431{ 432 struct tsl2583_chip *chip = iio_priv(indio_dev); 433 int ret; 434 435 /* Power on the device; ADC off. */ 436 ret = tsl2583_set_power_state(chip, TSL2583_CNTL_PWR_ON); 437 if (ret < 0) 438 return ret; 439 440 ret = i2c_smbus_write_byte_data(chip->client, 441 TSL2583_CMD_REG | TSL2583_INTERRUPT, 442 TSL2583_INTERRUPT_DISABLED); 443 if (ret < 0) { 444 dev_err(&chip->client->dev, 445 "%s: failed to disable interrupts\n", __func__); 446 return ret; 447 } 448 449 ret = tsl2583_set_als_time(chip); 450 if (ret < 0) 451 return ret; 452 453 ret = tsl2583_set_als_gain(chip); 454 if (ret < 0) 455 return ret; 456 457 usleep_range(3000, 3500); 458 459 ret = tsl2583_set_power_state(chip, TSL2583_CNTL_PWR_ON | 460 TSL2583_CNTL_ADC_ENBL); 461 if (ret < 0) 462 return ret; 463 464 return ret; 465} 466 467/* Sysfs Interface Functions */ 468 469static ssize_t in_illuminance_input_target_show(struct device *dev, 470 struct device_attribute *attr, 471 char *buf) 472{ 473 struct iio_dev *indio_dev = dev_to_iio_dev(dev); 474 struct tsl2583_chip *chip = iio_priv(indio_dev); 475 int ret; 476 477 mutex_lock(&chip->als_mutex); 478 ret = sprintf(buf, "%d\n", chip->als_settings.als_cal_target); 479 mutex_unlock(&chip->als_mutex); 480 481 return ret; 482} 483 484static ssize_t in_illuminance_input_target_store(struct device *dev, 485 struct device_attribute *attr, 486 const char *buf, size_t len) 487{ 488 struct iio_dev *indio_dev = dev_to_iio_dev(dev); 489 struct tsl2583_chip *chip = iio_priv(indio_dev); 490 int value; 491 492 if (kstrtoint(buf, 0, &value) || !value) 493 return -EINVAL; 494 495 mutex_lock(&chip->als_mutex); 496 chip->als_settings.als_cal_target = value; 497 mutex_unlock(&chip->als_mutex); 498 499 return len; 500} 501 502static ssize_t in_illuminance_calibrate_store(struct device *dev, 503 struct device_attribute *attr, 504 const char *buf, size_t len) 505{ 506 struct iio_dev *indio_dev = dev_to_iio_dev(dev); 507 struct tsl2583_chip *chip = iio_priv(indio_dev); 508 int value, ret; 509 510 if (kstrtoint(buf, 0, &value) || value != 1) 511 return -EINVAL; 512 513 mutex_lock(&chip->als_mutex); 514 515 ret = tsl2583_als_calibrate(indio_dev); 516 if (ret < 0) 517 goto done; 518 519 ret = len; 520done: 521 mutex_unlock(&chip->als_mutex); 522 523 return ret; 524} 525 526static ssize_t in_illuminance_lux_table_show(struct device *dev, 527 struct device_attribute *attr, 528 char *buf) 529{ 530 struct iio_dev *indio_dev = dev_to_iio_dev(dev); 531 struct tsl2583_chip *chip = iio_priv(indio_dev); 532 unsigned int i; 533 int offset = 0; 534 535 for (i = 0; i < ARRAY_SIZE(chip->als_settings.als_device_lux); i++) { 536 offset += sprintf(buf + offset, "%u,%u,%u,", 537 chip->als_settings.als_device_lux[i].ratio, 538 chip->als_settings.als_device_lux[i].ch0, 539 chip->als_settings.als_device_lux[i].ch1); 540 if (chip->als_settings.als_device_lux[i].ratio == 0) { 541 /* 542 * We just printed the first "0" entry. 543 * Now get rid of the extra "," and break. 544 */ 545 offset--; 546 break; 547 } 548 } 549 550 offset += sprintf(buf + offset, "\n"); 551 552 return offset; 553} 554 555static ssize_t in_illuminance_lux_table_store(struct device *dev, 556 struct device_attribute *attr, 557 const char *buf, size_t len) 558{ 559 struct iio_dev *indio_dev = dev_to_iio_dev(dev); 560 struct tsl2583_chip *chip = iio_priv(indio_dev); 561 const unsigned int max_ints = TSL2583_MAX_LUX_TABLE_ENTRIES * 3; 562 int value[TSL2583_MAX_LUX_TABLE_ENTRIES * 3 + 1]; 563 int ret = -EINVAL; 564 unsigned int n; 565 566 mutex_lock(&chip->als_mutex); 567 568 get_options(buf, ARRAY_SIZE(value), value); 569 570 /* 571 * We now have an array of ints starting at value[1], and 572 * enumerated by value[0]. 573 * We expect each group of three ints is one table entry, 574 * and the last table entry is all 0. 575 */ 576 n = value[0]; 577 if ((n % 3) || n < 6 || n > max_ints) { 578 dev_err(dev, 579 "%s: The number of entries in the lux table must be a multiple of 3 and within the range [6, %d]\n", 580 __func__, max_ints); 581 goto done; 582 } 583 if ((value[n - 2] | value[n - 1] | value[n]) != 0) { 584 dev_err(dev, "%s: The last 3 entries in the lux table must be zeros.\n", 585 __func__); 586 goto done; 587 } 588 589 memcpy(chip->als_settings.als_device_lux, &value[1], 590 value[0] * sizeof(value[1])); 591 592 ret = len; 593 594done: 595 mutex_unlock(&chip->als_mutex); 596 597 return ret; 598} 599 600static IIO_CONST_ATTR(in_illuminance_calibscale_available, "1 8 16 111"); 601static IIO_CONST_ATTR(in_illuminance_integration_time_available, 602 "0.050 0.100 0.150 0.200 0.250 0.300 0.350 0.400 0.450 0.500 0.550 0.600 0.650"); 603static IIO_DEVICE_ATTR_RW(in_illuminance_input_target, 0); 604static IIO_DEVICE_ATTR_WO(in_illuminance_calibrate, 0); 605static IIO_DEVICE_ATTR_RW(in_illuminance_lux_table, 0); 606 607static struct attribute *sysfs_attrs_ctrl[] = { 608 &iio_const_attr_in_illuminance_calibscale_available.dev_attr.attr, 609 &iio_const_attr_in_illuminance_integration_time_available.dev_attr.attr, 610 &iio_dev_attr_in_illuminance_input_target.dev_attr.attr, 611 &iio_dev_attr_in_illuminance_calibrate.dev_attr.attr, 612 &iio_dev_attr_in_illuminance_lux_table.dev_attr.attr, 613 NULL 614}; 615 616static const struct attribute_group tsl2583_attribute_group = { 617 .attrs = sysfs_attrs_ctrl, 618}; 619 620static const struct iio_chan_spec tsl2583_channels[] = { 621 { 622 .type = IIO_LIGHT, 623 .modified = 1, 624 .channel2 = IIO_MOD_LIGHT_IR, 625 .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), 626 }, 627 { 628 .type = IIO_LIGHT, 629 .modified = 1, 630 .channel2 = IIO_MOD_LIGHT_BOTH, 631 .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), 632 }, 633 { 634 .type = IIO_LIGHT, 635 .info_mask_separate = BIT(IIO_CHAN_INFO_PROCESSED) | 636 BIT(IIO_CHAN_INFO_CALIBBIAS) | 637 BIT(IIO_CHAN_INFO_CALIBSCALE) | 638 BIT(IIO_CHAN_INFO_INT_TIME), 639 }, 640}; 641 642static int tsl2583_set_pm_runtime_busy(struct tsl2583_chip *chip, bool on) 643{ 644 int ret; 645 646 if (on) { 647 ret = pm_runtime_resume_and_get(&chip->client->dev); 648 } else { 649 pm_runtime_mark_last_busy(&chip->client->dev); 650 ret = pm_runtime_put_autosuspend(&chip->client->dev); 651 } 652 653 return ret; 654} 655 656static int tsl2583_read_raw(struct iio_dev *indio_dev, 657 struct iio_chan_spec const *chan, 658 int *val, int *val2, long mask) 659{ 660 struct tsl2583_chip *chip = iio_priv(indio_dev); 661 int ret, pm_ret; 662 663 ret = tsl2583_set_pm_runtime_busy(chip, true); 664 if (ret < 0) 665 return ret; 666 667 mutex_lock(&chip->als_mutex); 668 669 ret = -EINVAL; 670 switch (mask) { 671 case IIO_CHAN_INFO_RAW: 672 if (chan->type == IIO_LIGHT) { 673 ret = tsl2583_get_lux(indio_dev); 674 if (ret < 0) 675 goto read_done; 676 677 /* 678 * From page 20 of the TSL2581, TSL2583 data 679 * sheet (TAOS134 − MARCH 2011): 680 * 681 * One of the photodiodes (channel 0) is 682 * sensitive to both visible and infrared light, 683 * while the second photodiode (channel 1) is 684 * sensitive primarily to infrared light. 685 */ 686 if (chan->channel2 == IIO_MOD_LIGHT_BOTH) 687 *val = chip->als_cur_info.als_ch0; 688 else 689 *val = chip->als_cur_info.als_ch1; 690 691 ret = IIO_VAL_INT; 692 } 693 break; 694 case IIO_CHAN_INFO_PROCESSED: 695 if (chan->type == IIO_LIGHT) { 696 ret = tsl2583_get_lux(indio_dev); 697 if (ret < 0) 698 goto read_done; 699 700 *val = ret; 701 ret = IIO_VAL_INT; 702 } 703 break; 704 case IIO_CHAN_INFO_CALIBBIAS: 705 if (chan->type == IIO_LIGHT) { 706 *val = chip->als_settings.als_gain_trim; 707 ret = IIO_VAL_INT; 708 } 709 break; 710 case IIO_CHAN_INFO_CALIBSCALE: 711 if (chan->type == IIO_LIGHT) { 712 *val = gainadj[chip->als_settings.als_gain].mean; 713 ret = IIO_VAL_INT; 714 } 715 break; 716 case IIO_CHAN_INFO_INT_TIME: 717 if (chan->type == IIO_LIGHT) { 718 *val = 0; 719 *val2 = chip->als_settings.als_time; 720 ret = IIO_VAL_INT_PLUS_MICRO; 721 } 722 break; 723 default: 724 break; 725 } 726 727read_done: 728 mutex_unlock(&chip->als_mutex); 729 730 if (ret < 0) { 731 tsl2583_set_pm_runtime_busy(chip, false); 732 return ret; 733 } 734 735 /* 736 * Preserve the ret variable if the call to 737 * tsl2583_set_pm_runtime_busy() is successful so the reading 738 * (if applicable) is returned to user space. 739 */ 740 pm_ret = tsl2583_set_pm_runtime_busy(chip, false); 741 if (pm_ret < 0) 742 return pm_ret; 743 744 return ret; 745} 746 747static int tsl2583_write_raw(struct iio_dev *indio_dev, 748 struct iio_chan_spec const *chan, 749 int val, int val2, long mask) 750{ 751 struct tsl2583_chip *chip = iio_priv(indio_dev); 752 int ret; 753 754 ret = tsl2583_set_pm_runtime_busy(chip, true); 755 if (ret < 0) 756 return ret; 757 758 mutex_lock(&chip->als_mutex); 759 760 ret = -EINVAL; 761 switch (mask) { 762 case IIO_CHAN_INFO_CALIBBIAS: 763 if (chan->type == IIO_LIGHT) { 764 chip->als_settings.als_gain_trim = val; 765 ret = 0; 766 } 767 break; 768 case IIO_CHAN_INFO_CALIBSCALE: 769 if (chan->type == IIO_LIGHT) { 770 unsigned int i; 771 772 for (i = 0; i < ARRAY_SIZE(gainadj); i++) { 773 if (gainadj[i].mean == val) { 774 chip->als_settings.als_gain = i; 775 ret = tsl2583_set_als_gain(chip); 776 break; 777 } 778 } 779 } 780 break; 781 case IIO_CHAN_INFO_INT_TIME: 782 if (chan->type == IIO_LIGHT && !val && val2 >= 50 && 783 val2 <= 650 && !(val2 % 50)) { 784 chip->als_settings.als_time = val2; 785 ret = tsl2583_set_als_time(chip); 786 } 787 break; 788 default: 789 break; 790 } 791 792 mutex_unlock(&chip->als_mutex); 793 794 if (ret < 0) { 795 tsl2583_set_pm_runtime_busy(chip, false); 796 return ret; 797 } 798 799 ret = tsl2583_set_pm_runtime_busy(chip, false); 800 if (ret < 0) 801 return ret; 802 803 return ret; 804} 805 806static const struct iio_info tsl2583_info = { 807 .attrs = &tsl2583_attribute_group, 808 .read_raw = tsl2583_read_raw, 809 .write_raw = tsl2583_write_raw, 810}; 811 812static int tsl2583_probe(struct i2c_client *clientp, 813 const struct i2c_device_id *idp) 814{ 815 int ret; 816 struct tsl2583_chip *chip; 817 struct iio_dev *indio_dev; 818 819 if (!i2c_check_functionality(clientp->adapter, 820 I2C_FUNC_SMBUS_BYTE_DATA)) { 821 dev_err(&clientp->dev, "%s: i2c smbus byte data functionality is unsupported\n", 822 __func__); 823 return -EOPNOTSUPP; 824 } 825 826 indio_dev = devm_iio_device_alloc(&clientp->dev, sizeof(*chip)); 827 if (!indio_dev) 828 return -ENOMEM; 829 830 chip = iio_priv(indio_dev); 831 chip->client = clientp; 832 i2c_set_clientdata(clientp, indio_dev); 833 834 mutex_init(&chip->als_mutex); 835 836 ret = i2c_smbus_read_byte_data(clientp, 837 TSL2583_CMD_REG | TSL2583_CHIPID); 838 if (ret < 0) { 839 dev_err(&clientp->dev, 840 "%s: failed to read the chip ID register\n", __func__); 841 return ret; 842 } 843 844 if ((ret & TSL2583_CHIP_ID_MASK) != TSL2583_CHIP_ID) { 845 dev_err(&clientp->dev, "%s: received an unknown chip ID %x\n", 846 __func__, ret); 847 return -EINVAL; 848 } 849 850 indio_dev->info = &tsl2583_info; 851 indio_dev->channels = tsl2583_channels; 852 indio_dev->num_channels = ARRAY_SIZE(tsl2583_channels); 853 indio_dev->modes = INDIO_DIRECT_MODE; 854 indio_dev->name = chip->client->name; 855 856 pm_runtime_enable(&clientp->dev); 857 pm_runtime_set_autosuspend_delay(&clientp->dev, 858 TSL2583_POWER_OFF_DELAY_MS); 859 pm_runtime_use_autosuspend(&clientp->dev); 860 861 ret = devm_iio_device_register(indio_dev->dev.parent, indio_dev); 862 if (ret) { 863 dev_err(&clientp->dev, "%s: iio registration failed\n", 864 __func__); 865 return ret; 866 } 867 868 /* Load up the V2 defaults (these are hard coded defaults for now) */ 869 tsl2583_defaults(chip); 870 871 dev_info(&clientp->dev, "Light sensor found.\n"); 872 873 return 0; 874} 875 876static int tsl2583_remove(struct i2c_client *client) 877{ 878 struct iio_dev *indio_dev = i2c_get_clientdata(client); 879 struct tsl2583_chip *chip = iio_priv(indio_dev); 880 881 iio_device_unregister(indio_dev); 882 883 pm_runtime_disable(&client->dev); 884 pm_runtime_set_suspended(&client->dev); 885 886 return tsl2583_set_power_state(chip, TSL2583_CNTL_PWR_OFF); 887} 888 889static int __maybe_unused tsl2583_suspend(struct device *dev) 890{ 891 struct iio_dev *indio_dev = i2c_get_clientdata(to_i2c_client(dev)); 892 struct tsl2583_chip *chip = iio_priv(indio_dev); 893 int ret; 894 895 mutex_lock(&chip->als_mutex); 896 897 ret = tsl2583_set_power_state(chip, TSL2583_CNTL_PWR_OFF); 898 899 mutex_unlock(&chip->als_mutex); 900 901 return ret; 902} 903 904static int __maybe_unused tsl2583_resume(struct device *dev) 905{ 906 struct iio_dev *indio_dev = i2c_get_clientdata(to_i2c_client(dev)); 907 struct tsl2583_chip *chip = iio_priv(indio_dev); 908 int ret; 909 910 mutex_lock(&chip->als_mutex); 911 912 ret = tsl2583_chip_init_and_power_on(indio_dev); 913 914 mutex_unlock(&chip->als_mutex); 915 916 return ret; 917} 918 919static const struct dev_pm_ops tsl2583_pm_ops = { 920 SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend, 921 pm_runtime_force_resume) 922 SET_RUNTIME_PM_OPS(tsl2583_suspend, tsl2583_resume, NULL) 923}; 924 925static const struct i2c_device_id tsl2583_idtable[] = { 926 { "tsl2580", 0 }, 927 { "tsl2581", 1 }, 928 { "tsl2583", 2 }, 929 {} 930}; 931MODULE_DEVICE_TABLE(i2c, tsl2583_idtable); 932 933static const struct of_device_id tsl2583_of_match[] = { 934 { .compatible = "amstaos,tsl2580", }, 935 { .compatible = "amstaos,tsl2581", }, 936 { .compatible = "amstaos,tsl2583", }, 937 { }, 938}; 939MODULE_DEVICE_TABLE(of, tsl2583_of_match); 940 941/* Driver definition */ 942static struct i2c_driver tsl2583_driver = { 943 .driver = { 944 .name = "tsl2583", 945 .pm = &tsl2583_pm_ops, 946 .of_match_table = tsl2583_of_match, 947 }, 948 .id_table = tsl2583_idtable, 949 .probe = tsl2583_probe, 950 .remove = tsl2583_remove, 951}; 952module_i2c_driver(tsl2583_driver); 953 954MODULE_AUTHOR("J. August Brenner <jbrenner@taosinc.com>"); 955MODULE_AUTHOR("Brian Masney <masneyb@onstation.org>"); 956MODULE_DESCRIPTION("TAOS tsl2583 ambient light sensor driver"); 957MODULE_LICENSE("GPL");