From 4d57f641935c609a99e95c7dbfcbaea1da5e7583 Mon Sep 17 00:00:00 2001 From: Jeppe Odgaard Date: Mon, 6 Mar 2023 11:45:13 +0100 Subject: [PATCH] drivers: watchdog: Add TI TPS382x driver Add support for the TI TPS382x series. The IC has an input pin which should be toggled by the processor and a output pin which should be connected to the RESET input of the processor. The timeout is not configurable. This device can be used by devices which does not have any internal hardware watchdog device. Signed-off-by: Jeppe Odgaard --- drivers/watchdog/CMakeLists.txt | 1 + drivers/watchdog/Kconfig | 2 + drivers/watchdog/Kconfig.ti_tps382x | 12 ++++ drivers/watchdog/wdt_ti_tps382x.c | 96 +++++++++++++++++++++++++++ dts/bindings/watchdog/ti,tps382x.yaml | 31 +++++++++ 5 files changed, 142 insertions(+) create mode 100644 drivers/watchdog/Kconfig.ti_tps382x create mode 100644 drivers/watchdog/wdt_ti_tps382x.c create mode 100644 dts/bindings/watchdog/ti,tps382x.yaml diff --git a/drivers/watchdog/CMakeLists.txt b/drivers/watchdog/CMakeLists.txt index 913b4091e5b..e4f25a098e0 100644 --- a/drivers/watchdog/CMakeLists.txt +++ b/drivers/watchdog/CMakeLists.txt @@ -30,6 +30,7 @@ zephyr_library_sources_ifdef(CONFIG_WDT_XEC wdt_mchp_xec.c) zephyr_library_sources_ifdef(CONFIG_WDT_COUNTER wdt_counter.c) zephyr_library_sources_ifdef(CONFIG_WDT_NXP_S32 wdt_nxp_s32.c) zephyr_library_sources_ifdef(CONFIG_WDT_SMARTBOND wdt_smartbond.c) +zephyr_library_sources_ifdef(CONFIG_WDT_TI_TPS382X wdt_ti_tps382x.c) zephyr_library_sources_ifdef(CONFIG_WDT_DW wdt_dw.c) diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig index 9bc18b28669..05f43080445 100644 --- a/drivers/watchdog/Kconfig +++ b/drivers/watchdog/Kconfig @@ -98,4 +98,6 @@ source "drivers/watchdog/Kconfig.dw" source "drivers/watchdog/Kconfig.smartbond" +source "drivers/watchdog/Kconfig.ti_tps382x" + endif # WATCHDOG diff --git a/drivers/watchdog/Kconfig.ti_tps382x b/drivers/watchdog/Kconfig.ti_tps382x new file mode 100644 index 00000000000..9ff0400af3e --- /dev/null +++ b/drivers/watchdog/Kconfig.ti_tps382x @@ -0,0 +1,12 @@ +# Copyright (c) 2023 Prevas A/S +# +# SPDX-License-Identifier: Apache-2.0 + +config WDT_TI_TPS382X + bool "External TI TPS382x Watchdog (WDT) Driver" + default y + depends on DT_HAS_TI_TPS382X_ENABLED + depends on GPIO + help + Enable WDT driver for TI TPS382x. This is an external IC and requires + a GPIO connection from the processor. diff --git a/drivers/watchdog/wdt_ti_tps382x.c b/drivers/watchdog/wdt_ti_tps382x.c new file mode 100644 index 00000000000..c9e94310c3f --- /dev/null +++ b/drivers/watchdog/wdt_ti_tps382x.c @@ -0,0 +1,96 @@ +/* + * Copyright (c) 2023, Prevas A/S + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#define DT_DRV_COMPAT ti_tps382x + +#include +#include +#include +#include + +LOG_MODULE_REGISTER(wdt_ti_tps382x, CONFIG_WDT_LOG_LEVEL); + +struct ti_tps382x_config { + struct gpio_dt_spec wdi_gpio; + int timeout; +}; + +static int ti_tps382x_init(const struct device *dev) +{ + const struct ti_tps382x_config *config = dev->config; + + if (!gpio_is_ready_dt(&config->wdi_gpio)) { + LOG_ERR("WDI gpio not ready"); + return -ENODEV; + } + + return 0; +} + +static int ti_tps382x_setup(const struct device *dev, uint8_t options) +{ + const struct ti_tps382x_config *config = dev->config; + + return gpio_pin_configure_dt(&config->wdi_gpio, GPIO_OUTPUT); +} + +static int ti_tps382x_disable(const struct device *dev) +{ + const struct ti_tps382x_config *config = dev->config; + + /* The watchdog timer can be disabled by disconnecting the WDI pin from + * the system. Do this by changing the gpio to an input (tri-state). + */ + return gpio_pin_configure_dt(&config->wdi_gpio, GPIO_INPUT); +} + +static int ti_tps382x_install_timeout(const struct device *dev, + const struct wdt_timeout_cfg *cfg) +{ + const struct ti_tps382x_config *config = dev->config; + + if (cfg->window.max != config->timeout) { + LOG_ERR("Upper limit of watchdog timeout must be %d not %u", + config->timeout, cfg->window.max); + return -EINVAL; + } else if (cfg->window.min != 0) { + LOG_ERR("Window timeouts not supported"); + return -EINVAL; + } else if (cfg->callback != NULL) { + LOG_ERR("Callbacks not supported"); + return -EINVAL; + } + + return 0; +} + +static int ti_tps382x_feed(const struct device *dev, int channel_id) +{ + const struct ti_tps382x_config *config = dev->config; + + return gpio_pin_toggle_dt(&config->wdi_gpio); +} + +static const struct wdt_driver_api ti_tps382x_api = { + .setup = ti_tps382x_setup, + .disable = ti_tps382x_disable, + .install_timeout = ti_tps382x_install_timeout, + .feed = ti_tps382x_feed, +}; + +#define WDT_TI_TPS382X_INIT(n) \ + static const struct ti_tps382x_config ti_tps382x_##n##config = { \ + .wdi_gpio = GPIO_DT_SPEC_INST_GET(n, wdi_gpios), \ + .timeout = DT_INST_PROP(n, timeout_period), \ + }; \ + \ + DEVICE_DT_INST_DEFINE( \ + n, ti_tps382x_init, NULL, NULL, &ti_tps382x_##n##config, \ + POST_KERNEL, CONFIG_KERNEL_INIT_PRIORITY_DEVICE, \ + &ti_tps382x_api \ + ); + +DT_INST_FOREACH_STATUS_OKAY(WDT_TI_TPS382X_INIT); diff --git a/dts/bindings/watchdog/ti,tps382x.yaml b/dts/bindings/watchdog/ti,tps382x.yaml new file mode 100644 index 00000000000..c6f1e1cd1c6 --- /dev/null +++ b/dts/bindings/watchdog/ti,tps382x.yaml @@ -0,0 +1,31 @@ +# Copyright (c) 2023, Prevas A/S + +description: Watchdog driver for external IC (TPS382x) + +compatible: "ti,tps382x" + +include: base.yaml + +properties: + wdi-gpios: + type: phandle-array + required: true + description: + WDI gpio. If WDI remains high or low longer than the timeout period, + then reset is triggered. The reset has a typical delay time of 200 ms for + TPS3823/4/8, TPS3823A. The timer clears when reset is asserted or + when WDI sees a rising edge or a falling edge. If unused, the WDI + connection must be high impedance to prevent it from causing a reset + event. + + timeout-period: + type: int + default: 1600 + description: + Time-out period in milliseconds. Typical for TPS3823/4/8 and TPS3823A is + 1.6 seconds but minimum is 0.9. To avoid false positive watchdog reset + the watchdog should be kicked within the minimum timeout period. The kick + interval also needs to compensate for MCU clock tolerances which means it + should be kicked with an interval less than 0.9 seconds. If this device + is used as fallback for the task watchdog this can be achieved by setting + e.g. TASK_WDT_MIN_TIMEOUT to 850 and TASK_WDT_HW_FALLBACK_DELAY to 750.