Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 27 additions & 11 deletions drivers/rtc/rtc-hibvt.c
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,13 @@ union u_spi_rw {
#define REG_LOCK_STAT BIT(1)
#define REG_LOCK_BYPASS BIT(2)

/*
* A counter that lost every supply restarts from zero and reads as 1970.
* Times before 2000-01-01 are refused both ways, so such a counter reads
* as unset and every time set_time() accepts can be read back.
*/
#define RTC_MIN_VALID_SEC 946684800UL

#define RTC_RW_RETRY_CNT 5
#define SPI_RW_RETRY_CNT 500
#define RTC_SLEEP_TIME_MS 20
Expand Down Expand Up @@ -212,12 +219,15 @@ static int hibvt_rtc_read_time(struct device *dev, struct rtc_time *time)
return ret;
}

if (raw_value & LV_INT_MASK) {
//dev_err(dev,
// "low voltage detected, date/time is not reliable.\n");
(unsigned int)hibvt_spi_write(rtc->regs, RTC_INT_CLR, 1);
//return -EINVAL;
}
/*
* Not a verdict on the time: on a hi3516ev300 the flag stays set,
* and returns about half a second after each clear, with a fresh
* backup cell that keeps the counter through a power cut, exactly as
* it did with a flat one. The counter below is what tells. Clear the
* flag by its own bit: writing 1 acknowledged the alarm instead.
*/
if (raw_value & LV_INT_MASK)
hibvt_spi_write(rtc->regs, RTC_INT_CLR, LV_INT_MASK);

ret |= (unsigned int)hibvt_spi_rtc_read(rtc->regs, RTC_LORD, &raw_value);
if (raw_value & REG_LOCK_BYPASS)
Expand Down Expand Up @@ -251,6 +261,13 @@ static int hibvt_rtc_read_time(struct device *dev, struct rtc_time *time)
day = (dayl | (dayh << 8));
seconds = DATE_TO_SEC(day, hour, minute, second);

/*
* Report a counter that restarted from zero as unset, so hctosys
* leaves the clock alone instead of stepping it to 1970.
*/
if (seconds < RTC_MIN_VALID_SEC)
return -EINVAL;
Comment thread
qodo-free-for-open-source-projects[bot] marked this conversation as resolved.

rtc_time_to_tm(seconds, time);

return rtc_valid_tm(time);
Expand All @@ -268,6 +285,8 @@ static int hibvt_rtc_set_time(struct device *dev, struct rtc_time *time)
ret = rtc_tm_to_time(time, &seconds);
if (ret)
return ret;
if (seconds < RTC_MIN_VALID_SEC)
return -EINVAL;
days = SEC_TO_DAY(seconds);

ret |= (unsigned int)hibvt_spi_rtc_write(rtc->regs, RTC_LR_10MS, 0);
Expand Down Expand Up @@ -554,11 +573,8 @@ static int hibvt_rtc_init(struct hibvt_rtc *rtc)
return ret;
}

if (val & LV_INT_MASK) {
/* dev_err(&rtc->rtc_dev->dev,
"low voltage detected, date/time is not reliable.\n"); */
hibvt_spi_write(rtc->regs, RTC_INT_CLR, 1);
}
if (val & LV_INT_MASK)
hibvt_spi_write(rtc->regs, RTC_INT_CLR, LV_INT_MASK);

return ret;
}
Expand Down