26
26
#include <linux/regmap.h>
27
27
#include <linux/iio/iio.h>
28
28
#include <linux/iio/sysfs.h>
29
+ #include <linux/pm_runtime.h>
29
30
30
31
#define ISL29028_CONV_TIME_MS 100
31
32
60
61
61
62
#define ISL29028_NUM_REGS (ISL29028_REG_TEST2_MODE + 1)
62
63
64
+ #define ISL29028_POWER_OFF_DELAY_MS 2000
65
+
63
66
enum isl29028_als_ir_mode {
64
67
ISL29028_MODE_NONE = 0 ,
65
68
ISL29028_MODE_ALS ,
@@ -297,16 +300,39 @@ static int isl29028_ir_get(struct isl29028_chip *chip, int *ir_data)
297
300
return isl29028_read_als_ir (chip , ir_data );
298
301
}
299
302
303
+ static int isl29028_set_pm_runtime_busy (struct isl29028_chip * chip , bool on )
304
+ {
305
+ struct device * dev = regmap_get_device (chip -> regmap );
306
+ int ret ;
307
+
308
+ if (on ) {
309
+ ret = pm_runtime_get_sync (dev );
310
+ if (ret < 0 )
311
+ pm_runtime_put_noidle (dev );
312
+ } else {
313
+ pm_runtime_mark_last_busy (dev );
314
+ ret = pm_runtime_put_autosuspend (dev );
315
+ }
316
+
317
+ return ret ;
318
+ }
319
+
300
320
/* Channel IO */
301
321
static int isl29028_write_raw (struct iio_dev * indio_dev ,
302
322
struct iio_chan_spec const * chan ,
303
323
int val , int val2 , long mask )
304
324
{
305
325
struct isl29028_chip * chip = iio_priv (indio_dev );
306
326
struct device * dev = regmap_get_device (chip -> regmap );
307
- int ret = - EINVAL ;
327
+ int ret ;
328
+
329
+ ret = isl29028_set_pm_runtime_busy (chip , true);
330
+ if (ret < 0 )
331
+ return ret ;
308
332
309
333
mutex_lock (& chip -> lock );
334
+
335
+ ret = - EINVAL ;
310
336
switch (chan -> type ) {
311
337
case IIO_PROXIMITY :
312
338
if (mask != IIO_CHAN_INFO_SAMP_FREQ ) {
@@ -350,6 +376,13 @@ static int isl29028_write_raw(struct iio_dev *indio_dev,
350
376
351
377
mutex_unlock (& chip -> lock );
352
378
379
+ if (ret < 0 )
380
+ return ret ;
381
+
382
+ ret = isl29028_set_pm_runtime_busy (chip , false);
383
+ if (ret < 0 )
384
+ return ret ;
385
+
353
386
return ret ;
354
387
}
355
388
@@ -359,9 +392,15 @@ static int isl29028_read_raw(struct iio_dev *indio_dev,
359
392
{
360
393
struct isl29028_chip * chip = iio_priv (indio_dev );
361
394
struct device * dev = regmap_get_device (chip -> regmap );
362
- int ret = - EINVAL ;
395
+ int ret , pm_ret ;
396
+
397
+ ret = isl29028_set_pm_runtime_busy (chip , true);
398
+ if (ret < 0 )
399
+ return ret ;
363
400
364
401
mutex_lock (& chip -> lock );
402
+
403
+ ret = - EINVAL ;
365
404
switch (mask ) {
366
405
case IIO_CHAN_INFO_RAW :
367
406
case IIO_CHAN_INFO_PROCESSED :
@@ -405,6 +444,18 @@ static int isl29028_read_raw(struct iio_dev *indio_dev,
405
444
406
445
mutex_unlock (& chip -> lock );
407
446
447
+ if (ret < 0 )
448
+ return ret ;
449
+
450
+ /**
451
+ * Preserve the ret variable if the call to
452
+ * isl29028_set_pm_runtime_busy() is successful so the reading
453
+ * (if applicable) is returned to user space.
454
+ */
455
+ pm_ret = isl29028_set_pm_runtime_busy (chip , false);
456
+ if (pm_ret < 0 )
457
+ return pm_ret ;
458
+
408
459
return ret ;
409
460
}
410
461
@@ -445,17 +496,18 @@ static const struct iio_info isl29028_info = {
445
496
.write_raw = isl29028_write_raw ,
446
497
};
447
498
448
- static int isl29028_chip_init_and_power_on (struct isl29028_chip * chip )
499
+ static int isl29028_clear_configure_reg (struct isl29028_chip * chip )
449
500
{
450
501
struct device * dev = regmap_get_device (chip -> regmap );
451
502
int ret ;
452
503
453
504
ret = regmap_write (chip -> regmap , ISL29028_REG_CONFIGURE , 0x0 );
454
- if (ret < 0 ) {
505
+ if (ret < 0 )
455
506
dev_err (dev , "%s(): Error %d clearing the CONFIGURE register\n" ,
456
507
__func__ , ret );
457
- return ret ;
458
- }
508
+
509
+ chip -> als_ir_mode = ISL29028_MODE_NONE ;
510
+ chip -> enable_prox = false;
459
511
460
512
return ret ;
461
513
}
@@ -509,7 +561,6 @@ static int isl29028_probe(struct i2c_client *client,
509
561
chip -> enable_prox = false;
510
562
chip -> prox_sampling = 20 ;
511
563
chip -> lux_scale = 2000 ;
512
- chip -> als_ir_mode = ISL29028_MODE_NONE ;
513
564
514
565
ret = regmap_write (chip -> regmap , ISL29028_REG_TEST1_MODE , 0x0 );
515
566
if (ret < 0 ) {
@@ -527,7 +578,7 @@ static int isl29028_probe(struct i2c_client *client,
527
578
return ret ;
528
579
}
529
580
530
- ret = isl29028_chip_init_and_power_on (chip );
581
+ ret = isl29028_clear_configure_reg (chip );
531
582
if (ret < 0 )
532
583
return ret ;
533
584
@@ -538,6 +589,11 @@ static int isl29028_probe(struct i2c_client *client,
538
589
indio_dev -> dev .parent = & client -> dev ;
539
590
indio_dev -> modes = INDIO_DIRECT_MODE ;
540
591
592
+ pm_runtime_enable (& client -> dev );
593
+ pm_runtime_set_autosuspend_delay (& client -> dev ,
594
+ ISL29028_POWER_OFF_DELAY_MS );
595
+ pm_runtime_use_autosuspend (& client -> dev );
596
+
541
597
ret = devm_iio_device_register (indio_dev -> dev .parent , indio_dev );
542
598
if (ret < 0 ) {
543
599
dev_err (& client -> dev ,
@@ -549,6 +605,50 @@ static int isl29028_probe(struct i2c_client *client,
549
605
return 0 ;
550
606
}
551
607
608
+ static int isl29028_remove (struct i2c_client * client )
609
+ {
610
+ struct iio_dev * indio_dev = i2c_get_clientdata (client );
611
+ struct isl29028_chip * chip = iio_priv (indio_dev );
612
+
613
+ iio_device_unregister (indio_dev );
614
+
615
+ pm_runtime_disable (& client -> dev );
616
+ pm_runtime_set_suspended (& client -> dev );
617
+ pm_runtime_put_noidle (& client -> dev );
618
+
619
+ return isl29028_clear_configure_reg (chip );
620
+ }
621
+
622
+ static int __maybe_unused isl29028_suspend (struct device * dev )
623
+ {
624
+ struct iio_dev * indio_dev = i2c_get_clientdata (to_i2c_client (dev ));
625
+ struct isl29028_chip * chip = iio_priv (indio_dev );
626
+ int ret ;
627
+
628
+ mutex_lock (& chip -> lock );
629
+
630
+ ret = isl29028_clear_configure_reg (chip );
631
+
632
+ mutex_unlock (& chip -> lock );
633
+
634
+ return ret ;
635
+ }
636
+
637
+ static int __maybe_unused isl29028_resume (struct device * dev )
638
+ {
639
+ /**
640
+ * The specific component (ALS/IR or proximity) will enable itself as
641
+ * needed the next time that the user requests a reading. This is done
642
+ * above in isl29028_set_als_ir_mode() and isl29028_enable_proximity().
643
+ */
644
+ return 0 ;
645
+ }
646
+
647
+ static const struct dev_pm_ops isl29028_pm_ops = {
648
+ SET_SYSTEM_SLEEP_PM_OPS (isl29028_suspend , isl29028_resume )
649
+ SET_RUNTIME_PM_OPS (isl29028_suspend , isl29028_resume , NULL )
650
+ };
651
+
552
652
static const struct i2c_device_id isl29028_id [] = {
553
653
{"isl29028" , 0 },
554
654
{}
@@ -565,9 +665,11 @@ MODULE_DEVICE_TABLE(of, isl29028_of_match);
565
665
static struct i2c_driver isl29028_driver = {
566
666
.driver = {
567
667
.name = "isl29028" ,
668
+ .pm = & isl29028_pm_ops ,
568
669
.of_match_table = isl29028_of_match ,
569
670
},
570
671
.probe = isl29028_probe ,
672
+ .remove = isl29028_remove ,
571
673
.id_table = isl29028_id ,
572
674
};
573
675
0 commit comments