1 /** 2 * Copyright (c) 2020 HiSilicon (Shanghai) Technologies CO., LIMITED. 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 * 15 * Description: Provides tcxo driver source \n 16 * 17 * History: \n 18 * 2022-08-16, Create file. \n 19 */ 20 21 #include <stdbool.h> 22 #include "common_def.h" 23 #include "soc_osal.h" 24 #include "hal_tcxo.h" 25 #include "tcxo_porting.h" 26 #include "tcxo.h" 27 28 #define USECS_PER_MSEC 1000 29 static bool g_tcxo_inited = false; 30 31 #if defined(CONFIG_TCXO_SUPPORT_LPM) 32 static uint64_t g_tcxo_sleep_compensation_count = 0; 33 static uint64_t g_tcxo_sleep_suspend_current_count = 0; 34 #endif 35 uapi_tcxo_init(void)36errcode_t uapi_tcxo_init(void) 37 { 38 errcode_t ret = ERRCODE_FAIL; 39 40 uint32_t irq_sts = osal_irq_lock(); 41 if (unlikely(g_tcxo_inited)) { 42 osal_irq_restore(irq_sts); 43 return ERRCODE_SUCC; 44 } 45 46 ret = hal_tcxo_init(); 47 if (ret != ERRCODE_SUCC) { 48 osal_irq_restore(irq_sts); 49 return ret; 50 } 51 52 g_tcxo_inited = true; 53 osal_irq_restore(irq_sts); 54 return ret; 55 } 56 uapi_tcxo_deinit(void)57errcode_t uapi_tcxo_deinit(void) 58 { 59 errcode_t ret = ERRCODE_FAIL; 60 61 uint32_t irq_sts = osal_irq_lock(); 62 if (unlikely(!g_tcxo_inited)) { 63 osal_irq_restore(irq_sts); 64 return ERRCODE_SUCC; 65 } 66 67 ret = hal_tcxo_deinit(); 68 69 g_tcxo_inited = false; 70 osal_irq_restore(irq_sts); 71 return ret; 72 } 73 uapi_tcxo_get_count(void)74uint64_t uapi_tcxo_get_count(void) 75 { 76 uint64_t count = 0; 77 uint32_t irq_sts = osal_irq_lock(); 78 if (unlikely(!g_tcxo_inited)) { 79 osal_irq_restore(irq_sts); 80 return count; 81 } 82 count = hal_tcxo_get(); 83 osal_irq_restore(irq_sts); 84 85 #if defined(CONFIG_TCXO_SUPPORT_LPM) 86 return count + g_tcxo_sleep_compensation_count; 87 #else 88 return count; 89 #endif 90 } 91 uapi_tcxo_get_ms(void)92uint64_t uapi_tcxo_get_ms(void) 93 { 94 return uapi_tcxo_get_count() / (tcxo_porting_ticks_per_usec_get() * USECS_PER_MSEC); 95 } 96 uapi_tcxo_get_us(void)97uint64_t uapi_tcxo_get_us(void) 98 { 99 return uapi_tcxo_get_count() / tcxo_porting_ticks_per_usec_get(); 100 } 101 uapi_tcxo_delay_count(uint64_t ticks_delay)102STATIC errcode_t uapi_tcxo_delay_count(uint64_t ticks_delay) 103 { 104 uint64_t target_ticks; 105 uint64_t origin_ticks; 106 107 origin_ticks = uapi_tcxo_get_count(); 108 target_ticks = origin_ticks + ticks_delay; 109 110 while (uapi_tcxo_get_count() < target_ticks) { 111 } 112 113 return ERRCODE_SUCC; 114 } 115 uapi_tcxo_delay_ms(uint32_t m_delay)116errcode_t uapi_tcxo_delay_ms(uint32_t m_delay) 117 { 118 uint64_t ticks_to_delay; 119 120 if (unlikely(!g_tcxo_inited)) { 121 return ERRCODE_FAIL; 122 } 123 124 ticks_to_delay = (uint64_t)m_delay * USECS_PER_MSEC * tcxo_porting_ticks_per_usec_get(); 125 126 return uapi_tcxo_delay_count(ticks_to_delay); 127 } 128 uapi_tcxo_delay_us(uint32_t u_delay)129errcode_t uapi_tcxo_delay_us(uint32_t u_delay) 130 { 131 uint64_t ticks_to_delay; 132 133 if (unlikely(!g_tcxo_inited)) { 134 return ERRCODE_FAIL; 135 } 136 137 ticks_to_delay = (uint64_t)u_delay * tcxo_porting_ticks_per_usec_get(); 138 139 return uapi_tcxo_delay_count(ticks_to_delay); 140 } 141 142 #if defined(CONFIG_TCXO_SUPPORT_LPM) uapi_tcxo_suspend(uintptr_t arg)143errcode_t uapi_tcxo_suspend(uintptr_t arg) 144 { 145 g_tcxo_sleep_suspend_current_count = uapi_tcxo_get_count(); 146 if ((uint64_t *)arg != NULL) { 147 *(uint64_t *)arg = g_tcxo_sleep_suspend_current_count; 148 } 149 return ERRCODE_SUCC; 150 } 151 uapi_tcxo_resume(uintptr_t arg)152errcode_t uapi_tcxo_resume(uintptr_t arg) 153 { 154 uint64_t sleep_compensation_us = *(uint64_t *)arg; 155 uint64_t sleep_compensation_count = sleep_compensation_us * tcxo_porting_ticks_per_usec_get(); 156 g_tcxo_sleep_compensation_count = g_tcxo_sleep_suspend_current_count + sleep_compensation_count; 157 uapi_tcxo_deinit(); 158 return uapi_tcxo_init(); 159 } 160 #endif /* CONFIG_TCXO_SUPPORT_LPM */