82 lines
1.5 KiB
C
82 lines
1.5 KiB
C
|
|
||
|
#include <linux/bcd.h>
|
||
|
#include <linux/time.h>
|
||
|
|
||
|
#include <asm/ds1216.h>
|
||
|
|
||
|
volatile unsigned char *ds1216_base;
|
||
|
|
||
|
/*
|
||
|
* Read the 64 bit we'd like to have - It a series
|
||
|
* of 64 bits showing up in the LSB of the base register.
|
||
|
*
|
||
|
*/
|
||
|
static unsigned char *ds1216_read(void)
|
||
|
{
|
||
|
static unsigned char rdbuf[8];
|
||
|
unsigned char c;
|
||
|
int i, j;
|
||
|
|
||
|
for (i = 0; i < 8; i++) {
|
||
|
c = 0x0;
|
||
|
for (j = 0; j < 8; j++) {
|
||
|
c |= (*ds1216_base & 0x1) << j;
|
||
|
}
|
||
|
rdbuf[i] = c;
|
||
|
}
|
||
|
|
||
|
return rdbuf;
|
||
|
}
|
||
|
|
||
|
static void ds1216_switch_ds_to_clock(void)
|
||
|
{
|
||
|
unsigned char magic[] = {
|
||
|
0xc5, 0x3a, 0xa3, 0x5c, 0xc5, 0x3a, 0xa3, 0x5c
|
||
|
};
|
||
|
int i,j,c;
|
||
|
|
||
|
/* Reset magic pointer */
|
||
|
c = *ds1216_base;
|
||
|
|
||
|
/* Write 64 bit magic to DS1216 */
|
||
|
for (i = 0; i < 8; i++) {
|
||
|
c = magic[i];
|
||
|
for (j = 0; j < 8; j++) {
|
||
|
*ds1216_base = c;
|
||
|
c = c >> 1;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
unsigned long ds1216_get_cmos_time(void)
|
||
|
{
|
||
|
unsigned char *rdbuf;
|
||
|
unsigned int year, month, date, hour, min, sec;
|
||
|
|
||
|
ds1216_switch_ds_to_clock();
|
||
|
rdbuf = ds1216_read();
|
||
|
|
||
|
sec = BCD2BIN(DS1216_SEC(rdbuf));
|
||
|
min = BCD2BIN(DS1216_MIN(rdbuf));
|
||
|
hour = BCD2BIN(DS1216_HOUR(rdbuf));
|
||
|
date = BCD2BIN(DS1216_DATE(rdbuf));
|
||
|
month = BCD2BIN(DS1216_MONTH(rdbuf));
|
||
|
year = BCD2BIN(DS1216_YEAR(rdbuf));
|
||
|
|
||
|
if (DS1216_1224(rdbuf) && DS1216_AMPM(rdbuf))
|
||
|
hour+=12;
|
||
|
|
||
|
if (year < 70)
|
||
|
year += 2000;
|
||
|
else
|
||
|
year += 1900;
|
||
|
|
||
|
return mktime(year, month, date, hour, min, sec);
|
||
|
}
|
||
|
|
||
|
int ds1216_set_rtc_mmss(unsigned long nowtime)
|
||
|
{
|
||
|
printk("ds1216_set_rtc_mmss called but not implemented\n");
|
||
|
return -1;
|
||
|
}
|