summaryrefslogtreecommitdiffstats
path: root/arch/mips/sni/ds1216.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/mips/sni/ds1216.c')
-rw-r--r--arch/mips/sni/ds1216.c81
1 files changed, 81 insertions, 0 deletions
diff --git a/arch/mips/sni/ds1216.c b/arch/mips/sni/ds1216.c
new file mode 100644
index 000000000000..1d92732c14f1
--- /dev/null
+++ b/arch/mips/sni/ds1216.c
@@ -0,0 +1,81 @@
+
+#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;
+}