1 /* 2 * IIO driver for the light sensor ISL29028. 3 * ISL29028 is Concurrent Ambient Light and Proximity Sensor 4 * 5 * Copyright (c) 2012, NVIDIA CORPORATION. All rights reserved. 6 * Copyright (c) 2016-2017 Brian Masney <masneyb@onstation.org> 7 * 8 * This program is free software; you can redistribute it and/or modify it 9 * under the terms and conditions of the GNU General Public License, 10 * version 2, as published by the Free Software Foundation. 11 * 12 * This program is distributed in the hope it will be useful, but WITHOUT 13 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 14 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 15 * more details. 16 * 17 * You should have received a copy of the GNU General Public License 18 * along with this program. If not, see <http://www.gnu.org/licenses/>. 19 * 20 * Datasheets: 21 * - http://www.intersil.com/content/dam/Intersil/documents/isl2/isl29028.pdf 22 * - http://www.intersil.com/content/dam/Intersil/documents/isl2/isl29030.pdf 23 */ 24 25 #include <linux/module.h> 26 #include <linux/i2c.h> 27 #include <linux/err.h> 28 #include <linux/mutex.h> 29 #include <linux/delay.h> 30 #include <linux/slab.h> 31 #include <linux/regmap.h> 32 #include <linux/iio/iio.h> 33 #include <linux/iio/sysfs.h> 34 #include <linux/pm_runtime.h> 35 36 #define ISL29028_CONV_TIME_MS 100 37 38 #define ISL29028_REG_CONFIGURE 0x01 39 40 #define ISL29028_CONF_ALS_IR_MODE_ALS 0 41 #define ISL29028_CONF_ALS_IR_MODE_IR BIT(0) 42 #define ISL29028_CONF_ALS_IR_MODE_MASK BIT(0) 43 44 #define ISL29028_CONF_ALS_RANGE_LOW_LUX 0 45 #define ISL29028_CONF_ALS_RANGE_HIGH_LUX BIT(1) 46 #define ISL29028_CONF_ALS_RANGE_MASK BIT(1) 47 48 #define ISL29028_CONF_ALS_DIS 0 49 #define ISL29028_CONF_ALS_EN BIT(2) 50 #define ISL29028_CONF_ALS_EN_MASK BIT(2) 51 52 #define ISL29028_CONF_PROX_SLP_SH 4 53 #define ISL29028_CONF_PROX_SLP_MASK (7 << ISL29028_CONF_PROX_SLP_SH) 54 55 #define ISL29028_CONF_PROX_EN BIT(7) 56 #define ISL29028_CONF_PROX_EN_MASK BIT(7) 57 58 #define ISL29028_REG_INTERRUPT 0x02 59 60 #define ISL29028_REG_PROX_DATA 0x08 61 #define ISL29028_REG_ALSIR_L 0x09 62 #define ISL29028_REG_ALSIR_U 0x0A 63 64 #define ISL29028_REG_TEST1_MODE 0x0E 65 #define ISL29028_REG_TEST2_MODE 0x0F 66 67 #define ISL29028_NUM_REGS (ISL29028_REG_TEST2_MODE + 1) 68 69 #define ISL29028_POWER_OFF_DELAY_MS 2000 70 71 struct isl29028_prox_data { 72 int sampling_int; 73 int sampling_fract; 74 int sleep_time; 75 }; 76 77 static const struct isl29028_prox_data isl29028_prox_data[] = { 78 { 1, 250000, 800 }, 79 { 2, 500000, 400 }, 80 { 5, 0, 200 }, 81 { 10, 0, 100 }, 82 { 13, 300000, 75 }, 83 { 20, 0, 50 }, 84 { 80, 0, 13 }, /* 85 * Note: Data sheet lists 12.5 ms sleep time. 86 * Round up a half millisecond for msleep(). 87 */ 88 { 100, 0, 0 } 89 }; 90 91 enum isl29028_als_ir_mode { 92 ISL29028_MODE_NONE = 0, 93 ISL29028_MODE_ALS, 94 ISL29028_MODE_IR, 95 }; 96 97 struct isl29028_chip { 98 struct mutex lock; 99 struct regmap *regmap; 100 int prox_sampling_int; 101 int prox_sampling_frac; 102 bool enable_prox; 103 int lux_scale; 104 enum isl29028_als_ir_mode als_ir_mode; 105 }; 106 107 static int isl29028_find_prox_sleep_index(int sampling_int, int sampling_fract) 108 { 109 int i; 110 111 for (i = 0; i < ARRAY_SIZE(isl29028_prox_data); ++i) { 112 if (isl29028_prox_data[i].sampling_int == sampling_int && 113 isl29028_prox_data[i].sampling_fract == sampling_fract) 114 return i; 115 } 116 117 return -EINVAL; 118 } 119 120 static int isl29028_set_proxim_sampling(struct isl29028_chip *chip, 121 int sampling_int, int sampling_fract) 122 { 123 struct device *dev = regmap_get_device(chip->regmap); 124 int sleep_index, ret; 125 126 sleep_index = isl29028_find_prox_sleep_index(sampling_int, 127 sampling_fract); 128 if (sleep_index < 0) 129 return sleep_index; 130 131 ret = regmap_update_bits(chip->regmap, ISL29028_REG_CONFIGURE, 132 ISL29028_CONF_PROX_SLP_MASK, 133 sleep_index << ISL29028_CONF_PROX_SLP_SH); 134 135 if (ret < 0) { 136 dev_err(dev, "%s(): Error %d setting the proximity sampling\n", 137 __func__, ret); 138 return ret; 139 } 140 141 chip->prox_sampling_int = sampling_int; 142 chip->prox_sampling_frac = sampling_fract; 143 144 return ret; 145 } 146 147 static int isl29028_enable_proximity(struct isl29028_chip *chip) 148 { 149 int prox_index, ret; 150 151 ret = isl29028_set_proxim_sampling(chip, chip->prox_sampling_int, 152 chip->prox_sampling_frac); 153 if (ret < 0) 154 return ret; 155 156 ret = regmap_update_bits(chip->regmap, ISL29028_REG_CONFIGURE, 157 ISL29028_CONF_PROX_EN_MASK, 158 ISL29028_CONF_PROX_EN); 159 if (ret < 0) 160 return ret; 161 162 /* Wait for conversion to be complete for first sample */ 163 prox_index = isl29028_find_prox_sleep_index(chip->prox_sampling_int, 164 chip->prox_sampling_frac); 165 if (prox_index < 0) 166 return prox_index; 167 168 msleep(isl29028_prox_data[prox_index].sleep_time); 169 170 return 0; 171 } 172 173 static int isl29028_set_als_scale(struct isl29028_chip *chip, int lux_scale) 174 { 175 struct device *dev = regmap_get_device(chip->regmap); 176 int val = (lux_scale == 2000) ? ISL29028_CONF_ALS_RANGE_HIGH_LUX : 177 ISL29028_CONF_ALS_RANGE_LOW_LUX; 178 int ret; 179 180 ret = regmap_update_bits(chip->regmap, ISL29028_REG_CONFIGURE, 181 ISL29028_CONF_ALS_RANGE_MASK, val); 182 if (ret < 0) { 183 dev_err(dev, "%s(): Error %d setting the ALS scale\n", __func__, 184 ret); 185 return ret; 186 } 187 188 chip->lux_scale = lux_scale; 189 190 return ret; 191 } 192 193 static int isl29028_set_als_ir_mode(struct isl29028_chip *chip, 194 enum isl29028_als_ir_mode mode) 195 { 196 int ret; 197 198 if (chip->als_ir_mode == mode) 199 return 0; 200 201 ret = isl29028_set_als_scale(chip, chip->lux_scale); 202 if (ret < 0) 203 return ret; 204 205 switch (mode) { 206 case ISL29028_MODE_ALS: 207 ret = regmap_update_bits(chip->regmap, ISL29028_REG_CONFIGURE, 208 ISL29028_CONF_ALS_IR_MODE_MASK, 209 ISL29028_CONF_ALS_IR_MODE_ALS); 210 if (ret < 0) 211 return ret; 212 213 ret = regmap_update_bits(chip->regmap, ISL29028_REG_CONFIGURE, 214 ISL29028_CONF_ALS_RANGE_MASK, 215 ISL29028_CONF_ALS_RANGE_HIGH_LUX); 216 break; 217 case ISL29028_MODE_IR: 218 ret = regmap_update_bits(chip->regmap, ISL29028_REG_CONFIGURE, 219 ISL29028_CONF_ALS_IR_MODE_MASK, 220 ISL29028_CONF_ALS_IR_MODE_IR); 221 break; 222 case ISL29028_MODE_NONE: 223 return regmap_update_bits(chip->regmap, ISL29028_REG_CONFIGURE, 224 ISL29028_CONF_ALS_EN_MASK, 225 ISL29028_CONF_ALS_DIS); 226 } 227 228 if (ret < 0) 229 return ret; 230 231 /* Enable the ALS/IR */ 232 ret = regmap_update_bits(chip->regmap, ISL29028_REG_CONFIGURE, 233 ISL29028_CONF_ALS_EN_MASK, 234 ISL29028_CONF_ALS_EN); 235 if (ret < 0) 236 return ret; 237 238 /* Need to wait for conversion time if ALS/IR mode enabled */ 239 msleep(ISL29028_CONV_TIME_MS); 240 241 chip->als_ir_mode = mode; 242 243 return 0; 244 } 245 246 static int isl29028_read_als_ir(struct isl29028_chip *chip, int *als_ir) 247 { 248 struct device *dev = regmap_get_device(chip->regmap); 249 unsigned int lsb; 250 unsigned int msb; 251 int ret; 252 253 ret = regmap_read(chip->regmap, ISL29028_REG_ALSIR_L, &lsb); 254 if (ret < 0) { 255 dev_err(dev, 256 "%s(): Error %d reading register ALSIR_L\n", 257 __func__, ret); 258 return ret; 259 } 260 261 ret = regmap_read(chip->regmap, ISL29028_REG_ALSIR_U, &msb); 262 if (ret < 0) { 263 dev_err(dev, 264 "%s(): Error %d reading register ALSIR_U\n", 265 __func__, ret); 266 return ret; 267 } 268 269 *als_ir = ((msb & 0xF) << 8) | (lsb & 0xFF); 270 271 return 0; 272 } 273 274 static int isl29028_read_proxim(struct isl29028_chip *chip, int *prox) 275 { 276 struct device *dev = regmap_get_device(chip->regmap); 277 unsigned int data; 278 int ret; 279 280 if (!chip->enable_prox) { 281 ret = isl29028_enable_proximity(chip); 282 if (ret < 0) 283 return ret; 284 285 chip->enable_prox = true; 286 } 287 288 ret = regmap_read(chip->regmap, ISL29028_REG_PROX_DATA, &data); 289 if (ret < 0) { 290 dev_err(dev, "%s(): Error %d reading register PROX_DATA\n", 291 __func__, ret); 292 return ret; 293 } 294 295 *prox = data; 296 297 return 0; 298 } 299 300 static int isl29028_als_get(struct isl29028_chip *chip, int *als_data) 301 { 302 struct device *dev = regmap_get_device(chip->regmap); 303 int ret; 304 int als_ir_data; 305 306 ret = isl29028_set_als_ir_mode(chip, ISL29028_MODE_ALS); 307 if (ret < 0) { 308 dev_err(dev, "%s(): Error %d enabling ALS mode\n", __func__, 309 ret); 310 return ret; 311 } 312 313 ret = isl29028_read_als_ir(chip, &als_ir_data); 314 if (ret < 0) 315 return ret; 316 317 /* 318 * convert als data count to lux. 319 * if lux_scale = 125, lux = count * 0.031 320 * if lux_scale = 2000, lux = count * 0.49 321 */ 322 if (chip->lux_scale == 125) 323 als_ir_data = (als_ir_data * 31) / 1000; 324 else 325 als_ir_data = (als_ir_data * 49) / 100; 326 327 *als_data = als_ir_data; 328 329 return 0; 330 } 331 332 static int isl29028_ir_get(struct isl29028_chip *chip, int *ir_data) 333 { 334 struct device *dev = regmap_get_device(chip->regmap); 335 int ret; 336 337 ret = isl29028_set_als_ir_mode(chip, ISL29028_MODE_IR); 338 if (ret < 0) { 339 dev_err(dev, "%s(): Error %d enabling IR mode\n", __func__, 340 ret); 341 return ret; 342 } 343 344 return isl29028_read_als_ir(chip, ir_data); 345 } 346 347 static int isl29028_set_pm_runtime_busy(struct isl29028_chip *chip, bool on) 348 { 349 struct device *dev = regmap_get_device(chip->regmap); 350 int ret; 351 352 if (on) { 353 ret = pm_runtime_get_sync(dev); 354 if (ret < 0) 355 pm_runtime_put_noidle(dev); 356 } else { 357 pm_runtime_mark_last_busy(dev); 358 ret = pm_runtime_put_autosuspend(dev); 359 } 360 361 return ret; 362 } 363 364 /* Channel IO */ 365 static int isl29028_write_raw(struct iio_dev *indio_dev, 366 struct iio_chan_spec const *chan, 367 int val, int val2, long mask) 368 { 369 struct isl29028_chip *chip = iio_priv(indio_dev); 370 struct device *dev = regmap_get_device(chip->regmap); 371 int ret; 372 373 ret = isl29028_set_pm_runtime_busy(chip, true); 374 if (ret < 0) 375 return ret; 376 377 mutex_lock(&chip->lock); 378 379 ret = -EINVAL; 380 switch (chan->type) { 381 case IIO_PROXIMITY: 382 if (mask != IIO_CHAN_INFO_SAMP_FREQ) { 383 dev_err(dev, 384 "%s(): proximity: Mask value 0x%08lx is not supported\n", 385 __func__, mask); 386 break; 387 } 388 389 if (val < 1 || val > 100) { 390 dev_err(dev, 391 "%s(): proximity: Sampling frequency %d is not in the range [1:100]\n", 392 __func__, val); 393 break; 394 } 395 396 ret = isl29028_set_proxim_sampling(chip, val, val2); 397 break; 398 case IIO_LIGHT: 399 if (mask != IIO_CHAN_INFO_SCALE) { 400 dev_err(dev, 401 "%s(): light: Mask value 0x%08lx is not supported\n", 402 __func__, mask); 403 break; 404 } 405 406 if (val != 125 && val != 2000) { 407 dev_err(dev, 408 "%s(): light: Lux scale %d is not in the set {125, 2000}\n", 409 __func__, val); 410 break; 411 } 412 413 ret = isl29028_set_als_scale(chip, val); 414 break; 415 default: 416 dev_err(dev, "%s(): Unsupported channel type %x\n", 417 __func__, chan->type); 418 break; 419 } 420 421 mutex_unlock(&chip->lock); 422 423 if (ret < 0) 424 return ret; 425 426 ret = isl29028_set_pm_runtime_busy(chip, false); 427 if (ret < 0) 428 return ret; 429 430 return ret; 431 } 432 433 static int isl29028_read_raw(struct iio_dev *indio_dev, 434 struct iio_chan_spec const *chan, 435 int *val, int *val2, long mask) 436 { 437 struct isl29028_chip *chip = iio_priv(indio_dev); 438 struct device *dev = regmap_get_device(chip->regmap); 439 int ret, pm_ret; 440 441 ret = isl29028_set_pm_runtime_busy(chip, true); 442 if (ret < 0) 443 return ret; 444 445 mutex_lock(&chip->lock); 446 447 ret = -EINVAL; 448 switch (mask) { 449 case IIO_CHAN_INFO_RAW: 450 case IIO_CHAN_INFO_PROCESSED: 451 switch (chan->type) { 452 case IIO_LIGHT: 453 ret = isl29028_als_get(chip, val); 454 break; 455 case IIO_INTENSITY: 456 ret = isl29028_ir_get(chip, val); 457 break; 458 case IIO_PROXIMITY: 459 ret = isl29028_read_proxim(chip, val); 460 break; 461 default: 462 break; 463 } 464 465 if (ret < 0) 466 break; 467 468 ret = IIO_VAL_INT; 469 break; 470 case IIO_CHAN_INFO_SAMP_FREQ: 471 if (chan->type != IIO_PROXIMITY) 472 break; 473 474 *val = chip->prox_sampling_int; 475 *val2 = chip->prox_sampling_frac; 476 ret = IIO_VAL_INT; 477 break; 478 case IIO_CHAN_INFO_SCALE: 479 if (chan->type != IIO_LIGHT) 480 break; 481 *val = chip->lux_scale; 482 ret = IIO_VAL_INT; 483 break; 484 default: 485 dev_err(dev, "%s(): mask value 0x%08lx is not supported\n", 486 __func__, mask); 487 break; 488 } 489 490 mutex_unlock(&chip->lock); 491 492 if (ret < 0) 493 return ret; 494 495 /** 496 * Preserve the ret variable if the call to 497 * isl29028_set_pm_runtime_busy() is successful so the reading 498 * (if applicable) is returned to user space. 499 */ 500 pm_ret = isl29028_set_pm_runtime_busy(chip, false); 501 if (pm_ret < 0) 502 return pm_ret; 503 504 return ret; 505 } 506 507 static IIO_CONST_ATTR(in_proximity_sampling_frequency_available, 508 "1.25 2.5 5 10 13.3 20 80 100"); 509 static IIO_CONST_ATTR(in_illuminance_scale_available, "125 2000"); 510 511 #define ISL29028_CONST_ATTR(name) (&iio_const_attr_##name.dev_attr.attr) 512 static struct attribute *isl29028_attributes[] = { 513 ISL29028_CONST_ATTR(in_proximity_sampling_frequency_available), 514 ISL29028_CONST_ATTR(in_illuminance_scale_available), 515 NULL, 516 }; 517 518 static const struct attribute_group isl29108_group = { 519 .attrs = isl29028_attributes, 520 }; 521 522 static const struct iio_chan_spec isl29028_channels[] = { 523 { 524 .type = IIO_LIGHT, 525 .info_mask_separate = BIT(IIO_CHAN_INFO_PROCESSED) | 526 BIT(IIO_CHAN_INFO_SCALE), 527 }, { 528 .type = IIO_INTENSITY, 529 .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), 530 }, { 531 .type = IIO_PROXIMITY, 532 .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | 533 BIT(IIO_CHAN_INFO_SAMP_FREQ), 534 } 535 }; 536 537 static const struct iio_info isl29028_info = { 538 .attrs = &isl29108_group, 539 .read_raw = isl29028_read_raw, 540 .write_raw = isl29028_write_raw, 541 }; 542 543 static int isl29028_clear_configure_reg(struct isl29028_chip *chip) 544 { 545 struct device *dev = regmap_get_device(chip->regmap); 546 int ret; 547 548 ret = regmap_write(chip->regmap, ISL29028_REG_CONFIGURE, 0x0); 549 if (ret < 0) 550 dev_err(dev, "%s(): Error %d clearing the CONFIGURE register\n", 551 __func__, ret); 552 553 chip->als_ir_mode = ISL29028_MODE_NONE; 554 chip->enable_prox = false; 555 556 return ret; 557 } 558 559 static bool isl29028_is_volatile_reg(struct device *dev, unsigned int reg) 560 { 561 switch (reg) { 562 case ISL29028_REG_INTERRUPT: 563 case ISL29028_REG_PROX_DATA: 564 case ISL29028_REG_ALSIR_L: 565 case ISL29028_REG_ALSIR_U: 566 return true; 567 default: 568 return false; 569 } 570 } 571 572 static const struct regmap_config isl29028_regmap_config = { 573 .reg_bits = 8, 574 .val_bits = 8, 575 .volatile_reg = isl29028_is_volatile_reg, 576 .max_register = ISL29028_NUM_REGS - 1, 577 .num_reg_defaults_raw = ISL29028_NUM_REGS, 578 .cache_type = REGCACHE_RBTREE, 579 }; 580 581 static int isl29028_probe(struct i2c_client *client, 582 const struct i2c_device_id *id) 583 { 584 struct isl29028_chip *chip; 585 struct iio_dev *indio_dev; 586 int ret; 587 588 indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*chip)); 589 if (!indio_dev) 590 return -ENOMEM; 591 592 chip = iio_priv(indio_dev); 593 594 i2c_set_clientdata(client, indio_dev); 595 mutex_init(&chip->lock); 596 597 chip->regmap = devm_regmap_init_i2c(client, &isl29028_regmap_config); 598 if (IS_ERR(chip->regmap)) { 599 ret = PTR_ERR(chip->regmap); 600 dev_err(&client->dev, "%s: Error %d initializing regmap\n", 601 __func__, ret); 602 return ret; 603 } 604 605 chip->enable_prox = false; 606 chip->prox_sampling_int = 20; 607 chip->prox_sampling_frac = 0; 608 chip->lux_scale = 2000; 609 610 ret = regmap_write(chip->regmap, ISL29028_REG_TEST1_MODE, 0x0); 611 if (ret < 0) { 612 dev_err(&client->dev, 613 "%s(): Error %d writing to TEST1_MODE register\n", 614 __func__, ret); 615 return ret; 616 } 617 618 ret = regmap_write(chip->regmap, ISL29028_REG_TEST2_MODE, 0x0); 619 if (ret < 0) { 620 dev_err(&client->dev, 621 "%s(): Error %d writing to TEST2_MODE register\n", 622 __func__, ret); 623 return ret; 624 } 625 626 ret = isl29028_clear_configure_reg(chip); 627 if (ret < 0) 628 return ret; 629 630 indio_dev->info = &isl29028_info; 631 indio_dev->channels = isl29028_channels; 632 indio_dev->num_channels = ARRAY_SIZE(isl29028_channels); 633 indio_dev->name = id->name; 634 indio_dev->dev.parent = &client->dev; 635 indio_dev->modes = INDIO_DIRECT_MODE; 636 637 pm_runtime_enable(&client->dev); 638 pm_runtime_set_autosuspend_delay(&client->dev, 639 ISL29028_POWER_OFF_DELAY_MS); 640 pm_runtime_use_autosuspend(&client->dev); 641 642 ret = devm_iio_device_register(indio_dev->dev.parent, indio_dev); 643 if (ret < 0) { 644 dev_err(&client->dev, 645 "%s(): iio registration failed with error %d\n", 646 __func__, ret); 647 return ret; 648 } 649 650 return 0; 651 } 652 653 static int isl29028_remove(struct i2c_client *client) 654 { 655 struct iio_dev *indio_dev = i2c_get_clientdata(client); 656 struct isl29028_chip *chip = iio_priv(indio_dev); 657 658 iio_device_unregister(indio_dev); 659 660 pm_runtime_disable(&client->dev); 661 pm_runtime_set_suspended(&client->dev); 662 pm_runtime_put_noidle(&client->dev); 663 664 return isl29028_clear_configure_reg(chip); 665 } 666 667 static int __maybe_unused isl29028_suspend(struct device *dev) 668 { 669 struct iio_dev *indio_dev = i2c_get_clientdata(to_i2c_client(dev)); 670 struct isl29028_chip *chip = iio_priv(indio_dev); 671 int ret; 672 673 mutex_lock(&chip->lock); 674 675 ret = isl29028_clear_configure_reg(chip); 676 677 mutex_unlock(&chip->lock); 678 679 return ret; 680 } 681 682 static int __maybe_unused isl29028_resume(struct device *dev) 683 { 684 /** 685 * The specific component (ALS/IR or proximity) will enable itself as 686 * needed the next time that the user requests a reading. This is done 687 * above in isl29028_set_als_ir_mode() and isl29028_enable_proximity(). 688 */ 689 return 0; 690 } 691 692 static const struct dev_pm_ops isl29028_pm_ops = { 693 SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend, 694 pm_runtime_force_resume) 695 SET_RUNTIME_PM_OPS(isl29028_suspend, isl29028_resume, NULL) 696 }; 697 698 static const struct i2c_device_id isl29028_id[] = { 699 {"isl29028", 0}, 700 {"isl29030", 0}, 701 {} 702 }; 703 MODULE_DEVICE_TABLE(i2c, isl29028_id); 704 705 static const struct of_device_id isl29028_of_match[] = { 706 { .compatible = "isl,isl29028", }, /* for backward compat., don't use */ 707 { .compatible = "isil,isl29028", }, 708 { .compatible = "isil,isl29030", }, 709 { }, 710 }; 711 MODULE_DEVICE_TABLE(of, isl29028_of_match); 712 713 static struct i2c_driver isl29028_driver = { 714 .driver = { 715 .name = "isl29028", 716 .pm = &isl29028_pm_ops, 717 .of_match_table = isl29028_of_match, 718 }, 719 .probe = isl29028_probe, 720 .remove = isl29028_remove, 721 .id_table = isl29028_id, 722 }; 723 724 module_i2c_driver(isl29028_driver); 725 726 MODULE_DESCRIPTION("ISL29028 Ambient Light and Proximity Sensor driver"); 727 MODULE_LICENSE("GPL v2"); 728 MODULE_AUTHOR("Laxman Dewangan <ldewangan@nvidia.com>"); 729