1 /* 2 * Copyright (c) 2022 Basalte bv 3 * Copyright (c) 2023 Gerson Fernando Budke 4 * 5 * SPDX-License-Identifier: Apache-2.0 6 */ 7 8 #define DT_DRV_COMPAT atmel_sam_rstc 9 10 #include <zephyr/device.h> 11 #include <zephyr/drivers/hwinfo.h> 12 #include <zephyr/drivers/clock_control/atmel_sam_pmc.h> 13 14 BUILD_ASSERT(DT_NUM_INST_STATUS_OKAY(DT_DRV_COMPAT) == 1, 15 "No atmel,sam-rstc compatible device found"); 16 z_impl_hwinfo_get_reset_cause(uint32_t * cause)17int z_impl_hwinfo_get_reset_cause(uint32_t *cause) 18 { 19 /* Get reason from Status Register */ 20 uint32_t reason = ((Rstc *)DT_INST_REG_ADDR(0))->RSTC_SR & RSTC_SR_RSTTYP_Msk; 21 22 switch (reason) { 23 case RSTC_SR_RSTTYP_GENERAL_RST: 24 *cause = RESET_POR; 25 break; 26 case RSTC_SR_RSTTYP_BACKUP_RST: 27 *cause = RESET_LOW_POWER_WAKE; 28 break; 29 case RSTC_SR_RSTTYP_WDT_RST: 30 *cause = RESET_WATCHDOG; 31 break; 32 case RSTC_SR_RSTTYP_SOFT_RST: 33 *cause = RESET_SOFTWARE; 34 break; 35 case RSTC_SR_RSTTYP_USER_RST: 36 *cause = RESET_USER; 37 break; 38 default: 39 break; 40 } 41 42 return 0; 43 } 44 z_impl_hwinfo_get_supported_reset_cause(uint32_t * supported)45int z_impl_hwinfo_get_supported_reset_cause(uint32_t *supported) 46 { 47 *supported = RESET_POR 48 | RESET_LOW_POWER_WAKE 49 | RESET_WATCHDOG 50 | RESET_SOFTWARE 51 | RESET_USER; 52 53 return 0; 54 } 55 hwinfo_rstc_init(void)56static int hwinfo_rstc_init(void) 57 { 58 Rstc *regs = (Rstc *)DT_INST_REG_ADDR(0); 59 const struct atmel_sam_pmc_config clock_cfg = SAM_DT_INST_CLOCK_PMC_CFG(0); 60 uint32_t mode; 61 62 63 /* Enable RSTC in PMC */ 64 (void)clock_control_on(SAM_DT_PMC_CONTROLLER, 65 (clock_control_subsys_t)&clock_cfg); 66 67 /* Get current Mode Register value */ 68 mode = regs->RSTC_MR; 69 70 /* Enable/disable user reset on NRST */ 71 #if DT_INST_PROP(0, user_nrst) 72 mode &= ~RSTC_MR_KEY_Msk; 73 mode |= (RSTC_MR_URSTEN | RSTC_MR_KEY_PASSWD); 74 #else 75 mode &= ~(RSTC_MR_URSTEN | RSTC_MR_KEY_Msk); 76 mode |= RSTC_MR_KEY_PASSWD; 77 #endif 78 79 /* Set Mode Register value */ 80 regs->RSTC_MR = mode; 81 82 return 0; 83 } 84 85 SYS_INIT(hwinfo_rstc_init, POST_KERNEL, CONFIG_KERNEL_INIT_PRIORITY_DEVICE); 86