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(i2c_slave
*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(i2c_slave
*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(i2c_slave
*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;
104 s
->now
.tm_year
= from_bcd(data
) + 100;
107 /* Control register. Currently ignored. */
110 s
->offset
= qemu_timedate_diff(&s
->now
);
112 s
->ptr
= (s
->ptr
+ 1) & 0xff;
116 static int ds1338_init(i2c_slave
*i2c
)
121 static I2CSlaveInfo ds1338_info
= {
122 .qdev
.name
= "ds1338",
123 .qdev
.size
= sizeof(DS1338State
),
125 .event
= ds1338_event
,
130 static void ds1338_register_devices(void)
132 i2c_register_slave(&ds1338_info
);
135 device_init(ds1338_register_devices
)