[U-Boot] [RFC PATCH] pcf2127: add watchdog support

Sean Nyekjaer sean.nyekjaer at prevas.dk
Thu Dec 15 07:38:03 CET 2016


Signed-off-by: Sean Nyekjaer <sean.nyekjaer at prevas.dk>
---
- I have just noticed that the RTC driver for this device have been merged,
  should the watchdog part be included in the rtc driver or standalone?
- The hw_watchdog_reset is called far too often the device here is on i2c,
  with what i have done the reset is written every 1s
- What should be the default delay? I have chosen 20?

 drivers/watchdog/Kconfig       | 11 +++++++
 drivers/watchdog/Makefile      |  1 +
 drivers/watchdog/pcf2127_wdt.c | 69 ++++++++++++++++++++++++++++++++++++++++++
 include/pcf2127_wdt.h          |  3 ++
 4 files changed, 84 insertions(+)
 create mode 100644 drivers/watchdog/pcf2127_wdt.c
 create mode 100644 include/pcf2127_wdt.h

diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig
index e69de29bb2..957f2f3a87 100644
--- a/drivers/watchdog/Kconfig
+++ b/drivers/watchdog/Kconfig
@@ -0,0 +1,11 @@
+#
+# Watchdog drivers configuration
+#
+
+menu "Watchdog"
+
+config PCF2127_WATCHDOG
+	depends on DM_I2C
+	bool "Enable pcf2127 i2c watchdog"
+
+endmenu
diff --git a/drivers/watchdog/Makefile b/drivers/watchdog/Makefile
index a007ae8234..3c573de016 100644
--- a/drivers/watchdog/Makefile
+++ b/drivers/watchdog/Makefile
@@ -15,3 +15,4 @@ obj-$(CONFIG_XILINX_TB_WATCHDOG) += xilinx_tb_wdt.o
 obj-$(CONFIG_BFIN_WATCHDOG)  += bfin_wdt.o
 obj-$(CONFIG_OMAP_WATCHDOG) += omap_wdt.o
 obj-$(CONFIG_DESIGNWARE_WATCHDOG) += designware_wdt.o
+obj-$(CONFIG_PCF2127_WATCHDOG) += pcf2127_wdt.o
diff --git a/drivers/watchdog/pcf2127_wdt.c b/drivers/watchdog/pcf2127_wdt.c
new file mode 100644
index 0000000000..f9276e3ea5
--- /dev/null
+++ b/drivers/watchdog/pcf2127_wdt.c
@@ -0,0 +1,69 @@
+#include <common.h>
+#include <i2c.h>
+#include <watchdog.h>
+#include <pcf2127_wdt.h>
+
+#define PCF2127_REG_WDT_CTRL		0x10
+#define PCF2127_REG_WDT_TIM		0x11
+
+#define PCF2127_WDT_MODE(wdt_mode)	(wdt_mode << 6)
+#define PCF2127_WDT_DISABLED		0b00	/* watchdog timer disabled */
+#define PCF2127_WDT_ENABLED_RST	0b11	/* watchdog timer enabled,
+						   rst activated when timeout */
+
+#define PCF2127_WDT_TIMER_SRC(src)	(src)
+#define PCF2127_WDT_4096HZ		0b00
+#define PCF2127_WDT_64HZ		0b01
+#define PCF2127_WDT_1HZ		0b10
+#define PCF2127_WDT_16mHZ		0b11
+
+#define DCNT				4194304
+
+static uchar timeout = 20;
+static bool wdt_active = false;
+static uint32_t cnt = DCNT-1; /* minus one to ensure the reset is called in SPL */
+
+int pcf2127_reg_read(const uchar reg, uchar *val)
+{
+	return i2c_read(PCF2127_I2C_ADDR, reg, 1, val, 1);
+}
+
+int pcf2127_reg_write(const uchar reg, uchar val)
+{
+	return i2c_write(PCF2127_I2C_ADDR, reg, 1, &val, 1);
+}
+
+static int pcf2127_wdt_setup(uchar mode, uchar tim_src)
+{
+	pcf2127_reg_write(PCF2127_REG_WDT_CTRL,
+		PCF2127_WDT_MODE(mode) | PCF2127_WDT_TIMER_SRC(tim_src));
+	return 0;
+}
+
+static int pcf2127_wdt_settimeout(uchar t_out)
+{
+	timeout = (uchar)t_out;
+	pcf2127_reg_write(PCF2127_REG_WDT_TIM, timeout);
+	return 0;
+}
+
+void pcf2127_wdt_enable(void)
+{
+	wdt_active = true;
+}
+
+void hw_watchdog_reset(void)
+{
+	if(wdt_active == true) {
+		if (cnt++ % DCNT == 0)
+			pcf2127_wdt_settimeout(20);
+	}
+}
+
+void hw_watchdog_init(void)
+{
+	if(wdt_active == true) {
+		pcf2127_wdt_setup(PCF2127_WDT_ENABLED_RST, PCF2127_WDT_1HZ);
+		pcf2127_wdt_settimeout(20);
+	}
+}
diff --git a/include/pcf2127_wdt.h b/include/pcf2127_wdt.h
new file mode 100644
index 0000000000..3f293b2348
--- /dev/null
+++ b/include/pcf2127_wdt.h
@@ -0,0 +1,3 @@
+#define PCF2127_I2C_ADDR 0x51
+
+void pcf2127_wdt_enable(void);
-- 
2.11.0



More information about the U-Boot mailing list