| /* |
| * 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); |