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", ®Node->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", ®Node->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", ®Node->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", ®Node->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", ®Node->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