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 "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("%s: test null", __func__);
35 return HDF_ERR_INVALID_OBJECT;
36 }
37
38 HDF_LOGE("%s:sampleRate[%u], type[%u], channelMode[%u], samplePrecision[%u],\
39 channelIfMode[%u], mclk[%u], bclk[%u], writeChannel[%u], i2slFsSel[%u]", __func__,
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("%s: test null", __func__);
63 return HDF_ERR_INVALID_OBJECT;
64 }
65
66 struct I2sCfg cfg;
67 I2sGetCfg(test->handle, &cfg);
68
69 HDF_LOGE("%s:sampleRate[%u], type[%u], channelMode[%u], samplePrecision[%u],\
70 channelIfMode[%u], mclk[%u], bclk[%u], writeChannel[%u], i2slFsSel[%u]", __func__,
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("%s: test null", __func__);
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("%s: test null", __func__);
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("%s: test null", __func__);
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("%s: test null", __func__);
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("%s: test null", __func__);
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("[%s] OsalFileOpen ret[%d] error\n", __func__, size);
130 return HDF_FAILURE;
131 }
132
133 int32_t totalLen = 0;
134 uint32_t readBuff = I2S_WRITE_BUFF_SIZE;
135 do {
136 size = OsalFileRead(&file, test->wbuf, readBuff);
137 printf("[%s] read file size[%d]", __func__, size);
138 if (size > 0) {
139 totalLen += size;
140 uint32_t wlen = 0;
141 int ret = I2sWrite(test->handle, test->wbuf, size, &wlen);
142 if (ret != HDF_SUCCESS) {
143 HDF_LOGE("%s: I2sPlayTest error", __func__);
144 return HDF_FAILURE;
145 }
146 printf("[%s] [%d] I2sPlayTest wlen[%u]\n", __func__, ret, wlen);
147 }
148 } while (size > 0);
149
150 OsalFileClose(&file);
151 return HDF_SUCCESS;
152 }
153
154 #define READ_TEST_SLEEP 2
155 #define READ_TEST_TIMES 1000
156 #define READ_TEST_FILE_SIZE (0x4000 * 10000)
157
I2sRecordTest(struct I2sTest * test)158 static int32_t I2sRecordTest(struct I2sTest *test)
159 {
160 if (test == NULL || test->handle == NULL || test->rbuf == NULL) {
161 HDF_LOGE("%s: test null", __func__);
162 return HDF_ERR_INVALID_OBJECT;
163 }
164
165 OsalFile file;
166 int32_t ret = OsalFileOpen(&file, TEST_READ_FILE_PATH_NAME, O_CREAT | OSAL_O_RDWR, OSAL_S_IWRITE);
167 if (ret < 0) {
168 HDF_LOGE("[%s] OsalFileOpen ret[%d] error\n", __func__, ret);
169 return HDF_FAILURE;
170 }
171
172 int i = 0;
173 uint32_t totalLen = 0;
174 while ((i <= READ_TEST_TIMES) && (totalLen <= READ_TEST_FILE_SIZE)) {
175 test->len = I2S_DATA_BUF_SIZE;
176 (void)memset_s(test->rbuf, I2S_DATA_BUF_SIZE, 0xee, I2S_DATA_BUF_SIZE);
177 if (I2sRead(test->handle, test->rbuf, test->len, &test->len) != HDF_SUCCESS) {
178 HDF_LOGE("%s: I2sRecordTest error \n", __func__);
179 return HDF_FAILURE;
180 }
181 if (test->len == 0) {
182 HDF_LOGD("%s: not available data.\n", __func__);
183 } else {
184 totalLen += test->len;
185 ret = OsalFileWrite(&file, test->rbuf, test->len);
186 if (ret < -1) {
187 HDF_LOGE("%s: write file error \n", __func__);
188 OsalFileClose(&file);
189 return HDF_FAILURE;
190 }
191 }
192
193 i++;
194 }
195
196 OsalFileClose(&file);
197 return HDF_SUCCESS;
198 }
199
I2sReadTest(struct I2sTest * test)200 static int32_t I2sReadTest(struct I2sTest *test)
201 {
202 if (test == NULL || test->handle == NULL || test->rbuf == NULL || test->wbuf == NULL) {
203 HDF_LOGE("%s: test null", __func__);
204 return HDF_ERR_INVALID_OBJECT;
205 }
206
207 if (I2sRead(test->handle, test->rbuf, test->len, &test->len) != HDF_SUCCESS) {
208 HDF_LOGE("%s: I2sRead error \n", __func__);
209 return HDF_FAILURE;
210 }
211
212 if (test->len > I2S_DATA_BUF_SIZE) {
213 HDF_LOGE("%s:I2sRead read data too large \n", __func__);
214 return HDF_FAILURE;
215 }
216
217 if (memcpy_s(test->wbuf, I2S_DATA_BUF_SIZE, test->rbuf, test->len) != EOK) {
218 HDF_LOGE("%s: memcpy buf failed", __func__);
219 return HDF_ERR_IO;
220 }
221
222 return HDF_SUCCESS;
223 }
224
I2sWriteTest(struct I2sTest * test)225 static int32_t I2sWriteTest(struct I2sTest *test)
226 {
227 if (test == NULL || test->handle == NULL || test->wbuf == NULL) {
228 HDF_LOGE("%s: test null", __func__);
229 return HDF_ERR_INVALID_OBJECT;
230 }
231
232 if (I2sWrite(test->handle, test->wbuf, test->len, &test->len) != HDF_SUCCESS) {
233 HDF_LOGE("%s: I2sWriteTest error \n", __func__);
234 return HDF_FAILURE;
235 }
236
237 return HDF_SUCCESS;
238 }
239
240
I2sWriteStartTest(struct I2sTest * test)241 static int32_t I2sWriteStartTest(struct I2sTest *test)
242 {
243 if (test == NULL || test->handle == NULL) {
244 HDF_LOGE("%s: test null", __func__);
245 return HDF_ERR_INVALID_OBJECT;
246 }
247
248 I2sStartWrite(test->handle);
249 return HDF_SUCCESS;
250 }
251
I2sReadStartTest(struct I2sTest * test)252 static int32_t I2sReadStartTest(struct I2sTest *test)
253 {
254 if (test == NULL || test->handle == NULL) {
255 HDF_LOGE("%s: test null", __func__);
256 return HDF_ERR_INVALID_OBJECT;
257 }
258
259 I2sStartRead(test->handle);
260 if (test->rbuf != NULL) {
261 HDF_LOGI("%s: rbuf[0] = [%u]\n", __func__, test->rbuf[0]);
262 }
263
264 return HDF_SUCCESS;
265 }
266
I2sWriteStopTest(struct I2sTest * test)267 static int32_t I2sWriteStopTest(struct I2sTest *test)
268 {
269 if (test == NULL || test->handle == NULL) {
270 HDF_LOGE("%s: test null", __func__);
271 return HDF_ERR_INVALID_OBJECT;
272 }
273
274 I2sStopWrite(test->handle);
275 return HDF_SUCCESS;
276 }
277
I2sReadStopTest(struct I2sTest * test)278 static int32_t I2sReadStopTest(struct I2sTest *test)
279 {
280 if (test == NULL || test->handle == NULL) {
281 HDF_LOGE("%s: test null", __func__);
282 return HDF_ERR_INVALID_OBJECT;
283 }
284
285 I2sStopRead(test->handle);
286 if (test->rbuf != NULL) {
287 HDF_LOGI("%s: rbuf[0] = [%u]\n", __func__, test->rbuf[0]);
288 }
289
290 return HDF_SUCCESS;
291 }
292
I2sReliabilityTest(struct I2sTest * test)293 static int32_t I2sReliabilityTest(struct I2sTest *test)
294 {
295 if (test == NULL || test->handle == NULL) {
296 HDF_LOGE("%s: test null", __func__);
297 return HDF_ERR_INVALID_OBJECT;
298 }
299
300 (void)I2sSetCfg(test->handle, NULL);
301 (void)I2sReadTest(NULL);
302
303 (void)test;
304 HDF_LOGE("%s: success", __func__);
305 return HDF_SUCCESS;
306 }
307
308 static struct I2sTestFunc g_i2sTestFunc[] = {
309 {I2S_SET_CFG_TEST, I2sSetCfgTest},
310 {I2S_GET_CFG_TEST, I2sGetCfgTest},
311 {I2S_OPEN_TEST, I2sOpenTest},
312 {I2S_CLOSE_TEST, I2sCloseTest},
313 {I2S_ENABLE_TEST, I2sEnableTest},
314 {I2S_DISABLE_TEST, I2sDisableTest},
315 {I2S_WRITE_START_TEST, I2sWriteStartTest},
316 {I2S_READ_START_TEST, I2sReadStartTest},
317 {I2S_WRITE_TEST, I2sWriteTest},
318 {I2S_READ_TEST, I2sReadTest},
319 {I2S_WRITE_STOP_TEST, I2sWriteStopTest},
320 {I2S_READ_STOP_TEST, I2sReadStopTest},
321 {I2S_RELIABILITY_TEST, I2sReliabilityTest},
322 {I2S_RECORD_TEST, I2sRecordTest},
323 {I2S_PLAY_TEST, I2sPlayTest},
324 };
325
I2sTestEntry(struct I2sTest * test,int32_t cmd)326 static int32_t I2sTestEntry(struct I2sTest *test, int32_t cmd)
327 {
328 int32_t i;
329 int32_t ret = HDF_ERR_NOT_SUPPORT;
330
331 HDF_LOGE("I2s test-- -- -- -- -- -->%s: enter cmd %d", __func__, cmd);
332
333 if (test == NULL) {
334 HDF_LOGE("%s: test null cmd %d", __func__, cmd);
335 return HDF_ERR_INVALID_OBJECT;
336 }
337
338 test->handle = I2sOpen(0);
339 if (test->handle == NULL) {
340 HDF_LOGE("%s: i2s test get handle fail", __func__);
341 return HDF_FAILURE;
342 }
343
344 for (i = 0; i < sizeof(g_i2sTestFunc) / sizeof(g_i2sTestFunc[0]); i++) {
345 if (cmd == g_i2sTestFunc[i].type && g_i2sTestFunc[i].Func != NULL) {
346 ret = g_i2sTestFunc[i].Func(test);
347 HDF_LOGE("%s: cmd %d ret %d", __func__, cmd, ret);
348 break;
349 }
350 }
351
352 I2sClose(test->handle);
353 return ret;
354 }
355
I2sTestBind(struct HdfDeviceObject * device)356 static int32_t I2sTestBind(struct HdfDeviceObject *device)
357 {
358 static struct I2sTest test;
359
360 if (device != NULL) {
361 device->service = &test.service;
362 } else {
363 HDF_LOGE("%s: device is NULL", __func__);
364 }
365 return HDF_SUCCESS;
366 }
367
I2sTestInitBuf(struct I2sTest * test)368 static int32_t I2sTestInitBuf(struct I2sTest *test)
369 {
370 if (test == NULL) {
371 HDF_LOGE("%s: test is null", __func__);
372 return HDF_FAILURE;
373 }
374
375 test->len = I2S_DATA_BUF_SIZE;
376 test->wbuf = (uint8_t *)OsalMemCalloc(test->len);
377 if (test->wbuf == NULL) {
378 HDF_LOGE("%s: wbuf OsalMemCalloc error\n", __func__);
379 return HDF_ERR_MALLOC_FAIL;
380 }
381
382 test->rbuf = (uint8_t *)OsalMemCalloc(test->len);
383 if (test->rbuf == NULL) {
384 HDF_LOGE("%s: rbuf OsalMemCalloc error\n", __func__);
385 OsalMemFree(test->wbuf);
386 return HDF_ERR_MALLOC_FAIL;
387 }
388
389 return HDF_SUCCESS;
390 }
391
I2sTestInitCodecFromHcs(struct I2sTest * test,const struct DeviceResourceNode * node)392 static int32_t I2sTestInitCodecFromHcs(struct I2sTest *test, const struct DeviceResourceNode *node)
393 {
394 struct DeviceResourceIface *face = NULL;
395
396 face = DeviceResourceGetIfaceInstance(HDF_CONFIG_SOURCE);
397 if (face == NULL) {
398 HDF_LOGE("%s: face is null", __func__);
399 return HDF_FAILURE;
400 }
401
402 int32_t ret = face->GetUint8(node, "writeChannel", &test->writeChannel, 0);
403 if (ret != HDF_SUCCESS) {
404 HDF_LOGE("%s: read writeChannel fail", __func__);
405 return HDF_FAILURE;
406 }
407 ret = face->GetUint8(node, "i2slFsSel", &test->i2slFsSel, 0);
408 if (ret != HDF_SUCCESS) {
409 HDF_LOGE("%s: read i2slFsSel fail", __func__);
410 return HDF_FAILURE;
411 }
412
413 ret = face->GetUint8(node, "channelMode", &test->channelMode, 0);
414 if (ret != HDF_SUCCESS) {
415 HDF_LOGE("%s: read channelMode fail", __func__);
416 return HDF_FAILURE;
417 }
418 ret = face->GetUint8(node, "channelIfMode", &test->channelIfMode, 0);
419 if (ret != HDF_SUCCESS) {
420 HDF_LOGE("%s: read channelIfMode fail", __func__);
421 return HDF_FAILURE;
422 }
423
424 return HDF_SUCCESS;
425 }
426
I2sTestInitFromHcs(struct I2sTest * test,const struct DeviceResourceNode * node)427 static int32_t I2sTestInitFromHcs(struct I2sTest *test, const struct DeviceResourceNode *node)
428 {
429 int32_t ret;
430 struct DeviceResourceIface *face = NULL;
431
432 face = DeviceResourceGetIfaceInstance(HDF_CONFIG_SOURCE);
433 if (face == NULL) {
434 HDF_LOGE("%s: face is null", __func__);
435 return HDF_FAILURE;
436 }
437 if (face->GetUint32 == NULL || face->GetUint32Array == NULL) {
438 HDF_LOGE("%s: GetUint32 or GetUint32Array not support", __func__);
439 return HDF_ERR_NOT_SUPPORT;
440 }
441 ret = face->GetUint8(node, "sampleRate", &test->sampleRate, 0);
442 if (ret != HDF_SUCCESS) {
443 HDF_LOGE("%s: read sampleRate fail", __func__);
444 return HDF_FAILURE;
445 }
446 ret = face->GetUint8(node, "type", &test->type, 0);
447 if (ret != HDF_SUCCESS) {
448 HDF_LOGE("%s: read type fail", __func__);
449 return HDF_FAILURE;
450 }
451 ret = face->GetUint8(node, "samplePrecision", &test->samplePrecision, 0);
452 if (ret != HDF_SUCCESS) {
453 HDF_LOGE("%s: read samplePrecision fail", __func__);
454 return HDF_FAILURE;
455 }
456 ret = face->GetUint32(node, "MCLK", &test->mclk, 0);
457 if (ret != HDF_SUCCESS) {
458 HDF_LOGE("%s: read MCLK fail", __func__);
459 return HDF_FAILURE;
460 }
461 ret = face->GetUint32(node, "BCLK", &test->bclk, 0);
462 if (ret != HDF_SUCCESS) {
463 HDF_LOGE("%s: read BCLK fail", __func__);
464 return HDF_FAILURE;
465 }
466
467 if (I2sTestInitCodecFromHcs (test, node) != HDF_SUCCESS) {
468 return HDF_FAILURE;
469 }
470
471 if (I2sTestInitBuf (test) != HDF_SUCCESS) {
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("%s: invalid parameter", __func__);
483 return HDF_ERR_INVALID_PARAM;
484 }
485 test = (struct I2sTest *)device->service;
486 if (I2sTestInitFromHcs(test, device->property) != HDF_SUCCESS) {
487 HDF_LOGE("%s: I2sTestInitFromHcs failed", __func__);
488 return HDF_FAILURE;
489 }
490
491 HDF_LOGE("%s: success", __func__);
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 return;
502 }
503 test = (struct I2sTest *)device->service;
504 if (test == NULL) {
505 return;
506 }
507 if (test->wbuf != NULL) {
508 OsalMemFree(test->wbuf);
509 }
510 if (test->rbuf != NULL) {
511 OsalMemFree(test->rbuf);
512 }
513 }
514
515 struct HdfDriverEntry g_i2sTestEntry = {
516 .moduleVersion = 1,
517 .Bind = I2sTestBind,
518 .Init = I2sTestInit,
519 .Release = I2sTestRelease,
520 .moduleName = "PLATFORM_I2S_TEST",
521 };
522 HDF_INIT(g_i2sTestEntry);
523