|  | /* | 
|  | * Copyright (c) 2022 Basalte bv | 
|  | * Copyright (c) 2023 Gerson Fernando Budke | 
|  | * | 
|  | * SPDX-License-Identifier: Apache-2.0 | 
|  | */ | 
|  |  | 
|  | #define DT_DRV_COMPAT atmel_sam_rstc | 
|  |  | 
|  | #include <zephyr/device.h> | 
|  | #include <zephyr/drivers/hwinfo.h> | 
|  | #include <zephyr/drivers/clock_control/atmel_sam_pmc.h> | 
|  |  | 
|  | BUILD_ASSERT(DT_NUM_INST_STATUS_OKAY(DT_DRV_COMPAT) == 1, | 
|  | "No atmel,sam-rstc compatible device found"); | 
|  |  | 
|  | int z_impl_hwinfo_get_reset_cause(uint32_t *cause) | 
|  | { | 
|  | /* Get reason from Status Register */ | 
|  | uint32_t reason = ((Rstc *)DT_INST_REG_ADDR(0))->RSTC_SR & RSTC_SR_RSTTYP_Msk; | 
|  |  | 
|  | switch (reason) { | 
|  | case RSTC_SR_RSTTYP_GENERAL_RST: | 
|  | *cause = RESET_POR; | 
|  | break; | 
|  | case RSTC_SR_RSTTYP_BACKUP_RST: | 
|  | *cause = RESET_LOW_POWER_WAKE; | 
|  | break; | 
|  | case RSTC_SR_RSTTYP_WDT_RST: | 
|  | *cause = RESET_WATCHDOG; | 
|  | break; | 
|  | case RSTC_SR_RSTTYP_SOFT_RST: | 
|  | *cause = RESET_SOFTWARE; | 
|  | break; | 
|  | case RSTC_SR_RSTTYP_USER_RST: | 
|  | *cause = RESET_USER; | 
|  | break; | 
|  | default: | 
|  | break; | 
|  | } | 
|  |  | 
|  | return 0; | 
|  | } | 
|  |  | 
|  | int z_impl_hwinfo_get_supported_reset_cause(uint32_t *supported) | 
|  | { | 
|  | *supported = RESET_POR | 
|  | | RESET_LOW_POWER_WAKE | 
|  | | RESET_WATCHDOG | 
|  | | RESET_SOFTWARE | 
|  | | RESET_USER; | 
|  |  | 
|  | return 0; | 
|  | } | 
|  |  | 
|  | static int hwinfo_rstc_init(void) | 
|  | { | 
|  | Rstc *regs = (Rstc *)DT_INST_REG_ADDR(0); | 
|  | const struct atmel_sam_pmc_config clock_cfg = SAM_DT_INST_CLOCK_PMC_CFG(0); | 
|  | uint32_t mode; | 
|  |  | 
|  |  | 
|  | /* Enable RSTC in PMC */ | 
|  | (void)clock_control_on(SAM_DT_PMC_CONTROLLER, | 
|  | (clock_control_subsys_t)&clock_cfg); | 
|  |  | 
|  | /* Get current Mode Register value */ | 
|  | mode = regs->RSTC_MR; | 
|  |  | 
|  | /* Enable/disable user reset on NRST */ | 
|  | #if DT_INST_PROP(0, user_nrst) | 
|  | mode &= ~RSTC_MR_KEY_Msk; | 
|  | mode |= (RSTC_MR_URSTEN | RSTC_MR_KEY_PASSWD); | 
|  | #else | 
|  | mode &= ~(RSTC_MR_URSTEN | RSTC_MR_KEY_Msk); | 
|  | mode |= RSTC_MR_KEY_PASSWD; | 
|  | #endif | 
|  |  | 
|  | /* Set Mode Register value */ | 
|  | regs->RSTC_MR = mode; | 
|  |  | 
|  | return 0; | 
|  | } | 
|  |  | 
|  | SYS_INIT(hwinfo_rstc_init, POST_KERNEL, CONFIG_KERNEL_INIT_PRIORITY_DEVICE); |