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