94
94
#define PCF2127_WD_VAL_MAX 255
95
95
#define PCF2127_WD_VAL_DEFAULT 60
96
96
97
+ /* Mask for currently enabled interrupts */
98
+ #define PCF2127_CTRL1_IRQ_MASK (PCF2127_BIT_CTRL1_TSF1)
99
+ #define PCF2127_CTRL2_IRQ_MASK ( \
100
+ PCF2127_BIT_CTRL2_AF | \
101
+ PCF2127_BIT_CTRL2_WDTF | \
102
+ PCF2127_BIT_CTRL2_TSF2)
103
+
97
104
struct pcf2127 {
98
105
struct rtc_device * rtc ;
99
106
struct watchdog_device wdd ;
100
107
struct regmap * regmap ;
108
+ time64_t ts ;
109
+ bool ts_valid ;
110
+ bool irq_enabled ;
101
111
};
102
112
103
113
/*
@@ -434,23 +444,96 @@ static int pcf2127_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm)
434
444
return pcf2127_rtc_alarm_irq_enable (dev , alrm -> enabled );
435
445
}
436
446
447
+ /*
448
+ * This function reads ctrl2 register, caller is responsible for calling
449
+ * pcf2127_wdt_active_ping()
450
+ */
451
+ static int pcf2127_rtc_ts_read (struct device * dev , time64_t * ts )
452
+ {
453
+ struct pcf2127 * pcf2127 = dev_get_drvdata (dev );
454
+ struct rtc_time tm ;
455
+ int ret ;
456
+ unsigned char data [25 ];
457
+
458
+ ret = regmap_bulk_read (pcf2127 -> regmap , PCF2127_REG_CTRL1 , data ,
459
+ sizeof (data ));
460
+ if (ret ) {
461
+ dev_err (dev , "%s: read error ret=%d\n" , __func__ , ret );
462
+ return ret ;
463
+ }
464
+
465
+ dev_dbg (dev ,
466
+ "%s: raw data is cr1=%02x, cr2=%02x, cr3=%02x, ts_sc=%02x, ts_mn=%02x, ts_hr=%02x, ts_dm=%02x, ts_mo=%02x, ts_yr=%02x\n" ,
467
+ __func__ , data [PCF2127_REG_CTRL1 ], data [PCF2127_REG_CTRL2 ],
468
+ data [PCF2127_REG_CTRL3 ], data [PCF2127_REG_TS_SC ],
469
+ data [PCF2127_REG_TS_MN ], data [PCF2127_REG_TS_HR ],
470
+ data [PCF2127_REG_TS_DM ], data [PCF2127_REG_TS_MO ],
471
+ data [PCF2127_REG_TS_YR ]);
472
+
473
+ tm .tm_sec = bcd2bin (data [PCF2127_REG_TS_SC ] & 0x7F );
474
+ tm .tm_min = bcd2bin (data [PCF2127_REG_TS_MN ] & 0x7F );
475
+ tm .tm_hour = bcd2bin (data [PCF2127_REG_TS_HR ] & 0x3F );
476
+ tm .tm_mday = bcd2bin (data [PCF2127_REG_TS_DM ] & 0x3F );
477
+ /* TS_MO register (month) value range: 1-12 */
478
+ tm .tm_mon = bcd2bin (data [PCF2127_REG_TS_MO ] & 0x1F ) - 1 ;
479
+ tm .tm_year = bcd2bin (data [PCF2127_REG_TS_YR ]);
480
+ if (tm .tm_year < 70 )
481
+ tm .tm_year += 100 ; /* assume we are in 1970...2069 */
482
+
483
+ ret = rtc_valid_tm (& tm );
484
+ if (ret ) {
485
+ dev_err (dev , "Invalid timestamp. ret=%d\n" , ret );
486
+ return ret ;
487
+ }
488
+
489
+ * ts = rtc_tm_to_time64 (& tm );
490
+ return 0 ;
491
+ };
492
+
493
+ static void pcf2127_rtc_ts_snapshot (struct device * dev )
494
+ {
495
+ struct pcf2127 * pcf2127 = dev_get_drvdata (dev );
496
+ int ret ;
497
+
498
+ /* Let userspace read the first timestamp */
499
+ if (pcf2127 -> ts_valid )
500
+ return ;
501
+
502
+ ret = pcf2127_rtc_ts_read (dev , & pcf2127 -> ts );
503
+ if (!ret )
504
+ pcf2127 -> ts_valid = true;
505
+ }
506
+
437
507
static irqreturn_t pcf2127_rtc_irq (int irq , void * dev )
438
508
{
439
509
struct pcf2127 * pcf2127 = dev_get_drvdata (dev );
440
- unsigned int ctrl2 = 0 ;
510
+ unsigned int ctrl1 , ctrl2 ;
441
511
int ret = 0 ;
442
512
513
+ ret = regmap_read (pcf2127 -> regmap , PCF2127_REG_CTRL1 , & ctrl1 );
514
+ if (ret )
515
+ return IRQ_NONE ;
516
+
443
517
ret = regmap_read (pcf2127 -> regmap , PCF2127_REG_CTRL2 , & ctrl2 );
444
518
if (ret )
445
519
return IRQ_NONE ;
446
520
447
- if (!(ctrl2 & PCF2127_BIT_CTRL2_AF ))
521
+ if (!(ctrl1 & PCF2127_CTRL1_IRQ_MASK || ctrl2 & PCF2127_CTRL2_IRQ_MASK ))
448
522
return IRQ_NONE ;
449
523
450
- regmap_write (pcf2127 -> regmap , PCF2127_REG_CTRL2 ,
451
- ctrl2 & ~(PCF2127_BIT_CTRL2_AF | PCF2127_BIT_CTRL2_WDTF ));
524
+ if (ctrl1 & PCF2127_BIT_CTRL1_TSF1 || ctrl2 & PCF2127_BIT_CTRL2_TSF2 )
525
+ pcf2127_rtc_ts_snapshot (dev );
526
+
527
+ if (ctrl1 & PCF2127_CTRL1_IRQ_MASK )
528
+ regmap_write (pcf2127 -> regmap , PCF2127_REG_CTRL1 ,
529
+ ctrl1 & ~PCF2127_CTRL1_IRQ_MASK );
530
+
531
+ if (ctrl2 & PCF2127_CTRL2_IRQ_MASK )
532
+ regmap_write (pcf2127 -> regmap , PCF2127_REG_CTRL2 ,
533
+ ctrl2 & ~PCF2127_CTRL2_IRQ_MASK );
452
534
453
- rtc_update_irq (pcf2127 -> rtc , 1 , RTC_IRQF | RTC_AF );
535
+ if (ctrl2 & PCF2127_BIT_CTRL2_AF )
536
+ rtc_update_irq (pcf2127 -> rtc , 1 , RTC_IRQF | RTC_AF );
454
537
455
538
pcf2127_wdt_active_ping (& pcf2127 -> wdd );
456
539
@@ -475,23 +558,27 @@ static ssize_t timestamp0_store(struct device *dev,
475
558
struct pcf2127 * pcf2127 = dev_get_drvdata (dev -> parent );
476
559
int ret ;
477
560
478
- ret = regmap_update_bits (pcf2127 -> regmap , PCF2127_REG_CTRL1 ,
479
- PCF2127_BIT_CTRL1_TSF1 , 0 );
480
- if (ret ) {
481
- dev_err (dev , "%s: update ctrl1 ret=%d\n" , __func__ , ret );
482
- return ret ;
483
- }
561
+ if (pcf2127 -> irq_enabled ) {
562
+ pcf2127 -> ts_valid = false;
563
+ } else {
564
+ ret = regmap_update_bits (pcf2127 -> regmap , PCF2127_REG_CTRL1 ,
565
+ PCF2127_BIT_CTRL1_TSF1 , 0 );
566
+ if (ret ) {
567
+ dev_err (dev , "%s: update ctrl1 ret=%d\n" , __func__ , ret );
568
+ return ret ;
569
+ }
484
570
485
- ret = regmap_update_bits (pcf2127 -> regmap , PCF2127_REG_CTRL2 ,
486
- PCF2127_BIT_CTRL2_TSF2 , 0 );
487
- if (ret ) {
488
- dev_err (dev , "%s: update ctrl2 ret=%d\n" , __func__ , ret );
489
- return ret ;
490
- }
571
+ ret = regmap_update_bits (pcf2127 -> regmap , PCF2127_REG_CTRL2 ,
572
+ PCF2127_BIT_CTRL2_TSF2 , 0 );
573
+ if (ret ) {
574
+ dev_err (dev , "%s: update ctrl2 ret=%d\n" , __func__ , ret );
575
+ return ret ;
576
+ }
491
577
492
- ret = pcf2127_wdt_active_ping (& pcf2127 -> wdd );
493
- if (ret )
494
- return ret ;
578
+ ret = pcf2127_wdt_active_ping (& pcf2127 -> wdd );
579
+ if (ret )
580
+ return ret ;
581
+ }
495
582
496
583
return count ;
497
584
};
@@ -500,50 +587,36 @@ static ssize_t timestamp0_show(struct device *dev,
500
587
struct device_attribute * attr , char * buf )
501
588
{
502
589
struct pcf2127 * pcf2127 = dev_get_drvdata (dev -> parent );
503
- struct rtc_time tm ;
590
+ unsigned int ctrl1 , ctrl2 ;
504
591
int ret ;
505
- unsigned char data [25 ];
506
-
507
- ret = regmap_bulk_read (pcf2127 -> regmap , PCF2127_REG_CTRL1 , data ,
508
- sizeof (data ));
509
- if (ret ) {
510
- dev_err (dev , "%s: read error ret=%d\n" , __func__ , ret );
511
- return ret ;
512
- }
513
-
514
- dev_dbg (dev ,
515
- "%s: raw data is cr1=%02x, cr2=%02x, cr3=%02x, ts_sc=%02x, "
516
- "ts_mn=%02x, ts_hr=%02x, ts_dm=%02x, ts_mo=%02x, ts_yr=%02x\n" ,
517
- __func__ , data [PCF2127_REG_CTRL1 ], data [PCF2127_REG_CTRL2 ],
518
- data [PCF2127_REG_CTRL3 ], data [PCF2127_REG_TS_SC ],
519
- data [PCF2127_REG_TS_MN ], data [PCF2127_REG_TS_HR ],
520
- data [PCF2127_REG_TS_DM ], data [PCF2127_REG_TS_MO ],
521
- data [PCF2127_REG_TS_YR ]);
592
+ time64_t ts ;
593
+
594
+ if (pcf2127 -> irq_enabled ) {
595
+ if (!pcf2127 -> ts_valid )
596
+ return 0 ;
597
+ ts = pcf2127 -> ts ;
598
+ } else {
599
+ ret = regmap_read (pcf2127 -> regmap , PCF2127_REG_CTRL1 , & ctrl1 );
600
+ if (ret )
601
+ return 0 ;
522
602
523
- ret = pcf2127_wdt_active_ping ( & pcf2127 -> wdd );
524
- if (ret )
525
- return ret ;
603
+ ret = regmap_read ( pcf2127 -> regmap , PCF2127_REG_CTRL2 , & ctrl2 );
604
+ if (ret )
605
+ return 0 ;
526
606
527
- if (!(data [ PCF2127_REG_CTRL1 ] & PCF2127_BIT_CTRL1_TSF1 ) &&
528
- !(data [ PCF2127_REG_CTRL2 ] & PCF2127_BIT_CTRL2_TSF2 ))
529
- return 0 ;
607
+ if (!(ctrl1 & PCF2127_BIT_CTRL1_TSF1 ) &&
608
+ !(ctrl2 & PCF2127_BIT_CTRL2_TSF2 ))
609
+ return 0 ;
530
610
531
- tm .tm_sec = bcd2bin (data [PCF2127_REG_TS_SC ] & 0x7F );
532
- tm .tm_min = bcd2bin (data [PCF2127_REG_TS_MN ] & 0x7F );
533
- tm .tm_hour = bcd2bin (data [PCF2127_REG_TS_HR ] & 0x3F );
534
- tm .tm_mday = bcd2bin (data [PCF2127_REG_TS_DM ] & 0x3F );
535
- /* TS_MO register (month) value range: 1-12 */
536
- tm .tm_mon = bcd2bin (data [PCF2127_REG_TS_MO ] & 0x1F ) - 1 ;
537
- tm .tm_year = bcd2bin (data [PCF2127_REG_TS_YR ]);
538
- if (tm .tm_year < 70 )
539
- tm .tm_year += 100 ; /* assume we are in 1970...2069 */
540
-
541
- ret = rtc_valid_tm (& tm );
542
- if (ret )
543
- return ret ;
611
+ ret = pcf2127_rtc_ts_read (dev -> parent , & ts );
612
+ if (ret )
613
+ return 0 ;
544
614
545
- return sprintf (buf , "%llu\n" ,
546
- (unsigned long long )rtc_tm_to_time64 (& tm ));
615
+ ret = pcf2127_wdt_active_ping (& pcf2127 -> wdd );
616
+ if (ret )
617
+ return ret ;
618
+ }
619
+ return sprintf (buf , "%llu\n" , (unsigned long long )ts );
547
620
};
548
621
549
622
static DEVICE_ATTR_RW (timestamp0 );
@@ -594,6 +667,7 @@ static int pcf2127_probe(struct device *dev, struct regmap *regmap,
594
667
dev_err (dev , "failed to request alarm irq\n" );
595
668
return ret ;
596
669
}
670
+ pcf2127 -> irq_enabled = true;
597
671
}
598
672
599
673
if (alarm_irq > 0 || device_property_read_bool (dev , "wakeup-source" )) {
0 commit comments