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