1 /*
2 * Copyright (c) 2021 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 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 [%d, %d] 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 %d 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("%s: invalid drs ops fail!", __func__);
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("%s: read minUv fail!", __func__);
143 return HDF_FAILURE;
144 }
145
146 ret = drsOps->GetUint32(node, "maxUv", ®Node->regulatorInfo.constraints.maxUv, 0);
147 if (ret != HDF_SUCCESS) {
148 HDF_LOGE("%s: read maxUv fail!", __func__);
149 return HDF_FAILURE;
150 }
151
152 ret = drsOps->GetUint32(node, "minUa", ®Node->regulatorInfo.constraints.minUa, 0);
153 if (ret != HDF_SUCCESS) {
154 HDF_LOGE("%s: read minUa fail!", __func__);
155 return HDF_FAILURE;
156 }
157
158 ret = drsOps->GetUint32(node, "maxUa", ®Node->regulatorInfo.constraints.maxUa, 0);
159 if (ret != HDF_SUCCESS) {
160 HDF_LOGE("%s: read maxUa fail!", __func__);
161 return HDF_FAILURE;
162 }
163
164 HDF_LOGD("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("%s: invalid drs ops fail!", __func__);
183 return HDF_FAILURE;
184 }
185
186 ret = drsOps->GetString(node, "name", &(regNode->regulatorInfo.name), "ERROR");
187 if (ret != HDF_SUCCESS) {
188 HDF_LOGE("%s: read name fail!", __func__);
189 return HDF_FAILURE;
190 }
191 if (regNode->regulatorInfo.name != NULL) {
192 HDF_LOGD("VirtualRegulatorReadHcs:name[%s]", regNode->regulatorInfo.name);
193 } else {
194 HDF_LOGE("VirtualRegulatorReadHcs:name 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("%s: read parentName fail!", __func__);
201 return HDF_FAILURE;
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("%s: read mode fail!", __func__);
213 return HDF_FAILURE;
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("%s: malloc node fail!", __func__);
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("%s: read drs fail! ret:%d", __func__, ret);
240 if (regNode != NULL) {
241 OsalMemFree(regNode);
242 regNode = NULL;
243 }
244 return ret;
245 }
246
247 regNode->priv = (void *)node;
248 regNode->ops = &g_method;
249
250 ret = RegulatorNodeAdd(regNode);
251 if (ret != HDF_SUCCESS) {
252 HDF_LOGE("%s: add regulator controller fail:%d!", __func__, ret);
253 if (regNode != NULL) {
254 OsalMemFree(regNode);
255 regNode = NULL;
256 }
257 return ret;
258 }
259 return HDF_SUCCESS;
260 }
261
VirtualRegulatorInit(struct HdfDeviceObject * device)262 static int32_t VirtualRegulatorInit(struct HdfDeviceObject *device)
263 {
264 int32_t ret;
265 const struct DeviceResourceNode *childNode = NULL;
266
267 if (device == NULL || device->property == NULL) {
268 HDF_LOGE("%s: device or property is NULL", __func__);
269 return HDF_ERR_INVALID_OBJECT;
270 }
271
272 DEV_RES_NODE_FOR_EACH_CHILD_NODE(device->property, childNode) {
273 ret = VirtualRegulatorParseAndInit(device, childNode);
274 if (ret != HDF_SUCCESS) {
275 HDF_LOGE("%s:VirtualRegulatorParseAndInit fail", __func__);
276 return HDF_FAILURE;
277 }
278 }
279 HDF_LOGI("%s: success", __func__);
280 return HDF_SUCCESS;
281 }
282
VirtualRegulatorRelease(struct HdfDeviceObject * device)283 static void VirtualRegulatorRelease(struct HdfDeviceObject *device)
284 {
285 HDF_LOGI("%s: enter", __func__);
286
287 if (device == NULL || device->property == NULL) {
288 HDF_LOGE("%s: device or property is NULL", __func__);
289 return;
290 }
291
292 RegulatorNodeRemoveAll();
293 }
294
295 struct HdfDriverEntry g_regulatorDriverEntry = {
296 .moduleVersion = 1,
297 .moduleName = "virtual_regulator_driver",
298 .Init = VirtualRegulatorInit,
299 .Release = VirtualRegulatorRelease,
300 };
301 HDF_INIT(g_regulatorDriverEntry);
302