Revision aec454d2
b/hw/twl92230.c | ||
---|---|---|
59 | 59 |
struct tm tm; |
60 | 60 |
struct tm new; |
61 | 61 |
struct tm alm; |
62 |
time_t sec;
|
|
63 |
time_t alm_sec;
|
|
64 |
time_t next_comp;
|
|
62 |
int sec_offset;
|
|
63 |
int alm_sec;
|
|
64 |
int next_comp;
|
|
65 | 65 |
struct tm *(*gettime)(const time_t *timep, struct tm *result); |
66 | 66 |
} rtc; |
67 | 67 |
qemu_irq handler[3]; |
... | ... | |
91 | 91 |
|
92 | 92 |
static void menelaus_rtc_update(struct menelaus_s *s) |
93 | 93 |
{ |
94 |
s->rtc.gettime(&s->rtc.sec, &s->rtc.tm);
|
|
94 |
qemu_get_timedate(&s->rtc.tm, s->rtc.sec_offset);
|
|
95 | 95 |
} |
96 | 96 |
|
97 | 97 |
static void menelaus_alm_update(struct menelaus_s *s) |
98 | 98 |
{ |
99 | 99 |
if ((s->rtc.ctrl & 3) == 3) |
100 |
s->rtc.alm_sec = mktime(&s->rtc.alm);
|
|
100 |
s->rtc.alm_sec = qemu_timedate_diff(&s->rtc.alm) - s->rtc.sec_offset;
|
|
101 | 101 |
} |
102 | 102 |
|
103 | 103 |
static void menelaus_rtc_hz(void *opaque) |
104 | 104 |
{ |
105 | 105 |
struct menelaus_s *s = (struct menelaus_s *) opaque; |
106 | 106 |
|
107 |
s->rtc.sec ++; |
|
107 |
s->rtc.next_comp --; |
|
108 |
s->rtc.alm_sec --; |
|
108 | 109 |
s->rtc.next += 1000; |
109 | 110 |
qemu_mod_timer(s->rtc.hz, s->rtc.next); |
110 | 111 |
if ((s->rtc.ctrl >> 3) & 3) { /* EVERY */ |
... | ... | |
118 | 119 |
} else |
119 | 120 |
s->status |= 1 << 8; /* RTCTMR */ |
120 | 121 |
if ((s->rtc.ctrl >> 1) & 1) { /* RTC_AL_EN */ |
121 |
if (s->rtc.sec == s->rtc.alm_sec)
|
|
122 |
if (s->rtc.alm_sec == 0)
|
|
122 | 123 |
s->status |= 1 << 9; /* RTCALM */ |
123 | 124 |
/* TODO: wake-up */ |
124 | 125 |
} |
125 |
if (s->rtc.next_comp >= s->rtc.sec) {
|
|
126 |
if (s->rtc.next_comp <= 0) {
|
|
126 | 127 |
s->rtc.next -= muldiv64((int16_t) s->rtc.comp, 1000, 0x8000); |
127 |
s->rtc.next_comp = s->rtc.sec + 3600;
|
|
128 |
s->rtc.next_comp = 3600; |
|
128 | 129 |
} |
129 | 130 |
menelaus_update(s); |
130 | 131 |
} |
... | ... | |
132 | 133 |
void menelaus_reset(i2c_slave *i2c) |
133 | 134 |
{ |
134 | 135 |
struct menelaus_s *s = (struct menelaus_s *) i2c; |
135 |
time_t ti; |
|
136 | 136 |
s->reg = 0x00; |
137 | 137 |
|
138 | 138 |
s->vcore[0] = 0x0c; /* XXX: X-loader needs 0x8c? check! */ |
... | ... | |
169 | 169 |
s->mmc_ctrl[2] = 0x00; |
170 | 170 |
s->mmc_debounce = 0x05; |
171 | 171 |
|
172 |
time(&ti); |
|
173 | 172 |
if (s->rtc.ctrl & 1) |
174 | 173 |
menelaus_rtc_stop(s); |
175 | 174 |
s->rtc.ctrl = 0x00; |
176 | 175 |
s->rtc.comp = 0x0000; |
177 | 176 |
s->rtc.next = 1000; |
178 |
s->rtc.sec = ti; |
|
179 |
s->rtc.next_comp = s->rtc.sec + 1800; |
|
177 |
s->rtc.sec_offset = 0; |
|
178 |
s->rtc.next_comp = 1800; |
|
179 |
s->rtc.alm_sec = 1800; |
|
180 | 180 |
s->rtc.alm.tm_sec = 0x00; |
181 | 181 |
s->rtc.alm.tm_min = 0x00; |
182 | 182 |
s->rtc.alm.tm_hour = 0x00; |
... | ... | |
627 | 627 |
s->status |= 1 << 10; /* RTCERR */ |
628 | 628 |
menelaus_update(s); |
629 | 629 |
} |
630 |
s->rtc.sec += difftime(mktime(&tm), mktime(&s->rtc.tm));
|
|
630 |
s->rtc.sec_offset = qemu_timedate_diff(&tm);
|
|
631 | 631 |
break; |
632 | 632 |
case MENELAUS_RTC_SEC: |
633 | 633 |
s->rtc.tm.tm_sec = from_bcd(value & 0x7f); |
... | ... | |
888 | 888 |
s->i2c.recv = menelaus_rx; |
889 | 889 |
s->i2c.send = menelaus_tx; |
890 | 890 |
|
891 |
/* TODO: use the qemu gettime functions */ |
|
892 |
s->rtc.gettime = localtime_r; |
|
893 |
|
|
894 | 891 |
s->irq = irq; |
895 | 892 |
s->rtc.hz = qemu_new_timer(rt_clock, menelaus_rtc_hz, s); |
896 | 893 |
s->in = qemu_allocate_irqs(menelaus_gpio_set, s, 3); |
Also available in: Unified diff