• 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  * Description: Low-power management operations for peripheral devices.
15  *
16  * Create:  2021-4-28
17  */
18 
19 #include "lpm_dev_ops.h"
20 #include "securec.h"
21 #include "irmalloc.h"
22 #include "soc_osal.h"
23 
24 #define ops_(a, b) ((a) ? (a) : (b))
25 
26 static lpm_dev_ops_t *g_dev_ops = NULL;
27 static lpm_clock_init_callback g_display_clocks_init_handler = NULL;
28 
lpm_dev_ops_init(void)29 bool lpm_dev_ops_init(void)
30 {
31     if (g_dev_ops != NULL) {
32         return false;
33     }
34     uint32_t irq_sts = osal_irq_lock();
35     g_dev_ops = irmalloc(sizeof(lpm_dev_ops_t) * DEV_MAX);
36     if (g_dev_ops == NULL) {
37         osal_irq_restore(irq_sts);
38         return false;
39     }
40     if (memset_s(g_dev_ops, sizeof(lpm_dev_ops_t) * DEV_MAX, 0, sizeof(lpm_dev_ops_t) * DEV_MAX) != EOK) {
41         osal_irq_restore(irq_sts);
42         return false;
43     }
44     osal_irq_restore(irq_sts);
45 
46     return true;
47 }
48 
lpm_dev_ops_deinit(void)49 bool lpm_dev_ops_deinit(void)
50 {
51     if (g_dev_ops == NULL) {
52         return false;
53     }
54     uint32_t irq_sts = osal_irq_lock();
55     irfree(g_dev_ops);
56     g_dev_ops = NULL;
57     osal_irq_restore(irq_sts);
58 
59     return true;
60 }
61 
lpm_dev_ops_register(lpm_dev_id_t id,lpm_dev_ops_t * ops)62 bool lpm_dev_ops_register(lpm_dev_id_t id, lpm_dev_ops_t *ops)
63 {
64     if (id >= DEV_MAX || (g_dev_ops == NULL) || (ops == NULL)) {
65         return false;
66     }
67     uint32_t irq_sts = osal_irq_lock();
68     if (memcpy_s(&g_dev_ops[id], sizeof(lpm_dev_ops_t), ops, sizeof(lpm_dev_ops_t)) != EOK) {
69         osal_irq_restore(irq_sts);
70         return false;
71     }
72     osal_irq_restore(irq_sts);
73 
74     return true;
75 }
76 
lpm_dev_ops_unregister(lpm_dev_id_t id)77 bool lpm_dev_ops_unregister(lpm_dev_id_t id)
78 {
79     if (id >= DEV_MAX || (g_dev_ops == NULL)) {
80         return false;
81     }
82     uint32_t irq_sts = osal_irq_lock();
83     if (memset_s(&g_dev_ops[id], sizeof(lpm_dev_ops_t), 0, sizeof(lpm_dev_ops_t)) != EOK) {
84         osal_irq_restore(irq_sts);
85         return false;
86     }
87     osal_irq_restore(irq_sts);
88 
89     return true;
90 }
91 
lpm_dev_ops_update(lpm_dev_id_t id,lpm_dev_ops_t * ops)92 int lpm_dev_ops_update(lpm_dev_id_t id, lpm_dev_ops_t *ops)
93 {
94     if (id >= DEV_MAX || ops == NULL) {
95         return LPM_RET_ERR;
96     }
97 
98     if (g_dev_ops == NULL) {
99         return LPM_RET_UNINIT;
100     }
101     uint32_t irq_sts = osal_irq_lock();
102     g_dev_ops[id].power_on    = ops_(ops->power_on, g_dev_ops[id].power_on);
103     g_dev_ops[id].power_sts   = ops_(ops->power_sts, g_dev_ops[id].power_sts);
104     g_dev_ops[id].set_voltage = ops_(ops->set_voltage, g_dev_ops[id].set_voltage);
105     g_dev_ops[id].get_voltage = ops_(ops->get_voltage, g_dev_ops[id].get_voltage);
106     g_dev_ops[id].clock_en    = ops_(ops->clock_en, g_dev_ops[id].clock_en);
107     g_dev_ops[id].clock_sts   = ops_(ops->clock_sts, g_dev_ops[id].clock_sts);
108     g_dev_ops[id].set_freq    = ops_(ops->set_freq, g_dev_ops[id].set_freq);
109     g_dev_ops[id].get_freq    = ops_(ops->get_freq, g_dev_ops[id].get_freq);
110     g_dev_ops[id].set_div_num = ops_(ops->set_div_num, g_dev_ops[id].set_div_num);
111     g_dev_ops[id].get_div_num = ops_(ops->get_div_num, g_dev_ops[id].get_div_num);
112     g_dev_ops[id].sub_clken   = ops_(ops->sub_clken, g_dev_ops[id].sub_clken);
113     g_dev_ops[id].resume      = ops_(ops->resume, g_dev_ops[id].resume);
114     g_dev_ops[id].suspend     = ops_(ops->suspend, g_dev_ops[id].suspend);
115     osal_irq_restore(irq_sts);
116     return LPM_RET_OK;
117 }
118 
lpm_dev_power_on(lpm_dev_id_t id,bool on)119 int lpm_dev_power_on(lpm_dev_id_t id, bool on)
120 {
121     if (g_dev_ops == NULL) {
122         return LPM_RET_ERR;
123     }
124     if (g_dev_ops[id].power_on) {
125         return g_dev_ops[id].power_on(on);
126     } else {
127         return LPM_RET_NOREG;
128     }
129 }
130 
lpm_dev_get_power_sts(lpm_dev_id_t id)131 int lpm_dev_get_power_sts(lpm_dev_id_t id)
132 {
133     if (g_dev_ops == NULL) {
134         return LPM_RET_ERR;
135     }
136     if (g_dev_ops[id].power_sts) {
137         return g_dev_ops[id].power_sts();
138     } else {
139         return LPM_RET_NOREG;
140     }
141 }
142 
lpm_dev_set_voltage(lpm_dev_id_t id,int vset)143 int lpm_dev_set_voltage(lpm_dev_id_t id, int vset)
144 {
145     if (g_dev_ops == NULL) {
146         return LPM_RET_ERR;
147     }
148     if (g_dev_ops[id].set_voltage) {
149         return g_dev_ops[id].set_voltage(vset);
150     } else {
151         return LPM_RET_NOREG;
152     }
153 }
154 
lpm_dev_get_voltage(lpm_dev_id_t id)155 int lpm_dev_get_voltage(lpm_dev_id_t id)
156 {
157     if (g_dev_ops == NULL) {
158         return LPM_RET_ERR;
159     }
160     if (g_dev_ops[id].get_voltage) {
161         return g_dev_ops[id].get_voltage();
162     } else {
163         return LPM_RET_NOREG;
164     }
165 }
166 
lpm_dev_clock_en(lpm_dev_id_t id,bool on)167 int lpm_dev_clock_en(lpm_dev_id_t id, bool on)
168 {
169     if (g_dev_ops == NULL) {
170         return LPM_RET_ERR;
171     }
172     if (g_dev_ops[id].clock_en) {
173         return g_dev_ops[id].clock_en(on);
174     } else {
175         return LPM_RET_NOREG;
176     }
177 }
178 
lpm_dev_get_clock_sts(lpm_dev_id_t id)179 int lpm_dev_get_clock_sts(lpm_dev_id_t id)
180 {
181     if (g_dev_ops == NULL) {
182         return LPM_RET_ERR;
183     }
184     if (g_dev_ops[id].clock_sts) {
185         return g_dev_ops[id].clock_sts();
186     } else {
187         return LPM_RET_NOREG;
188     }
189 }
190 
lpm_dev_set_freq(lpm_dev_id_t id,int freq)191 int lpm_dev_set_freq(lpm_dev_id_t id, int freq)
192 {
193     if (g_dev_ops == NULL) {
194         return LPM_RET_ERR;
195     }
196     if (g_dev_ops[id].set_freq) {
197         return g_dev_ops[id].set_freq(freq);
198     } else {
199         return LPM_RET_NOREG;
200     }
201 }
202 
lpm_dev_get_freq(lpm_dev_id_t id)203 int lpm_dev_get_freq(lpm_dev_id_t id)
204 {
205     if (g_dev_ops == NULL) {
206         return LPM_RET_ERR;
207     }
208     if (g_dev_ops[id].get_freq) {
209         return g_dev_ops[id].get_freq();
210     } else {
211         return LPM_RET_NOREG;
212     }
213 }
214 
lpm_dev_set_div_num(lpm_dev_id_t id,int clk_div)215 int lpm_dev_set_div_num(lpm_dev_id_t id, int clk_div)
216 {
217     if (g_dev_ops == NULL) {
218         return LPM_RET_ERR;
219     }
220     if (g_dev_ops[id].set_div_num) {
221         return g_dev_ops[id].set_div_num(clk_div);
222     } else {
223         return LPM_RET_NOREG;
224     }
225 }
226 
lpm_dev_get_div_num(lpm_dev_id_t id)227 int lpm_dev_get_div_num(lpm_dev_id_t id)
228 {
229     if (g_dev_ops == NULL) {
230         return LPM_RET_ERR;
231     }
232     if (g_dev_ops[id].get_div_num) {
233         return g_dev_ops[id].get_div_num();
234     } else {
235         return LPM_RET_NOREG;
236     }
237 }
238 
lpm_dev_sub_bus_clken(lpm_dev_id_t id,int bus,bool on)239 int lpm_dev_sub_bus_clken(lpm_dev_id_t id, int bus, bool on)
240 {
241     if (g_dev_ops == NULL) {
242         return LPM_RET_ERR;
243     }
244     if (g_dev_ops[id].sub_clken) {
245         return g_dev_ops[id].sub_clken(bus, on);
246     } else {
247         return LPM_RET_NOREG;
248     }
249 }
250 
lpm_display_clocks_init_register_callback(lpm_clock_init_callback callback)251 void lpm_display_clocks_init_register_callback(lpm_clock_init_callback callback)
252 {
253     if (callback != NULL) {
254         g_display_clocks_init_handler = callback;
255     }
256 }
257 
lpm_display_clocks_init(void)258 void lpm_display_clocks_init(void)
259 {
260     if (g_display_clocks_init_handler != NULL) {
261         g_display_clocks_init_handler();
262     }
263 }