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 "i2s_test.h"
10 #include <unistd.h>
11 #include "device_resource_if.h"
12 #include "hdf_base.h"
13 #include "hdf_log.h"
14 #include "i2s_if.h"
15 #include "osal_file.h"
16 #include "osal_mem.h"
17 #include "osal_test_type.h"
18 #include "osal_time.h"
19 
20 #define HDF_LOG_TAG i2s_test_c
21 
22 #define TEST_READ_FILE_PATH_NAME "/nfs/i2s.wav"
23 #define TEST_WRITE_FILE_PATH_NAME "/nfs/i2s1.wav"
24 #define I2S_DATA_BUF_SIZE               0x1000
25 
26 struct I2sTestFunc {
27     enum I2sTestCmd type;
28     int32_t (*Func)(struct I2sTest *test);
29 };
30 
I2sSetCfgTest(struct I2sTest * test)31 static int32_t I2sSetCfgTest(struct I2sTest *test)
32 {
33     if (test == NULL) {
34         HDF_LOGE("I2sSetCfgTest: test is null!");
35         return HDF_ERR_INVALID_OBJECT;
36     }
37 
38     HDF_LOGD("I2sSetCfgTest: sampleRate[%u], type[%u], channelMode[%u], samplePrecision[%u], \
39         channelIfMode[%u], mclk[%u], bclk[%u], writeChannel[%u], i2slFsSel[%u]",
40         test->sampleRate, test->type, test->channelMode, test->samplePrecision,
41         test->channelIfMode, test->mclk, test->bclk, test->writeChannel, test->i2slFsSel);
42 
43     struct I2sCfg cfg;
44     cfg.sampleRate = test->sampleRate;
45     cfg.type = test->type;
46     cfg.channelMode = test->channelMode;
47     cfg.samplePrecision = test->samplePrecision;
48     cfg.channelIfMode = test->channelIfMode;
49     cfg.mclk = test->mclk;
50     cfg.bclk = test->bclk;
51     cfg.writeChannel = test->writeChannel;
52     cfg.i2slFsSel = test->i2slFsSel;
53     cfg.width = I2S_WORDWIDTH_16BIT;
54 
55     I2sSetCfg(test->handle, &cfg);
56     return HDF_SUCCESS;
57 }
58 
I2sGetCfgTest(struct I2sTest * test)59 static int32_t I2sGetCfgTest(struct I2sTest *test)
60 {
61     if (test == NULL) {
62         HDF_LOGE("I2sGetCfgTest: test is null!");
63         return HDF_ERR_INVALID_OBJECT;
64     }
65 
66     struct I2sCfg cfg;
67     I2sGetCfg(test->handle, &cfg);
68 
69     HDF_LOGD("I2sGetCfgTest: sampleRate[%u], type[%u], channelMode[%u], samplePrecision[%u], \
70         channelIfMode[%u], mclk[%u], bclk[%u], writeChannel[%u], i2slFsSel[%u]",
71         test->sampleRate, test->type, test->channelMode, test->samplePrecision,
72         test->channelIfMode, test->mclk, test->bclk, test->writeChannel, test->i2slFsSel);
73     return HDF_SUCCESS;
74 }
75 
I2sOpenTest(struct I2sTest * test)76 static int32_t I2sOpenTest(struct I2sTest *test)
77 {
78     if (test == NULL) {
79         HDF_LOGE("I2sOpenTest: test is null!");
80         return HDF_ERR_INVALID_OBJECT;
81     }
82 
83     return HDF_SUCCESS;
84 }
85 
I2sCloseTest(struct I2sTest * test)86 static int32_t I2sCloseTest(struct I2sTest *test)
87 {
88     if (test == NULL) {
89         HDF_LOGE("I2sCloseTest: test is null!");
90         return HDF_ERR_INVALID_OBJECT;
91     }
92 
93     return HDF_SUCCESS;
94 }
95 
I2sEnableTest(struct I2sTest * test)96 static int32_t I2sEnableTest(struct I2sTest *test)
97 {
98     if (test == NULL || test->handle == NULL || test->wbuf == NULL) {
99         HDF_LOGE("I2sEnableTest: test or handle or wbuf is null!");
100         return HDF_ERR_INVALID_OBJECT;
101     }
102 
103     I2sEnable(test->handle);
104     return HDF_SUCCESS;
105 }
106 
I2sDisableTest(struct I2sTest * test)107 static int32_t I2sDisableTest(struct I2sTest *test)
108 {
109     if (test == NULL || test->handle == NULL || test->wbuf == NULL) {
110         HDF_LOGE("I2sDisableTest: test or handle or wbuf is null!");
111         return HDF_ERR_INVALID_OBJECT;
112     }
113 
114     I2sDisable(test->handle);
115     return HDF_SUCCESS;
116 }
117 
118 #define I2S_WRITE_BUFF_SIZE 0x2000
I2sPlayTest(struct I2sTest * test)119 static int32_t I2sPlayTest(struct I2sTest *test)
120 {
121     if (test == NULL || test->handle == NULL || test->wbuf == NULL) {
122         HDF_LOGE("I2sPlayTest: test or handle or wbuf is null!");
123         return HDF_ERR_INVALID_OBJECT;
124     }
125 
126     OsalFile file;
127     int32_t size = OsalFileOpen(&file, TEST_WRITE_FILE_PATH_NAME, O_CREAT | OSAL_O_RDWR, OSAL_S_IREAD);
128     if (size < 0) {
129         printf("[I2sPlayTest] OsalFileOpen ret[%d] error!\n", size);
130         return HDF_FAILURE;
131     }
132 
133     uint32_t readBuff = I2S_WRITE_BUFF_SIZE;
134     do {
135         size = OsalFileRead(&file, test->wbuf, readBuff);
136         printf("[I2sPlayTest] read file size[%d]", size);
137         if (size > 0) {
138             uint32_t wlen = 0;
139             int ret = I2sWrite(test->handle, test->wbuf, size, &wlen);
140             if (ret != HDF_SUCCESS) {
141                 HDF_LOGE("I2sPlayTest: I2sPlayTest error!");
142                 return HDF_FAILURE;
143             }
144             printf("[I2sPlayTest] [%d] I2sPlayTest wlen[%u]\n", ret, wlen);
145         }
146     } while (size > 0);
147 
148     OsalFileClose(&file);
149     return HDF_SUCCESS;
150 }
151 
152 #define READ_TEST_SLEEP        2
153 #define READ_TEST_TIMES        1000
154 #define READ_TEST_FILE_SIZE    (0x4000 * 10000)
155 
I2sRecordTest(struct I2sTest * test)156 static int32_t I2sRecordTest(struct I2sTest *test)
157 {
158     if (test == NULL || test->handle == NULL || test->rbuf == NULL) {
159         HDF_LOGE("I2sRecordTest: test or handle or rbuf is null!");
160         return HDF_ERR_INVALID_OBJECT;
161     }
162 
163     OsalFile file;
164     int32_t ret = OsalFileOpen(&file, TEST_READ_FILE_PATH_NAME, O_CREAT | OSAL_O_RDWR, OSAL_S_IWRITE);
165     if (ret < 0) {
166         HDF_LOGE("[I2sRecordTest] OsalFileOpen ret[%d] error!\n", ret);
167         return HDF_FAILURE;
168     }
169 
170     int i = 0;
171     uint32_t totalLen = 0;
172     while ((i <= READ_TEST_TIMES) && (totalLen <= READ_TEST_FILE_SIZE)) {
173         test->len = I2S_DATA_BUF_SIZE;
174         (void)memset_s(test->rbuf, I2S_DATA_BUF_SIZE, 0xee, I2S_DATA_BUF_SIZE);
175         if (I2sRead(test->handle, test->rbuf, test->len, &test->len) != HDF_SUCCESS) {
176             HDF_LOGE("I2sRecordTest: I2sRecordTest error!\n");
177             return HDF_FAILURE;
178         }
179         if (test->len == 0) {
180             HDF_LOGD("I2sRecordTest: not available data!\n");
181         } else {
182             totalLen += test->len;
183             ret = OsalFileWrite(&file, test->rbuf, test->len);
184             if (ret < -1) {
185                 HDF_LOGE("I2sRecordTest: write file error!\n");
186                 OsalFileClose(&file);
187                 return HDF_FAILURE;
188             }
189         }
190 
191         i++;
192     }
193 
194     OsalFileClose(&file);
195     return HDF_SUCCESS;
196 }
197 
I2sReadTest(struct I2sTest * test)198 static int32_t I2sReadTest(struct I2sTest *test)
199 {
200     if (test == NULL || test->handle == NULL || test->rbuf == NULL  || test->wbuf == NULL) {
201         HDF_LOGE("I2sReadTest: test or handle or rbuf or wbuf is null!");
202         return HDF_ERR_INVALID_OBJECT;
203     }
204 
205     if (I2sRead(test->handle, test->rbuf, test->len, &test->len) != HDF_SUCCESS) {
206         HDF_LOGE("I2sReadTest: I2sRead error!\n");
207         return HDF_FAILURE;
208     }
209 
210     if (test->len > I2S_DATA_BUF_SIZE) {
211         HDF_LOGE("I2sReadTest: I2sRead read data too large!\n");
212         return HDF_FAILURE;
213     }
214 
215     if (memcpy_s(test->wbuf, I2S_DATA_BUF_SIZE, test->rbuf, test->len) != EOK) {
216         HDF_LOGE("I2sReadTest: memcpy buf fail!");
217         return HDF_ERR_IO;
218     }
219 
220     return HDF_SUCCESS;
221 }
222 
I2sWriteTest(struct I2sTest * test)223 static int32_t I2sWriteTest(struct I2sTest *test)
224 {
225     if (test == NULL || test->handle == NULL || test->wbuf == NULL) {
226         HDF_LOGE("I2sWriteTest: test or handle or wbuf is null!");
227         return HDF_ERR_INVALID_OBJECT;
228     }
229 
230     if (I2sWrite(test->handle, test->wbuf, test->len, &test->len) != HDF_SUCCESS) {
231         HDF_LOGE("I2sWriteTest: I2sWriteTest error!\n");
232         return HDF_FAILURE;
233     }
234 
235     return HDF_SUCCESS;
236 }
237 
238 
I2sWriteStartTest(struct I2sTest * test)239 static int32_t I2sWriteStartTest(struct I2sTest *test)
240 {
241     if (test == NULL || test->handle == NULL) {
242         HDF_LOGE("I2sWriteStartTest: test or handle is null!");
243         return HDF_ERR_INVALID_OBJECT;
244     }
245 
246     I2sStartWrite(test->handle);
247     return HDF_SUCCESS;
248 }
249 
I2sReadStartTest(struct I2sTest * test)250 static int32_t I2sReadStartTest(struct I2sTest *test)
251 {
252     if (test == NULL || test->handle == NULL) {
253         HDF_LOGE("I2sReadStartTest: test or handle is null!");
254         return HDF_ERR_INVALID_OBJECT;
255     }
256 
257     I2sStartRead(test->handle);
258     if (test->rbuf != NULL) {
259         HDF_LOGI("I2sReadStartTest: rbuf[0] = [%u]\n", test->rbuf[0]);
260     }
261 
262     return HDF_SUCCESS;
263 }
264 
I2sWriteStopTest(struct I2sTest * test)265 static int32_t I2sWriteStopTest(struct I2sTest *test)
266 {
267     if (test == NULL || test->handle == NULL) {
268         HDF_LOGE("I2sWriteStopTest: test or handle is null!");
269         return HDF_ERR_INVALID_OBJECT;
270     }
271 
272     I2sStopWrite(test->handle);
273     return HDF_SUCCESS;
274 }
275 
I2sReadStopTest(struct I2sTest * test)276 static int32_t I2sReadStopTest(struct I2sTest *test)
277 {
278     if (test == NULL || test->handle == NULL) {
279         HDF_LOGE("I2sReadStopTest: test or handle is null!");
280         return HDF_ERR_INVALID_OBJECT;
281     }
282 
283     I2sStopRead(test->handle);
284     if (test->rbuf != NULL) {
285         HDF_LOGI("I2sReadStopTest: rbuf[0] = [%u]\n", test->rbuf[0]);
286     }
287 
288     return HDF_SUCCESS;
289 }
290 
I2sReliabilityTest(struct I2sTest * test)291 static int32_t I2sReliabilityTest(struct I2sTest *test)
292 {
293     if (test == NULL || test->handle == NULL) {
294         HDF_LOGE("I2sReliabilityTest: test or handle is null!");
295         return HDF_ERR_INVALID_OBJECT;
296     }
297 
298     (void)I2sSetCfg(test->handle, NULL);
299     (void)I2sReadTest(NULL);
300 
301     (void)test;
302     HDF_LOGD("I2sReliabilityTest: success!");
303     return HDF_SUCCESS;
304 }
305 
306 static struct I2sTestFunc g_i2sTestFunc[] = {
307     {I2S_SET_CFG_TEST, I2sSetCfgTest},
308     {I2S_GET_CFG_TEST, I2sGetCfgTest},
309     {I2S_OPEN_TEST, I2sOpenTest},
310     {I2S_CLOSE_TEST, I2sCloseTest},
311     {I2S_ENABLE_TEST, I2sEnableTest},
312     {I2S_DISABLE_TEST, I2sDisableTest},
313     {I2S_WRITE_START_TEST, I2sWriteStartTest},
314     {I2S_READ_START_TEST, I2sReadStartTest},
315     {I2S_WRITE_TEST, I2sWriteTest},
316     {I2S_READ_TEST, I2sReadTest},
317     {I2S_WRITE_STOP_TEST, I2sWriteStopTest},
318     {I2S_READ_STOP_TEST, I2sReadStopTest},
319     {I2S_RELIABILITY_TEST, I2sReliabilityTest},
320     {I2S_RECORD_TEST, I2sRecordTest},
321     {I2S_PLAY_TEST, I2sPlayTest},
322 };
323 
I2sTestEntry(struct I2sTest * test,int32_t cmd)324 static int32_t I2sTestEntry(struct I2sTest *test, int32_t cmd)
325 {
326     int32_t i;
327     int32_t ret = HDF_ERR_NOT_SUPPORT;
328 
329     HDF_LOGE("I2s test-- -- -- -- -- -->I2sTestEntry: enter cmd %d", cmd);
330 
331     if (test == NULL) {
332         HDF_LOGE("I2sTestEntry: test is null, cmd %d!", cmd);
333         return HDF_ERR_INVALID_OBJECT;
334     }
335 
336     test->handle = I2sOpen(0);
337     if (test->handle == NULL) {
338         HDF_LOGE("I2sTestEntry: i2s test get handle fail!");
339         return HDF_FAILURE;
340     }
341 
342     for (i = 0; i < sizeof(g_i2sTestFunc) / sizeof(g_i2sTestFunc[0]); i++) {
343         if (cmd == g_i2sTestFunc[i].type && g_i2sTestFunc[i].Func != NULL) {
344             ret = g_i2sTestFunc[i].Func(test);
345             HDF_LOGE("I2sTestEntry: cmd %d ret %d", cmd, ret);
346             break;
347         }
348     }
349 
350     I2sClose(test->handle);
351     return ret;
352 }
353 
I2sTestBind(struct HdfDeviceObject * device)354 static int32_t I2sTestBind(struct HdfDeviceObject *device)
355 {
356     static struct I2sTest test;
357 
358     if (device != NULL) {
359         device->service = &test.service;
360     } else {
361         HDF_LOGE("I2sTestBind: device is null!");
362     }
363     return HDF_SUCCESS;
364 }
365 
I2sTestInitBuf(struct I2sTest * test)366 static int32_t I2sTestInitBuf(struct I2sTest *test)
367 {
368     if (test == NULL) {
369         HDF_LOGE("I2sTestInitBuf: test is null!");
370         return HDF_FAILURE;
371     }
372 
373     test->len = I2S_DATA_BUF_SIZE;
374     test->wbuf = (uint8_t *)OsalMemCalloc(test->len);
375     if (test->wbuf == NULL) {
376         HDF_LOGE("I2sTestInitBuf: wbuf OsalMemCalloc error!\n");
377         return HDF_ERR_MALLOC_FAIL;
378     }
379 
380     test->rbuf = (uint8_t *)OsalMemCalloc(test->len);
381     if (test->rbuf == NULL) {
382         HDF_LOGE("I2sTestInitBuf: rbuf OsalMemCalloc error!\n");
383         OsalMemFree(test->wbuf);
384         return HDF_ERR_MALLOC_FAIL;
385     }
386 
387     return HDF_SUCCESS;
388 }
389 
I2sTestInitCodecFromHcs(struct I2sTest * test,const struct DeviceResourceNode * node)390 static int32_t I2sTestInitCodecFromHcs(struct I2sTest *test, const struct DeviceResourceNode *node)
391 {
392     struct DeviceResourceIface *face = NULL;
393 
394     face = DeviceResourceGetIfaceInstance(HDF_CONFIG_SOURCE);
395     if (face == NULL) {
396         HDF_LOGE("I2sTestInitCodecFromHcs: face is null!");
397         return HDF_FAILURE;
398     }
399 
400     int32_t ret = face->GetUint8(node, "writeChannel", &test->writeChannel, 0);
401     if (ret != HDF_SUCCESS) {
402         HDF_LOGE("I2sTestInitCodecFromHcs: read writeChannel fail!");
403         return HDF_FAILURE;
404     }
405     ret = face->GetUint8(node, "i2slFsSel", &test->i2slFsSel, 0);
406     if (ret != HDF_SUCCESS) {
407         HDF_LOGE("I2sTestInitCodecFromHcs: read i2slFsSel fail!");
408         return HDF_FAILURE;
409     }
410 
411     ret = face->GetUint8(node, "channelMode", &test->channelMode, 0);
412     if (ret != HDF_SUCCESS) {
413         HDF_LOGE("I2sTestInitCodecFromHcs: read channelMode fail!");
414         return HDF_FAILURE;
415     }
416     ret = face->GetUint8(node, "channelIfMode", &test->channelIfMode, 0);
417     if (ret != HDF_SUCCESS) {
418         HDF_LOGE("I2sTestInitCodecFromHcs: read channelIfMode fail!");
419         return HDF_FAILURE;
420     }
421 
422     return HDF_SUCCESS;
423 }
424 
I2sTestInitFromHcs(struct I2sTest * test,const struct DeviceResourceNode * node)425 static int32_t I2sTestInitFromHcs(struct I2sTest *test, const struct DeviceResourceNode *node)
426 {
427     int32_t ret;
428     struct DeviceResourceIface *face = NULL;
429 
430     face = DeviceResourceGetIfaceInstance(HDF_CONFIG_SOURCE);
431     if (face == NULL) {
432         HDF_LOGE("I2sTestInitFromHcs: face is null!");
433         return HDF_FAILURE;
434     }
435     if (face->GetUint32 == NULL || face->GetUint32Array == NULL) {
436         HDF_LOGE("I2sTestInitFromHcs: GetUint32 or GetUint32Array not support!");
437         return HDF_ERR_NOT_SUPPORT;
438     }
439     ret = face->GetUint8(node, "sampleRate", &test->sampleRate, 0);
440     if (ret != HDF_SUCCESS) {
441         HDF_LOGE("I2sTestInitFromHcs: read sampleRate fail!");
442         return HDF_FAILURE;
443     }
444     ret = face->GetUint8(node, "type", &test->type, 0);
445     if (ret != HDF_SUCCESS) {
446         HDF_LOGE("I2sTestInitFromHcs: read type fail!");
447         return HDF_FAILURE;
448     }
449     ret = face->GetUint8(node, "samplePrecision", &test->samplePrecision, 0);
450     if (ret != HDF_SUCCESS) {
451         HDF_LOGE("I2sTestInitFromHcs: read samplePrecision fail!");
452         return HDF_FAILURE;
453     }
454     ret = face->GetUint32(node, "MCLK", &test->mclk, 0);
455     if (ret != HDF_SUCCESS) {
456         HDF_LOGE("I2sTestInitFromHcs: read MCLK fail!");
457         return HDF_FAILURE;
458     }
459     ret = face->GetUint32(node, "BCLK", &test->bclk, 0);
460     if (ret != HDF_SUCCESS) {
461         HDF_LOGE("I2sTestInitFromHcs: read BCLK fail!");
462         return HDF_FAILURE;
463     }
464 
465     if (I2sTestInitCodecFromHcs (test, node) != HDF_SUCCESS) {
466         HDF_LOGE("I2sTestInitFromHcs: init codec from hcs fail!");
467         return HDF_FAILURE;
468     }
469 
470     if (I2sTestInitBuf (test) != HDF_SUCCESS) {
471         HDF_LOGE("I2sTestInitFromHcs: init buf fail!");
472         return HDF_FAILURE;
473     }
474     return HDF_SUCCESS;
475 }
476 
I2sTestInit(struct HdfDeviceObject * device)477 static int32_t I2sTestInit(struct HdfDeviceObject *device)
478 {
479     struct I2sTest *test = NULL;
480 
481     if (device == NULL || device->service == NULL || device->property == NULL) {
482         HDF_LOGE("I2sTestInit: invalid parameter!");
483         return HDF_ERR_INVALID_PARAM;
484     }
485     test = (struct I2sTest *)device->service;
486     if (I2sTestInitFromHcs(test, device->property) != HDF_SUCCESS) {
487         HDF_LOGE("I2sTestInit: I2sTestInitFromHcs fail!");
488         return HDF_FAILURE;
489     }
490 
491     HDF_LOGD("I2sTestInit: success!");
492     test->TestEntry = I2sTestEntry;
493     return HDF_SUCCESS;
494 }
495 
I2sTestRelease(struct HdfDeviceObject * device)496 static void I2sTestRelease(struct HdfDeviceObject *device)
497 {
498     struct I2sTest *test = NULL;
499 
500     if (device == NULL) {
501         HDF_LOGE("I2sTestRelease: device is null!");
502         return;
503     }
504     test = (struct I2sTest *)device->service;
505     if (test == NULL) {
506         HDF_LOGE("I2sTestRelease: test is null!");
507         return;
508     }
509     if (test->wbuf != NULL) {
510         OsalMemFree(test->wbuf);
511     }
512     if (test->rbuf != NULL) {
513         OsalMemFree(test->rbuf);
514     }
515 }
516 
517 struct HdfDriverEntry g_i2sTestEntry = {
518     .moduleVersion = 1,
519     .Bind = I2sTestBind,
520     .Init = I2sTestInit,
521     .Release = I2sTestRelease,
522     .moduleName = "PLATFORM_I2S_TEST",
523 };
524 HDF_INIT(g_i2sTestEntry);
525