• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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)36 errcode_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)57 errcode_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)74 uint64_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)92 uint64_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)97 uint64_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)102 STATIC 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)116 errcode_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)129 errcode_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)143 errcode_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)152 errcode_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 */