aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/rtc/rtc-isl12057.c20
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
104static int isl12057_rtc_tm_to_regs(u8 *regs, struct rtc_time *tm) 109static 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;