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_test.h"
10 #include "device_resource_if.h"
11 #include "hdf_log.h"
12 #include "osal_thread.h"
13 #include "osal_time.h"
14 #include "securec.h"
15 #include "regulator_if.h"
16 #if defined(CONFIG_DRIVERS_HDF_PLATFORM_REGULATOR)
17 #include "virtual/regulator_linux_voltage_virtual_driver.h"
18 #include "virtual/regulator_linux_current_virtual_driver.h"
19 #endif
20
21 #define HDF_LOG_TAG regulator_test_c
22
23 struct RegulatorTestFunc {
24 enum RegulatorTestCmd type;
25 int32_t (*Func)(struct RegulatorTest *test);
26 };
27
28 enum RegulatorVoltage {
29 VOLTAGE_50_UV = 50,
30 VOLTAGE_250_UV = 250,
31 VOLTAGE_2500_UV = 2500,
32 };
33
34 enum RegulatorCurrent {
35 CURRENT_50_UA = 50,
36 CURRENT_250_UA = 250,
37 };
38
RegulatorEnableTest(struct RegulatorTest * test)39 static int32_t RegulatorEnableTest(struct RegulatorTest *test)
40 {
41 if (test == NULL || test->handle == NULL) {
42 HDF_LOGE("RegulatorEnableTest: test or handle is null!");
43 return HDF_ERR_INVALID_OBJECT;
44 }
45
46 RegulatorEnable(test->handle);
47 return HDF_SUCCESS;
48 }
49
RegulatorDisableTest(struct RegulatorTest * test)50 static int32_t RegulatorDisableTest(struct RegulatorTest *test)
51 {
52 if (test == NULL || test->handle == NULL) {
53 HDF_LOGE("RegulatorDisableTest: test or handle is null!");
54 return HDF_ERR_INVALID_OBJECT;
55 }
56
57 RegulatorDisable(test->handle);
58 return HDF_SUCCESS;
59 }
60
RegulatorForceDisableTest(struct RegulatorTest * test)61 static int32_t RegulatorForceDisableTest(struct RegulatorTest *test)
62 {
63 if (test == NULL || test->handle == NULL) {
64 HDF_LOGE("RegulatorForceDisableTest: test or handle is null!");
65 return HDF_ERR_INVALID_OBJECT;
66 }
67
68 RegulatorForceDisable(test->handle);
69 return HDF_SUCCESS;
70 }
71
RegulatorSetVoltageTest(struct RegulatorTest * test)72 static int32_t RegulatorSetVoltageTest(struct RegulatorTest *test)
73 {
74 if (test == NULL || test->handle == NULL) {
75 HDF_LOGE("RegulatorSetVoltageTest: test or handle is null!");
76 return HDF_ERR_INVALID_OBJECT;
77 }
78
79 if (test->mode != REGULATOR_CHANGE_VOLTAGE) {
80 return HDF_SUCCESS;
81 }
82
83 if (RegulatorSetVoltage(test->handle, test->minUv, test->maxUv) != HDF_SUCCESS) {
84 HDF_LOGE("RegulatorSetVoltageTest: [%d, %d] test fail", test->maxUv, test->minUv);
85 return HDF_FAILURE;
86 }
87
88 return HDF_SUCCESS;
89 }
90
RegulatorGetVoltageTest(struct RegulatorTest * test)91 static int32_t RegulatorGetVoltageTest(struct RegulatorTest *test)
92 {
93 if (test == NULL || test->handle == NULL) {
94 HDF_LOGE("RegulatorGetVoltageTest: test or handle is null!");
95 return HDF_ERR_INVALID_OBJECT;
96 }
97
98 if (test->mode != REGULATOR_CHANGE_VOLTAGE) {
99 return HDF_SUCCESS;
100 }
101
102 if (RegulatorGetVoltage(test->handle, &test->uv) != HDF_SUCCESS) {
103 HDF_LOGE("RegulatorGetVoltageTest: test fail!");
104 return HDF_FAILURE;
105 }
106
107 return HDF_SUCCESS;
108 }
109
RegulatorSetCurrentTest(struct RegulatorTest * test)110 static int32_t RegulatorSetCurrentTest(struct RegulatorTest *test)
111 {
112 if (test == NULL || test->handle == NULL) {
113 HDF_LOGE("RegulatorSetCurrentTest: test or handle is null!");
114 return HDF_ERR_INVALID_OBJECT;
115 }
116
117 if (test->mode != REGULATOR_CHANGE_CURRENT) {
118 return HDF_SUCCESS;
119 }
120
121 if (RegulatorSetCurrent(test->handle, test->minUa, test->maxUa) != HDF_SUCCESS) {
122 HDF_LOGE("RegulatorSetCurrentTest: [%d, %d] test fail!", test->minUa, test->maxUa);
123 return HDF_FAILURE;
124 }
125
126 return HDF_SUCCESS;
127 }
128
RegulatorGetCurrentTest(struct RegulatorTest * test)129 static int32_t RegulatorGetCurrentTest(struct RegulatorTest *test)
130 {
131 if (test == NULL || test->handle == NULL) {
132 HDF_LOGE("RegulatorGetCurrentTest: test or handle is null!");
133 return HDF_ERR_INVALID_OBJECT;
134 }
135
136 if (test->mode != REGULATOR_CHANGE_CURRENT) {
137 return HDF_SUCCESS;
138 }
139
140 if (RegulatorGetCurrent(test->handle, &test->ua) != HDF_SUCCESS) {
141 HDF_LOGE("RegulatorGetCurrentTest: test fail!");
142 return HDF_FAILURE;
143 }
144
145 return HDF_SUCCESS;
146 }
147
RegulatorGetStatusTest(struct RegulatorTest * test)148 static int32_t RegulatorGetStatusTest(struct RegulatorTest *test)
149 {
150 if (test == NULL || test->handle == NULL) {
151 HDF_LOGE("RegulatorGetStatusTest: test or handle is null!");
152 return HDF_ERR_INVALID_OBJECT;
153 }
154
155 if (RegulatorGetStatus(test->handle, &test->status) != HDF_SUCCESS) {
156 HDF_LOGE("RegulatorGetStatusTest: test fail!");
157 return HDF_FAILURE;
158 }
159
160 if ((test->status != REGULATOR_STATUS_ON) && (test->status != REGULATOR_STATUS_OFF)) {
161 HDF_LOGE("RegulatorGetStatusTest: regulator status invalid %d!", test->status);
162 return HDF_FAILURE;
163 }
164
165 return HDF_SUCCESS;
166 }
167
RegulatorTestThreadFunc(void * param)168 static int RegulatorTestThreadFunc(void *param)
169 {
170 DevHandle handle = RegulatorOpen("regulator_virtual_1");
171 if (handle == NULL) {
172 HDF_LOGE("RegulatorTestThreadFunc: regulator test get handle fail!");
173 *((int32_t *)param) = 1;
174 return HDF_FAILURE;
175 }
176
177 if (RegulatorSetVoltage(handle, VOLTAGE_250_UV, VOLTAGE_2500_UV) != HDF_SUCCESS) {
178 HDF_LOGE("RegulatorTestThreadFunc: test fail!");
179 RegulatorClose(handle);
180 *((int32_t *)param) = 1;
181 return HDF_FAILURE;
182 }
183
184 RegulatorClose(handle);
185 *((int32_t *)param) = 1;
186 return HDF_SUCCESS;
187 }
188
RegulatorTestStartThread(struct OsalThread * thread1,struct OsalThread * thread2,const int32_t * count1,const int32_t * count2)189 static int32_t RegulatorTestStartThread(struct OsalThread *thread1, struct OsalThread *thread2,
190 const int32_t *count1, const int32_t *count2)
191 {
192 int32_t ret;
193 uint32_t time = 0;
194 struct OsalThreadParam cfg1;
195 struct OsalThreadParam cfg2;
196
197 if (memset_s(&cfg1, sizeof(cfg1), 0, sizeof(cfg1)) != EOK ||
198 memset_s(&cfg2, sizeof(cfg2), 0, sizeof(cfg2)) != EOK) {
199 HDF_LOGE("RegulatorTestStartThread: memset_s fail!");
200 return HDF_ERR_IO;
201 }
202 cfg1.name = "RegulatorTestThread-1";
203 cfg2.name = "RegulatorTestThread-2";
204 cfg1.priority = cfg2.priority = OSAL_THREAD_PRI_DEFAULT;
205 cfg1.stackSize = cfg2.stackSize = REGULATOR_TEST_STACK_SIZE;
206
207 ret = OsalThreadStart(thread1, &cfg1);
208 if (ret != HDF_SUCCESS) {
209 HDF_LOGE("RegulatorTestStartThread: start test thread1 fail, ret: %d!", ret);
210 return ret;
211 }
212
213 ret = OsalThreadStart(thread2, &cfg2);
214 if (ret != HDF_SUCCESS) {
215 HDF_LOGE("RegulatorTestStartThread: start test thread2 fail, ret: %d!", ret);
216 }
217
218 while (*count1 == 0 || *count2 == 0) {
219 HDF_LOGE("RegulatorTestStartThread: waitting testing Regulator thread finish...");
220 OsalMSleep(REGULATOR_TEST_WAIT_TIMES);
221 time++;
222 if (time > REGULATOR_TEST_WAIT_TIMEOUT) {
223 break;
224 }
225 }
226 return ret;
227 }
228
RegulatorTestMultiThread(struct RegulatorTest * test)229 static int32_t RegulatorTestMultiThread(struct RegulatorTest *test)
230 {
231 int32_t ret;
232 struct OsalThread thread1;
233 struct OsalThread thread2;
234 int32_t count1 = 0;
235 int32_t count2 = 0;
236
237 (void)test;
238 ret = OsalThreadCreate(&thread1, (OsalThreadEntry)RegulatorTestThreadFunc, (void *)&count1);
239 if (ret != HDF_SUCCESS) {
240 HDF_LOGE("RegulatorTestMultiThread: create test thread1 fail, ret: %d!", ret);
241 return ret;
242 }
243
244 ret = OsalThreadCreate(&thread2, (OsalThreadEntry)RegulatorTestThreadFunc, (void *)&count2);
245 if (ret != HDF_SUCCESS) {
246 (void)OsalThreadDestroy(&thread1);
247 HDF_LOGE("RegulatorTestMultiThread: create test thread2 fail, ret: %d!", ret);
248 return ret;
249 }
250
251 ret = RegulatorTestStartThread(&thread1, &thread2, &count1, &count2);
252 if (ret != HDF_SUCCESS) {
253 HDF_LOGE("RegulatorTestMultiThread: test start thread fail, ret: %d!", ret);
254 }
255
256 (void)OsalThreadDestroy(&thread1);
257 (void)OsalThreadDestroy(&thread2);
258 return ret;
259 }
260
RegulatorTestReliability(struct RegulatorTest * test)261 static int32_t RegulatorTestReliability(struct RegulatorTest *test)
262 {
263 HDF_LOGD("RegulatorTestReliability: test for Regulator ...");
264 if (test == NULL || test->handle == NULL) {
265 HDF_LOGE("RegulatorTestReliability: test or handle is null!");
266 return HDF_ERR_INVALID_OBJECT;
267 }
268
269 RegulatorSetVoltage(test->handle, VOLTAGE_250_UV, VOLTAGE_50_UV);
270 RegulatorSetCurrent(test->handle, CURRENT_250_UA, CURRENT_50_UA);
271 RegulatorGetCurrent(test->handle, NULL);
272 return HDF_SUCCESS;
273 }
274
275 static struct RegulatorTestFunc g_regulatorTestFunc[] = {
276 {REGULATOR_ENABLE_TEST, RegulatorEnableTest},
277 {REGULATOR_DISABLE_TEST, RegulatorDisableTest},
278 {REGULATOR_FORCE_DISABLE_TEST, RegulatorForceDisableTest},
279 {REGULATOR_SET_VOLTAGE_TEST, RegulatorSetVoltageTest},
280 {REGULATOR_GET_VOLTAGE_TEST, RegulatorGetVoltageTest},
281 {REGULATOR_SET_CURRENT_TEST, RegulatorSetCurrentTest},
282 {REGULATOR_GET_CURRENT_TEST, RegulatorGetCurrentTest},
283 {REGULATOR_GET_STATUS_TEST, RegulatorGetStatusTest},
284 {REGULATOR_MULTI_THREAD_TEST, RegulatorTestMultiThread},
285 {REGULATOR_RELIABILITY_TEST, RegulatorTestReliability},
286 };
287
RegulatorTestEntry(struct RegulatorTest * test,int32_t cmd)288 static int32_t RegulatorTestEntry(struct RegulatorTest *test, int32_t cmd)
289 {
290 int32_t i;
291 int32_t ret = HDF_ERR_NOT_SUPPORT;
292
293 if (test == NULL || test->name == NULL) {
294 HDF_LOGE("RegulatorTestEntry: test or name is null!");
295 return HDF_ERR_INVALID_OBJECT;
296 }
297
298 if (cmd != REGULATOR_MULTI_THREAD_TEST) {
299 test->handle = RegulatorOpen(test->name);
300 if (test->handle == NULL) {
301 HDF_LOGE("RegulatorTestEntry: regulator test get handle fail!");
302 return HDF_FAILURE;
303 }
304 }
305
306 for (i = 0; i < sizeof(g_regulatorTestFunc) / sizeof(g_regulatorTestFunc[0]); i++) {
307 if (cmd == g_regulatorTestFunc[i].type && g_regulatorTestFunc[i].Func != NULL) {
308 ret = g_regulatorTestFunc[i].Func(test);
309 HDF_LOGD("RegulatorTestEntry: cmd %d ret %d!", cmd, ret);
310 break;
311 }
312 }
313
314 if (cmd != REGULATOR_MULTI_THREAD_TEST) {
315 RegulatorClose(test->handle);
316 }
317 return ret;
318 }
319
RegulatorTestBind(struct HdfDeviceObject * device)320 static int32_t RegulatorTestBind(struct HdfDeviceObject *device)
321 {
322 static struct RegulatorTest test;
323
324 if (device != NULL) {
325 device->service = &test.service;
326 } else {
327 HDF_LOGE("RegulatorTestBind: device is null!");
328 }
329
330 HDF_LOGI("RegulatorTestBind: success!\r\n");
331 return HDF_SUCCESS;
332 }
333
RegulatorTestInitFromHcs(struct RegulatorTest * test,const struct DeviceResourceNode * node)334 static int32_t RegulatorTestInitFromHcs(struct RegulatorTest *test, const struct DeviceResourceNode *node)
335 {
336 int32_t ret;
337 struct DeviceResourceIface *face = NULL;
338
339 face = DeviceResourceGetIfaceInstance(HDF_CONFIG_SOURCE);
340 if (face == NULL) {
341 HDF_LOGE("RegulatorTestInitFromHcs: face is null!");
342 return HDF_FAILURE;
343 }
344 if (face->GetUint32 == NULL || face->GetUint32Array == NULL) {
345 HDF_LOGE("RegulatorTestInitFromHcs: GetUint32 or GetUint32Array not support");
346 return HDF_ERR_NOT_SUPPORT;
347 }
348
349 ret = face->GetString(node, "name", &(test->name), "ERROR");
350 if (ret != HDF_SUCCESS) {
351 HDF_LOGE("RegulatorTestInitFromHcs: read name fail!");
352 return HDF_FAILURE;
353 }
354
355 ret = face->GetUint8(node, "mode", &test->mode, 0);
356 if (ret != HDF_SUCCESS) {
357 HDF_LOGE("RegulatorTestInitFromHcs: read mode fail!");
358 return HDF_FAILURE;
359 }
360
361 ret = face->GetUint32(node, "minUv", &test->minUv, 0);
362 if (ret != HDF_SUCCESS) {
363 HDF_LOGE("RegulatorTestInitFromHcs: read minUv fail!");
364 return HDF_FAILURE;
365 }
366
367 ret = face->GetUint32(node, "maxUv", &test->maxUv, 0);
368 if (ret != HDF_SUCCESS) {
369 HDF_LOGE("RegulatorTestInitFromHcs: read maxUv fail!");
370 return HDF_FAILURE;
371 }
372
373 ret = face->GetUint32(node, "minUa", &test->minUa, 0);
374 if (ret != HDF_SUCCESS) {
375 HDF_LOGE("RegulatorTestInitFromHcs: read minUa fail!");
376 return HDF_FAILURE;
377 }
378
379 ret = face->GetUint32(node, "maxUa", &test->maxUa, 0);
380 if (ret != HDF_SUCCESS) {
381 HDF_LOGE("RegulatorTestInitFromHcs: read maxUa fail!");
382 return HDF_FAILURE;
383 }
384
385 HDF_LOGI("RegulatorTestInitFromHcs: regulator test init:[%s][%d]--[%d][%d]--[%d][%d]!",
386 test->name, test->mode, test->minUv, test->maxUv, test->minUa, test->maxUa);
387
388 return HDF_SUCCESS;
389 }
390
RegulatorTestInit(struct HdfDeviceObject * device)391 static int32_t RegulatorTestInit(struct HdfDeviceObject *device)
392 {
393 struct RegulatorTest *test = NULL;
394
395 HDF_LOGI("RegulatorTestInit: enter!\r\n");
396
397 #if defined(CONFIG_DRIVERS_HDF_PLATFORM_REGULATOR)
398 VirtualVoltageRegulatorAdapterInit();
399 VirtualCurrentRegulatorAdapterInit();
400 #endif
401
402 if (device == NULL || device->service == NULL || device->property == NULL) {
403 HDF_LOGE("RegulatorTestInit: invalid parameter!");
404 return HDF_ERR_INVALID_PARAM;
405 }
406 test = (struct RegulatorTest *)device->service;
407
408 if (RegulatorTestInitFromHcs(test, device->property) != HDF_SUCCESS) {
409 HDF_LOGE("RegulatorTestInit: RegulatorTestInitFromHcs fail!");
410 return HDF_FAILURE;
411 }
412
413 test->TestEntry = RegulatorTestEntry;
414 HDF_LOGI("RegulatorTestInit: success!");
415
416 return HDF_SUCCESS;
417 }
418
RegulatorTestRelease(struct HdfDeviceObject * device)419 static void RegulatorTestRelease(struct HdfDeviceObject *device)
420 {
421 (void)device;
422 }
423
424 struct HdfDriverEntry g_regulatorTestEntry = {
425 .moduleVersion = 1,
426 .Bind = RegulatorTestBind,
427 .Init = RegulatorTestInit,
428 .Release = RegulatorTestRelease,
429 .moduleName = "PLATFORM_REGULATOR_TEST",
430 };
431 HDF_INIT(g_regulatorTestEntry);
432