2 * IIO driver for the light sensor ISL29028.
3 * ISL29028 is Concurrent Ambient Light and Proximity Sensor
5 * Copyright (c) 2012, NVIDIA CORPORATION. All rights reserved.
6 * Copyright (c) 2016-2017 Brian Masney <masneyb@onstation.org>
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.
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
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/>.
21 * - http://www.intersil.com/content/dam/Intersil/documents/isl2/isl29028.pdf
22 * - http://www.intersil.com/content/dam/Intersil/documents/isl2/isl29030.pdf
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>
36 #define ISL29028_CONV_TIME_MS 100
38 #define ISL29028_REG_CONFIGURE 0x01
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)
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)
48 #define ISL29028_CONF_ALS_DIS 0
49 #define ISL29028_CONF_ALS_EN BIT(2)
50 #define ISL29028_CONF_ALS_EN_MASK BIT(2)
52 #define ISL29028_CONF_PROX_SLP_SH 4
53 #define ISL29028_CONF_PROX_SLP_MASK (7 << ISL29028_CONF_PROX_SLP_SH)
55 #define ISL29028_CONF_PROX_EN BIT(7)
56 #define ISL29028_CONF_PROX_EN_MASK BIT(7)
58 #define ISL29028_REG_INTERRUPT 0x02
60 #define ISL29028_REG_PROX_DATA 0x08
61 #define ISL29028_REG_ALSIR_L 0x09
62 #define ISL29028_REG_ALSIR_U 0x0A
64 #define ISL29028_REG_TEST1_MODE 0x0E
65 #define ISL29028_REG_TEST2_MODE 0x0F
67 #define ISL29028_NUM_REGS (ISL29028_REG_TEST2_MODE + 1)
69 #define ISL29028_POWER_OFF_DELAY_MS 2000
71 struct isl29028_prox_data
{
77 static const struct isl29028_prox_data isl29028_prox_data
[] = {
85 * Note: Data sheet lists 12.5 ms sleep time.
86 * Round up a half millisecond for msleep().
91 enum isl29028_als_ir_mode
{
92 ISL29028_MODE_NONE
= 0,
97 struct isl29028_chip
{
99 struct regmap
*regmap
;
100 int prox_sampling_int
;
101 int prox_sampling_frac
;
104 enum isl29028_als_ir_mode als_ir_mode
;
107 static int isl29028_find_prox_sleep_index(int sampling_int
, int sampling_fract
)
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
)
120 static int isl29028_set_proxim_sampling(struct isl29028_chip
*chip
,
121 int sampling_int
, int sampling_fract
)
123 struct device
*dev
= regmap_get_device(chip
->regmap
);
124 int sleep_index
, ret
;
126 sleep_index
= isl29028_find_prox_sleep_index(sampling_int
,
131 ret
= regmap_update_bits(chip
->regmap
, ISL29028_REG_CONFIGURE
,
132 ISL29028_CONF_PROX_SLP_MASK
,
133 sleep_index
<< ISL29028_CONF_PROX_SLP_SH
);
136 dev_err(dev
, "%s(): Error %d setting the proximity sampling\n",
141 chip
->prox_sampling_int
= sampling_int
;
142 chip
->prox_sampling_frac
= sampling_fract
;
147 static int isl29028_enable_proximity(struct isl29028_chip
*chip
)
151 ret
= isl29028_set_proxim_sampling(chip
, chip
->prox_sampling_int
,
152 chip
->prox_sampling_frac
);
156 ret
= regmap_update_bits(chip
->regmap
, ISL29028_REG_CONFIGURE
,
157 ISL29028_CONF_PROX_EN_MASK
,
158 ISL29028_CONF_PROX_EN
);
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
);
168 msleep(isl29028_prox_data
[prox_index
].sleep_time
);
173 static int isl29028_set_als_scale(struct isl29028_chip
*chip
, int lux_scale
)
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
;
180 ret
= regmap_update_bits(chip
->regmap
, ISL29028_REG_CONFIGURE
,
181 ISL29028_CONF_ALS_RANGE_MASK
, val
);
183 dev_err(dev
, "%s(): Error %d setting the ALS scale\n", __func__
,
188 chip
->lux_scale
= lux_scale
;
193 static int isl29028_set_als_ir_mode(struct isl29028_chip
*chip
,
194 enum isl29028_als_ir_mode mode
)
198 if (chip
->als_ir_mode
== mode
)
201 ret
= isl29028_set_als_scale(chip
, chip
->lux_scale
);
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
);
213 ret
= regmap_update_bits(chip
->regmap
, ISL29028_REG_CONFIGURE
,
214 ISL29028_CONF_ALS_RANGE_MASK
,
215 ISL29028_CONF_ALS_RANGE_HIGH_LUX
);
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
);
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
);
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
);
238 /* Need to wait for conversion time if ALS/IR mode enabled */
239 msleep(ISL29028_CONV_TIME_MS
);
241 chip
->als_ir_mode
= mode
;
246 static int isl29028_read_als_ir(struct isl29028_chip
*chip
, int *als_ir
)
248 struct device
*dev
= regmap_get_device(chip
->regmap
);
253 ret
= regmap_read(chip
->regmap
, ISL29028_REG_ALSIR_L
, &lsb
);
256 "%s(): Error %d reading register ALSIR_L\n",
261 ret
= regmap_read(chip
->regmap
, ISL29028_REG_ALSIR_U
, &msb
);
264 "%s(): Error %d reading register ALSIR_U\n",
269 *als_ir
= ((msb
& 0xF) << 8) | (lsb
& 0xFF);
274 static int isl29028_read_proxim(struct isl29028_chip
*chip
, int *prox
)
276 struct device
*dev
= regmap_get_device(chip
->regmap
);
280 if (!chip
->enable_prox
) {
281 ret
= isl29028_enable_proximity(chip
);
285 chip
->enable_prox
= true;
288 ret
= regmap_read(chip
->regmap
, ISL29028_REG_PROX_DATA
, &data
);
290 dev_err(dev
, "%s(): Error %d reading register PROX_DATA\n",
300 static int isl29028_als_get(struct isl29028_chip
*chip
, int *als_data
)
302 struct device
*dev
= regmap_get_device(chip
->regmap
);
306 ret
= isl29028_set_als_ir_mode(chip
, ISL29028_MODE_ALS
);
308 dev_err(dev
, "%s(): Error %d enabling ALS mode\n", __func__
,
313 ret
= isl29028_read_als_ir(chip
, &als_ir_data
);
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
322 if (chip
->lux_scale
== 125)
323 als_ir_data
= (als_ir_data
* 31) / 1000;
325 als_ir_data
= (als_ir_data
* 49) / 100;
327 *als_data
= als_ir_data
;
332 static int isl29028_ir_get(struct isl29028_chip
*chip
, int *ir_data
)
334 struct device
*dev
= regmap_get_device(chip
->regmap
);
337 ret
= isl29028_set_als_ir_mode(chip
, ISL29028_MODE_IR
);
339 dev_err(dev
, "%s(): Error %d enabling IR mode\n", __func__
,
344 return isl29028_read_als_ir(chip
, ir_data
);
347 static int isl29028_set_pm_runtime_busy(struct isl29028_chip
*chip
, bool on
)
349 struct device
*dev
= regmap_get_device(chip
->regmap
);
353 ret
= pm_runtime_get_sync(dev
);
355 pm_runtime_put_noidle(dev
);
357 pm_runtime_mark_last_busy(dev
);
358 ret
= pm_runtime_put_autosuspend(dev
);
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
)
369 struct isl29028_chip
*chip
= iio_priv(indio_dev
);
370 struct device
*dev
= regmap_get_device(chip
->regmap
);
373 ret
= isl29028_set_pm_runtime_busy(chip
, true);
377 mutex_lock(&chip
->lock
);
380 switch (chan
->type
) {
382 if (mask
!= IIO_CHAN_INFO_SAMP_FREQ
) {
384 "%s(): proximity: Mask value 0x%08lx is not supported\n",
389 if (val
< 1 || val
> 100) {
391 "%s(): proximity: Sampling frequency %d is not in the range [1:100]\n",
396 ret
= isl29028_set_proxim_sampling(chip
, val
, val2
);
399 if (mask
!= IIO_CHAN_INFO_SCALE
) {
401 "%s(): light: Mask value 0x%08lx is not supported\n",
406 if (val
!= 125 && val
!= 2000) {
408 "%s(): light: Lux scale %d is not in the set {125, 2000}\n",
413 ret
= isl29028_set_als_scale(chip
, val
);
416 dev_err(dev
, "%s(): Unsupported channel type %x\n",
417 __func__
, chan
->type
);
421 mutex_unlock(&chip
->lock
);
426 ret
= isl29028_set_pm_runtime_busy(chip
, false);
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
)
437 struct isl29028_chip
*chip
= iio_priv(indio_dev
);
438 struct device
*dev
= regmap_get_device(chip
->regmap
);
441 ret
= isl29028_set_pm_runtime_busy(chip
, true);
445 mutex_lock(&chip
->lock
);
449 case IIO_CHAN_INFO_RAW
:
450 case IIO_CHAN_INFO_PROCESSED
:
451 switch (chan
->type
) {
453 ret
= isl29028_als_get(chip
, val
);
456 ret
= isl29028_ir_get(chip
, val
);
459 ret
= isl29028_read_proxim(chip
, val
);
470 case IIO_CHAN_INFO_SAMP_FREQ
:
471 if (chan
->type
!= IIO_PROXIMITY
)
474 *val
= chip
->prox_sampling_int
;
475 *val2
= chip
->prox_sampling_frac
;
478 case IIO_CHAN_INFO_SCALE
:
479 if (chan
->type
!= IIO_LIGHT
)
481 *val
= chip
->lux_scale
;
485 dev_err(dev
, "%s(): mask value 0x%08lx is not supported\n",
490 mutex_unlock(&chip
->lock
);
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.
500 pm_ret
= isl29028_set_pm_runtime_busy(chip
, false);
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");
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
),
518 static const struct attribute_group isl29108_group
= {
519 .attrs
= isl29028_attributes
,
522 static const struct iio_chan_spec isl29028_channels
[] = {
525 .info_mask_separate
= BIT(IIO_CHAN_INFO_PROCESSED
) |
526 BIT(IIO_CHAN_INFO_SCALE
),
528 .type
= IIO_INTENSITY
,
529 .info_mask_separate
= BIT(IIO_CHAN_INFO_RAW
),
531 .type
= IIO_PROXIMITY
,
532 .info_mask_separate
= BIT(IIO_CHAN_INFO_RAW
) |
533 BIT(IIO_CHAN_INFO_SAMP_FREQ
),
537 static const struct iio_info isl29028_info
= {
538 .attrs
= &isl29108_group
,
539 .read_raw
= isl29028_read_raw
,
540 .write_raw
= isl29028_write_raw
,
543 static int isl29028_clear_configure_reg(struct isl29028_chip
*chip
)
545 struct device
*dev
= regmap_get_device(chip
->regmap
);
548 ret
= regmap_write(chip
->regmap
, ISL29028_REG_CONFIGURE
, 0x0);
550 dev_err(dev
, "%s(): Error %d clearing the CONFIGURE register\n",
553 chip
->als_ir_mode
= ISL29028_MODE_NONE
;
554 chip
->enable_prox
= false;
559 static bool isl29028_is_volatile_reg(struct device
*dev
, unsigned int reg
)
562 case ISL29028_REG_INTERRUPT
:
563 case ISL29028_REG_PROX_DATA
:
564 case ISL29028_REG_ALSIR_L
:
565 case ISL29028_REG_ALSIR_U
:
572 static const struct regmap_config isl29028_regmap_config
= {
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
,
581 static int isl29028_probe(struct i2c_client
*client
,
582 const struct i2c_device_id
*id
)
584 struct isl29028_chip
*chip
;
585 struct iio_dev
*indio_dev
;
588 indio_dev
= devm_iio_device_alloc(&client
->dev
, sizeof(*chip
));
592 chip
= iio_priv(indio_dev
);
594 i2c_set_clientdata(client
, indio_dev
);
595 mutex_init(&chip
->lock
);
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",
605 chip
->enable_prox
= false;
606 chip
->prox_sampling_int
= 20;
607 chip
->prox_sampling_frac
= 0;
608 chip
->lux_scale
= 2000;
610 ret
= regmap_write(chip
->regmap
, ISL29028_REG_TEST1_MODE
, 0x0);
612 dev_err(&client
->dev
,
613 "%s(): Error %d writing to TEST1_MODE register\n",
618 ret
= regmap_write(chip
->regmap
, ISL29028_REG_TEST2_MODE
, 0x0);
620 dev_err(&client
->dev
,
621 "%s(): Error %d writing to TEST2_MODE register\n",
626 ret
= isl29028_clear_configure_reg(chip
);
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
;
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
);
642 ret
= devm_iio_device_register(indio_dev
->dev
.parent
, indio_dev
);
644 dev_err(&client
->dev
,
645 "%s(): iio registration failed with error %d\n",
653 static int isl29028_remove(struct i2c_client
*client
)
655 struct iio_dev
*indio_dev
= i2c_get_clientdata(client
);
656 struct isl29028_chip
*chip
= iio_priv(indio_dev
);
658 iio_device_unregister(indio_dev
);
660 pm_runtime_disable(&client
->dev
);
661 pm_runtime_set_suspended(&client
->dev
);
662 pm_runtime_put_noidle(&client
->dev
);
664 return isl29028_clear_configure_reg(chip
);
667 static int __maybe_unused
isl29028_suspend(struct device
*dev
)
669 struct iio_dev
*indio_dev
= i2c_get_clientdata(to_i2c_client(dev
));
670 struct isl29028_chip
*chip
= iio_priv(indio_dev
);
673 mutex_lock(&chip
->lock
);
675 ret
= isl29028_clear_configure_reg(chip
);
677 mutex_unlock(&chip
->lock
);
682 static int __maybe_unused
isl29028_resume(struct device
*dev
)
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().
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
)
698 static const struct i2c_device_id isl29028_id
[] = {
703 MODULE_DEVICE_TABLE(i2c
, isl29028_id
);
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", },
711 MODULE_DEVICE_TABLE(of
, isl29028_of_match
);
713 static struct i2c_driver isl29028_driver
= {
716 .pm
= &isl29028_pm_ops
,
717 .of_match_table
= isl29028_of_match
,
719 .probe
= isl29028_probe
,
720 .remove
= isl29028_remove
,
721 .id_table
= isl29028_id
,
724 module_i2c_driver(isl29028_driver
);
726 MODULE_DESCRIPTION("ISL29028 Ambient Light and Proximity Sensor driver");
727 MODULE_LICENSE("GPL v2");
728 MODULE_AUTHOR("Laxman Dewangan <ldewangan@nvidia.com>");