1 /*
2 * Copyright (c) 2021 HiSilicon (Shanghai) Technologies CO., LIMITED.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15 #include "i2s_hi35xx.h"
16 #include "i2s_aiao_hi35xx.h"
17 #include "i2s_codec_hi35xx.h"
18 #include "i2s_core.h"
19 #include "device_resource_if.h"
20 #include "hdf_base.h"
21 #include "hdf_log.h"
22 #include "los_vm_phys.h"
23 #include "los_vm_iomap.h"
24 #include "osal_io.h"
25 #include "osal_irq.h"
26 #include "osal_mem.h"
27 #include "osal_sem.h"
28 #include "osal_time.h"
29 #include "platform_dumper.h"
30
31 #define HDF_LOG_TAG i2s_hi35xx
32
I2sDumperDump(struct I2sConfigInfo * configInfo)33 static void I2sDumperDump(struct I2sConfigInfo *configInfo)
34 {
35 int32_t ret;
36 struct PlatformDumperData datas[] = {
37 {"I2S_AIAO_INT_ENA", PLATFORM_DUMPER_REGISTERL, (void *)(configInfo->regBase + I2S_AIAO_INT_ENA)},
38 {"RX_IF_ATTR1", PLATFORM_DUMPER_REGISTERL, (void *)(configInfo->regBase + RX_IF_ATTR1)},
39 {"RX_DSP_CTRL", PLATFORM_DUMPER_REGISTERL, (void *)(configInfo->regBase + RX_DSP_CTRL)},
40 {"RX_BUFF_SIZE", PLATFORM_DUMPER_REGISTERL, (void *)(configInfo->regBase + RX_BUFF_SIZE)},
41 {"RX_BUFF_WPTR", PLATFORM_DUMPER_REGISTERL, (void *)(configInfo->regBase + RX_BUFF_WPTR)},
42 {"RX_BUFF_RPTR", PLATFORM_DUMPER_REGISTERL, (void *)(configInfo->regBase + RX_BUFF_RPTR)},
43 {"RX_TRANS_SIZE", PLATFORM_DUMPER_REGISTERL, (void *)(configInfo->regBase + RX_TRANS_SIZE)},
44 {"RX_INT_ENA", PLATFORM_DUMPER_REGISTERL, (void *)(configInfo->regBase + RX_INT_ENA)},
45 {"RX_INT_STATUS", PLATFORM_DUMPER_REGISTERL, (void *)(configInfo->regBase + RX_INT_STATUS)},
46 {"RX_INT_CLR", PLATFORM_DUMPER_REGISTERL, (void *)(configInfo->regBase + RX_INT_CLR)},
47 {"TX_IF_ATTR1", PLATFORM_DUMPER_REGISTERL, (void *)(configInfo->regBase + TX_IF_ATTR1)},
48 {"TX_DSP_CTRL", PLATFORM_DUMPER_REGISTERL, (void *)(configInfo->regBase + TX_DSP_CTRL)},
49 {"TX_BUFF_SADDR", PLATFORM_DUMPER_REGISTERL, (void *)(configInfo->regBase + TX_BUFF_SADDR)},
50 {"TX_BUFF_SIZE", PLATFORM_DUMPER_REGISTERL, (void *)(configInfo->regBase + TX_BUFF_SIZE)},
51 {"TX_BUFF_WPTR", PLATFORM_DUMPER_REGISTERL, (void *)(configInfo->regBase + TX_BUFF_WPTR)},
52 {"TX_BUFF_RPTR", PLATFORM_DUMPER_REGISTERL, (void *)(configInfo->regBase + TX_BUFF_RPTR)},
53 {"TX_TRANS_SIZE", PLATFORM_DUMPER_REGISTERL, (void *)(configInfo->regBase + TX_TRANS_SIZE)},
54 {"AUDIO_CTRL_REG_1", PLATFORM_DUMPER_REGISTERL, (void *)(configInfo->regBase + AUDIO_CTRL_REG_1)},
55 {"AUDIO_DAC_REG_0", PLATFORM_DUMPER_REGISTERL, (void *)(configInfo->regBase + AUDIO_DAC_REG_0)},
56 };
57
58 if (configInfo->dumper == NULL) {
59 HDF_LOGE("%s: configInfo dumper is NULL!", __func__);
60 return;
61 }
62 ret = PlatformDumperAddDatas(configInfo->dumper, datas, sizeof(datas) / sizeof(struct PlatformDumperData));
63 if (ret != HDF_SUCCESS) {
64 return;
65 }
66 (void)PlatformDumperDump(configInfo->dumper);
67 (void)PlatformDumperClearDatas(configInfo->dumper);
68 }
69
I2sDumperCreate(struct I2sConfigInfo * configInfo)70 static int32_t I2sDumperCreate(struct I2sConfigInfo *configInfo)
71 {
72 struct PlatformDumper *dumper = NULL;
73 char *name = NULL;
74
75 name = (char *)OsalMemCalloc(I2S_DUMPER_NAME_LEN);
76 if (name == NULL) {
77 HDF_LOGE("%s: alloc name fail", __func__);
78 return HDF_ERR_MALLOC_FAIL;
79 }
80
81 if (snprintf_s(name, I2S_DUMPER_NAME_LEN, I2S_DUMPER_NAME_LEN - 1, "%s%u",
82 I2S_DUMPER_NAME_PREFIX, configInfo->busNum) < 0) {
83 HDF_LOGE("%s: snprintf_s name fail!", __func__);
84 OsalMemFree(name);
85 return HDF_ERR_IO;
86 }
87 dumper = PlatformDumperCreate(name);
88 if (dumper == NULL) {
89 HDF_LOGE("%s: get dumper for %s fail!", __func__, name);
90 OsalMemFree(name);
91 return HDF_ERR_IO;
92 }
93 configInfo->dumper = dumper;
94 configInfo->dumperName = name;
95
96 return HDF_SUCCESS;
97 }
98
I2sDumperDestroy(struct I2sConfigInfo * configInfo)99 static inline void I2sDumperDestroy(struct I2sConfigInfo *configInfo)
100 {
101 PlatformDumperDestroy(configInfo->dumper);
102 OsalMemFree(configInfo->dumperName);
103 }
104
GetI2sRxRegInfo(struct I2sConfigInfo * i2sCfg)105 void GetI2sRxRegInfo(struct I2sConfigInfo *i2sCfg)
106 {
107 I2S_PRINT_LOG_DBG("%s: PERI_CRG103[%px][%px][%px]", __func__,
108 i2sCfg->crg103Addr, i2sCfg->regBase, i2sCfg->codecAddr);
109 uint32_t value = OSAL_READL(i2sCfg->crg103Addr);
110 I2S_PRINT_LOG_DBG("%s: PERI_CRG103[0x%x]", __func__, value);
111 GetI2sAiaoRxInfo(i2sCfg);
112 GetI2sAiaoTxInfo(i2sCfg);
113 GetI2sCodecInfo(i2sCfg);
114 }
115
GetI2sTxRegInfo(struct I2sConfigInfo * i2sCfg)116 void GetI2sTxRegInfo(struct I2sConfigInfo *i2sCfg)
117 {
118 GetI2sAiaoTxInfo(i2sCfg);
119 GetI2sCodecInfo(i2sCfg);
120 }
121
Hi35xxI2sRegWrite(uint32_t value,volatile unsigned char * addr)122 int32_t Hi35xxI2sRegWrite(uint32_t value, volatile unsigned char *addr)
123 {
124 if (addr == NULL) {
125 I2S_PRINT_LOG_ERR("%s: addr is NULL", __func__);
126 return HDF_ERR_INVALID_PARAM;
127 }
128 I2S_PRINT_LOG_DBG("%s: I2S set REG: addr[%px] value[0x%x]", __func__, addr, value);
129 OSAL_WRITEL(value, addr);
130 return HDF_SUCCESS;
131 }
132
Hi35xxI2sRegRead(volatile unsigned char * addr)133 uint32_t Hi35xxI2sRegRead(volatile unsigned char *addr)
134 {
135 if (addr == NULL) {
136 I2S_PRINT_LOG_ERR("%s: addr is NULL", __func__);
137 return 0;
138 }
139
140 uint32_t val = OSAL_READL(addr);
141 I2S_PRINT_LOG_DBG("%s: I2S read REG: addr[%px] value[0x%x]", __func__, addr, val);
142 return val;
143 }
144
Hi35xxI2sEnable(struct I2sCntlr * cntlr)145 static int32_t Hi35xxI2sEnable(struct I2sCntlr *cntlr)
146 {
147 if (cntlr == NULL || cntlr->priv == NULL) {
148 I2S_PRINT_LOG_ERR("%s: cntlr priv or cfg is NULL", __func__);
149 return HDF_ERR_INVALID_PARAM;
150 }
151 return HDF_SUCCESS;
152 }
153
Hi35xxI2sDisable(struct I2sCntlr * cntlr)154 static int32_t Hi35xxI2sDisable(struct I2sCntlr *cntlr)
155 {
156 if (cntlr == NULL || cntlr->priv == NULL) {
157 I2S_PRINT_LOG_ERR("%s: cntlr priv or cfg is NULL", __func__);
158 return HDF_ERR_INVALID_PARAM;
159 }
160
161 struct I2sConfigInfo *i2sCfg = (struct I2sConfigInfo *)cntlr->priv;
162 if (Hi35xxI2sRegWrite(0x0, i2sCfg->crg103Addr) != HDF_SUCCESS) {
163 I2S_PRINT_LOG_ERR("%s: Hi35xxI2sRegWrite i2sCfg->crg103Addr failed", __func__);
164 I2sDumperDump(i2sCfg);
165 return HDF_FAILURE;
166 }
167
168 return HDF_SUCCESS;
169 }
170
Hi35xxI2sOpen(struct I2sCntlr * cntlr)171 static int32_t Hi35xxI2sOpen(struct I2sCntlr *cntlr)
172 {
173 (void)cntlr;
174 return HDF_SUCCESS;
175 }
176
Hi35xxI2sClose(struct I2sCntlr * cntlr)177 static int32_t Hi35xxI2sClose(struct I2sCntlr *cntlr)
178 {
179 (void)cntlr;
180 return HDF_SUCCESS;
181 }
182
Hi35xxI2sGetCfg(struct I2sCntlr * cntlr,struct I2sCfg * cfg)183 static int32_t Hi35xxI2sGetCfg(struct I2sCntlr *cntlr, struct I2sCfg *cfg)
184 {
185 if (cntlr == NULL || cntlr->priv == NULL || cfg == NULL) {
186 I2S_PRINT_LOG_ERR("%s: cntlr priv or cfg is NULL", __func__);
187 return HDF_ERR_INVALID_PARAM;
188 }
189
190 struct I2sConfigInfo *i2sCfg = (struct I2sConfigInfo *)cntlr->priv;
191
192 cfg->sampleRate = i2sCfg->sampleRate;
193 cfg->width = i2sCfg->width;
194 cfg->writeChannel = i2sCfg->writeChannel;
195 cfg->channelIfMode = i2sCfg->channelIfMode;
196 cfg->channelMode = i2sCfg->channelMode;
197 AudioCodecGetCfgI2slFsSel(i2sCfg->i2slFsSel, &cfg->i2slFsSel);
198
199 cfg->bclk = i2sCfg->bclk;
200 cfg->mclk = i2sCfg->mclk;
201 cfg->type = i2sCfg->type;
202 cfg->samplePrecision = i2sCfg->samplePrecision;
203
204 I2S_PRINT_LOG_DBG("%s: writeChannel[%u], i2slFsSel[%u], mclk[%d], bclk[%d], sampleRate[%u], \
205 type[%u], channelMode[%u], channelIfMode[%u], samplePrecision[%u]", __func__,
206 cfg->writeChannel, cfg->i2slFsSel, cfg->mclk, cfg->bclk, cfg->sampleRate,
207 cfg->type, cfg->channelMode, cfg->channelIfMode, cfg->samplePrecision);
208 return HDF_SUCCESS;
209 }
210
Hi35xxI2sSetCfg(struct I2sCntlr * cntlr,struct I2sCfg * cfg)211 static int32_t Hi35xxI2sSetCfg(struct I2sCntlr *cntlr, struct I2sCfg *cfg)
212 {
213 struct I2sConfigInfo *i2sCfg = NULL;
214
215 if (cntlr == NULL || cntlr->priv == NULL || cfg == NULL) {
216 I2S_PRINT_LOG_ERR("%s: cntlr priv or cfg is NULL", __func__);
217 return HDF_ERR_INVALID_PARAM;
218 }
219
220 i2sCfg = (struct I2sConfigInfo *)cntlr->priv;
221
222 I2S_PRINT_LOG_DBG("%s: writeChannel[%u], i2slFsSel[%u], mclk[%d], bclk[%d], sampleRate[%u], \
223 type[%u], channelMode[%u], channelIfMode[%u], samplePrecision[%u]", __func__,
224 cfg->writeChannel, cfg->i2slFsSel, cfg->mclk, cfg->bclk, cfg->sampleRate,
225 cfg->type, cfg->channelMode, cfg->channelIfMode, cfg->samplePrecision);
226
227 // audio or output
228 i2sCfg->writeChannel = cfg->writeChannel;
229 if (AudioCodecSetCfgI2slFsSel(&i2sCfg->i2slFsSel, cfg->i2slFsSel) != HDF_SUCCESS) {
230 I2S_PRINT_LOG_ERR("%s: AudioCodecSetCfgI2slFsSel error", __func__);
231 return HDF_FAILURE;
232 }
233 // Audio Codec info set
234 Hi35xxSetAudioCodec(i2sCfg, cfg->sampleRate, cfg->width);
235 i2sCfg->mclk = cfg->mclk;
236 i2sCfg->bclk = cfg->bclk;
237 int32_t rate = Hi35xxSampleRateShift(cfg->sampleRate);
238 if (rate == HDF_ERR_INVALID_PARAM) {
239 I2S_PRINT_LOG_ERR("%s: Hi35xxSampleRateShift error", __func__);
240 return HDF_FAILURE;
241 }
242 if (Hi35xxSetCfgAiaoFsclkDiv(&i2sCfg->regCfg100.aiaoFsclkDiv, (cfg->bclk / rate)) != 0) {
243 I2S_PRINT_LOG_ERR("%s: Hi35xxSetCfgAiaoFsclkDiv set error", __func__);
244 return HDF_FAILURE;
245 }
246 if (Hi35xxSetCfgAiaoBclkDiv(&i2sCfg->regCfg100.aiaoBclkDiv, (cfg->mclk / cfg->bclk)) != 0) {
247 I2S_PRINT_LOG_ERR("%s: Hi35xxSetCfgAiaoFsclkDiv set error", __func__);
248 return HDF_FAILURE;
249 }
250
251 i2sCfg->regCfg100.aiaoSrstReq = I2S_AIAO_SRST_REQ_NO_RESET;
252 i2sCfg->regCfg100.aiaoCken = I2S_AIAO_CKEN_OPEN;
253 i2sCfg->regRxIfAttr1.rxSdSourceSel = RX_SD_SOURCE_SEL_NORMAL;
254 i2sCfg->type = cfg->type;
255 if (AiaoGetRxIfAttri(i2sCfg, cfg->type, cfg->channelMode, cfg->channelIfMode, cfg->samplePrecision)
256 != HDF_SUCCESS) {
257 I2S_PRINT_LOG_ERR("%s: AiaoGetRxIfAttri failed", __func__);
258 return HDF_FAILURE;
259 }
260
261 // Rx
262 CfgSetI2sCrgCfg000(i2sCfg, cfg->i2slFsSel, cfg->sampleRate);
263 CfgSetI2sCrgCfg100(i2sCfg);
264 CfgSetRxIfSAttr1(i2sCfg);
265
266 // Tx
267 CfgSetI2sCrgCfg008(i2sCfg, cfg->i2slFsSel, cfg->sampleRate);
268 CfgSetI2sCrgCfg108(i2sCfg);
269 CfgSetTxIfSAttr1(i2sCfg);
270 I2sDumperDump(i2sCfg);
271 return HDF_SUCCESS;
272 }
273
Hi35xxI2sStartWrite(struct I2sCntlr * cntlr)274 static int32_t Hi35xxI2sStartWrite(struct I2sCntlr *cntlr)
275 {
276 if (cntlr == NULL || cntlr->priv == NULL) {
277 I2S_PRINT_LOG_ERR("%s: cntlr priv or cfg is NULL", __func__);
278 return HDF_ERR_INVALID_PARAM;
279 }
280 struct I2sConfigInfo *i2sCfg = (struct I2sConfigInfo *)cntlr->priv;
281
282 // prepare tx buff
283 if (Hi35xxI2sWriteGetBuff(i2sCfg) != HDF_SUCCESS) {
284 I2S_PRINT_LOG_ERR("%s: Hi35xxI2sWrite error", __func__);
285 I2sDumperDump(i2sCfg);
286 return HDF_FAILURE;
287 }
288 CfgSetTxBuffInfo(i2sCfg);
289 i2sCfg->isplay = true;
290 i2sCfg->txEn = false;
291
292 I2S_PRINT_LOG_DBG("%s: after set TX CRG--------->\r\n\r\n", __func__);
293 GetI2sTxRegInfo(i2sCfg);
294 I2S_PRINT_LOG_DBG("%s: after set TX CRG--------->\r\n\r\n", __func__);
295
296 return HDF_SUCCESS;
297 }
298
Hi35xxI2sStopWrite(struct I2sCntlr * cntlr)299 static int32_t Hi35xxI2sStopWrite(struct I2sCntlr *cntlr)
300 {
301 struct I2sConfigInfo *i2sCfg = NULL;
302
303 if (cntlr == NULL || cntlr->priv == NULL) {
304 I2S_PRINT_LOG_ERR("%s: cntlr priv or cfg is NULL", __func__);
305 return HDF_ERR_INVALID_PARAM;
306 }
307 i2sCfg = (struct I2sConfigInfo *)cntlr->priv;
308
309 uint32_t value = Hi35xxI2sRegRead(i2sCfg->regBase + TX_DSP_CTRL);
310 value &= ~TX_DISABLE;
311 value |= (0x0 << TX_DISABLE_SHIFT);
312 if (Hi35xxI2sRegWrite(value, i2sCfg->regBase + TX_DSP_CTRL) != HDF_SUCCESS) {
313 I2S_PRINT_LOG_ERR("%s: Hi35xxI2sRegWrite i2sCfg->regBase + TX_DSP_CTRL failed", __func__);
314 I2sDumperDump(i2sCfg);
315 return HDF_FAILURE;
316 }
317
318 while (1) {
319 value = Hi35xxI2sRegRead(i2sCfg->regBase + TX_DSP_CTRL);
320 I2S_PRINT_LOG_DBG("%s: TX_DSP_CTRL[0x%x]", __func__, value);
321 if ((value & TX_DISABLE_DONE) == TX_DISABLE_DONE) {
322 I2S_PRINT_LOG_ERR("%s: TX_DSP_CTRL stop success val 0x%x", __func__, value);
323 break;
324 } else {
325 OsalMSleep(AIAO_STOP_RX_TX_MSLEEP);
326 }
327 }
328
329 GetI2sTxRegInfo(i2sCfg);
330 i2sCfg->isplay = false;
331 i2sCfg->txEn = false;
332 if (i2sCfg->txVirData != NULL) {
333 LOS_DmaMemFree(i2sCfg->txVirData);
334 i2sCfg->txVirData = NULL;
335 i2sCfg->txWptr = 0;
336 i2sCfg->txRptr = 0;
337 i2sCfg->txSize = 0;
338 CfgSetTxBuffInfo(i2sCfg);
339 }
340 return HDF_SUCCESS;
341 }
342
Hi35xxI2sStartRead(struct I2sCntlr * cntlr)343 static int32_t Hi35xxI2sStartRead(struct I2sCntlr *cntlr)
344 {
345 struct I2sConfigInfo *i2sCfg = NULL;
346 if (cntlr == NULL || cntlr->priv == NULL) {
347 I2S_PRINT_LOG_ERR("%s: cntlr priv or cfg is NULL", __func__);
348 return HDF_ERR_INVALID_PARAM;
349 }
350 i2sCfg = (struct I2sConfigInfo *)cntlr->priv;
351
352 // prepare rx buff
353 if (Hi35xxI2sReadGetBuff(i2sCfg) != 0) {
354 I2S_PRINT_LOG_ERR("%s: Hi35xxI2sRead error", __func__);
355 I2sDumperDump(i2sCfg);
356 return HDF_FAILURE;
357 }
358
359 CfgSetRxBuffInfo(i2sCfg);
360 CfgStartRecord(i2sCfg);
361
362 I2S_PRINT_LOG_DBG("%s: after set RX CRG--------->\r\n\r\n", __func__);
363 GetI2sRxRegInfo(i2sCfg);
364 I2S_PRINT_LOG_DBG("%s: after set RX CRG--------->\r\n\r\n", __func__);
365
366 return HDF_SUCCESS;
367 }
368
Hi35xxI2sStopRead(struct I2sCntlr * cntlr)369 static int32_t Hi35xxI2sStopRead(struct I2sCntlr *cntlr)
370 {
371 struct I2sConfigInfo *i2sCfg = NULL;
372
373 if (cntlr == NULL || cntlr->priv == NULL) {
374 I2S_PRINT_LOG_ERR("%s: cntlr priv or cfg is NULL", __func__);
375 return HDF_ERR_INVALID_PARAM;
376 }
377 i2sCfg = (struct I2sConfigInfo *)cntlr->priv;
378
379 I2S_PRINT_LOG_DBG("%s: before stop", __func__);
380 GetI2sRxRegInfo(i2sCfg);
381 I2S_PRINT_LOG_DBG("%s: before stop", __func__);
382
383 // stop read
384 uint32_t value = Hi35xxI2sRegRead(i2sCfg->regBase + RX_DSP_CTRL);
385 value &= ~RX_DISABLE;
386 value |= (0x0 << RX_DISABLE_SHIFT);
387 if (Hi35xxI2sRegWrite(value, i2sCfg->regBase + RX_DSP_CTRL) != HDF_SUCCESS) {
388 I2S_PRINT_LOG_ERR("%s: Hi35xxI2sRegWrite i2sCfg->regBase + RX_DSP_CTRL failed", __func__);
389 I2sDumperDump(i2sCfg);
390 return HDF_FAILURE;
391 }
392
393 while (1) {
394 value = Hi35xxI2sRegRead(i2sCfg->regBase + RX_DSP_CTRL);
395 I2S_PRINT_LOG_DBG("%s: RX_DSP_CTRL val 0x%x", __func__, value);
396 if ((value & RX_DISABLE_DONE) == RX_DISABLE_DONE) {
397 I2S_PRINT_LOG_ERR("%s: RX_DSP_CTRL stop success val 0x%x", __func__, value);
398 break;
399 } else {
400 OsalMSleep(AIAO_STOP_RX_TX_MSLEEP);
401 }
402 }
403
404 I2S_PRINT_LOG_DBG("%s: after stop", __func__);
405 GetI2sRxRegInfo(i2sCfg);
406 I2S_PRINT_LOG_DBG("%s: after stop", __func__);
407
408 if (i2sCfg->rxVirData != NULL) {
409 LOS_DmaMemFree(i2sCfg->rxVirData);
410 i2sCfg->rxVirData = NULL;
411 i2sCfg->rxWptr = 0;
412 i2sCfg->rxRptr = 0;
413 i2sCfg->rxSize = 0;
414 CfgSetRxBuffInfo(i2sCfg);
415 }
416 return HDF_SUCCESS;
417 }
418
Hi35xxI2sRead(struct I2sCntlr * cntlr,struct I2sMsg * msgs)419 static int32_t Hi35xxI2sRead(struct I2sCntlr *cntlr, struct I2sMsg *msgs)
420 {
421 if (cntlr == NULL || cntlr->priv == NULL || msgs == NULL || msgs->rbuf == NULL || msgs->pRlen == NULL) {
422 I2S_PRINT_LOG_ERR("%s: input param is invalid", __func__);
423 return HDF_ERR_INVALID_PARAM;
424 }
425
426 struct I2sConfigInfo *i2sCfg = NULL;
427 i2sCfg = (struct I2sConfigInfo *)cntlr->priv;
428
429 uint32_t rptrOffset = 0;
430 if (GetRxBuffData(i2sCfg, msgs, &rptrOffset) != HDF_SUCCESS) {
431 I2S_PRINT_LOG_ERR("%s: GetRxBuffData failed", __func__);
432 I2sDumperDump(i2sCfg);
433 return HDF_FAILURE;
434 }
435
436 if (*msgs->pRlen == 0) {
437 I2S_PRINT_LOG_DBG("%s: not available data.", __func__);
438 return HDF_SUCCESS;
439 }
440
441 if (Hi35xxI2sRegWrite(rptrOffset, i2sCfg->regBase + RX_BUFF_RPTR) != HDF_SUCCESS) {
442 I2S_PRINT_LOG_ERR("%s: Hi35xxI2sRegWrite i2sCfg->regBase + RX_BUFF_RPTR failed", __func__);
443 return HDF_FAILURE;
444 }
445 return HDF_SUCCESS;
446 }
447
Hi35xxI2sWrite(struct I2sCntlr * cntlr,struct I2sMsg * msgs)448 static int32_t Hi35xxI2sWrite(struct I2sCntlr *cntlr, struct I2sMsg *msgs)
449 {
450 if (cntlr == NULL || cntlr->priv == NULL || msgs == NULL) {
451 I2S_PRINT_LOG_ERR("%s: input param is invalid", __func__);
452 return HDF_ERR_INVALID_PARAM;
453 }
454
455 struct I2sConfigInfo *i2sCfg = NULL;
456 i2sCfg = (struct I2sConfigInfo *)cntlr->priv;
457
458 I2S_PRINT_LOG_DBG("%s:len[0x%x], isplay[%d], txSize[0x%x]", __func__,
459 msgs->len, i2sCfg->isplay, i2sCfg->txSize);
460
461 if (i2sCfg->txVirData == NULL) {
462 I2S_PRINT_LOG_ERR("%s: txVirData NULL", __func__);
463 return HDF_FAILURE;
464 }
465
466 if (!i2sCfg->isplay) {
467 I2S_PRINT_LOG_ERR("%s: play is not set", __func__);
468 return HDF_FAILURE;
469 }
470
471 if (msgs->len >= i2sCfg->txSize) {
472 I2S_PRINT_LOG_ERR("%s: play data too big", __func__);
473 return HDF_FAILURE;
474 }
475 // play data set
476 CfgStartPlay(i2sCfg);
477
478 uint32_t offset = 0;
479 if (UpdateTxBuffData(i2sCfg, msgs, &offset) != HDF_SUCCESS) {
480 I2S_PRINT_LOG_ERR("%s:UpdateTxBuffData failed", __func__);
481 return HDF_FAILURE;
482 }
483
484 I2S_PRINT_LOG_DBG("%s: offset[0x%x]", __func__, offset);
485 if (*msgs->pRlen == 0) {
486 I2S_PRINT_LOG_DBG("%s: tx buff full, wait to write.", __func__);
487 return HDF_SUCCESS;
488 }
489
490 if (Hi35xxI2sRegWrite(offset, i2sCfg->regBase + TX_BUFF_WPTR) != HDF_SUCCESS) {
491 I2S_PRINT_LOG_ERR("%s: Hi35xxI2sRegWrite i2sCfg->regBase + TX_BUFF_WPTR failed", __func__);
492 return HDF_FAILURE;
493 }
494
495 return HDF_SUCCESS;
496 }
497
Hi35xxI2sTransfer(struct I2sCntlr * cntlr,struct I2sMsg * msgs)498 static int32_t Hi35xxI2sTransfer(struct I2sCntlr *cntlr, struct I2sMsg *msgs)
499 {
500 if (cntlr == NULL || cntlr->priv == NULL || msgs == NULL) {
501 I2S_PRINT_LOG_ERR("%s: input param is invalid", __func__);
502 return HDF_ERR_INVALID_PARAM;
503 }
504
505 struct I2sConfigInfo *i2sCfg = NULL;
506 i2sCfg = (struct I2sConfigInfo *)cntlr->priv;
507
508 if (msgs->rbuf != NULL) {
509 Hi35xxI2sRead(cntlr, msgs);
510 } else if (msgs->wbuf != NULL) {
511 Hi35xxI2sWrite(cntlr, msgs);
512 } else {
513 I2S_PRINT_LOG_ERR("%s: buf null", __func__);
514 I2sDumperDump(i2sCfg);
515 return HDF_FAILURE;
516 }
517 return HDF_SUCCESS;
518 }
519
520 struct I2sCntlrMethod g_i2sCntlrMethod = {
521 .GetCfg = Hi35xxI2sGetCfg,
522 .SetCfg = Hi35xxI2sSetCfg,
523 .Transfer = Hi35xxI2sTransfer,
524 .Open = Hi35xxI2sOpen,
525 .Close = Hi35xxI2sClose,
526 .Enable = Hi35xxI2sEnable,
527 .Disable = Hi35xxI2sDisable,
528 .StartWrite = Hi35xxI2sStartWrite,
529 .StopWrite = Hi35xxI2sStopWrite,
530 .StartRead = Hi35xxI2sStartRead,
531 .StopRead = Hi35xxI2sStopRead,
532 };
533
I2sGetConfigInfoFromHcs(struct I2sCntlr * cntlr,const struct DeviceResourceNode * node)534 static int32_t I2sGetConfigInfoFromHcs(struct I2sCntlr *cntlr, const struct DeviceResourceNode *node)
535 {
536 struct DeviceResourceIface *iface = DeviceResourceGetIfaceInstance(HDF_CONFIG_SOURCE);
537
538 if (cntlr == NULL || node == NULL || iface == NULL || iface->GetUint32 == NULL) {
539 I2S_PRINT_LOG_ERR("%s: iface is invalid", __func__);
540 return HDF_FAILURE;
541 }
542 if (iface->GetUint32(node, "busNum", &cntlr->busNum, 0) != HDF_SUCCESS) {
543 I2S_PRINT_LOG_ERR("%s: read busNum fail", __func__);
544 return HDF_FAILURE;
545 }
546 if (iface->GetUint32(node, "irqNum", &cntlr->irqNum, 0) != HDF_SUCCESS) {
547 I2S_PRINT_LOG_ERR("%s: read irqNum fail", __func__);
548 return HDF_FAILURE;
549 }
550 return HDF_SUCCESS;
551 }
552
I2sGetRegCfgFromHcs(struct I2sConfigInfo * configInfo,const struct DeviceResourceNode * node)553 static int32_t I2sGetRegCfgFromHcs(struct I2sConfigInfo *configInfo, const struct DeviceResourceNode *node)
554 {
555 uint32_t tmp;
556 struct DeviceResourceIface *iface = DeviceResourceGetIfaceInstance(HDF_CONFIG_SOURCE);
557
558 if (configInfo == NULL || node == NULL || iface == NULL || iface->GetUint32 == NULL) {
559 I2S_PRINT_LOG_ERR("%s: face is invalid", __func__);
560 return HDF_FAILURE;
561 }
562 if (iface->GetUint32(node, "i2s_pad_enable", &tmp, 0) != HDF_SUCCESS) {
563 I2S_PRINT_LOG_ERR("%s: read i2s_pad_enable fail", __func__);
564 return HDF_FAILURE;
565 }
566 configInfo->i2sPadEnable = tmp;
567 if (iface->GetUint32(node, "audio_enable", &tmp, 0) != HDF_SUCCESS) {
568 I2S_PRINT_LOG_ERR("%s: read audio_enable fail", __func__);
569 return HDF_FAILURE;
570 }
571 configInfo->audioEnable = tmp;
572 if (iface->GetUint32(node, "PERI_CRG103", &configInfo->PERICRG103, 0) != HDF_SUCCESS) {
573 I2S_PRINT_LOG_ERR("%s: read PERI_CRG103 fail", __func__);
574 return HDF_FAILURE;
575 }
576 if (iface->GetUint32(node, "regBase", &tmp, 0) != HDF_SUCCESS) {
577 I2S_PRINT_LOG_ERR("%s: read regBase fail", __func__);
578 return HDF_FAILURE;
579 }
580 I2S_PRINT_LOG_DBG("%s: regBase[0x%x]", __func__, tmp);
581
582 configInfo->regBase = OsalIoRemap(tmp, I2S_AIAO_MAX_REG_SIZE);
583 I2S_PRINT_LOG_DBG("%s:regBase[0x%x][%px]", __func__, tmp, configInfo->regBase);
584 configInfo->codecAddr = OsalIoRemap(AUDIO_CODEC_BASE_ADDR, ACODEC_MAX_REG_SIZE);
585 I2S_PRINT_LOG_DBG("%s:codecAddr[0x%x][%px]", __func__, AUDIO_CODEC_BASE_ADDR, configInfo->codecAddr);
586 configInfo->crg103Addr = OsalIoRemap(PERI_CRG103, sizeof(unsigned int));
587 I2S_PRINT_LOG_DBG("%s:crg103Addr[0x%x][%px]", __func__, PERI_CRG103, configInfo->crg103Addr);
588
589 return HDF_SUCCESS;
590 }
591
PeriCrg103Set(struct I2sConfigInfo * configInfo)592 static int32_t PeriCrg103Set(struct I2sConfigInfo *configInfo)
593 {
594 if (configInfo == NULL) {
595 I2S_PRINT_LOG_ERR("%s: configInfo is null", __func__);
596 return HDF_FAILURE;
597 }
598
599 if (Hi35xxI2sRegWrite(configInfo->PERICRG103, configInfo->crg103Addr) != HDF_SUCCESS) {
600 I2S_PRINT_LOG_ERR("%s: Hi35xxI2sRegWrite configInfo->crg103Addr failed", __func__);
601 return HDF_FAILURE;
602 }
603
604 return HDF_SUCCESS;
605 }
606
I2sInit(struct I2sCntlr * cntlr,const struct HdfDeviceObject * device)607 static int32_t I2sInit(struct I2sCntlr *cntlr, const struct HdfDeviceObject *device)
608 {
609 int32_t ret;
610 struct I2sConfigInfo *configInfo = NULL;
611
612 if (device->property == NULL || cntlr == NULL) {
613 I2S_PRINT_LOG_ERR("%s: property is null", __func__);
614 return HDF_FAILURE;
615 }
616
617 configInfo = (struct I2sConfigInfo *)OsalMemCalloc(sizeof(*configInfo));
618 if (configInfo == NULL) {
619 I2S_PRINT_LOG_ERR("%s: OsalMemCalloc configInfo error", __func__);
620 return HDF_ERR_MALLOC_FAIL;
621 }
622
623 ret = I2sGetConfigInfoFromHcs(cntlr, device->property);
624 if (ret != HDF_SUCCESS) {
625 I2S_PRINT_LOG_ERR("%s: I2sGetConfigInfoFromHcs error", __func__);
626 OsalMemFree(configInfo);
627 return HDF_FAILURE;
628 }
629
630 ret = I2sGetRegCfgFromHcs(configInfo, device->property);
631 if (ret != HDF_SUCCESS) {
632 I2S_PRINT_LOG_ERR("%s: I2sGetRegCfgFromHcs error", __func__);
633 OsalMemFree(configInfo);
634 return HDF_FAILURE;
635 }
636 configInfo->busNum = cntlr->busNum;
637 configInfo->isplay = false;
638 configInfo->rxVirData = NULL;
639 configInfo->txVirData = NULL;
640
641 // CLK RESET
642 (void)PeriCrg103Set(configInfo);
643 (void)AiaoInit(configInfo);
644 (void)CodecInit(configInfo);
645
646 cntlr->priv = configInfo;
647 cntlr->method = &g_i2sCntlrMethod;
648
649 ret = I2sDumperCreate(configInfo);
650 if (ret != HDF_SUCCESS) {
651 HDF_LOGE("%s: create dumper failed:%d", __func__, ret);
652 OsalMemFree(configInfo);
653 return ret;
654 }
655 I2sDumperDump(configInfo);
656 return HDF_SUCCESS;
657 }
658
HdfI2sDeviceBind(struct HdfDeviceObject * device)659 static int32_t HdfI2sDeviceBind(struct HdfDeviceObject *device)
660 {
661 if (device == NULL) {
662 I2S_PRINT_LOG_ERR("%s: device NULL", __func__);
663 return HDF_ERR_INVALID_OBJECT;
664 }
665 return (I2sCntlrCreate(device) == NULL) ? HDF_FAILURE : HDF_SUCCESS;
666 }
667
HdfI2sDeviceInit(struct HdfDeviceObject * device)668 static int32_t HdfI2sDeviceInit(struct HdfDeviceObject *device)
669 {
670 struct I2sCntlr *cntlr = NULL;
671
672 if (device == NULL) {
673 I2S_PRINT_LOG_ERR("%s: device NULL", __func__);
674 return HDF_ERR_INVALID_OBJECT;
675 }
676
677 cntlr = I2sCntlrFromDevice(device);
678 if (cntlr == NULL) {
679 I2S_PRINT_LOG_ERR("%s: cntlr is null", __func__);
680 return HDF_FAILURE;
681 }
682
683 int32_t ret = I2sInit(cntlr, device);
684 if (ret != HDF_SUCCESS) {
685 I2S_PRINT_LOG_ERR("%s: I2sInit error", __func__);
686 return HDF_FAILURE;
687 }
688 return ret;
689 }
690
HdfI2sDeviceRelease(struct HdfDeviceObject * device)691 static void HdfI2sDeviceRelease(struct HdfDeviceObject *device)
692 {
693 struct I2sCntlr *cntlr = NULL;
694 if (device == NULL) {
695 I2S_PRINT_LOG_ERR("%s: device is NULL", __func__);
696 return;
697 }
698
699 cntlr = I2sCntlrFromDevice(device);
700 if (cntlr == NULL) {
701 I2S_PRINT_LOG_ERR("%s: cntlr is NULL", __func__);
702 return;
703 }
704
705 if (cntlr->priv != NULL) {
706 struct I2sConfigInfo *configInfo = cntlr->priv;
707 if (configInfo->regBase != 0) {
708 OsalIoUnmap((void *)configInfo->regBase);
709 }
710 if (configInfo->codecAddr != 0) {
711 OsalIoUnmap((void *)configInfo->codecAddr);
712 }
713 if (configInfo->crg103Addr != 0) {
714 OsalIoUnmap((void *)configInfo->crg103Addr);
715 }
716 I2sDumperDestroy(configInfo);
717 OsalMemFree(cntlr->priv);
718 }
719
720 I2sCntlrDestroy(cntlr);
721 }
722
723 struct HdfDriverEntry g_hdfI2sDevice = {
724 .moduleVersion = 1,
725 .moduleName = "HDF_PLATFORM_I2S",
726 .Bind = HdfI2sDeviceBind,
727 .Init = HdfI2sDeviceInit,
728 .Release = HdfI2sDeviceRelease,
729 };
730
731 HDF_INIT(g_hdfI2sDevice);
732