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