• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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