1 /* 2 * SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD 3 * 4 * SPDX-License-Identifier: Apache-2.0 5 */ 6 #include <zephyr/kernel.h> 7 8 #include "hal/clk_gate_ll.h" 9 #include "esp_attr.h" 10 #include "esp_private/periph_ctrl.h" 11 #include "soc/soc_caps.h" 12 13 #if SOC_MODEM_CLOCK_IS_INDEPENDENT 14 #include "esp_private/esp_modem_clock.h" 15 #endif 16 17 static int periph_spinlock; 18 19 #define ENTER_CRITICAL_SECTION() do { periph_spinlock = irq_lock(); } while(0) 20 #define LEAVE_CRITICAL_SECTION() irq_unlock(periph_spinlock); 21 22 static uint8_t ref_counts[PERIPH_MODULE_MAX] = {0}; 23 24 #pragma GCC diagnostic push 25 #pragma GCC diagnostic ignored "-Warray-bounds" periph_module_enable(periph_module_t periph)26void periph_module_enable(periph_module_t periph) 27 { 28 assert(periph < PERIPH_MODULE_MAX); 29 ENTER_CRITICAL_SECTION(); 30 if (ref_counts[periph] == 0) { 31 periph_ll_enable_clk_clear_rst(periph); 32 } 33 ref_counts[periph]++; 34 LEAVE_CRITICAL_SECTION(); 35 } 36 #pragma GCC diagnostic pop 37 38 #pragma GCC diagnostic push 39 #pragma GCC diagnostic ignored "-Warray-bounds" periph_module_disable(periph_module_t periph)40void periph_module_disable(periph_module_t periph) 41 { 42 assert(periph < PERIPH_MODULE_MAX); 43 ENTER_CRITICAL_SECTION(); 44 ref_counts[periph]--; 45 if (ref_counts[periph] == 0) { 46 periph_ll_disable_clk_set_rst(periph); 47 } 48 LEAVE_CRITICAL_SECTION(); 49 } 50 #pragma GCC diagnostic pop 51 periph_module_reset(periph_module_t periph)52void periph_module_reset(periph_module_t periph) 53 { 54 assert(periph < PERIPH_MODULE_MAX); 55 ENTER_CRITICAL_SECTION(); 56 periph_ll_reset(periph); 57 LEAVE_CRITICAL_SECTION(); 58 } 59 60 #if !SOC_IEEE802154_BLE_ONLY wifi_bt_common_module_enable(void)61IRAM_ATTR void wifi_bt_common_module_enable(void) 62 { 63 #if SOC_MODEM_CLOCK_IS_INDEPENDENT 64 modem_clock_module_enable(PERIPH_PHY_MODULE); 65 #else 66 ENTER_CRITICAL_SECTION(); 67 if (ref_counts[PERIPH_WIFI_BT_COMMON_MODULE] == 0) { 68 periph_ll_wifi_bt_module_enable_clk_clear_rst(); 69 } 70 ref_counts[PERIPH_WIFI_BT_COMMON_MODULE]++; 71 LEAVE_CRITICAL_SECTION(); 72 #endif 73 } 74 wifi_bt_common_module_disable(void)75IRAM_ATTR void wifi_bt_common_module_disable(void) 76 { 77 #if SOC_MODEM_CLOCK_IS_INDEPENDENT 78 modem_clock_module_disable(PERIPH_PHY_MODULE); 79 #else 80 ENTER_CRITICAL_SECTION(); 81 ref_counts[PERIPH_WIFI_BT_COMMON_MODULE]--; 82 if (ref_counts[PERIPH_WIFI_BT_COMMON_MODULE] == 0) { 83 periph_ll_wifi_bt_module_disable_clk_set_rst(); 84 } 85 LEAVE_CRITICAL_SECTION(); 86 #endif 87 } 88 #endif 89 90 #if CONFIG_WIFI_ESP32 wifi_module_enable(void)91void wifi_module_enable(void) 92 { 93 #if SOC_MODEM_CLOCK_IS_INDEPENDENT 94 modem_clock_module_enable(PERIPH_WIFI_MODULE); 95 #else 96 ENTER_CRITICAL_SECTION(); 97 periph_ll_wifi_module_enable_clk_clear_rst(); 98 LEAVE_CRITICAL_SECTION(); 99 #endif 100 } 101 wifi_module_disable(void)102void wifi_module_disable(void) 103 { 104 #if SOC_MODEM_CLOCK_IS_INDEPENDENT 105 modem_clock_module_disable(PERIPH_WIFI_MODULE); 106 #else 107 ENTER_CRITICAL_SECTION(); 108 periph_ll_wifi_module_disable_clk_set_rst(); 109 LEAVE_CRITICAL_SECTION(); 110 #endif 111 } 112 #endif // CONFIG_WIFI_ESP32 113