diff options
-rw-r--r-- | drivers/rtc/rtc-isl12057.c | 20 |
1 files changed, 16 insertions, 4 deletions
diff --git a/drivers/rtc/rtc-isl12057.c b/drivers/rtc/rtc-isl12057.c index 8c3f60737df8..b538fabfcfd3 100644 --- a/drivers/rtc/rtc-isl12057.c +++ b/drivers/rtc/rtc-isl12057.c | |||
@@ -41,6 +41,7 @@ | |||
41 | #define ISL12057_REG_RTC_DW 0x03 /* Day of the Week */ | 41 | #define ISL12057_REG_RTC_DW 0x03 /* Day of the Week */ |
42 | #define ISL12057_REG_RTC_DT 0x04 /* Date */ | 42 | #define ISL12057_REG_RTC_DT 0x04 /* Date */ |
43 | #define ISL12057_REG_RTC_MO 0x05 /* Month */ | 43 | #define ISL12057_REG_RTC_MO 0x05 /* Month */ |
44 | #define ISL12057_REG_RTC_MO_CEN BIT(7) /* Century bit */ | ||
44 | #define ISL12057_REG_RTC_YR 0x06 /* Year */ | 45 | #define ISL12057_REG_RTC_YR 0x06 /* Year */ |
45 | #define ISL12057_RTC_SEC_LEN 7 | 46 | #define ISL12057_RTC_SEC_LEN 7 |
46 | 47 | ||
@@ -99,24 +100,35 @@ static void isl12057_rtc_regs_to_tm(struct rtc_time *tm, u8 *regs) | |||
99 | tm->tm_wday = bcd2bin(regs[ISL12057_REG_RTC_DW]) - 1; /* starts at 1 */ | 100 | tm->tm_wday = bcd2bin(regs[ISL12057_REG_RTC_DW]) - 1; /* starts at 1 */ |
100 | tm->tm_mon = bcd2bin(regs[ISL12057_REG_RTC_MO] & 0x1f) - 1; /* ditto */ | 101 | tm->tm_mon = bcd2bin(regs[ISL12057_REG_RTC_MO] & 0x1f) - 1; /* ditto */ |
101 | tm->tm_year = bcd2bin(regs[ISL12057_REG_RTC_YR]) + 100; | 102 | tm->tm_year = bcd2bin(regs[ISL12057_REG_RTC_YR]) + 100; |
103 | |||
104 | /* Check if years register has overflown from 99 to 00 */ | ||
105 | if (regs[ISL12057_REG_RTC_MO] & ISL12057_REG_RTC_MO_CEN) | ||
106 | tm->tm_year += 100; | ||
102 | } | 107 | } |
103 | 108 | ||
104 | static int isl12057_rtc_tm_to_regs(u8 *regs, struct rtc_time *tm) | 109 | static int isl12057_rtc_tm_to_regs(u8 *regs, struct rtc_time *tm) |
105 | { | 110 | { |
111 | u8 century_bit; | ||
112 | |||
106 | /* | 113 | /* |
107 | * The clock has an 8 bit wide bcd-coded register for the year. | 114 | * The clock has an 8 bit wide bcd-coded register for the year. |
115 | * It also has a century bit encoded in MO flag which provides | ||
116 | * information about overflow of year register from 99 to 00. | ||
108 | * tm_year is an offset from 1900 and we are interested in the | 117 | * tm_year is an offset from 1900 and we are interested in the |
109 | * 2000-2099 range, so any value less than 100 is invalid. | 118 | * 2000-2199 range, so any value less than 100 or larger than |
119 | * 299 is invalid. | ||
110 | */ | 120 | */ |
111 | if (tm->tm_year < 100) | 121 | if (tm->tm_year < 100 || tm->tm_year > 299) |
112 | return -EINVAL; | 122 | return -EINVAL; |
113 | 123 | ||
124 | century_bit = (tm->tm_year > 199) ? ISL12057_REG_RTC_MO_CEN : 0; | ||
125 | |||
114 | regs[ISL12057_REG_RTC_SC] = bin2bcd(tm->tm_sec); | 126 | regs[ISL12057_REG_RTC_SC] = bin2bcd(tm->tm_sec); |
115 | regs[ISL12057_REG_RTC_MN] = bin2bcd(tm->tm_min); | 127 | regs[ISL12057_REG_RTC_MN] = bin2bcd(tm->tm_min); |
116 | regs[ISL12057_REG_RTC_HR] = bin2bcd(tm->tm_hour); /* 24-hour format */ | 128 | regs[ISL12057_REG_RTC_HR] = bin2bcd(tm->tm_hour); /* 24-hour format */ |
117 | regs[ISL12057_REG_RTC_DT] = bin2bcd(tm->tm_mday); | 129 | regs[ISL12057_REG_RTC_DT] = bin2bcd(tm->tm_mday); |
118 | regs[ISL12057_REG_RTC_MO] = bin2bcd(tm->tm_mon + 1); | 130 | regs[ISL12057_REG_RTC_MO] = bin2bcd(tm->tm_mon + 1) | century_bit; |
119 | regs[ISL12057_REG_RTC_YR] = bin2bcd(tm->tm_year - 100); | 131 | regs[ISL12057_REG_RTC_YR] = bin2bcd(tm->tm_year % 100); |
120 | regs[ISL12057_REG_RTC_DW] = bin2bcd(tm->tm_wday + 1); | 132 | regs[ISL12057_REG_RTC_DW] = bin2bcd(tm->tm_wday + 1); |
121 | 133 | ||
122 | return 0; | 134 | return 0; |