Thomas Bogendoerfer | c066a32 | 2006-12-28 18:22:32 +0100 | [diff] [blame^] | 1 | |
| 2 | #include <linux/bcd.h> |
| 3 | #include <linux/time.h> |
| 4 | |
| 5 | #include <asm/ds1216.h> |
| 6 | |
| 7 | volatile unsigned char *ds1216_base; |
| 8 | |
| 9 | /* |
| 10 | * Read the 64 bit we'd like to have - It a series |
| 11 | * of 64 bits showing up in the LSB of the base register. |
| 12 | * |
| 13 | */ |
| 14 | static unsigned char *ds1216_read(void) |
| 15 | { |
| 16 | static unsigned char rdbuf[8]; |
| 17 | unsigned char c; |
| 18 | int i, j; |
| 19 | |
| 20 | for (i = 0; i < 8; i++) { |
| 21 | c = 0x0; |
| 22 | for (j = 0; j < 8; j++) { |
| 23 | c |= (*ds1216_base & 0x1) << j; |
| 24 | } |
| 25 | rdbuf[i] = c; |
| 26 | } |
| 27 | |
| 28 | return rdbuf; |
| 29 | } |
| 30 | |
| 31 | static void ds1216_switch_ds_to_clock(void) |
| 32 | { |
| 33 | unsigned char magic[] = { |
| 34 | 0xc5, 0x3a, 0xa3, 0x5c, 0xc5, 0x3a, 0xa3, 0x5c |
| 35 | }; |
| 36 | int i,j,c; |
| 37 | |
| 38 | /* Reset magic pointer */ |
| 39 | c = *ds1216_base; |
| 40 | |
| 41 | /* Write 64 bit magic to DS1216 */ |
| 42 | for (i = 0; i < 8; i++) { |
| 43 | c = magic[i]; |
| 44 | for (j = 0; j < 8; j++) { |
| 45 | *ds1216_base = c; |
| 46 | c = c >> 1; |
| 47 | } |
| 48 | } |
| 49 | } |
| 50 | |
| 51 | unsigned long ds1216_get_cmos_time(void) |
| 52 | { |
| 53 | unsigned char *rdbuf; |
| 54 | unsigned int year, month, date, hour, min, sec; |
| 55 | |
| 56 | ds1216_switch_ds_to_clock(); |
| 57 | rdbuf = ds1216_read(); |
| 58 | |
| 59 | sec = BCD2BIN(DS1216_SEC(rdbuf)); |
| 60 | min = BCD2BIN(DS1216_MIN(rdbuf)); |
| 61 | hour = BCD2BIN(DS1216_HOUR(rdbuf)); |
| 62 | date = BCD2BIN(DS1216_DATE(rdbuf)); |
| 63 | month = BCD2BIN(DS1216_MONTH(rdbuf)); |
| 64 | year = BCD2BIN(DS1216_YEAR(rdbuf)); |
| 65 | |
| 66 | if (DS1216_1224(rdbuf) && DS1216_AMPM(rdbuf)) |
| 67 | hour+=12; |
| 68 | |
| 69 | if (year < 70) |
| 70 | year += 2000; |
| 71 | else |
| 72 | year += 1900; |
| 73 | |
| 74 | return mktime(year, month, date, hour, min, sec); |
| 75 | } |
| 76 | |
| 77 | int ds1216_set_rtc_mmss(unsigned long nowtime) |
| 78 | { |
| 79 | printk("ds1216_set_rtc_mmss called but not implemented\n"); |
| 80 | return -1; |
| 81 | } |