1/* 2 * A iio driver for the light sensor ISL 29018. 3 * 4 * IIO driver for monitoring ambient light intensity in luxi, proximity 5 * sensing and infrared sensing. 6 * 7 * Copyright (c) 2010, NVIDIA Corporation. 8 * 9 * This program is free software; you can redistribute it and/or modify 10 * it under the terms of the GNU General Public License as published by 11 * the Free Software Foundation; either version 2 of the License, or 12 * (at your option) any later version. 13 * 14 * This program is distributed in the hope that it will be useful, but WITHOUT 15 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 16 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 17 * more details. 18 * 19 * You should have received a copy of the GNU General Public License along 20 * with this program; if not, write to the Free Software Foundation, Inc., 21 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 22 */ 23 24#include <linux/module.h> 25#include <linux/i2c.h> 26#include <linux/err.h> 27#include <linux/mutex.h> 28#include <linux/delay.h> 29#include <linux/slab.h> 30#include "../iio.h" 31#include "../sysfs.h" 32#define CONVERSION_TIME_MS 100 33 34#define ISL29018_REG_ADD_COMMAND1 0x00 35#define COMMMAND1_OPMODE_SHIFT 5 36#define COMMMAND1_OPMODE_MASK (7 << COMMMAND1_OPMODE_SHIFT) 37#define COMMMAND1_OPMODE_POWER_DOWN 0 38#define COMMMAND1_OPMODE_ALS_ONCE 1 39#define COMMMAND1_OPMODE_IR_ONCE 2 40#define COMMMAND1_OPMODE_PROX_ONCE 3 41 42#define ISL29018_REG_ADD_COMMANDII 0x01 43#define COMMANDII_RESOLUTION_SHIFT 2 44#define COMMANDII_RESOLUTION_MASK (0x3 << COMMANDII_RESOLUTION_SHIFT) 45 46#define COMMANDII_RANGE_SHIFT 0 47#define COMMANDII_RANGE_MASK (0x3 << COMMANDII_RANGE_SHIFT) 48 49#define COMMANDII_SCHEME_SHIFT 7 50#define COMMANDII_SCHEME_MASK (0x1 << COMMANDII_SCHEME_SHIFT) 51 52#define ISL29018_REG_ADD_DATA_LSB 0x02 53#define ISL29018_REG_ADD_DATA_MSB 0x03 54#define ISL29018_MAX_REGS (ISL29018_REG_ADD_DATA_MSB+1) 55 56#define ISL29018_REG_TEST 0x08 57#define ISL29018_TEST_SHIFT 0 58#define ISL29018_TEST_MASK (0xFF << ISL29018_TEST_SHIFT) 59 60struct isl29018_chip { 61 struct i2c_client *client; 62 struct mutex lock; 63 unsigned int lux_scale; 64 unsigned int range; 65 unsigned int adc_bit; 66 int prox_scheme; 67 u8 reg_cache[ISL29018_MAX_REGS]; 68}; 69 70static int isl29018_write_data(struct i2c_client *client, u8 reg, 71 u8 val, u8 mask, u8 shift) 72{ 73 u8 regval = val; 74 int ret; 75 struct isl29018_chip *chip = iio_priv(i2c_get_clientdata(client)); 76 77 /* don't cache or mask REG_TEST */ 78 if (reg < ISL29018_MAX_REGS) { 79 regval = chip->reg_cache[reg]; 80 regval &= ~mask; 81 regval |= val << shift; 82 } 83 84 ret = i2c_smbus_write_byte_data(client, reg, regval); 85 if (ret) { 86 dev_err(&client->dev, "Write to device fails status %x\n", ret); 87 } else { 88 /* don't update cache on err */ 89 if (reg < ISL29018_MAX_REGS) 90 chip->reg_cache[reg] = regval; 91 } 92 93 return ret; 94} 95 96static int isl29018_set_range(struct i2c_client *client, unsigned long range, 97 unsigned int *new_range) 98{ 99 static const unsigned long supp_ranges[] = {1000, 4000, 16000, 64000}; 100 int i; 101 102 for (i = 0; i < ARRAY_SIZE(supp_ranges); ++i) { 103 if (range <= supp_ranges[i]) { 104 *new_range = (unsigned int)supp_ranges[i]; 105 break; 106 } 107 } 108 109 if (i >= ARRAY_SIZE(supp_ranges)) 110 return -EINVAL; 111 112 return isl29018_write_data(client, ISL29018_REG_ADD_COMMANDII, 113 i, COMMANDII_RANGE_MASK, COMMANDII_RANGE_SHIFT); 114} 115 116static int isl29018_set_resolution(struct i2c_client *client, 117 unsigned long adcbit, unsigned int *conf_adc_bit) 118{ 119 static const unsigned long supp_adcbit[] = {16, 12, 8, 4}; 120 int i; 121 122 for (i = 0; i < ARRAY_SIZE(supp_adcbit); ++i) { 123 if (adcbit >= supp_adcbit[i]) { 124 *conf_adc_bit = (unsigned int)supp_adcbit[i]; 125 break; 126 } 127 } 128 129 if (i >= ARRAY_SIZE(supp_adcbit)) 130 return -EINVAL; 131 132 return isl29018_write_data(client, ISL29018_REG_ADD_COMMANDII, 133 i, COMMANDII_RESOLUTION_MASK, 134 COMMANDII_RESOLUTION_SHIFT); 135} 136 137static int isl29018_read_sensor_input(struct i2c_client *client, int mode) 138{ 139 int status; 140 int lsb; 141 int msb; 142 143 /* Set mode */ 144 status = isl29018_write_data(client, ISL29018_REG_ADD_COMMAND1, 145 mode, COMMMAND1_OPMODE_MASK, COMMMAND1_OPMODE_SHIFT); 146 if (status) { 147 dev_err(&client->dev, "Error in setting operating mode\n"); 148 return status; 149 } 150 msleep(CONVERSION_TIME_MS); 151 lsb = i2c_smbus_read_byte_data(client, ISL29018_REG_ADD_DATA_LSB); 152 if (lsb < 0) { 153 dev_err(&client->dev, "Error in reading LSB DATA\n"); 154 return lsb; 155 } 156 157 msb = i2c_smbus_read_byte_data(client, ISL29018_REG_ADD_DATA_MSB); 158 if (msb < 0) { 159 dev_err(&client->dev, "Error in reading MSB DATA\n"); 160 return msb; 161 } 162 dev_vdbg(&client->dev, "MSB 0x%x and LSB 0x%x\n", msb, lsb); 163 164 return (msb << 8) | lsb; 165} 166 167static int isl29018_read_lux(struct i2c_client *client, int *lux) 168{ 169 int lux_data; 170 struct isl29018_chip *chip = iio_priv(i2c_get_clientdata(client)); 171 172 lux_data = isl29018_read_sensor_input(client, 173 COMMMAND1_OPMODE_ALS_ONCE); 174 175 if (lux_data < 0) 176 return lux_data; 177 178 *lux = (lux_data * chip->range * chip->lux_scale) >> chip->adc_bit; 179 180 return 0; 181} 182 183static int isl29018_read_ir(struct i2c_client *client, int *ir) 184{ 185 int ir_data; 186 187 ir_data = isl29018_read_sensor_input(client, COMMMAND1_OPMODE_IR_ONCE); 188 189 if (ir_data < 0) 190 return ir_data; 191 192 *ir = ir_data; 193 194 return 0; 195} 196 197static int isl29018_read_proximity_ir(struct i2c_client *client, int scheme, 198 int *near_ir) 199{ 200 int status; 201 int prox_data = -1; 202 int ir_data = -1; 203 204 /* Do proximity sensing with required scheme */ 205 status = isl29018_write_data(client, ISL29018_REG_ADD_COMMANDII, 206 scheme, COMMANDII_SCHEME_MASK, COMMANDII_SCHEME_SHIFT); 207 if (status) { 208 dev_err(&client->dev, "Error in setting operating mode\n"); 209 return status; 210 } 211 212 prox_data = isl29018_read_sensor_input(client, 213 COMMMAND1_OPMODE_PROX_ONCE); 214 if (prox_data < 0) 215 return prox_data; 216 217 if (scheme == 1) { 218 *near_ir = prox_data; 219 return 0; 220 } 221 222 ir_data = isl29018_read_sensor_input(client, 223 COMMMAND1_OPMODE_IR_ONCE); 224 225 if (ir_data < 0) 226 return ir_data; 227 228 if (prox_data >= ir_data) 229 *near_ir = prox_data - ir_data; 230 else 231 *near_ir = 0; 232 233 return 0; 234} 235 236/* Sysfs interface */ 237/* range */ 238static ssize_t show_range(struct device *dev, 239 struct device_attribute *attr, char *buf) 240{ 241 struct iio_dev *indio_dev = dev_get_drvdata(dev); 242 struct isl29018_chip *chip = iio_priv(indio_dev); 243 244 return sprintf(buf, "%u\n", chip->range); 245} 246 247static ssize_t store_range(struct device *dev, 248 struct device_attribute *attr, const char *buf, size_t count) 249{ 250 struct iio_dev *indio_dev = dev_get_drvdata(dev); 251 struct isl29018_chip *chip = iio_priv(indio_dev); 252 struct i2c_client *client = chip->client; 253 int status; 254 unsigned long lval; 255 unsigned int new_range; 256 257 if (strict_strtoul(buf, 10, &lval)) 258 return -EINVAL; 259 260 if (!(lval == 1000UL || lval == 4000UL || 261 lval == 16000UL || lval == 64000UL)) { 262 dev_err(dev, "The range is not supported\n"); 263 return -EINVAL; 264 } 265 266 mutex_lock(&chip->lock); 267 status = isl29018_set_range(client, lval, &new_range); 268 if (status < 0) { 269 mutex_unlock(&chip->lock); 270 dev_err(dev, "Error in setting max range\n"); 271 return status; 272 } 273 chip->range = new_range; 274 mutex_unlock(&chip->lock); 275 276 return count; 277} 278 279/* resolution */ 280static ssize_t show_resolution(struct device *dev, 281 struct device_attribute *attr, char *buf) 282{ 283 struct iio_dev *indio_dev = dev_get_drvdata(dev); 284 struct isl29018_chip *chip = iio_priv(indio_dev); 285 286 return sprintf(buf, "%u\n", chip->adc_bit); 287} 288 289static ssize_t store_resolution(struct device *dev, 290 struct device_attribute *attr, const char *buf, size_t count) 291{ 292 struct iio_dev *indio_dev = dev_get_drvdata(dev); 293 struct isl29018_chip *chip = iio_priv(indio_dev); 294 struct i2c_client *client = chip->client; 295 int status; 296 unsigned long lval; 297 unsigned int new_adc_bit; 298 299 if (strict_strtoul(buf, 10, &lval)) 300 return -EINVAL; 301 if (!(lval == 4 || lval == 8 || lval == 12 || lval == 16)) { 302 dev_err(dev, "The resolution is not supported\n"); 303 return -EINVAL; 304 } 305 306 mutex_lock(&chip->lock); 307 status = isl29018_set_resolution(client, lval, &new_adc_bit); 308 if (status < 0) { 309 mutex_unlock(&chip->lock); 310 dev_err(dev, "Error in setting resolution\n"); 311 return status; 312 } 313 chip->adc_bit = new_adc_bit; 314 mutex_unlock(&chip->lock); 315 316 return count; 317} 318 319/* proximity scheme */ 320static ssize_t show_prox_infrared_supression(struct device *dev, 321 struct device_attribute *attr, char *buf) 322{ 323 struct iio_dev *indio_dev = dev_get_drvdata(dev); 324 struct isl29018_chip *chip = iio_priv(indio_dev); 325 326 /* return the "proximity scheme" i.e. if the chip does on chip 327 infrared supression (1 means perform on chip supression) */ 328 return sprintf(buf, "%d\n", chip->prox_scheme); 329} 330 331static ssize_t store_prox_infrared_supression(struct device *dev, 332 struct device_attribute *attr, const char *buf, size_t count) 333{ 334 struct iio_dev *indio_dev = dev_get_drvdata(dev); 335 struct isl29018_chip *chip = iio_priv(indio_dev); 336 unsigned long lval; 337 338 if (strict_strtoul(buf, 10, &lval)) 339 return -EINVAL; 340 if (!(lval == 0UL || lval == 1UL)) { 341 dev_err(dev, "The mode is not supported\n"); 342 return -EINVAL; 343 } 344 345 /* get the "proximity scheme" i.e. if the chip does on chip 346 infrared supression (1 means perform on chip supression) */ 347 mutex_lock(&chip->lock); 348 chip->prox_scheme = (int)lval; 349 mutex_unlock(&chip->lock); 350 351 return count; 352} 353 354/* Channel IO */ 355static int isl29018_write_raw(struct iio_dev *indio_dev, 356 struct iio_chan_spec const *chan, 357 int val, 358 int val2, 359 long mask) 360{ 361 struct isl29018_chip *chip = iio_priv(indio_dev); 362 int ret = -EINVAL; 363 364 mutex_lock(&chip->lock); 365 if (mask == IIO_CHAN_INFO_CALIBSCALE && chan->type == IIO_LIGHT) { 366 chip->lux_scale = val; 367 ret = 0; 368 } 369 mutex_unlock(&chip->lock); 370 371 return 0; 372} 373 374static int isl29018_read_raw(struct iio_dev *indio_dev, 375 struct iio_chan_spec const *chan, 376 int *val, 377 int *val2, 378 long mask) 379{ 380 int ret = -EINVAL; 381 struct isl29018_chip *chip = iio_priv(indio_dev); 382 struct i2c_client *client = chip->client; 383 384 mutex_lock(&chip->lock); 385 switch (mask) { 386 case 0: 387 switch (chan->type) { 388 case IIO_LIGHT: 389 ret = isl29018_read_lux(client, val); 390 break; 391 case IIO_INTENSITY: 392 ret = isl29018_read_ir(client, val); 393 break; 394 case IIO_PROXIMITY: 395 ret = isl29018_read_proximity_ir(client, 396 chip->prox_scheme, val); 397 break; 398 default: 399 break; 400 } 401 if (!ret) 402 ret = IIO_VAL_INT; 403 break; 404 case IIO_CHAN_INFO_CALIBSCALE: 405 if (chan->type == IIO_LIGHT) { 406 *val = chip->lux_scale; 407 ret = IIO_VAL_INT; 408 } 409 break; 410 default: 411 break; 412 } 413 mutex_unlock(&chip->lock); 414 return ret; 415} 416 417static const struct iio_chan_spec isl29018_channels[] = { 418 { 419 .type = IIO_LIGHT, 420 .indexed = 1, 421 .channel = 0, 422 .processed_val = IIO_PROCESSED, 423 .info_mask = IIO_CHAN_INFO_CALIBSCALE_SEPARATE_BIT, 424 }, { 425 .type = IIO_INTENSITY, 426 .modified = 1, 427 .channel2 = IIO_MOD_LIGHT_IR, 428 }, { 429 /* Unindexed in current ABI. But perhaps it should be. */ 430 .type = IIO_PROXIMITY, 431 } 432}; 433 434static IIO_DEVICE_ATTR(range, S_IRUGO | S_IWUSR, show_range, store_range, 0); 435static IIO_CONST_ATTR(range_available, "1000 4000 16000 64000"); 436static IIO_CONST_ATTR(adc_resolution_available, "4 8 12 16"); 437static IIO_DEVICE_ATTR(adc_resolution, S_IRUGO | S_IWUSR, 438 show_resolution, store_resolution, 0); 439static IIO_DEVICE_ATTR(proximity_on_chip_ambient_infrared_supression, 440 S_IRUGO | S_IWUSR, 441 show_prox_infrared_supression, 442 store_prox_infrared_supression, 0); 443 444#define ISL29018_DEV_ATTR(name) (&iio_dev_attr_##name.dev_attr.attr) 445#define ISL29018_CONST_ATTR(name) (&iio_const_attr_##name.dev_attr.attr) 446static struct attribute *isl29018_attributes[] = { 447 ISL29018_DEV_ATTR(range), 448 ISL29018_CONST_ATTR(range_available), 449 ISL29018_DEV_ATTR(adc_resolution), 450 ISL29018_CONST_ATTR(adc_resolution_available), 451 ISL29018_DEV_ATTR(proximity_on_chip_ambient_infrared_supression), 452 NULL 453}; 454 455static const struct attribute_group isl29108_group = { 456 .attrs = isl29018_attributes, 457}; 458 459static int isl29018_chip_init(struct i2c_client *client) 460{ 461 struct isl29018_chip *chip = iio_priv(i2c_get_clientdata(client)); 462 int status; 463 int new_adc_bit; 464 unsigned int new_range; 465 466 memset(chip->reg_cache, 0, sizeof(chip->reg_cache)); 467 468 /* Code added per Intersil Application Note 1534: 469 * When VDD sinks to approximately 1.8V or below, some of 470 * the part's registers may change their state. When VDD 471 * recovers to 2.25V (or greater), the part may thus be in an 472 * unknown mode of operation. The user can return the part to 473 * a known mode of operation either by (a) setting VDD = 0V for 474 * 1 second or more and then powering back up with a slew rate 475 * of 0.5V/ms or greater, or (b) via I2C disable all ALS/PROX 476 * conversions, clear the test registers, and then rewrite all 477 * registers to the desired values. 478 * ... 479 * FOR ISL29011, ISL29018, ISL29021, ISL29023 480 * 1. Write 0x00 to register 0x08 (TEST) 481 * 2. Write 0x00 to register 0x00 (CMD1) 482 * 3. Rewrite all registers to the desired values 483 * 484 * ISL29018 Data Sheet (FN6619.1, Feb 11, 2010) essentially says 485 * the same thing EXCEPT the data sheet asks for a 1ms delay after 486 * writing the CMD1 register. 487 */ 488 status = isl29018_write_data(client, ISL29018_REG_TEST, 0, 489 ISL29018_TEST_MASK, ISL29018_TEST_SHIFT); 490 if (status < 0) { 491 dev_err(&client->dev, "Failed to clear isl29018 TEST reg." 492 "(%d)\n", status); 493 return status; 494 } 495 496 /* See Intersil AN1534 comments above. 497 * "Operating Mode" (COMMAND1) register is reprogrammed when 498 * data is read from the device. 499 */ 500 status = isl29018_write_data(client, ISL29018_REG_ADD_COMMAND1, 0, 501 0xff, 0); 502 if (status < 0) { 503 dev_err(&client->dev, "Failed to clear isl29018 CMD1 reg." 504 "(%d)\n", status); 505 return status; 506 } 507 508 msleep(1); /* per data sheet, page 10 */ 509 510 /* set defaults */ 511 status = isl29018_set_range(client, chip->range, &new_range); 512 if (status < 0) { 513 dev_err(&client->dev, "Init of isl29018 fails\n"); 514 return status; 515 } 516 517 status = isl29018_set_resolution(client, chip->adc_bit, 518 &new_adc_bit); 519 520 return 0; 521} 522 523static const struct iio_info isl29108_info = { 524 .attrs = &isl29108_group, 525 .driver_module = THIS_MODULE, 526 .read_raw = &isl29018_read_raw, 527 .write_raw = &isl29018_write_raw, 528}; 529 530static int __devinit isl29018_probe(struct i2c_client *client, 531 const struct i2c_device_id *id) 532{ 533 struct isl29018_chip *chip; 534 struct iio_dev *indio_dev; 535 int err; 536 537 indio_dev = iio_allocate_device(sizeof(*chip)); 538 if (indio_dev == NULL) { 539 dev_err(&client->dev, "iio allocation fails\n"); 540 err = -ENOMEM; 541 goto exit; 542 } 543 chip = iio_priv(indio_dev); 544 545 i2c_set_clientdata(client, indio_dev); 546 chip->client = client; 547 548 mutex_init(&chip->lock); 549 550 chip->lux_scale = 1; 551 chip->range = 1000; 552 chip->adc_bit = 16; 553 554 err = isl29018_chip_init(client); 555 if (err) 556 goto exit_iio_free; 557 558 indio_dev->info = &isl29108_info; 559 indio_dev->channels = isl29018_channels; 560 indio_dev->num_channels = ARRAY_SIZE(isl29018_channels); 561 indio_dev->name = id->name; 562 indio_dev->dev.parent = &client->dev; 563 indio_dev->modes = INDIO_DIRECT_MODE; 564 err = iio_device_register(indio_dev); 565 if (err) { 566 dev_err(&client->dev, "iio registration fails\n"); 567 goto exit_iio_free; 568 } 569 570 return 0; 571exit_iio_free: 572 iio_free_device(indio_dev); 573exit: 574 return err; 575} 576 577static int __devexit isl29018_remove(struct i2c_client *client) 578{ 579 struct iio_dev *indio_dev = i2c_get_clientdata(client); 580 581 dev_dbg(&client->dev, "%s()\n", __func__); 582 iio_device_unregister(indio_dev); 583 iio_free_device(indio_dev); 584 585 return 0; 586} 587 588static const struct i2c_device_id isl29018_id[] = { 589 {"isl29018", 0}, 590 {} 591}; 592 593MODULE_DEVICE_TABLE(i2c, isl29018_id); 594 595static const struct of_device_id isl29018_of_match[] = { 596 { .compatible = "invn,isl29018", }, 597 { }, 598}; 599MODULE_DEVICE_TABLE(of, isl29018_of_match); 600 601static struct i2c_driver isl29018_driver = { 602 .class = I2C_CLASS_HWMON, 603 .driver = { 604 .name = "isl29018", 605 .owner = THIS_MODULE, 606 .of_match_table = isl29018_of_match, 607 }, 608 .probe = isl29018_probe, 609 .remove = __devexit_p(isl29018_remove), 610 .id_table = isl29018_id, 611}; 612module_i2c_driver(isl29018_driver); 613 614MODULE_DESCRIPTION("ISL29018 Ambient Light Sensor driver"); 615MODULE_LICENSE("GPL"); 616