• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021-2023 Huawei Device Co., Ltd.
3  *
4  * HDF is dual licensed: you can use it either under the terms of
5  * the GPL, or the BSD license, at your option.
6  * See the LICENSE file in the root of this repository for complete details.
7  */
8 
9 #include "regulator_core.h"
10 #include "hdf_log.h"
11 #include "osal_mem.h"
12 #include "osal_time.h"
13 #include "securec.h"
14 #include "regulator_tree_mgr.h"
15 
16 #define HDF_LOG_TAG regulator_core
17 struct RegulatorManager {
18     struct IDeviceIoService service;
19     struct HdfDeviceObject *device;
20     struct DListHead regulatorHead;
21     struct OsalMutex lock;
22 };
23 
24 static struct RegulatorManager *g_regulatorManager = NULL;
25 
RegulatorNodeOpen(const char * name)26 struct RegulatorNode *RegulatorNodeOpen(const char *name)
27 {
28     CHECK_NULL_PTR_RETURN_VALUE(name, NULL);
29     struct RegulatorNode *pos = NULL;
30     struct RegulatorNode *tmp = NULL;
31 
32     struct RegulatorManager *manager = g_regulatorManager;
33     CHECK_NULL_PTR_RETURN_VALUE(manager, NULL);
34 
35     if (OsalMutexLock(&manager->lock) != HDF_SUCCESS) {
36         HDF_LOGE("RegulatorNodeOpen: lock regulator manager fail!");
37         return NULL;
38     }
39 
40     DLIST_FOR_EACH_ENTRY_SAFE(pos, tmp, &manager->regulatorHead, struct RegulatorNode, node) {
41         if (strcmp(name, pos->regulatorInfo.name) == 0) {
42             if ((pos->ops->open != NULL) && pos->ops->open(pos) != HDF_SUCCESS) {
43                 (void)OsalMutexUnlock(&manager->lock);
44                 HDF_LOGE("RegulatorNodeOpen: open regulator[%s] fail!", name);
45                 return NULL;
46             }
47             (void)OsalMutexUnlock(&manager->lock);
48             return pos;
49         }
50     }
51 
52     (void)OsalMutexUnlock(&manager->lock);
53     HDF_LOGE("RegulatorNodeOpen: No %s regulator exist!", name);
54     return NULL;
55 }
56 
RegulatorNodeClose(struct RegulatorNode * node)57 int32_t RegulatorNodeClose(struct RegulatorNode *node)
58 {
59     CHECK_NULL_PTR_RETURN_VALUE(node, HDF_ERR_INVALID_OBJECT);
60     return HDF_SUCCESS;
61 }
62 
RegulatorNodeListPrint(void)63 void RegulatorNodeListPrint(void)
64 {
65     struct RegulatorNode *pos = NULL;
66     struct RegulatorNode *tmp = NULL;
67 
68     struct RegulatorManager *manager = g_regulatorManager;
69     CHECK_NULL_PTR_RETURN(manager);
70 
71     if (OsalMutexLock(&manager->lock) != HDF_SUCCESS) {
72         HDF_LOGE("RegulatorNodeListPrint: lock regulator manager fail!");
73         return;
74     }
75 
76     DLIST_FOR_EACH_ENTRY_SAFE(pos, tmp, &manager->regulatorHead, struct RegulatorNode, node) {
77         HDF_LOGI("RegulatorNodeListPrint: name[%s], [%u][%hhu][%hhu], [%u][%u]--[%u][%u]",
78             pos->regulatorInfo.name, pos->regulatorInfo.status,
79             pos->regulatorInfo.constraints.alwaysOn, pos->regulatorInfo.constraints.mode,
80             pos->regulatorInfo.constraints.minUv, pos->regulatorInfo.constraints.maxUv,
81             pos->regulatorInfo.constraints.minUa, pos->regulatorInfo.constraints.maxUa);
82         if ((pos->regulatorInfo.parentName != NULL) && (strlen(pos->regulatorInfo.parentName) > 0)) {
83             HDF_LOGI("RegulatorNodeListPrint:parentName[%s]", pos->regulatorInfo.parentName);
84         }
85     }
86 
87     (void)OsalMutexUnlock(&manager->lock);
88     RegulatorTreePrint();
89 }
90 
RegulatorNodeSetParent(struct RegulatorNode * node)91 int32_t RegulatorNodeSetParent(struct RegulatorNode *node)
92 {
93     CHECK_NULL_PTR_RETURN_VALUE(node, HDF_ERR_INVALID_PARAM);
94     struct RegulatorNode *pos = NULL;
95     struct RegulatorNode *tmp = NULL;
96     struct RegulatorManager *manager = g_regulatorManager;
97     CHECK_NULL_PTR_RETURN_VALUE(manager, HDF_FAILURE);
98 
99     if (OsalMutexLock(&manager->lock) != HDF_SUCCESS) {
100         HDF_LOGE("RegulatorNodeSetParent: lock regulator manager fail!");
101         return HDF_ERR_DEVICE_BUSY;
102     }
103     // parent set
104     if ((node->regulatorInfo.parentName != NULL)
105         && (strlen(node->regulatorInfo.parentName) > 0)) {
106         DLIST_FOR_EACH_ENTRY_SAFE(pos, tmp, &manager->regulatorHead, struct RegulatorNode, node) {
107             if (strcmp(node->regulatorInfo.parentName, pos->regulatorInfo.name) == 0) {
108                 if (RegulatorTreeSet(node->regulatorInfo.name, node, pos) != HDF_SUCCESS) {
109                     HDF_LOGE("RegulatorNodeSetParent: RegulatorTreeSet fail!");
110                     (void)OsalMutexUnlock(&manager->lock);
111                     return HDF_FAILURE;
112                 } else {
113                     HDF_LOGI("RegulatorNodeSetParent:regulator [%s] RegulatorTreeSet success!",
114                         node->regulatorInfo.name);
115                     (void)OsalMutexUnlock(&manager->lock);
116                     return HDF_SUCCESS;
117                 }
118             }
119         }
120 
121         HDF_LOGE("RegulatorNodeSetParent: RegulatorTreeSet find %s parent %s error!",
122             node->regulatorInfo.name, node->regulatorInfo.parentName);
123         (void)OsalMutexUnlock(&manager->lock);
124         return HDF_FAILURE;
125     }
126 
127     (void)OsalMutexUnlock(&manager->lock);
128     HDF_LOGD("RegulatorNodeSetParent: the node %s no need to set parent!", node->regulatorInfo.name);
129     return HDF_SUCCESS;
130 }
131 
RegulatorNodeSetChild(struct RegulatorNode * parent)132 int32_t RegulatorNodeSetChild(struct RegulatorNode *parent)
133 {
134     CHECK_NULL_PTR_RETURN_VALUE(parent, HDF_ERR_INVALID_PARAM);
135     struct RegulatorNode *pos = NULL;
136     struct RegulatorNode *tmp = NULL;
137     struct RegulatorManager *manager = g_regulatorManager;
138     CHECK_NULL_PTR_RETURN_VALUE(manager, HDF_FAILURE);
139 
140     if (OsalMutexLock(&manager->lock) != HDF_SUCCESS) {
141         HDF_LOGE("RegulatorNodeSetChild: lock regulator manager fail!");
142         return HDF_ERR_DEVICE_BUSY;
143     }
144 
145     DLIST_FOR_EACH_ENTRY_SAFE(pos, tmp, &manager->regulatorHead, struct RegulatorNode, node) {
146         if ((pos->regulatorInfo.parentName != NULL) &&
147             (strcmp(parent->regulatorInfo.name, pos->regulatorInfo.parentName) == 0)) {
148             HDF_LOGD("RegulatorNodeSetChild: node[%s] parent is %s, tree info process!",
149                 pos->regulatorInfo.parentName, parent->regulatorInfo.name);
150             if (RegulatorTreeSet(pos->regulatorInfo.name, pos, parent) != HDF_SUCCESS) {
151                 HDF_LOGE("RegulatorNodeSetChild: RegulatorTreeSet fail!");
152                 (void)OsalMutexUnlock(&manager->lock);
153                 return HDF_FAILURE;
154             }
155         }
156     }
157 
158     HDF_LOGD("RegulatorNodeSetChild: the node %s child info process success", parent->regulatorInfo.name);
159     (void)OsalMutexUnlock(&manager->lock);
160     return HDF_SUCCESS;
161 }
162 
RegulatorNodeInitEnable(struct RegulatorNode * node)163 void RegulatorNodeInitEnable(struct RegulatorNode *node)
164 {
165     CHECK_NULL_PTR_RETURN(node);
166     if (node->regulatorInfo.status == REGULATOR_STATUS_ON) {
167         HDF_LOGD("RegulatorNodeInitEnable: %s status on", node->regulatorInfo.name);
168         return;
169     }
170 
171     bool isChildAlwayson = RegulatorTreeIsChildAlwayson(node->regulatorInfo.name);
172     bool isChildOn = RegulatorTreeIsChildStatusOn(node->regulatorInfo.name);
173     // if regulator alwaysOn is true or there is child's alwaysOn is true or there is child's status on, then process
174     if ((node->regulatorInfo.constraints.alwaysOn) || (isChildAlwayson) || (isChildOn)) {
175         // RegulatorTreeIsUpNodeComplete is false, call RegulatorNodeEnable will fail.
176         if (RegulatorTreeIsUpNodeComplete(node->regulatorInfo.name)) {
177             HDF_LOGD("RegulatorNodeInitEnable: %s UpNodeComplete", node->regulatorInfo.name);
178             RegulatorNodeEnable(node);
179             return;
180         }
181         if (OsalMutexLock(&node->lock) != HDF_SUCCESS) {
182             HDF_LOGE("RegulatorNodeInitEnable: lock regulator %s fail!", node->regulatorInfo.name);
183             return;
184         }
185         // first enable
186         if (node->ops->enable(node) != HDF_SUCCESS) {
187             (void)OsalMutexUnlock(&node->lock);
188             HDF_LOGE("RegulatorNodeInitEnable: %s fail!", node->regulatorInfo.name);
189             return;
190         }
191         node->regulatorInfo.status = REGULATOR_STATUS_ON;
192         RegulatorNodeStatusCb(node);
193 
194         (void)OsalMutexUnlock(&node->lock);
195         HDF_LOGD("RegulatorNodeInitEnable: %s success", node->regulatorInfo.name);
196         return;
197     }
198 }
199 
200 /*
201 * complete up and down management topology
202 * process alwayson
203 */
RegulatorNodeInitProcess(struct RegulatorNode * node)204 int32_t RegulatorNodeInitProcess(struct RegulatorNode *node)
205 {
206     CHECK_NULL_PTR_RETURN_VALUE(node, HDF_ERR_INVALID_PARAM);
207 
208     // parent or child set
209     if (RegulatorNodeSetParent(node) != HDF_SUCCESS) {
210         HDF_LOGD("RegulatorNodeInitProcess: node %s RegulatorNodeSetParent fail, parent not add!",
211             node->regulatorInfo.name);
212     }
213 
214     if (RegulatorNodeSetChild(node) != HDF_SUCCESS) {
215         HDF_LOGE("RegulatorNodeInitProcess: node %s RegulatorNodeSetChild fail!", node->regulatorInfo.name);
216         return HDF_FAILURE;
217     }
218 
219     if (node->regulatorInfo.constraints.mode == REGULATOR_CHANGE_CURRENT) {
220         RegulatorNodeSetCurrent(node, node->regulatorInfo.constraints.minUa, node->regulatorInfo.constraints.maxUa);
221     } else if (node->regulatorInfo.constraints.mode == REGULATOR_CHANGE_VOLTAGE) {
222         RegulatorNodeSetVoltage(node, node->regulatorInfo.constraints.minUv, node->regulatorInfo.constraints.maxUv);
223     }
224 
225     RegulatorNodeInitEnable(node);
226 
227     HDF_LOGD("RegulatorNodeInitProcess: the node %s init success", node->regulatorInfo.name);
228     return HDF_SUCCESS;
229 }
230 
RegulatorNodeAdd(struct RegulatorNode * node)231 int32_t RegulatorNodeAdd(struct RegulatorNode *node)
232 {
233     CHECK_NULL_PTR_RETURN_VALUE(node, HDF_ERR_INVALID_PARAM);
234     CHECK_NULL_PTR_RETURN_VALUE(node->ops, HDF_ERR_INVALID_PARAM);
235     struct RegulatorNode *pos = NULL;
236     struct RegulatorNode *tmp = NULL;
237     struct RegulatorManager *manager = g_regulatorManager;
238     CHECK_NULL_PTR_RETURN_VALUE(manager, HDF_FAILURE);
239 
240     DLIST_FOR_EACH_ENTRY_SAFE(pos, tmp, &manager->regulatorHead, struct RegulatorNode, node) {
241         if (strcmp(node->regulatorInfo.name, pos->regulatorInfo.name) == 0) {
242             HDF_LOGE("RegulatorNodeAdd: regulatorInfo[%s] existed!", node->regulatorInfo.name);
243             return HDF_FAILURE;
244         }
245     }
246 
247     // init node info
248     node->regulatorInfo.cb = NULL;
249     node->regulatorInfo.useCount = 0;
250     node->regulatorInfo.status = REGULATOR_STATUS_OFF;
251     node->regulatorInfo.useCount = 0;
252     if (OsalMutexInit(&node->lock) != HDF_SUCCESS) {
253         HDF_LOGE("RegulatorNodeAdd: OsalMutexInit %s fail!", node->regulatorInfo.name);
254         return HDF_FAILURE;
255     }
256 
257     if (OsalMutexLock(&manager->lock) != HDF_SUCCESS) {
258         HDF_LOGE("RegulatorManagerAddNode: lock regulator manager fail!");
259         return HDF_ERR_DEVICE_BUSY;
260     }
261     DListInsertTail(&node->node, &manager->regulatorHead);
262     (void)OsalMutexUnlock(&manager->lock);
263 
264     if (RegulatorNodeInitProcess(node) != HDF_SUCCESS) {
265         HDF_LOGE("RegulatorNodeAdd: node %s RegulatorNodeInitProcess fail!", node->regulatorInfo.name);
266         return HDF_FAILURE;
267     }
268 
269     HDF_LOGI("RegulatorNodeAdd: add regulator name[%s] success!", node->regulatorInfo.name);
270 
271     return HDF_SUCCESS;
272 }
273 
RegulatorNodeRemove(const char * name)274 int32_t RegulatorNodeRemove(const char *name)
275 {
276     CHECK_NULL_PTR_RETURN_VALUE(name, HDF_ERR_INVALID_PARAM);
277 
278     struct RegulatorNode *pos = NULL;
279     struct RegulatorNode *tmp = NULL;
280     struct RegulatorManager *manager = g_regulatorManager;
281     if (manager == NULL) {
282         HDF_LOGE("RegulatorNodeRemoveAll: regulator manager null!");
283         return HDF_ERR_NOT_SUPPORT;
284     }
285 
286     if (OsalMutexLock(&manager->lock) != HDF_SUCCESS) {
287         HDF_LOGE("RegulatorNodeRemoveAll: lock regulator manager fail!");
288         return HDF_ERR_DEVICE_BUSY;
289     }
290 
291     DLIST_FOR_EACH_ENTRY_SAFE(pos, tmp, &manager->regulatorHead, struct RegulatorNode, node) {
292         if (strcmp(pos->regulatorInfo.name, name) == 0) {
293             if ((pos->ops->release != NULL) && pos->ops->release(pos) != HDF_SUCCESS) {
294                 HDF_LOGE("RegulatorNodeRemoveAll: release regulator[%s] fail!", pos->regulatorInfo.name);
295             }
296             DListRemove(&pos->node);
297             (void)OsalMutexDestroy(&pos->lock);
298             OsalMemFree(pos);
299             break;
300         }
301     }
302 
303     (void)OsalMutexUnlock(&manager->lock);
304     HDF_LOGI("RegulatorNodeRemoveAll: remove regulator %s success!", name);
305     return HDF_SUCCESS;
306 }
307 
RegulatorNodeRemoveAll(void)308 int32_t RegulatorNodeRemoveAll(void)
309 {
310     if (RegulatorTreeNodeRemoveAll() != HDF_SUCCESS) {
311         HDF_LOGE("RegulatorNodeRemoveAll: RegulatorTreeNodeRemoveAll fail!");
312         return HDF_FAILURE;
313     }
314 
315     struct RegulatorNode *pos = NULL;
316     struct RegulatorNode *tmp = NULL;
317     struct RegulatorManager *manager = g_regulatorManager;
318     if (manager == NULL) {
319         HDF_LOGE("RegulatorNodeRemoveAll: regulator manager is null!");
320         return HDF_ERR_NOT_SUPPORT;
321     }
322 
323     if (OsalMutexLock(&manager->lock) != HDF_SUCCESS) {
324         HDF_LOGE("RegulatorNodeRemoveAll: lock regulator manager fail!");
325         return HDF_ERR_DEVICE_BUSY;
326     }
327 
328     DLIST_FOR_EACH_ENTRY_SAFE(pos, tmp, &manager->regulatorHead, struct RegulatorNode, node) {
329         if ((pos->ops->release != NULL) && pos->ops->release(pos) != HDF_SUCCESS) {
330             HDF_LOGE("RegulatorNodeRemoveAll: release regulator[%s] fail!", pos->regulatorInfo.name);
331         }
332         DListRemove(&pos->node);
333         (void)OsalMutexDestroy(&pos->lock);
334         OsalMemFree(pos);
335     }
336 
337     (void)OsalMutexUnlock(&manager->lock);
338     HDF_LOGI("RegulatorNodeRemoveAll: remove all regulator success!");
339     return HDF_SUCCESS;
340 }
341 
RegulatorNodeStatusCb(struct RegulatorNode * node)342 int32_t RegulatorNodeStatusCb(struct RegulatorNode *node)
343 {
344     CHECK_NULL_PTR_RETURN_VALUE(node, HDF_ERR_INVALID_PARAM);
345     CHECK_NULL_PTR_RETURN_VALUE(node->regulatorInfo.cb, HDF_SUCCESS);
346     struct RegulatorStatusChangeInfo info;
347     (void)memset_s(&info, sizeof(struct RegulatorStatusChangeInfo), 0, sizeof(struct RegulatorStatusChangeInfo));
348 
349     info.status = node->regulatorInfo.status;
350     info.name = node->regulatorInfo.name;
351     HDF_LOGI("RegulatorNodeStatusCb: Cb %s %u", info.name, info.status);
352 
353     return node->regulatorInfo.cb(&info);
354 }
355 
RegulatorNodeEnable(struct RegulatorNode * node)356 int32_t RegulatorNodeEnable(struct RegulatorNode *node)
357 {
358     CHECK_NULL_PTR_RETURN_VALUE(node, HDF_ERR_INVALID_PARAM);
359     if (node->regulatorInfo.status == REGULATOR_STATUS_ON) {
360         HDF_LOGD("RegulatorNodeEnable: %s status on!", node->regulatorInfo.name);
361         return HDF_SUCCESS;
362     }
363 
364     if (OsalMutexLock(&node->lock) != HDF_SUCCESS) {
365         HDF_LOGE("RegulatorNodeEnable: lock regulator %s fail!", node->regulatorInfo.name);
366         return HDF_ERR_DEVICE_BUSY;
367     }
368 
369     if ((node->regulatorInfo.parentName != NULL) && (strlen(node->regulatorInfo.parentName) > 0)) {
370         struct RegulatorNode *parent = RegulatorTreeGetParent(node->regulatorInfo.name);
371         if (parent == NULL) {
372             (void)OsalMutexUnlock(&node->lock);
373             HDF_LOGE("RegulatorNodeEnable: %s fail!", node->regulatorInfo.name);
374             return HDF_FAILURE;
375         }
376         if (RegulatorNodeEnable(parent) != HDF_SUCCESS) {
377             (void)OsalMutexUnlock(&node->lock);
378             HDF_LOGE("RegulatorNodeEnable: %s fail!", parent->regulatorInfo.name);
379             return HDF_FAILURE;
380         }
381     }
382 
383     // first enable
384     if (node->ops->enable(node) != HDF_SUCCESS) {
385         (void)OsalMutexUnlock(&node->lock);
386         HDF_LOGE("RegulatorNodeEnable: enable: %s fail!", node->regulatorInfo.name);
387         return HDF_FAILURE;
388     }
389     RegulatorNodeStatusCb(node);
390 
391     (void)OsalMutexUnlock(&node->lock);
392     return HDF_SUCCESS;
393 }
394 
RegulatorNodeDisable(struct RegulatorNode * node)395 int32_t RegulatorNodeDisable(struct RegulatorNode *node)
396 {
397     CHECK_NULL_PTR_RETURN_VALUE(node, HDF_ERR_INVALID_PARAM);
398     if ((node->regulatorInfo.status == REGULATOR_STATUS_OFF) || (node->regulatorInfo.constraints.alwaysOn)) {
399         HDF_LOGI("RegulatorNodeDisable: %s [%u][%hhu], unsatisfied closing adjusment",
400             node->regulatorInfo.name, node->regulatorInfo.status, node->regulatorInfo.constraints.alwaysOn);
401         return HDF_SUCCESS;
402     }
403 
404     if (OsalMutexLock(&node->lock) != HDF_SUCCESS) {
405         HDF_LOGE("RegulatorNodeDisable: lock regulator %s fail!", node->regulatorInfo.name);
406         return HDF_ERR_DEVICE_BUSY;
407     }
408 
409     if (!RegulatorTreeIsAllChildDisable(node->regulatorInfo.name)) {
410         (void)OsalMutexUnlock(&node->lock);
411         HDF_LOGE("RegulatorNodeDisable: there is %s child not disable, so disable node fail!",
412             node->regulatorInfo.name);
413         return HDF_FAILURE;
414     }
415 
416     // the regulator no user, can disable
417 
418     if (node->ops->disable(node) != HDF_SUCCESS) {
419         (void)OsalMutexUnlock(&node->lock);
420         HDF_LOGE("RegulatorNodeDisable: disable %s fail!", node->regulatorInfo.name);
421         return HDF_FAILURE;
422     }
423 
424     RegulatorNodeStatusCb(node);
425 
426     // set parent
427     if ((node->regulatorInfo.parentName != NULL) && (strlen(node->regulatorInfo.parentName) > 0)) {
428         struct RegulatorNode *parent = RegulatorTreeGetParent(node->regulatorInfo.name);
429         if (parent == NULL) {
430             (void)OsalMutexUnlock(&node->lock);
431             HDF_LOGE("RegulatorNodeDisable: %s fail!", node->regulatorInfo.name);
432             return HDF_FAILURE;
433         }
434         if (RegulatorNodeDisable(parent) != HDF_SUCCESS) {
435             (void)OsalMutexUnlock(&node->lock);
436             HDF_LOGD("RegulatorNodeDisable: disable %s's parent %s fail!",
437                 node->regulatorInfo.name, parent->regulatorInfo.name);
438             return HDF_SUCCESS;
439         }
440     }
441 
442     (void)OsalMutexUnlock(&node->lock);
443     return HDF_SUCCESS;
444 }
445 
RegulatorNodeForceDisable(struct RegulatorNode * node)446 int32_t RegulatorNodeForceDisable(struct RegulatorNode *node)
447 {
448     CHECK_NULL_PTR_RETURN_VALUE(node, HDF_ERR_INVALID_PARAM);
449     if (OsalMutexLock(&node->lock) != HDF_SUCCESS) {
450         HDF_LOGE("RegulatorNodeForceDisable: lock regulator %s fail!", node->regulatorInfo.name);
451         return HDF_ERR_DEVICE_BUSY;
452     }
453 
454     if (node->regulatorInfo.status == REGULATOR_STATUS_OFF) {
455         (void)OsalMutexUnlock(&node->lock);
456         return HDF_SUCCESS;
457     }
458 
459     // if the regulator force disable ,set all child node disable
460     if (RegulatorTreeChildForceDisable(node) != HDF_SUCCESS) {
461         (void)OsalMutexUnlock(&node->lock);
462         HDF_LOGE("RegulatorNodeForceDisable: RegulatorTreeConsumerForceDisable: %s fail!", node->regulatorInfo.name);
463         return HDF_FAILURE;
464     }
465 
466     if (node->ops->forceDisable != NULL) {
467         if (node->ops->forceDisable(node) != HDF_SUCCESS) {
468             (void)OsalMutexUnlock(&node->lock);
469             HDF_LOGE("RegulatorNodeForceDisable: forceDisable %s fail!", node->regulatorInfo.name);
470             return HDF_FAILURE;
471         }
472     } else if (node->ops->disable(node) != HDF_SUCCESS) {
473         (void)OsalMutexUnlock(&node->lock);
474         HDF_LOGE("RegulatorNodeForceDisable: disable %s fail!", node->regulatorInfo.name);
475         return HDF_FAILURE;
476     }
477     node->regulatorInfo.status = REGULATOR_STATUS_OFF;
478     RegulatorNodeStatusCb(node);
479     HDF_LOGI("RegulatorNodeForceDisable:regulator %s force disable success", node->regulatorInfo.name);
480 
481     // set parent
482     if ((node->regulatorInfo.parentName != NULL) && (strlen(node->regulatorInfo.parentName) > 0)) {
483         struct RegulatorNode *parent = RegulatorTreeGetParent(node->regulatorInfo.name);
484         if (parent == NULL) {
485             (void)OsalMutexUnlock(&node->lock);
486             HDF_LOGE("RegulatorNodeForceDisable: %s get parent fail!", node->regulatorInfo.name);
487             return HDF_FAILURE;
488         }
489         if (RegulatorNodeDisable(parent) != HDF_SUCCESS) {
490             (void)OsalMutexUnlock(&node->lock);
491             HDF_LOGD("RegulatorNodeForceDisable: disable %s's parent %s fail!",
492                 node->regulatorInfo.name, parent->regulatorInfo.name);
493             return HDF_SUCCESS;
494         }
495     }
496 
497     (void)OsalMutexUnlock(&node->lock);
498     return HDF_SUCCESS;
499 }
500 
RegulatorNodeSetVoltage(struct RegulatorNode * node,uint32_t minUv,uint32_t maxUv)501 int32_t RegulatorNodeSetVoltage(struct RegulatorNode *node, uint32_t minUv, uint32_t maxUv)
502 {
503     CHECK_NULL_PTR_RETURN_VALUE(node, HDF_ERR_INVALID_PARAM);
504     if (node->regulatorInfo.constraints.mode != REGULATOR_CHANGE_VOLTAGE) {
505         HDF_LOGE("RegulatorNodeSetVoltage: %s mode %d is invalid!",
506             node->regulatorInfo.name, node->regulatorInfo.constraints.mode);
507         return HDF_FAILURE;
508     }
509 
510     if (minUv == node->regulatorInfo.minUv && maxUv == node->regulatorInfo.maxUv) {
511         return HDF_SUCCESS;
512     }
513 
514     if ((minUv > maxUv) ||
515         (minUv < node->regulatorInfo.constraints.minUv ||
516         maxUv > node->regulatorInfo.constraints.maxUv)) {
517         HDF_LOGE("RegulatorNodeSetVoltage: %s Uv [%u, %u] invalid!",
518             node->regulatorInfo.name, minUv, maxUv);
519         return HDF_FAILURE;
520     }
521 
522     if (OsalMutexLock(&node->lock) != HDF_SUCCESS) {
523         HDF_LOGE("RegulatorNodeSetVoltage: lock regulator %s fail!", node->regulatorInfo.name);
524         return HDF_ERR_DEVICE_BUSY;
525     }
526 
527     int ret = node->ops->setVoltage(node, minUv, maxUv);
528     if (ret != HDF_SUCCESS) {
529         (void)OsalMutexUnlock(&node->lock);
530         HDF_LOGE("RegulatorNodeSetVoltage: setVoltage %s fail!", node->regulatorInfo.name);
531         return HDF_FAILURE;
532     }
533 
534     node->regulatorInfo.minUv = minUv;
535     node->regulatorInfo.maxUv = maxUv;
536     (void)OsalMutexUnlock(&node->lock);
537 
538     return HDF_SUCCESS;
539 }
540 
RegulatorNodeGetVoltage(struct RegulatorNode * node,uint32_t * voltage)541 int32_t RegulatorNodeGetVoltage(struct RegulatorNode *node, uint32_t *voltage)
542 {
543     CHECK_NULL_PTR_RETURN_VALUE(node, HDF_ERR_INVALID_PARAM);
544     CHECK_NULL_PTR_RETURN_VALUE(voltage, HDF_ERR_INVALID_PARAM);
545 
546     if (node->regulatorInfo.constraints.mode != REGULATOR_CHANGE_VOLTAGE) {
547         HDF_LOGE("RegulatorNodeSetVoltage: %s mode %hhu is invalid!",
548             node->regulatorInfo.name, node->regulatorInfo.constraints.mode);
549         return HDF_FAILURE;
550     }
551 
552     int ret = node->ops->getVoltage(node, voltage);
553     if (ret != HDF_SUCCESS) {
554         HDF_LOGE("RegulatorNodeGetVoltage: getVoltage %s fail!", node->regulatorInfo.name);
555         return HDF_FAILURE;
556     }
557 
558     return HDF_SUCCESS;
559 }
560 
RegulatorNodeSetCurrent(struct RegulatorNode * node,uint32_t minUA,uint32_t maxUA)561 int32_t RegulatorNodeSetCurrent(struct RegulatorNode *node, uint32_t minUA, uint32_t maxUA)
562 {
563     CHECK_NULL_PTR_RETURN_VALUE(node, HDF_ERR_INVALID_PARAM);
564     if (node->regulatorInfo.constraints.mode != REGULATOR_CHANGE_CURRENT) {
565         HDF_LOGE("RegulatorNodeSetVoltage: %s mode %hhu invalid!",
566             node->regulatorInfo.name, node->regulatorInfo.constraints.mode);
567         return HDF_FAILURE;
568     }
569 
570     if (minUA == node->regulatorInfo.minUa && maxUA == node->regulatorInfo.maxUa) {
571         return HDF_SUCCESS;
572     }
573 
574     if ((minUA > maxUA) ||
575         (minUA < node->regulatorInfo.constraints.minUa ||
576         maxUA > node->regulatorInfo.constraints.maxUa)) {
577         HDF_LOGE("RegulatorNodeSetCurrent: %s UA [%u, %u] invalid!",
578             node->regulatorInfo.name, minUA, maxUA);
579         return HDF_FAILURE;
580     }
581 
582     if (OsalMutexLock(&node->lock) != HDF_SUCCESS) {
583         HDF_LOGE("RegulatorNodeSetCurrent: lock regulator %s fail!", node->regulatorInfo.name);
584         return HDF_ERR_DEVICE_BUSY;
585     }
586 
587     int ret = node->ops->setCurrent(node, minUA, maxUA);
588     if (ret != HDF_SUCCESS) {
589         (void)OsalMutexUnlock(&node->lock);
590         HDF_LOGE("RegulatorNodeSetCurrent: setCurrent %s fail!", node->regulatorInfo.name);
591         return HDF_FAILURE;
592     }
593 
594     node->regulatorInfo.minUa = minUA;
595     node->regulatorInfo.maxUa = maxUA;
596     (void)OsalMutexUnlock(&node->lock);
597     return HDF_SUCCESS;
598 }
599 
RegulatorNodeGetCurrent(struct RegulatorNode * node,uint32_t * regCurrent)600 int32_t RegulatorNodeGetCurrent(struct RegulatorNode *node, uint32_t *regCurrent)
601 {
602     CHECK_NULL_PTR_RETURN_VALUE(node, HDF_ERR_INVALID_OBJECT);
603     CHECK_NULL_PTR_RETURN_VALUE(regCurrent, HDF_ERR_INVALID_OBJECT);
604     if (node->regulatorInfo.constraints.mode != REGULATOR_CHANGE_CURRENT) {
605         HDF_LOGE("RegulatorNodeGetCurrent: %s mode %hhu is invalid!",
606             node->regulatorInfo.name, node->regulatorInfo.constraints.mode);
607         return HDF_FAILURE;
608     }
609 
610     int ret = node->ops->getCurrent(node, regCurrent);
611     if (ret != HDF_SUCCESS) {
612         HDF_LOGE("RegulatorNodeGetCurrent: getCurrent %s fail!", node->regulatorInfo.name);
613         return HDF_FAILURE;
614     }
615 
616     return HDF_SUCCESS;
617 }
618 
RegulatorNodeGetStatus(struct RegulatorNode * node,uint32_t * status)619 int32_t RegulatorNodeGetStatus(struct RegulatorNode *node, uint32_t *status)
620 {
621     CHECK_NULL_PTR_RETURN_VALUE(node, HDF_ERR_INVALID_OBJECT);
622     CHECK_NULL_PTR_RETURN_VALUE(status, HDF_ERR_INVALID_OBJECT);
623     if (node->ops->getStatus(node, status) != HDF_SUCCESS) {
624         HDF_LOGE("RegulatorNodeGetStatus: getStatus %s fail!", node->regulatorInfo.name);
625         return HDF_FAILURE;
626     }
627 
628     return HDF_SUCCESS;
629 }
630 
RegulatorNodeRegisterStatusChangeCb(struct RegulatorNode * node,RegulatorStatusChangecb cb)631 int32_t RegulatorNodeRegisterStatusChangeCb(struct RegulatorNode *node, RegulatorStatusChangecb cb)
632 {
633     CHECK_NULL_PTR_RETURN_VALUE(node, HDF_ERR_INVALID_OBJECT);
634     CHECK_NULL_PTR_RETURN_VALUE(cb, HDF_ERR_INVALID_OBJECT);
635     node->regulatorInfo.cb = cb;
636     return HDF_SUCCESS;
637 }
638 
RegulatorTreeInfoInit(struct RegulatorNode * node)639 int32_t RegulatorTreeInfoInit(struct RegulatorNode *node)
640 {
641     struct RegulatorNode *pos = NULL;
642     struct RegulatorNode *tmp = NULL;
643     CHECK_NULL_PTR_RETURN_VALUE(node, HDF_ERR_INVALID_OBJECT);
644     struct RegulatorManager *manager = g_regulatorManager;
645     CHECK_NULL_PTR_RETURN_VALUE(manager, HDF_ERR_INVALID_OBJECT);
646 
647     if ((node->regulatorInfo.parentName != NULL)
648         && (strlen(node->regulatorInfo.parentName) > 0)) {
649         DLIST_FOR_EACH_ENTRY_SAFE(pos, tmp, &manager->regulatorHead, struct RegulatorNode, node) {
650             if (strcmp(node->regulatorInfo.parentName, pos->regulatorInfo.name) == 0) {
651                 if (RegulatorTreeSet(node->regulatorInfo.name, node, pos) != HDF_SUCCESS) {
652                     HDF_LOGE("RegulatorTreeInfoInit: RegulatorTreeSet fail!");
653                     return HDF_FAILURE;
654                 } else {
655                     HDF_LOGI("RegulatorTreeInfoInit:regulator [%s] RegulatorTreeSet success!",
656                         node->regulatorInfo.name);
657                     return HDF_SUCCESS;
658                 }
659             }
660         }
661 
662         HDF_LOGE("RegulatorTreeInfoInit: RegulatorTreeSet find %s parent %s error",
663             node->regulatorInfo.name, node->regulatorInfo.parentName);
664         return HDF_FAILURE;
665     }
666     return HDF_SUCCESS;
667 }
668 
RegulatorManagerBind(struct HdfDeviceObject * device)669 static int32_t RegulatorManagerBind(struct HdfDeviceObject *device)
670 {
671     int32_t ret;
672     struct RegulatorManager *manager = NULL;
673 
674     HDF_LOGI("RegulatorManagerBind: enter!");
675     CHECK_NULL_PTR_RETURN_VALUE(device, HDF_ERR_INVALID_OBJECT);
676 
677     manager = (struct RegulatorManager *)OsalMemCalloc(sizeof(*manager));
678     if (manager == NULL) {
679         HDF_LOGE("RegulatorManagerBind: malloc manager fail!");
680         return HDF_ERR_MALLOC_FAIL;
681     }
682 
683     ret = OsalMutexInit(&manager->lock);
684     if (ret != HDF_SUCCESS) {
685         HDF_LOGE("RegulatorManagerBind: mutex init fail, ret: %d!", ret);
686         OsalMemFree(manager);
687         return HDF_FAILURE;
688     }
689 
690     manager->device = device;
691     device->service = &manager->service;
692     DListHeadInit(&manager->regulatorHead);
693     g_regulatorManager = manager;
694 
695     if (RegulatorTreeManagerInit() != HDF_SUCCESS) {
696         HDF_LOGE("RegulatorManagerBind: RegulatorTreeManagerInit init fail!");
697         OsalMemFree(manager);
698         return HDF_FAILURE;
699     }
700     HDF_LOGI("RegulatorManagerBind: success!");
701     return HDF_SUCCESS;
702 }
703 
RegulatorManagerInit(struct HdfDeviceObject * device)704 static int32_t RegulatorManagerInit(struct HdfDeviceObject *device)
705 {
706     (void)device;
707 
708     HDF_LOGI("RegulatorManagerInit: success!");
709     return HDF_SUCCESS;
710 }
711 
RegulatorManagerRelease(struct HdfDeviceObject * device)712 static void RegulatorManagerRelease(struct HdfDeviceObject *device)
713 {
714     HDF_LOGI("RegulatorManagerRelease: enter!");
715     CHECK_NULL_PTR_RETURN(device);
716 
717     if (RegulatorNodeRemoveAll() != HDF_SUCCESS) {
718         HDF_LOGE("RegulatorManagerRelease: RegulatorNodeRemoveAll fail!");
719         return;
720     }
721 
722     struct RegulatorManager *manager = (struct RegulatorManager *)device->service;
723     CHECK_NULL_PTR_RETURN(manager);
724     OsalMutexDestroy(&manager->lock);
725     OsalMemFree(manager);
726     g_regulatorManager = NULL;
727 
728     if (RegulatorTreeManagerDestory() != HDF_SUCCESS) {
729         HDF_LOGE("RegulatorManagerRelease: RegulatorTreeManagerDestory fail!");
730         return;
731     }
732 }
733 
734 struct HdfDriverEntry g_regulatorManagerEntry = {
735     .moduleVersion = 1,
736     .Bind = RegulatorManagerBind,
737     .Init = RegulatorManagerInit,
738     .Release = RegulatorManagerRelease,
739     .moduleName = "HDF_PLATFORM_REGULATOR_MANAGER",
740 };
741 
742 HDF_INIT(g_regulatorManagerEntry);
743