diff mbox

[U-Boot] rtc: add support maxim dallas rtc ds1347

Message ID 535287D8.4030105@gmail.com
State Deferred
Delegated to: Tom Rini
Headers show

Commit Message

Raghavendra Ganiga April 19, 2014, 2:27 p.m. UTC
From 48802d37079bfc3e705cd43af78b7b2186a02046 Mon Sep 17 00:00:00 2001
From: Raghavendra Ganiga <ravi23ganiga@gmail.com>
Date: Thu, 17 Apr 2014 23:14:22 +0530
Subject: [PATCH] rtc: add support maxim dallas rtc ds1347

This is a patch to add support for
maxim dallas rtc ds1347

Signed-off-by: Raghavendra Chandra Ganiga <ravi23ganiga@gmail.com>
---
 drivers/rtc/Makefile |    1 +
 drivers/rtc/ds1347.c |  180 ++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 181 insertions(+)
 create mode 100644 drivers/rtc/ds1347.c
diff mbox

Patch

diff --git a/drivers/rtc/Makefile b/drivers/rtc/Makefile
index 003d322..d26d4e1 100644
--- a/drivers/rtc/Makefile
+++ b/drivers/rtc/Makefile
@@ -17,6 +17,7 @@  obj-$(CONFIG_RTC_DS1306) += ds1306.o
 obj-$(CONFIG_RTC_DS1307) += ds1307.o
 obj-$(CONFIG_RTC_DS1338) += ds1307.o
 obj-$(CONFIG_RTC_DS1337) += ds1337.o
+obj-$(CONFIG_RTC_DS1347) += ds1347.o
 obj-$(CONFIG_RTC_DS1374) += ds1374.o
 obj-$(CONFIG_RTC_DS1388) += ds1337.o
 obj-$(CONFIG_RTC_DS1556) += ds1556.o
