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  /* hcs topology for example
10 dev  ---+-> Regulator-1(voltage) -+-> Regulator-2(voltage) -+-> Regulator-3(voltage) -+-> Regulator-4(voltage)
11            |                              |
12            |                              | -+-> Regulator-5(voltage) -+-> Regulator-6(voltage) -+-> Regulator-7(voltage) -+-> Regulator-8(voltage)
13            |                                       |
14            |                                       | -+-> Regulator-9
15            |
16          ---+-> Regulator-10(current)
17            |
18            |
19          ---+-> Regulator-11(current) -+-> Regulator-12(current) -+-> Regulator-14(current)
20            |                                   |
21            |                                   | -+-> Regulator-13(current)
22 */
23 
24 #include "device_resource_if.h"
25 #include "hdf_log.h"
26 #include "osal_mem.h"
27 #include "regulator/regulator_core.h"
28 
29 #define HDF_LOG_TAG regulator_virtual
30 #define VOLTAGE_2500_UV 2500
31 #define CURRENT_2500_UA 2500
32 
VirtualRegulatorEnable(struct RegulatorNode * node)33 static int32_t VirtualRegulatorEnable(struct RegulatorNode *node)
34 {
35     if (node == NULL) {
36         HDF_LOGE("VirtualRegulatorEnable node null\n");
37         return HDF_ERR_INVALID_OBJECT;
38     }
39 
40     node->regulatorInfo.status = REGULATOR_STATUS_ON;
41     HDF_LOGD("VirtualRegulatorEnable %s success !\n", node->regulatorInfo.name);
42     return HDF_SUCCESS;
43 }
44 
VirtualRegulatorDisable(struct RegulatorNode * node)45 static int32_t VirtualRegulatorDisable(struct RegulatorNode *node)
46 {
47     if (node == NULL) {
48         HDF_LOGE("VirtualRegulatorDisable node null\n");
49         return HDF_ERR_INVALID_OBJECT;
50     }
51 
52     node->regulatorInfo.status = REGULATOR_STATUS_OFF;
53     HDF_LOGD("VirtualRegulatorDisable %s success !\n", node->regulatorInfo.name);
54     return HDF_SUCCESS;
55 }
56 
VirtualRegulatorSetVoltage(struct RegulatorNode * node,uint32_t minUv,uint32_t maxUv)57 static int32_t VirtualRegulatorSetVoltage(struct RegulatorNode *node, uint32_t minUv, uint32_t maxUv)
58 {
59     if (node == NULL) {
60         HDF_LOGE("VirtualRegulatorEnable node null\n");
61         return HDF_ERR_INVALID_OBJECT;
62     }
63 
64     HDF_LOGD("VirtualRegulatorSetVoltage %s [%u, %u] success!\n",
65         node->regulatorInfo.name, minUv, maxUv);
66     return HDF_SUCCESS;
67 }
68 
VirtualRegulatorGetVoltage(struct RegulatorNode * node,uint32_t * voltage)69 static int32_t VirtualRegulatorGetVoltage(struct RegulatorNode *node, uint32_t *voltage)
70 {
71     if (node == NULL || voltage == NULL) {
72         HDF_LOGE("VirtualRegulatorGetVoltage param null\n");
73         return HDF_ERR_INVALID_OBJECT;
74     }
75 
76     *voltage = VOLTAGE_2500_UV;
77     HDF_LOGD("VirtualRegulatorGetVoltage get %s %d success !\n", node->regulatorInfo.name, *voltage);
78     return HDF_SUCCESS;
79 }
80 
VirtualRegulatorSetCurrent(struct RegulatorNode * node,uint32_t minUa,uint32_t maxUa)81 static int32_t VirtualRegulatorSetCurrent(struct RegulatorNode *node, uint32_t minUa, uint32_t maxUa)
82 {
83     if (node == NULL) {
84         HDF_LOGE("VirtualRegulatorSetCurrent node null\n");
85         return HDF_ERR_INVALID_OBJECT;
86     }
87 
88     HDF_LOGD("VirtualRegulatorSetCurrent %s [%d, %d] success!\n",
89         node->regulatorInfo.name, minUa, maxUa);
90     return HDF_SUCCESS;
91 }
92 
VirtualRegulatorGetCurrent(struct RegulatorNode * node,uint32_t * current)93 static int32_t VirtualRegulatorGetCurrent(struct RegulatorNode *node, uint32_t *current)
94 {
95     if (node == NULL || current == NULL) {
96         HDF_LOGE("VirtualRegulatorGetCurrent param null\n");
97         return HDF_ERR_INVALID_OBJECT;
98     }
99 
100     *current = CURRENT_2500_UA;
101     HDF_LOGD("VirtualRegulatorGetCurrent get %s %u success !\n", node->regulatorInfo.name, *current);
102     return HDF_SUCCESS;
103 }
104 
VirtualRegulatorGetStatus(struct RegulatorNode * node,uint32_t * status)105 static int32_t VirtualRegulatorGetStatus(struct RegulatorNode *node, uint32_t *status)
106 {
107     if (node == NULL || status == NULL) {
108         HDF_LOGE("VirtualRegulatorGetStatus param null\n");
109         return HDF_ERR_INVALID_OBJECT;
110     }
111 
112     *status = node->regulatorInfo.status;
113     HDF_LOGD("VirtualRegulatorGetStatus get %s %d success !\n", node->regulatorInfo.name, *status);
114     return HDF_SUCCESS;
115 }
116 
117 static struct RegulatorMethod g_method = {
118     .enable = VirtualRegulatorEnable,
119     .disable = VirtualRegulatorDisable,
120     .setVoltage = VirtualRegulatorSetVoltage,
121     .getVoltage = VirtualRegulatorGetVoltage,
122     .setCurrent = VirtualRegulatorSetCurrent,
123     .getCurrent = VirtualRegulatorGetCurrent,
124     .getStatus = VirtualRegulatorGetStatus,
125 };
126 
VirtualRegulatorContinueReadHcs(struct RegulatorNode * regNode,const struct DeviceResourceNode * node)127 static int32_t VirtualRegulatorContinueReadHcs(struct RegulatorNode *regNode, const struct DeviceResourceNode *node)
128 {
129     int32_t ret;
130     struct DeviceResourceIface *drsOps = NULL;
131 
132     HDF_LOGD("VirtualRegulatorContinueReadHcs enter!");
133 
134     drsOps = DeviceResourceGetIfaceInstance(HDF_CONFIG_SOURCE);
135     if (drsOps == NULL || drsOps->GetString == NULL) {
136         HDF_LOGE("VirtualRegulatorContinueReadHcs: invalid drs ops fail!");
137         return HDF_FAILURE;
138     }
139 
140     ret = drsOps->GetUint32(node, "minUv", &regNode->regulatorInfo.constraints.minUv, 0);
141     if (ret != HDF_SUCCESS) {
142         HDF_LOGE("VirtualRegulatorContinueReadHcs: read minUv fail, ret: %d!", ret);
143         return ret;
144     }
145 
146     ret = drsOps->GetUint32(node, "maxUv", &regNode->regulatorInfo.constraints.maxUv, 0);
147     if (ret != HDF_SUCCESS) {
148         HDF_LOGE("VirtualRegulatorContinueReadHcs: read maxUv fail, ret: %d!", ret);
149         return ret;
150     }
151 
152     ret = drsOps->GetUint32(node, "minUa", &regNode->regulatorInfo.constraints.minUa, 0);
153     if (ret != HDF_SUCCESS) {
154         HDF_LOGE("VirtualRegulatorContinueReadHcs: read minUa fail, ret: %d!", ret);
155         return ret;
156     }
157 
158     ret = drsOps->GetUint32(node, "maxUa", &regNode->regulatorInfo.constraints.maxUa, 0);
159     if (ret != HDF_SUCCESS) {
160         HDF_LOGE("VirtualRegulatorContinueReadHcs: read maxUa fail, ret: %d!", ret);
161         return ret;
162     }
163 
164     HDF_LOGD("VirtualRegulatorContinueReadHcs: regulatorInfo:[%s][%d][%d]--[%d][%d]--[%d][%d]!",
165         regNode->regulatorInfo.name, regNode->regulatorInfo.constraints.alwaysOn,
166         regNode->regulatorInfo.constraints.mode,
167         regNode->regulatorInfo.constraints.minUv, regNode->regulatorInfo.constraints.maxUv,
168         regNode->regulatorInfo.constraints.minUa, regNode->regulatorInfo.constraints.maxUa);
169 
170     return HDF_SUCCESS;
171 }
172 
VirtualRegulatorReadHcs(struct RegulatorNode * regNode,const struct DeviceResourceNode * node)173 static int32_t VirtualRegulatorReadHcs(struct RegulatorNode *regNode, const struct DeviceResourceNode *node)
174 {
175     int32_t ret;
176     struct DeviceResourceIface *drsOps = NULL;
177 
178     HDF_LOGD("VirtualRegulatorReadHcs enter:");
179 
180     drsOps = DeviceResourceGetIfaceInstance(HDF_CONFIG_SOURCE);
181     if (drsOps == NULL || drsOps->GetString == NULL) {
182         HDF_LOGE("VirtualRegulatorReadHcs: invalid drs ops fail!");
183         return HDF_FAILURE;
184     }
185 
186     ret = drsOps->GetString(node, "name", &(regNode->regulatorInfo.name), "ERROR");
187     if (ret != HDF_SUCCESS) {
188         HDF_LOGE("VirtualRegulatorReadHcs: read name fail, ret: %d!", ret);
189         return ret;
190     }
191     if (regNode->regulatorInfo.name != NULL) {
192         HDF_LOGD("VirtualRegulatorReadHcs:name[%s]", regNode->regulatorInfo.name);
193     } else {
194         HDF_LOGE("VirtualRegulatorReadHcs:name is null!");
195         return HDF_FAILURE;
196     }
197 
198     ret = drsOps->GetString(node, "parentName", &(regNode->regulatorInfo.parentName), "ERROR");
199     if (ret != HDF_SUCCESS) {
200         HDF_LOGE("VirtualRegulatorReadHcs: read parentName fail, ret: %d!", ret);
201         return ret;
202     }
203     if (regNode->regulatorInfo.parentName != NULL) {
204         HDF_LOGD("VirtualRegulatorReadHcs:parentName[%s]", regNode->regulatorInfo.parentName);
205     }
206 
207     regNode->regulatorInfo.constraints.alwaysOn = drsOps->GetBool(node, "alwaysOn");
208     HDF_LOGD("VirtualRegulatorReadHcs:alwaysOn[%d]", regNode->regulatorInfo.constraints.alwaysOn);
209 
210     ret = drsOps->GetUint8(node, "mode", &regNode->regulatorInfo.constraints.mode, 0);
211     if (ret != HDF_SUCCESS) {
212         HDF_LOGE("VirtualRegulatorReadHcs: read mode fail, ret: %d!", ret);
213         return ret;
214     }
215 
216     if (VirtualRegulatorContinueReadHcs(regNode, node) != HDF_SUCCESS) {
217         return HDF_FAILURE;
218     }
219 
220     return HDF_SUCCESS;
221 }
222 
VirtualRegulatorParseAndInit(struct HdfDeviceObject * device,const struct DeviceResourceNode * node)223 static int32_t VirtualRegulatorParseAndInit(struct HdfDeviceObject *device, const struct DeviceResourceNode *node)
224 {
225     int32_t ret;
226     struct RegulatorNode *regNode = NULL;
227     (void)device;
228 
229     regNode = (struct RegulatorNode *)OsalMemCalloc(sizeof(*regNode));
230     if (regNode == NULL) {
231         HDF_LOGE("VirtualRegulatorParseAndInit: malloc node fail!");
232         return HDF_ERR_MALLOC_FAIL;
233     }
234 
235     HDF_LOGD("VirtualRegulatorParseAndInit");
236 
237     ret = VirtualRegulatorReadHcs(regNode, node);
238     if (ret != HDF_SUCCESS) {
239         HDF_LOGE("VirtualRegulatorParseAndInit: read drs fail, ret: %d!", ret);
240         OsalMemFree(regNode);
241         regNode = NULL;
242         return ret;
243     }
244 
245     regNode->priv = (void *)node;
246     regNode->ops = &g_method;
247 
248     ret = RegulatorNodeAdd(regNode);
249     if (ret != HDF_SUCCESS) {
250         HDF_LOGE("VirtualRegulatorParseAndInit: add regulator controller fail, ret: %d!", ret);
251         OsalMemFree(regNode);
252         regNode = NULL;
253         return ret;
254     }
255     return HDF_SUCCESS;
256 }
257 
VirtualRegulatorInit(struct HdfDeviceObject * device)258 static int32_t VirtualRegulatorInit(struct HdfDeviceObject *device)
259 {
260     int32_t ret;
261     const struct DeviceResourceNode *childNode = NULL;
262 
263     if (device == NULL || device->property == NULL) {
264         HDF_LOGE("VirtualRegulatorInit: device or property is null!");
265         return HDF_ERR_INVALID_OBJECT;
266     }
267 
268     DEV_RES_NODE_FOR_EACH_CHILD_NODE(device->property, childNode) {
269         ret = VirtualRegulatorParseAndInit(device, childNode);
270         if (ret != HDF_SUCCESS) {
271             HDF_LOGE("VirtualRegulatorInit: VirtualRegulatorParseAndInit fail, ret: %d!", ret);
272             return ret;
273         }
274     }
275     HDF_LOGI("VirtualRegulatorInit: success!");
276     return HDF_SUCCESS;
277 }
278 
VirtualRegulatorRelease(struct HdfDeviceObject * device)279 static void VirtualRegulatorRelease(struct HdfDeviceObject *device)
280 {
281     HDF_LOGI("VirtualRegulatorRelease: enter!");
282 
283     if (device == NULL || device->property == NULL) {
284         HDF_LOGE("VirtualRegulatorRelease: device or property is null!");
285         return;
286     }
287 
288     RegulatorNodeRemoveAll();
289 }
290 
291 struct HdfDriverEntry g_regulatorDriverEntry = {
292     .moduleVersion = 1,
293     .moduleName = "virtual_regulator_driver",
294     .Init = VirtualRegulatorInit,
295     .Release = VirtualRegulatorRelease,
296 };
297 HDF_INIT(g_regulatorDriverEntry);
298