diff --git a/dts/bindings/power/atmel,sam-supc.yaml b/dts/bindings/power/atmel,sam-supc.yaml new file mode 100644 index 00000000000..fdba03f87cf --- /dev/null +++ b/dts/bindings/power/atmel,sam-supc.yaml @@ -0,0 +1,47 @@ +# Copyright (c) 2023 Bjarki Arge Andreasen +# SPDX-License-Identifier: Apache-2.0 + +description: | + Atmel SAM SUPC (Supply-Controller) controller + + The supply controller manages the voltage reference, power supply and supply + monitoring of the device. It have a special feature that it can wake-up the + device from a low-power state using special peripherals as wake-up sources. + + The dedicated peripherals that can wake-up the core supply domain are: RTC, + RTT, Supply Monitor and GPIOs. In the first three peripherals it is necessary + inform the wakeup-source-id property on their respective nodes. + + rtc: rtc@xxx { + ... + wakeup-source-id = <&supc SUPC_WAKEUP_SOURCE_RTC>; + ... + }; + + The special peripheral will wake-up the device only when the standard property + wakeup-source is defined, e.g.: + + &rtc { + ... + wakeup-source; + ... + }; + + The SUPC wakeup source ids that can be enabled are defined in the + zephyr/include/zephyr/dt-bindings/power/atmel_sam_supc.h header file. + +compatible: "atmel,sam-supc" + +include: + - name: base.yaml + +properties: + reg: + required: true + + "#wakeup-source-id-cells": + type: int + const: 1 + +wakeup-source-id-cells: + - wakeup-source-id diff --git a/include/zephyr/drivers/power/atmel_sam_supc.h b/include/zephyr/drivers/power/atmel_sam_supc.h new file mode 100644 index 00000000000..e31e3d7565f --- /dev/null +++ b/include/zephyr/drivers/power/atmel_sam_supc.h @@ -0,0 +1,18 @@ +/* + * Copyright (c) 2023 Bjarki Arge Andreasen + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_INCLUDE_DRIVERS_POWER_ATMEL_SAM_SUPC_H_ +#define ZEPHYR_INCLUDE_DRIVERS_POWER_ATMEL_SAM_SUPC_H_ + +#define SAM_DT_SUPC_CONTROLLER DEVICE_DT_GET(DT_NODELABEL(supc)) + +#define SAM_DT_SUPC_WAKEUP_SOURCE_ID(node_id) \ + DT_PROP_BY_IDX(node_id, wakeup_source_id wakeup_source_id) + +#define SAM_DT_INST_SUPC_WAKEUP_SOURCE_ID(inst) \ + SAM_DT_SUPC_WAKEUP_SOURCE_ID(DT_DRV_INST(inst)) + +#endif /* ZEPHYR_INCLUDE_DRIVERS_POWER_ATMEL_SAM_SUPC_H_ */ diff --git a/include/zephyr/dt-bindings/power/atmel_sam_supc.h b/include/zephyr/dt-bindings/power/atmel_sam_supc.h new file mode 100644 index 00000000000..547a97ef704 --- /dev/null +++ b/include/zephyr/dt-bindings/power/atmel_sam_supc.h @@ -0,0 +1,15 @@ +/* + * Copyright (c) 2023 Bjarki Arge Andreasen + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_INCLUDE_DT_BINDINGS_POWER_ATMEL_SAM_SUPC_H_ +#define ZEPHYR_INCLUDE_DT_BINDINGS_POWER_ATMEL_SAM_SUPC_H_ + +#define SUPC_WAKEUP_SOURCE_FWUP 0 +#define SUPC_WAKEUP_SOURCE_SM 1 +#define SUPC_WAKEUP_SOURCE_RTT 2 +#define SUPC_WAKEUP_SOURCE_RTC 3 + +#endif /* ZEPHYR_INCLUDE_DT_BINDINGS_POWER_ATMEL_SAM_SUPC_H_ */ diff --git a/soc/arm/atmel_sam/common/CMakeLists.txt b/soc/arm/atmel_sam/common/CMakeLists.txt index 7b57af36217..0c8602d1a35 100644 --- a/soc/arm/atmel_sam/common/CMakeLists.txt +++ b/soc/arm/atmel_sam/common/CMakeLists.txt @@ -3,6 +3,7 @@ zephyr_include_directories(.) zephyr_library_sources_ifndef(CONFIG_SOC_SERIES_SAM4L soc_pmc.c) zephyr_library_sources_ifndef(CONFIG_SOC_SERIES_SAM4L soc_gpio.c) +zephyr_library_sources_ifndef(CONFIG_SOC_SERIES_SAM4L soc_supc.c) zephyr_library_sources_ifdef(CONFIG_SOC_SERIES_SAM4L soc_sam4l_pm.c) zephyr_library_sources_ifdef(CONFIG_SOC_SERIES_SAM4L soc_sam4l_gpio.c) diff --git a/soc/arm/atmel_sam/common/soc_supc.c b/soc/arm/atmel_sam/common/soc_supc.c new file mode 100644 index 00000000000..cf6ce80ab2c --- /dev/null +++ b/soc/arm/atmel_sam/common/soc_supc.c @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2023 Bjarki Arge Andreasen + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include + +#define SOC_SUPC_WAKEUP_SOURCE_IDS (3) + +void soc_supc_core_voltage_regulator_off(void) +{ + SUPC->SUPC_CR = SUPC_CR_KEY_PASSWD | SUPC_CR_VROFF_STOP_VREG; +} + +void soc_supc_slow_clock_select_crystal_osc(void) +{ + SUPC->SUPC_CR = SUPC_CR_KEY_PASSWD | SUPC_CR_XTALSEL_CRYSTAL_SEL; + + /* Wait for oscillator to be stabilized. */ + while (!(SUPC->SUPC_SR & SUPC_SR_OSCSEL)) { + } +} + +void soc_supc_enable_wakeup_source(uint32_t wakeup_source_id) +{ + __ASSERT(wakeup_source_id <= SOC_SUPC_WAKEUP_SOURCE_IDS, + "Wakeup source channel is invalid"); + + SUPC->SUPC_WUMR |= 1 << wakeup_source_id; +} diff --git a/soc/arm/atmel_sam/common/soc_supc.h b/soc/arm/atmel_sam/common/soc_supc.h new file mode 100644 index 00000000000..b925eb5f18c --- /dev/null +++ b/soc/arm/atmel_sam/common/soc_supc.h @@ -0,0 +1,26 @@ +/* + * Copyright (c) 2023 Bjarki Arge Andreasen + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef _ATMEL_SAM_SOC_SUPC_H_ +#define _ATMEL_SAM_SOC_SUPC_H_ + +#include + +/** + * @brief Enable the clock of specified peripheral module. + */ +void soc_supc_core_voltage_regulator_off(void); + +/** + * @brief Switch slow clock source to external crystal oscillator + */ +void soc_supc_slow_clock_select_crystal_osc(void); + +/** + * @brief Enable wakeup source + */ +void soc_supc_enable_wakeup_source(uint32_t wakeup_source_id); + +#endif /* _ATMEL_SAM_SOC_SUPC_H_ */ diff --git a/soc/arm/atmel_sam/sam3x/soc.h b/soc/arm/atmel_sam/sam3x/soc.h index 0d7842fac1c..3fe78a7e6ba 100644 --- a/soc/arm/atmel_sam/sam3x/soc.h +++ b/soc/arm/atmel_sam/sam3x/soc.h @@ -38,6 +38,7 @@ #include "../common/soc_pmc.h" #include "../common/soc_gpio.h" +#include "../common/soc_supc.h" #include "../common/atmel_sam_dt.h" /** Processor Clock (HCLK) Frequency */ diff --git a/soc/arm/atmel_sam/sam4e/soc.h b/soc/arm/atmel_sam/sam4e/soc.h index 523c5487748..290653e148a 100644 --- a/soc/arm/atmel_sam/sam4e/soc.h +++ b/soc/arm/atmel_sam/sam4e/soc.h @@ -38,6 +38,7 @@ #include "../common/soc_pmc.h" #include "../common/soc_gpio.h" +#include "../common/soc_supc.h" #include "../common/atmel_sam_dt.h" /** Processor Clock (HCLK) Frequency */ diff --git a/soc/arm/atmel_sam/sam4s/soc.h b/soc/arm/atmel_sam/sam4s/soc.h index e469c3ac19a..ec3ab20471e 100644 --- a/soc/arm/atmel_sam/sam4s/soc.h +++ b/soc/arm/atmel_sam/sam4s/soc.h @@ -52,6 +52,7 @@ #include "../common/soc_pmc.h" #include "../common/soc_gpio.h" +#include "../common/soc_supc.h" #include "../common/atmel_sam_dt.h" /** Processor Clock (HCLK) Frequency */ diff --git a/soc/arm/atmel_sam/same70/soc.h b/soc/arm/atmel_sam/same70/soc.h index 37f10e2792a..ad72b4d2ef0 100644 --- a/soc/arm/atmel_sam/same70/soc.h +++ b/soc/arm/atmel_sam/same70/soc.h @@ -64,6 +64,7 @@ #include "../common/soc_pmc.h" #include "../common/soc_gpio.h" +#include "../common/soc_supc.h" #include "../common/atmel_sam_dt.h" /** Processor Clock (HCLK) Frequency */ diff --git a/soc/arm/atmel_sam/samv71/soc.h b/soc/arm/atmel_sam/samv71/soc.h index 264f92c5172..4c85be42136 100644 --- a/soc/arm/atmel_sam/samv71/soc.h +++ b/soc/arm/atmel_sam/samv71/soc.h @@ -65,6 +65,7 @@ #include "../common/soc_pmc.h" #include "../common/soc_gpio.h" +#include "../common/soc_supc.h" #include "../common/atmel_sam_dt.h" /** Processor Clock (HCLK) Frequency */