From: Chuanhua Han <chuanhua.han@nxp.com>
To: u-boot@lists.denx.de
Subject: [U-Boot] [PATCH v4] rtc: Add DM support to ds3231
Date: Fri, 21 Jun 2019 16:21:53 +0800 [thread overview]
Message-ID: <20190621082153.19690-1-chuanhua.han@nxp.com> (raw)
Add an implementation of the ds3231 driver that uses the driver
model i2c APIs.
Signed-off-by: Chuanhua Han <chuanhua.han@nxp.com>
---
Changes in v4:
- Delete the original 'rel' variable in the ds3231_rtc_get
function, return 0 successfully, and return -EINVAL directly
when the RTC oscillator is stopped.
Changes in v3:
- Update copyright information.
Changes in v2:
- Replace "#ifndef CONFIG_DM_RTC" with "#if !CONFIG_IS_ENABLED(DM_RTC)".
drivers/rtc/ds3231.c | 107 +++++++++++++++++++++++++++++++++++++++++++
1 file changed, 107 insertions(+)
diff --git a/drivers/rtc/ds3231.c b/drivers/rtc/ds3231.c
index 9352ff87a2..79b026af4b 100644
--- a/drivers/rtc/ds3231.c
+++ b/drivers/rtc/ds3231.c
@@ -2,6 +2,9 @@
/*
* (C) Copyright 2006
* Markus Klotzbuecher, mk at denx.de
+ *
+ * (C) Copyright 2019 NXP
+ * Chuanhua Han <chuanhua.han@nxp.com>
*/
/*
@@ -13,6 +16,7 @@
#include <common.h>
#include <command.h>
+#include <dm.h>
#include <rtc.h>
#include <i2c.h>
@@ -50,6 +54,7 @@
#define RTC_STAT_BIT_EN32KHZ 0x8 /* Enable 32KHz Output */
+#if !CONFIG_IS_ENABLED(DM_RTC)
static uchar rtc_read (uchar reg);
static void rtc_write (uchar reg, uchar val);
@@ -164,3 +169,105 @@ static void rtc_write (uchar reg, uchar val)
{
i2c_reg_write (CONFIG_SYS_I2C_RTC_ADDR, reg, val);
}
+#else
+static int ds3231_rtc_get(struct udevice *dev, struct rtc_time *tmp)
+{
+ uchar sec, min, hour, mday, wday, mon_cent, year, status;
+
+ status = dm_i2c_reg_read(dev, RTC_STAT_REG_ADDR);
+ sec = dm_i2c_reg_read(dev, RTC_SEC_REG_ADDR);
+ min = dm_i2c_reg_read(dev, RTC_MIN_REG_ADDR);
+ hour = dm_i2c_reg_read(dev, RTC_HR_REG_ADDR);
+ wday = dm_i2c_reg_read(dev, RTC_DAY_REG_ADDR);
+ mday = dm_i2c_reg_read(dev, RTC_DATE_REG_ADDR);
+ mon_cent = dm_i2c_reg_read(dev, RTC_MON_REG_ADDR);
+ year = dm_i2c_reg_read(dev, RTC_YR_REG_ADDR);
+
+ if (status & RTC_STAT_BIT_OSF) {
+ printf("### Warning: RTC oscillator has stopped\n");
+ /* clear the OSF flag */
+ dm_i2c_reg_write(dev, RTC_STAT_REG_ADDR,
+ dm_i2c_reg_read(dev, RTC_STAT_REG_ADDR)
+ & ~RTC_STAT_BIT_OSF);
+ return -EINVAL;
+ }
+
+ tmp->tm_sec = bcd2bin(sec & 0x7F);
+ tmp->tm_min = bcd2bin(min & 0x7F);
+ tmp->tm_hour = bcd2bin(hour & 0x3F);
+ tmp->tm_mday = bcd2bin(mday & 0x3F);
+ tmp->tm_mon = bcd2bin(mon_cent & 0x1F);
+ tmp->tm_year = bcd2bin(year) + ((mon_cent & 0x80) ? 2000 : 1900);
+ tmp->tm_wday = bcd2bin((wday - 1) & 0x07);
+ tmp->tm_yday = 0;
+ tmp->tm_isdst = 0;
+
+ debug("Get DATE: %4d-%02d-%02d (wday=%d) TIME: %2d:%02d:%02d\n",
+ tmp->tm_year, tmp->tm_mon, tmp->tm_mday, tmp->tm_wday,
+ tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
+
+ return 0;
+}
+
+static int ds3231_rtc_set(struct udevice *dev, const struct rtc_time *tmp)
+{
+ uchar century;
+
+ debug("Set DATE: %4d-%02d-%02d (wday=%d) TIME: %2d:%02d:%02d\n",
+ tmp->tm_year, tmp->tm_mon, tmp->tm_mday, tmp->tm_wday,
+ tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
+
+ dm_i2c_reg_write(dev, RTC_YR_REG_ADDR, bin2bcd(tmp->tm_year % 100));
+
+ century = (tmp->tm_year >= 2000) ? 0x80 : 0;
+ dm_i2c_reg_write(dev, RTC_MON_REG_ADDR, bin2bcd(tmp->tm_mon) | century);
+
+ dm_i2c_reg_write(dev, RTC_DAY_REG_ADDR, bin2bcd(tmp->tm_wday + 1));
+ dm_i2c_reg_write(dev, RTC_DATE_REG_ADDR, bin2bcd(tmp->tm_mday));
+ dm_i2c_reg_write(dev, RTC_HR_REG_ADDR, bin2bcd(tmp->tm_hour));
+ dm_i2c_reg_write(dev, RTC_MIN_REG_ADDR, bin2bcd(tmp->tm_min));
+ dm_i2c_reg_write(dev, RTC_SEC_REG_ADDR, bin2bcd(tmp->tm_sec));
+
+ return 0;
+}
+
+static int ds3231_rtc_reset(struct udevice *dev)
+{
+ int ret;
+
+ ret = dm_i2c_reg_write(dev, RTC_CTL_REG_ADDR,
+ RTC_CTL_BIT_RS1 | RTC_CTL_BIT_RS2);
+ if (ret < 0)
+ return ret;
+
+ return 0;
+}
+
+static int ds3231_probe(struct udevice *dev)
+{
+ i2c_set_chip_flags(dev, DM_I2C_CHIP_RD_ADDRESS |
+ DM_I2C_CHIP_WR_ADDRESS);
+
+ return 0;
+}
+
+static const struct rtc_ops ds3231_rtc_ops = {
+ .get = ds3231_rtc_get,
+ .set = ds3231_rtc_set,
+ .reset = ds3231_rtc_reset,
+};
+
+static const struct udevice_id ds3231_rtc_ids[] = {
+ { .compatible = "dallas,ds3231" },
+ { .compatible = "dallas,ds3232" },
+ { }
+};
+
+U_BOOT_DRIVER(rtc_ds3231) = {
+ .name = "rtc-ds3231",
+ .id = UCLASS_RTC,
+ .probe = ds3231_probe,
+ .of_match = ds3231_rtc_ids,
+ .ops = &ds3231_rtc_ops,
+};
+#endif
--
2.17.1
next reply other threads:[~2019-06-21 8:21 UTC|newest]
Thread overview: 7+ messages / expand[flat|nested] mbox.gz Atom feed top
2019-06-21 8:21 Chuanhua Han [this message]
2019-06-21 11:32 ` [U-Boot] [PATCH v4] rtc: Add DM support to ds3231 Lukasz Majewski
2019-07-08 4:06 ` [U-Boot] [EXT] " Chuanhua Han
2019-07-16 2:34 ` Chuanhua Han
2019-07-16 7:06 ` Lukasz Majewski
2019-07-16 7:12 ` Chuanhua Han
2019-07-18 23:56 ` [U-Boot] " Tom Rini
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20190621082153.19690-1-chuanhua.han@nxp.com \
--to=chuanhua.han@nxp.com \
--cc=u-boot@lists.denx.de \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.