diff --git a/drivers/rtc/ds1347.c b/drivers/rtc/ds1347.c
new file mode 100644
index 0000000..b452c36
--- /dev/null
+++ b/drivers/rtc/ds1347.c
@@ -0,0 +1,180 @@ 
+/*
+ * Dallas Maxim RTC DS1347 Driver
+ *
+ * Copyright (C) 2014 Raghavendra Chandra Ganiga <ravi23ganiga@gmail.com>
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include <common.h>
+#include <rtc.h>
+#include <spi.h>
+
+#if defined(CONFIG_CMD_DATE)
+
+/*
+* DS1347 Registers
+*/
+#define RTC_SECONDS_REG		0x01
+#define RTC_MINUTES_REG		0x03
+#define RTC_HOURS_REG		0x05
+#define RTC_DATE_REG		0x07
+#define RTC_MONTH_REG		0x09
+#define RTC_DAY_REG		0x0B
+#define RTC_YEAR_REG		0x0D
+#define RTC_CONTROL_REG		0x0F
+#define RTC_CENTURY_REG		0x13
+#define RTC_ALARM_CONFIG_REG	0x15
+#define RTC_STATUS_REG		0x17
+#define RTC_ALARM_SEC_REG	0x19
+#define RTC_ALARM_MIN_REG	0x1B
+#define RTC_ALARM_HOUR_REG	0x1D
+#define RTC_ALARM_DATE_REG	0x1F
+#define RTC_ALARM_MONTH_REG	0x21
+#define RTC_ALARM_DAY_REG	0x23
+#define RTC_ALARM_YEAR_REG	0x25
+#define RTC_BURST_REG		0x3F
+
+static struct spi_slave *slave;
+
+static unsigned char rtc_read(unsigned char address);
+static int rtc_write(unsigned char address, unsigned char value);
+
+int rtc_get(struct rtc_time *tm)
+{
+	int ret;
+	unsigned char data, century;
+	if (!slave) {
+		slave = spi_setup_slave(CONFIG_DS1347_BUS,
+					CONFIG_DS1347_CS, 1000000,
+					SPI_MODE_3);
+		if (!slave)
+			return -1;
+	}
+
+	ret = spi_claim_bus(slave);
+	if (ret)
+		return -1;
+
+	data = rtc_read(RTC_SECONDS_REG);
+	tm->tm_sec	= bcd2bin(data);
+
+	data = rtc_read(RTC_MINUTES_REG);
+	tm->tm_min	= bcd2bin(data);
+
+	data = rtc_read(RTC_HOURS_REG);
+	tm->tm_hour	= bcd2bin(data);
+
+	data = rtc_read(RTC_DATE_REG);
+	tm->tm_mday	= bcd2bin(data);
+
+	data = rtc_read(RTC_MONTH_REG);
+	tm->tm_mon	= bcd2bin(data);
+
+	/* use the century register support in rtc */
+	century = rtc_read(RTC_CENTURY_REG);
+	data = rtc_read(RTC_YEAR_REG);
+	tm->tm_year	= bcd2bin(data) + (bcd2bin(century) * 100);
+
+	data = rtc_read(RTC_DAY_REG);
+	tm->tm_wday	= bcd2bin(data) - 1;
+
+	tm->tm_yday	= 0;
+	tm->tm_isdst	= 0;
+
+	spi_release_bus(slave);
+
+	return 0;
+}
+
+int rtc_set(struct rtc_time *tm)
+{
+	int ret;
+	unsigned char data;
+
+	if (!slave) {
+		slave = spi_setup_slave(CONFIG_DS1347_BUS,
+					CONFIG_DS1347_CS, 1000000,
+					SPI_MODE_3);
+
+		if (!slave)
+			return -1;
+	}
+
+	ret = spi_claim_bus(slave);
+	if (ret)
+		return -1;
+
+	rtc_write(RTC_SECONDS_REG, bin2bcd(tm->tm_sec));
+
+	rtc_write(RTC_MINUTES_REG, bin2bcd(tm->tm_min));
+
+	rtc_write(RTC_HOURS_REG, bin2bcd(tm->tm_hour));
+
+	rtc_write(RTC_DATE_REG, bin2bcd(tm->tm_mday));
+
+	rtc_write(RTC_MONTH_REG, bin2bcd(tm->tm_mon));
+
+	/* use the century register support in rtc */
+	data = tm->tm_year / 100;
+	rtc_write(RTC_CENTURY_REG, bin2bcd(data));
+
+	data = tm->tm_year % 100;
+	rtc_write(RTC_YEAR_REG, bin2bcd(data));
+
+	rtc_write(RTC_DAY_REG, bin2bcd(tm->tm_wday + 1));
+
+	spi_release_bus(slave);
+
+	return 0;
+}
+
+void rtc_reset(void)
+{
+	int ret;
+
+	if (!slave) {
+		slave = spi_setup_slave(CONFIG_DS1347_BUS,
+					CONFIG_DS1347_CS, 1000000,
+					SPI_MODE_3);
+
+		if (!slave)
+			return;
+	}
+
+	ret = spi_claim_bus(slave);
+	if (ret)
+		return;
+
+	/* Disable Write Protection */
+	ret = rtc_write(RTC_CONTROL_REG, 0x00);
+
+	/* Disable RTC Alarm - no alarm support */
+	ret = rtc_write(RTC_ALARM_CONFIG_REG, 0x00);
+
+	/* Enable Oscillator and No Glitch Filter */
+	ret = rtc_write(RTC_STATUS_REG, 0x00);
+
+	spi_release_bus(slave);
+}
+/*
+* Helper Functions
+*/
+static unsigned char rtc_read(unsigned char address)
+{
+	address |= 0x80;
+
+	return spi_w8r8(slave, address);
+}
+
+static int rtc_write(unsigned char address, unsigned char value)
+{
+	unsigned char dout[2];
+
+	dout[0] = address;
+	dout[1] = value;
+
+	return spi_xfer(slave, 16, dout, NULL, SPI_XFER_BEGIN | SPI_XFER_END);
+}
+
+#endif /* CONFIG_CMD_DATE */