Fix the RTC device model to operate correctly in 12-hour mode. The following

table documents the values in the RTC 'hour' field in the two modes:

Hour-of-the-day		12-hour mode	24-hour mode
12	AM		12		0
[1-11]	AM		[1-11]		[1-11]
12	PM		0x80 | 12	12
[1-11]	PM		0x80 | [1-11]	[13-23]

Reported by:	Julian Hsiao (madoka@nyanisore.net)
MFC after:	1 week
This commit is contained in:
Neel Natu 2015-03-28 02:55:16 +00:00
parent b3de46ab23
commit f213ae0be6

View File

@ -214,9 +214,27 @@ secs_to_rtc(time_t rtctime, struct vrtc *vrtc, int force_update)
rtc->sec = rtcset(rtc, ct.sec);
rtc->min = rtcset(rtc, ct.min);
hour = ct.hour;
if ((rtc->reg_b & RTCSB_24HR) == 0)
hour = (hour % 12) + 1; /* convert to a 12-hour format */
if (rtc->reg_b & RTCSB_24HR) {
hour = ct.hour;
} else {
/*
* Convert to the 12-hour format.
*/
switch (ct.hour) {
case 0: /* 12 AM */
case 12: /* 12 PM */
hour = 12;
break;
default:
/*
* The remaining 'ct.hour' values are interpreted as:
* [1 - 11] -> 1 - 11 AM
* [13 - 23] -> 1 - 11 PM
*/
hour = ct.hour % 12;
break;
}
}
rtc->hour = rtcset(rtc, hour);
@ -287,9 +305,26 @@ rtc_to_secs(struct vrtc *vrtc)
}
error = rtcget(rtc, hour, &ct.hour);
if ((rtc->reg_b & RTCSB_24HR) == 0) {
ct.hour -= 1;
if (pm)
ct.hour += 12;
if (ct.hour >= 1 && ct.hour <= 12) {
/*
* Convert from 12-hour format to internal 24-hour
* representation as follows:
*
* 12-hour format ct.hour
* 12 AM 0
* 1 - 11 AM 1 - 11
* 12 PM 12
* 1 - 11 PM 13 - 23
*/
if (ct.hour == 12)
ct.hour = 0;
if (pm)
ct.hour += 12;
} else {
VM_CTR2(vm, "Invalid RTC 12-hour format %#x/%d",
rtc->hour, ct.hour);
goto fail;
}
}
if (error || ct.hour < 0 || ct.hour > 23) {