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.
21 static void ds1338_event(i2c_slave
*i2c
, enum i2c_event event
)
23 DS1338State
*s
= FROM_I2C_SLAVE(DS1338State
, i2c
);
27 qemu_get_timedate(&s
->now
, s
->offset
);
28 s
->nvram
[0] = to_bcd(s
->now
.tm_sec
);
29 s
->nvram
[1] = to_bcd(s
->now
.tm_min
);
30 if (s
->nvram
[2] & 0x40) {
31 s
->nvram
[2] = (to_bcd((s
->now
.tm_hour
% 12)) + 1) | 0x40;
32 if (s
->now
.tm_hour
>= 12) {
36 s
->nvram
[2] = to_bcd(s
->now
.tm_hour
);
38 s
->nvram
[3] = to_bcd(s
->now
.tm_wday
) + 1;
39 s
->nvram
[4] = to_bcd(s
->now
.tm_mday
);
40 s
->nvram
[5] = to_bcd(s
->now
.tm_mon
) + 1;
41 s
->nvram
[6] = to_bcd(s
->now
.tm_year
- 100);
51 static int ds1338_recv(i2c_slave
*i2c
)
53 DS1338State
*s
= FROM_I2C_SLAVE(DS1338State
, i2c
);
56 res
= s
->nvram
[s
->ptr
];
57 s
->ptr
= (s
->ptr
+ 1) & 0xff;
61 static int ds1338_send(i2c_slave
*i2c
, uint8_t data
)
63 DS1338State
*s
= FROM_I2C_SLAVE(DS1338State
, i2c
);
69 s
->nvram
[s
->ptr
- 8] = data
;
71 qemu_get_timedate(&s
->now
, s
->offset
);
74 /* TODO: Implement CH (stop) bit. */
75 s
->now
.tm_sec
= from_bcd(data
& 0x7f);
78 s
->now
.tm_min
= from_bcd(data
& 0x7f);
83 data
= from_bcd(data
& 0x4f) + 11;
85 data
= from_bcd(data
& 0x1f) - 1;
88 data
= from_bcd(data
);
90 s
->now
.tm_hour
= data
;
93 s
->now
.tm_wday
= from_bcd(data
& 7) - 1;
96 s
->now
.tm_mday
= from_bcd(data
& 0x3f);
99 s
->now
.tm_mon
= from_bcd(data
& 0x1f) - 1;
101 s
->now
.tm_year
= from_bcd(data
) + 100;
104 /* Control register. Currently ignored. */
107 s
->offset
= qemu_timedate_diff(&s
->now
);
109 s
->ptr
= (s
->ptr
+ 1) & 0xff;
113 static int ds1338_init(i2c_slave
*i2c
)
118 static I2CSlaveInfo ds1338_info
= {
119 .qdev
.name
= "ds1338",
120 .qdev
.size
= sizeof(DS1338State
),
122 .event
= ds1338_event
,
127 static void ds1338_register_devices(void)
129 i2c_register_slave(&ds1338_info
);
132 device_init(ds1338_register_devices
)