2 * MAXIM DS1338 I2C RTC+NVRAM
4 * Copyright (c) 2009 CodeSourcery.
5 * Written by Paul Brook
7 * This code is licensed under the GNU GPL v2.
9 * Contributions after 2012-01-13 are licensed under the terms of the
10 * GNU GPL, version 2 or (at your option) any later version.
24 static void ds1338_event(I2CSlave
*i2c
, enum i2c_event event
)
26 DS1338State
*s
= FROM_I2C_SLAVE(DS1338State
, i2c
);
30 qemu_get_timedate(&s
->now
, s
->offset
);
31 s
->nvram
[0] = to_bcd(s
->now
.tm_sec
);
32 s
->nvram
[1] = to_bcd(s
->now
.tm_min
);
33 if (s
->nvram
[2] & 0x40) {
34 s
->nvram
[2] = (to_bcd((s
->now
.tm_hour
% 12)) + 1) | 0x40;
35 if (s
->now
.tm_hour
>= 12) {
39 s
->nvram
[2] = to_bcd(s
->now
.tm_hour
);
41 s
->nvram
[3] = to_bcd(s
->now
.tm_wday
) + 1;
42 s
->nvram
[4] = to_bcd(s
->now
.tm_mday
);
43 s
->nvram
[5] = to_bcd(s
->now
.tm_mon
) + 1;
44 s
->nvram
[6] = to_bcd(s
->now
.tm_year
- 100);
54 static int ds1338_recv(I2CSlave
*i2c
)
56 DS1338State
*s
= FROM_I2C_SLAVE(DS1338State
, i2c
);
59 res
= s
->nvram
[s
->ptr
];
60 s
->ptr
= (s
->ptr
+ 1) & 0xff;
64 static int ds1338_send(I2CSlave
*i2c
, uint8_t data
)
66 DS1338State
*s
= FROM_I2C_SLAVE(DS1338State
, i2c
);
72 s
->nvram
[s
->ptr
- 8] = data
;
74 qemu_get_timedate(&s
->now
, s
->offset
);
77 /* TODO: Implement CH (stop) bit. */
78 s
->now
.tm_sec
= from_bcd(data
& 0x7f);
81 s
->now
.tm_min
= from_bcd(data
& 0x7f);
86 data
= from_bcd(data
& 0x4f) + 11;
88 data
= from_bcd(data
& 0x1f) - 1;
91 data
= from_bcd(data
);
93 s
->now
.tm_hour
= data
;
96 s
->now
.tm_wday
= from_bcd(data
& 7) - 1;
99 s
->now
.tm_mday
= from_bcd(data
& 0x3f);
102 s
->now
.tm_mon
= from_bcd(data
& 0x1f) - 1;
105 s
->now
.tm_year
= from_bcd(data
) + 100;
108 /* Control register. Currently ignored. */
111 s
->offset
= qemu_timedate_diff(&s
->now
);
113 s
->ptr
= (s
->ptr
+ 1) & 0xff;
117 static int ds1338_init(I2CSlave
*i2c
)
122 static void ds1338_class_init(ObjectClass
*klass
, void *data
)
124 I2CSlaveClass
*k
= I2C_SLAVE_CLASS(klass
);
126 k
->init
= ds1338_init
;
127 k
->event
= ds1338_event
;
128 k
->recv
= ds1338_recv
;
129 k
->send
= ds1338_send
;
132 static TypeInfo ds1338_info
= {
134 .parent
= TYPE_I2C_SLAVE
,
135 .instance_size
= sizeof(DS1338State
),
136 .class_init
= ds1338_class_init
,
139 static void ds1338_register_types(void)
141 type_register_static(&ds1338_info
);
144 type_init(ds1338_register_types
)