1 /*
2 * Copyright (c) 2023, Prevas A/S
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
7 #define DT_DRV_COMPAT ti_tps382x
8
9 #include <errno.h>
10 #include <zephyr/drivers/gpio.h>
11 #include <zephyr/drivers/watchdog.h>
12 #include <zephyr/logging/log.h>
13
14 LOG_MODULE_REGISTER(wdt_ti_tps382x, CONFIG_WDT_LOG_LEVEL);
15
16 struct ti_tps382x_config {
17 struct gpio_dt_spec wdi_gpio;
18 int timeout;
19 };
20
ti_tps382x_init(const struct device * dev)21 static int ti_tps382x_init(const struct device *dev)
22 {
23 const struct ti_tps382x_config *config = dev->config;
24
25 if (!gpio_is_ready_dt(&config->wdi_gpio)) {
26 LOG_ERR("WDI gpio not ready");
27 return -ENODEV;
28 }
29
30 return 0;
31 }
32
ti_tps382x_setup(const struct device * dev,uint8_t options)33 static int ti_tps382x_setup(const struct device *dev, uint8_t options)
34 {
35 const struct ti_tps382x_config *config = dev->config;
36
37 return gpio_pin_configure_dt(&config->wdi_gpio, GPIO_OUTPUT);
38 }
39
ti_tps382x_disable(const struct device * dev)40 static int ti_tps382x_disable(const struct device *dev)
41 {
42 const struct ti_tps382x_config *config = dev->config;
43
44 /* The watchdog timer can be disabled by disconnecting the WDI pin from
45 * the system. Do this by changing the gpio to an input (tri-state).
46 */
47 return gpio_pin_configure_dt(&config->wdi_gpio, GPIO_INPUT);
48 }
49
ti_tps382x_install_timeout(const struct device * dev,const struct wdt_timeout_cfg * cfg)50 static int ti_tps382x_install_timeout(const struct device *dev,
51 const struct wdt_timeout_cfg *cfg)
52 {
53 const struct ti_tps382x_config *config = dev->config;
54
55 if (cfg->window.max != config->timeout) {
56 LOG_ERR("Upper limit of watchdog timeout must be %d not %u",
57 config->timeout, cfg->window.max);
58 return -EINVAL;
59 } else if (cfg->window.min != 0) {
60 LOG_ERR("Window timeouts not supported");
61 return -EINVAL;
62 } else if (cfg->callback != NULL) {
63 LOG_ERR("Callbacks not supported");
64 return -EINVAL;
65 }
66
67 return 0;
68 }
69
ti_tps382x_feed(const struct device * dev,int channel_id)70 static int ti_tps382x_feed(const struct device *dev, int channel_id)
71 {
72 const struct ti_tps382x_config *config = dev->config;
73
74 return gpio_pin_toggle_dt(&config->wdi_gpio);
75 }
76
77 static DEVICE_API(wdt, ti_tps382x_api) = {
78 .setup = ti_tps382x_setup,
79 .disable = ti_tps382x_disable,
80 .install_timeout = ti_tps382x_install_timeout,
81 .feed = ti_tps382x_feed,
82 };
83
84 #define WDT_TI_TPS382X_INIT(n) \
85 static const struct ti_tps382x_config ti_tps382x_##n##config = { \
86 .wdi_gpio = GPIO_DT_SPEC_INST_GET(n, wdi_gpios), \
87 .timeout = DT_INST_PROP(n, timeout_period), \
88 }; \
89 \
90 DEVICE_DT_INST_DEFINE( \
91 n, ti_tps382x_init, NULL, NULL, &ti_tps382x_##n##config, \
92 POST_KERNEL, CONFIG_KERNEL_INIT_PRIORITY_DEVICE, \
93 &ti_tps382x_api \
94 );
95
96 DT_INST_FOREACH_STATUS_OKAY(WDT_TI_TPS382X_INIT);
97