zephyr/drivers/watchdog/wdt_ti_tps382x.c
Jeppe Odgaard 4d57f64193 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 <jeppe.odgaard@prevas.dk>
2023-03-21 09:35:58 +01:00

97 lines
2.7 KiB
C

/*
* Copyright (c) 2023, Prevas A/S
*
* SPDX-License-Identifier: Apache-2.0
*/
#define DT_DRV_COMPAT ti_tps382x
#include <errno.h>
#include <zephyr/drivers/gpio.h>
#include <zephyr/drivers/watchdog.h>
#include <zephyr/logging/log.h>
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);