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