[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