You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
123 lines
3.5 KiB
123 lines
3.5 KiB
/* |
|
* Copyright (c) 2024 BayLibre, SAS |
|
* |
|
* SPDX-License-Identifier: Apache-2.0 |
|
*/ |
|
|
|
#define DT_DRV_COMPAT ti_cc23x0_wdt |
|
|
|
#include <zephyr/drivers/watchdog.h> |
|
#include <zephyr/irq.h> |
|
#include <soc.h> |
|
#include <errno.h> |
|
|
|
#include <inc/hw_ckmd.h> |
|
#include <inc/hw_types.h> |
|
#include <inc/hw_memmap.h> |
|
|
|
#define LOG_LEVEL CONFIG_WDT_LOG_LEVEL |
|
#include <zephyr/logging/log.h> |
|
|
|
LOG_MODULE_REGISTER(wdt_cc23x0); |
|
|
|
#define CC23X0_WDT_UNLOCK(_base) (HWREG((_base) + CKMD_O_WDTLOCK) = 0x1ACCE551) |
|
#define CC23X0_WDT_LOCK(_base) (HWREG((_base) + CKMD_O_WDTLOCK) = 0x1) |
|
#define CC23X0_WDT_FEED(_base, _value) (HWREG((_base) + CKMD_O_WDTCNT) = (_value)) |
|
#define CC23X0_WDT_STALL_ENABLE(_base) (HWREG((_base) + CKMD_O_WDTTEST) = 0x1) |
|
#define CC23X0_WDT_STALL_DISABLE(_base) (HWREG((_base) + CKMD_O_WDTTEST) = 0x0) |
|
|
|
#define WDT_SOURCE_FREQ 32768 |
|
#define WDT_MS_RATIO (WDT_SOURCE_FREQ / 1000) |
|
#define WDT_MAX_RELOAD_MS 0xffffffff / WDT_MS_RATIO |
|
#define WDT_MS_TO_TICKS(_ms) ((_ms) * WDT_MS_RATIO) |
|
|
|
struct wdt_cc23x0_data { |
|
uint8_t enabled; |
|
uint32_t reload; |
|
uint8_t flags; |
|
}; |
|
|
|
struct wdt_cc23x0_config { |
|
uint32_t base; |
|
}; |
|
|
|
static int wdt_cc23x0_install_timeout(const struct device *dev, const struct wdt_timeout_cfg *cfg) |
|
{ |
|
struct wdt_cc23x0_data *data = dev->data; |
|
|
|
/* window watchdog not supported */ |
|
if (cfg->window.min != 0U || cfg->window.max == 0U) { |
|
return -EINVAL; |
|
} |
|
|
|
if (cfg->window.max > WDT_MAX_RELOAD_MS) { |
|
return -EINVAL; |
|
} |
|
data->reload = WDT_MS_TO_TICKS(cfg->window.max); |
|
data->flags = cfg->flags; |
|
|
|
LOG_DBG("raw reload value: %d", data->reload); |
|
|
|
return 0; |
|
} |
|
|
|
static int wdt_cc23x0_setup(const struct device *dev, uint8_t options) |
|
{ |
|
const struct wdt_cc23x0_config *config = dev->config; |
|
|
|
/* Stall the WDT counter when halted by debugger */ |
|
if ((options & WDT_OPT_PAUSE_HALTED_BY_DBG) != 0U) { |
|
CC23X0_WDT_STALL_ENABLE(config->base); |
|
} else { |
|
CC23X0_WDT_STALL_DISABLE(config->base); |
|
} |
|
|
|
return 0; |
|
} |
|
|
|
static int wdt_cc23x0_disable(const struct device *dev) |
|
{ |
|
ARG_UNUSED(dev); |
|
|
|
return -ENOTSUP; |
|
} |
|
|
|
static int wdt_cc23x0_feed(const struct device *dev, int channel_id) |
|
{ |
|
ARG_UNUSED(channel_id); |
|
|
|
const struct wdt_cc23x0_config *config = dev->config; |
|
struct wdt_cc23x0_data *data = dev->data; |
|
|
|
CC23X0_WDT_UNLOCK(config->base); |
|
CC23X0_WDT_FEED(config->base, data->reload); |
|
|
|
return 0; |
|
} |
|
|
|
static int wdt_cc23x0_init(const struct device *dev) |
|
{ |
|
ARG_UNUSED(dev); |
|
|
|
return 0; |
|
} |
|
|
|
static DEVICE_API(wdt, wdt_cc23x0_api) = { |
|
.setup = wdt_cc23x0_setup, |
|
.disable = wdt_cc23x0_disable, |
|
.install_timeout = wdt_cc23x0_install_timeout, |
|
.feed = wdt_cc23x0_feed, |
|
}; |
|
|
|
#define CC23X0_WDT_INIT(index) \ |
|
static struct wdt_cc23x0_data wdt_cc23x0_data_##index = { \ |
|
.reload = WDT_MS_TO_TICKS(CONFIG_WDT_CC23X0_INITIAL_TIMEOUT), \ |
|
}; \ |
|
static struct wdt_cc23x0_config wdt_cc23x0_config_##index = { \ |
|
.base = DT_INST_REG_ADDR(index), \ |
|
}; \ |
|
DEVICE_DT_INST_DEFINE(index, wdt_cc23x0_init, NULL, &wdt_cc23x0_data_##index, \ |
|
&wdt_cc23x0_config_##index, POST_KERNEL, \ |
|
CONFIG_KERNEL_INIT_PRIORITY_DEFAULT, &wdt_cc23x0_api); |
|
|
|
DT_INST_FOREACH_STATUS_OKAY(CC23X0_WDT_INIT)
|
|
|