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
30 #define HDF_LOG_TAG i2s_hi35xx
31
GetI2sRxRegInfo(struct I2sConfigInfo * i2sCfg)32 void GetI2sRxRegInfo(struct I2sConfigInfo *i2sCfg)
33 {
34 I2S_PRINT_LOG_DBG("%s: PERI_CRG103[%px][%px][%px]", __func__,
35 i2sCfg->crg103Addr, i2sCfg->regBase, i2sCfg->codecAddr);
36 uint32_t value = OSAL_READL(i2sCfg->crg103Addr);
37 I2S_PRINT_LOG_DBG("%s: PERI_CRG103[0x%x]", __func__, value);
38 GetI2sAiaoRxInfo(i2sCfg);
39 GetI2sAiaoTxInfo(i2sCfg);
40 GetI2sCodecInfo(i2sCfg);
41 }
42
GetI2sTxRegInfo(struct I2sConfigInfo * i2sCfg)43 void GetI2sTxRegInfo(struct I2sConfigInfo *i2sCfg)
44 {
45 GetI2sAiaoTxInfo(i2sCfg);
46 GetI2sCodecInfo(i2sCfg);
47 }
48
Hi35xxI2sRegWrite(uint32_t value,volatile unsigned char * addr)49 int32_t Hi35xxI2sRegWrite(uint32_t value, volatile unsigned char *addr)
50 {
51 if (addr == NULL) {
52 I2S_PRINT_LOG_ERR("%s: addr is NULL", __func__);
53 return HDF_ERR_INVALID_PARAM;
54 }
55 I2S_PRINT_LOG_DBG("%s: I2S set REG: addr[%px] value[0x%x]", __func__, addr, value);
56 OSAL_WRITEL(value, addr);
57 return HDF_SUCCESS;
58 }
59
Hi35xxI2sRegRead(volatile unsigned char * addr)60 uint32_t Hi35xxI2sRegRead(volatile unsigned char *addr)
61 {
62 if (addr == NULL) {
63 I2S_PRINT_LOG_ERR("%s: addr is NULL", __func__);
64 return 0;
65 }
66
67 uint32_t val = OSAL_READL(addr);
68 I2S_PRINT_LOG_DBG("%s: I2S read REG: addr[%px] value[0x%x]", __func__, addr, val);
69 return val;
70 }
71
Hi35xxI2sEnable(struct I2sCntlr * cntlr)72 static int32_t Hi35xxI2sEnable(struct I2sCntlr *cntlr)
73 {
74 if (cntlr == NULL || cntlr->priv == NULL) {
75 I2S_PRINT_LOG_ERR("%s: cntlr priv or cfg is NULL", __func__);
76 return HDF_ERR_INVALID_PARAM;
77 }
78 return HDF_SUCCESS;
79 }
80
Hi35xxI2sDisable(struct I2sCntlr * cntlr)81 static int32_t Hi35xxI2sDisable(struct I2sCntlr *cntlr)
82 {
83 if (cntlr == NULL || cntlr->priv == NULL) {
84 I2S_PRINT_LOG_ERR("%s: cntlr priv or cfg is NULL", __func__);
85 return HDF_ERR_INVALID_PARAM;
86 }
87
88 struct I2sConfigInfo *i2sCfg = (struct I2sConfigInfo *)cntlr->priv;
89 if (Hi35xxI2sRegWrite(0x0, i2sCfg->crg103Addr) != HDF_SUCCESS) {
90 I2S_PRINT_LOG_ERR("%s: Hi35xxI2sRegWrite i2sCfg->crg103Addr failed", __func__);
91 return HDF_FAILURE;
92 }
93
94 return HDF_SUCCESS;
95 }
96
Hi35xxI2sOpen(struct I2sCntlr * cntlr)97 static int32_t Hi35xxI2sOpen(struct I2sCntlr *cntlr)
98 {
99 (void)cntlr;
100 return HDF_SUCCESS;
101 }
102
Hi35xxI2sClose(struct I2sCntlr * cntlr)103 static int32_t Hi35xxI2sClose(struct I2sCntlr *cntlr)
104 {
105 (void)cntlr;
106 return HDF_SUCCESS;
107 }
108
Hi35xxI2sGetCfg(struct I2sCntlr * cntlr,struct I2sCfg * cfg)109 static int32_t Hi35xxI2sGetCfg(struct I2sCntlr *cntlr, struct I2sCfg *cfg)
110 {
111 if (cntlr == NULL || cntlr->priv == NULL || cfg == NULL) {
112 I2S_PRINT_LOG_ERR("%s: cntlr priv or cfg is NULL", __func__);
113 return HDF_ERR_INVALID_PARAM;
114 }
115
116 struct I2sConfigInfo *i2sCfg = (struct I2sConfigInfo *)cntlr->priv;
117
118 cfg->sampleRate = i2sCfg->sampleRate;
119 cfg->width = i2sCfg->width;
120 cfg->writeChannel = i2sCfg->writeChannel;
121 cfg->channelIfMode = i2sCfg->channelIfMode;
122 cfg->channelMode = i2sCfg->channelMode;
123 AudioCodecGetCfgI2slFsSel(i2sCfg->i2slFsSel, &cfg->i2slFsSel);
124
125 cfg->bclk = i2sCfg->bclk;
126 cfg->mclk = i2sCfg->mclk;
127 cfg->type = i2sCfg->type;
128 cfg->samplePrecision = i2sCfg->samplePrecision;
129
130 I2S_PRINT_LOG_DBG("%s: writeChannel[%u], i2slFsSel[%u], mclk[%d], bclk[%d], sampleRate[%u], \
131 type[%u], channelMode[%u], channelIfMode[%u], samplePrecision[%u]", __func__,
132 cfg->writeChannel, cfg->i2slFsSel, cfg->mclk, cfg->bclk, cfg->sampleRate,
133 cfg->type, cfg->channelMode, cfg->channelIfMode, cfg->samplePrecision);
134 return HDF_SUCCESS;
135 }
136
Hi35xxI2sSetCfg(struct I2sCntlr * cntlr,struct I2sCfg * cfg)137 static int32_t Hi35xxI2sSetCfg(struct I2sCntlr *cntlr, struct I2sCfg *cfg)
138 {
139 struct I2sConfigInfo *i2sCfg = NULL;
140
141 if (cntlr == NULL || cntlr->priv == NULL || cfg == NULL) {
142 I2S_PRINT_LOG_ERR("%s: cntlr priv or cfg is NULL", __func__);
143 return HDF_ERR_INVALID_PARAM;
144 }
145
146 i2sCfg = (struct I2sConfigInfo *)cntlr->priv;
147
148 I2S_PRINT_LOG_DBG("%s: writeChannel[%u], i2slFsSel[%u], mclk[%d], bclk[%d], sampleRate[%u], \
149 type[%u], channelMode[%u], channelIfMode[%u], samplePrecision[%u]", __func__,
150 cfg->writeChannel, cfg->i2slFsSel, cfg->mclk, cfg->bclk, cfg->sampleRate,
151 cfg->type, cfg->channelMode, cfg->channelIfMode, cfg->samplePrecision);
152
153 // audio or output
154 i2sCfg->writeChannel = cfg->writeChannel;
155 if (AudioCodecSetCfgI2slFsSel(&i2sCfg->i2slFsSel, cfg->i2slFsSel) != HDF_SUCCESS) {
156 I2S_PRINT_LOG_ERR("%s: AudioCodecSetCfgI2slFsSel error", __func__);
157 return HDF_FAILURE;
158 }
159 // Audio Codec info set
160 Hi35xxSetAudioCodec(i2sCfg, cfg->sampleRate, cfg->width);
161 i2sCfg->mclk = cfg->mclk;
162 i2sCfg->bclk = cfg->bclk;
163 int32_t rate = Hi35xxSampleRateShift(cfg->sampleRate);
164 if (rate == HDF_ERR_INVALID_PARAM) {
165 I2S_PRINT_LOG_ERR("%s: Hi35xxSampleRateShift error", __func__);
166 return HDF_FAILURE;
167 }
168 if (Hi35xxSetCfgAiaoFsclkDiv(&i2sCfg->regCfg100.aiaoFsclkDiv, (cfg->bclk / rate)) != 0) {
169 I2S_PRINT_LOG_ERR("%s: Hi35xxSetCfgAiaoFsclkDiv set error", __func__);
170 return HDF_FAILURE;
171 }
172 if (Hi35xxSetCfgAiaoBclkDiv(&i2sCfg->regCfg100.aiaoBclkDiv, (cfg->mclk / cfg->bclk)) != 0) {
173 I2S_PRINT_LOG_ERR("%s: Hi35xxSetCfgAiaoFsclkDiv set error", __func__);
174 return HDF_FAILURE;
175 }
176
177 i2sCfg->regCfg100.aiaoSrstReq = I2S_AIAO_SRST_REQ_NO_RESET;
178 i2sCfg->regCfg100.aiaoCken = I2S_AIAO_CKEN_OPEN;
179 i2sCfg->regRxIfAttr1.rxSdSourceSel = RX_SD_SOURCE_SEL_NORMAL;
180 i2sCfg->type = cfg->type;
181 if (AiaoGetRxIfAttri(i2sCfg, cfg->type, cfg->channelMode, cfg->channelIfMode, cfg->samplePrecision)
182 != HDF_SUCCESS) {
183 I2S_PRINT_LOG_ERR("%s: AiaoGetRxIfAttri failed", __func__);
184 return HDF_FAILURE;
185 }
186
187 // Rx
188 CfgSetI2sCrgCfg000(i2sCfg, cfg->i2slFsSel, cfg->sampleRate);
189 CfgSetI2sCrgCfg100(i2sCfg);
190 CfgSetRxIfSAttr1(i2sCfg);
191
192 // Tx
193 CfgSetI2sCrgCfg008(i2sCfg, cfg->i2slFsSel, cfg->sampleRate);
194 CfgSetI2sCrgCfg108(i2sCfg);
195 CfgSetTxIfSAttr1(i2sCfg);
196 return HDF_SUCCESS;
197 }
198
Hi35xxI2sStartWrite(struct I2sCntlr * cntlr)199 static int32_t Hi35xxI2sStartWrite(struct I2sCntlr *cntlr)
200 {
201 if (cntlr == NULL || cntlr->priv == NULL) {
202 I2S_PRINT_LOG_ERR("%s: cntlr priv or cfg is NULL", __func__);
203 return HDF_ERR_INVALID_PARAM;
204 }
205 struct I2sConfigInfo *i2sCfg = (struct I2sConfigInfo *)cntlr->priv;
206
207 // prepare tx buff
208 if (Hi35xxI2sWriteGetBuff(i2sCfg) != HDF_SUCCESS) {
209 I2S_PRINT_LOG_ERR("%s: Hi35xxI2sWrite error", __func__);
210 return HDF_FAILURE;
211 }
212 CfgSetTxBuffInfo(i2sCfg);
213 i2sCfg->isplay = true;
214 i2sCfg->txEn = false;
215
216 I2S_PRINT_LOG_DBG("%s: after set TX CRG--------->\r\n\r\n", __func__);
217 GetI2sTxRegInfo(i2sCfg);
218 I2S_PRINT_LOG_DBG("%s: after set TX CRG--------->\r\n\r\n", __func__);
219
220 return HDF_SUCCESS;
221 }
222
Hi35xxI2sStopWrite(struct I2sCntlr * cntlr)223 static int32_t Hi35xxI2sStopWrite(struct I2sCntlr *cntlr)
224 {
225 struct I2sConfigInfo *i2sCfg = NULL;
226
227 if (cntlr == NULL || cntlr->priv == NULL) {
228 I2S_PRINT_LOG_ERR("%s: cntlr priv or cfg is NULL", __func__);
229 return HDF_ERR_INVALID_PARAM;
230 }
231 i2sCfg = (struct I2sConfigInfo *)cntlr->priv;
232
233 uint32_t value = Hi35xxI2sRegRead(i2sCfg->regBase + TX_DSP_CTRL);
234 value &= ~TX_DISABLE;
235 value |= (0x0 << TX_DISABLE_SHIFT);
236 if (Hi35xxI2sRegWrite(value, i2sCfg->regBase + TX_DSP_CTRL) != HDF_SUCCESS) {
237 I2S_PRINT_LOG_ERR("%s: Hi35xxI2sRegWrite i2sCfg->regBase + TX_DSP_CTRL failed", __func__);
238 return HDF_FAILURE;
239 }
240
241 while (1) {
242 value = Hi35xxI2sRegRead(i2sCfg->regBase + TX_DSP_CTRL);
243 I2S_PRINT_LOG_DBG("%s: TX_DSP_CTRL[0x%x]", __func__, value);
244 if ((value & TX_DISABLE_DONE) == TX_DISABLE_DONE) {
245 I2S_PRINT_LOG_ERR("%s: TX_DSP_CTRL stop success val 0x%x", __func__, value);
246 break;
247 } else {
248 OsalMSleep(AIAO_STOP_RX_TX_MSLEEP);
249 }
250 }
251
252 GetI2sTxRegInfo(i2sCfg);
253 i2sCfg->isplay = false;
254 i2sCfg->txEn = false;
255 if (i2sCfg->txVirData != NULL) {
256 LOS_DmaMemFree(i2sCfg->txVirData);
257 i2sCfg->txVirData = NULL;
258 i2sCfg->txWptr = 0;
259 i2sCfg->txRptr = 0;
260 i2sCfg->txSize = 0;
261 CfgSetTxBuffInfo(i2sCfg);
262 }
263 return HDF_SUCCESS;
264 }
265
Hi35xxI2sStartRead(struct I2sCntlr * cntlr)266 static int32_t Hi35xxI2sStartRead(struct I2sCntlr *cntlr)
267 {
268 struct I2sConfigInfo *i2sCfg = NULL;
269 if (cntlr == NULL || cntlr->priv == NULL) {
270 I2S_PRINT_LOG_ERR("%s: cntlr priv or cfg is NULL", __func__);
271 return HDF_ERR_INVALID_PARAM;
272 }
273 i2sCfg = (struct I2sConfigInfo *)cntlr->priv;
274
275 // prepare rx buff
276 if (Hi35xxI2sReadGetBuff(i2sCfg) != 0) {
277 I2S_PRINT_LOG_ERR("%s: Hi35xxI2sRead error", __func__);
278 return HDF_FAILURE;
279 }
280
281 CfgSetRxBuffInfo(i2sCfg);
282 CfgStartRecord(i2sCfg);
283
284 I2S_PRINT_LOG_DBG("%s: after set RX CRG--------->\r\n\r\n", __func__);
285 GetI2sRxRegInfo(i2sCfg);
286 I2S_PRINT_LOG_DBG("%s: after set RX CRG--------->\r\n\r\n", __func__);
287
288 return HDF_SUCCESS;
289 }
290
Hi35xxI2sStopRead(struct I2sCntlr * cntlr)291 static int32_t Hi35xxI2sStopRead(struct I2sCntlr *cntlr)
292 {
293 struct I2sConfigInfo *i2sCfg = NULL;
294
295 if (cntlr == NULL || cntlr->priv == NULL) {
296 I2S_PRINT_LOG_ERR("%s: cntlr priv or cfg is NULL", __func__);
297 return HDF_ERR_INVALID_PARAM;
298 }
299 i2sCfg = (struct I2sConfigInfo *)cntlr->priv;
300
301 I2S_PRINT_LOG_DBG("%s: before stop", __func__);
302 GetI2sRxRegInfo(i2sCfg);
303 I2S_PRINT_LOG_DBG("%s: before stop", __func__);
304
305 // stop read
306 uint32_t value = Hi35xxI2sRegRead(i2sCfg->regBase + RX_DSP_CTRL);
307 value &= ~RX_DISABLE;
308 value |= (0x0 << RX_DISABLE_SHIFT);
309 if (Hi35xxI2sRegWrite(value, i2sCfg->regBase + RX_DSP_CTRL) != HDF_SUCCESS) {
310 I2S_PRINT_LOG_ERR("%s: Hi35xxI2sRegWrite i2sCfg->regBase + RX_DSP_CTRL failed", __func__);
311 return HDF_FAILURE;
312 }
313
314 while (1) {
315 value = Hi35xxI2sRegRead(i2sCfg->regBase + RX_DSP_CTRL);
316 I2S_PRINT_LOG_DBG("%s: RX_DSP_CTRL val 0x%x", __func__, value);
317 if ((value & RX_DISABLE_DONE) == RX_DISABLE_DONE) {
318 I2S_PRINT_LOG_ERR("%s: RX_DSP_CTRL stop success val 0x%x", __func__, value);
319 break;
320 } else {
321 OsalMSleep(AIAO_STOP_RX_TX_MSLEEP);
322 }
323 }
324
325 I2S_PRINT_LOG_DBG("%s: after stop", __func__);
326 GetI2sRxRegInfo(i2sCfg);
327 I2S_PRINT_LOG_DBG("%s: after stop", __func__);
328
329 if (i2sCfg->rxVirData != NULL) {
330 LOS_DmaMemFree(i2sCfg->rxVirData);
331 i2sCfg->rxVirData = NULL;
332 i2sCfg->rxWptr = 0;
333 i2sCfg->rxRptr = 0;
334 i2sCfg->rxSize = 0;
335 CfgSetRxBuffInfo(i2sCfg);
336 }
337 return HDF_SUCCESS;
338 }
339
Hi35xxI2sRead(struct I2sCntlr * cntlr,struct I2sMsg * msgs)340 static int32_t Hi35xxI2sRead(struct I2sCntlr *cntlr, struct I2sMsg *msgs)
341 {
342 if (cntlr == NULL || cntlr->priv == NULL || msgs == NULL || msgs->rbuf == NULL || msgs->pRlen == NULL) {
343 I2S_PRINT_LOG_ERR("%s: input param is invalid", __func__);
344 return HDF_ERR_INVALID_PARAM;
345 }
346
347 struct I2sConfigInfo *i2sCfg = NULL;
348 i2sCfg = (struct I2sConfigInfo *)cntlr->priv;
349
350 uint32_t rptrOffset = 0;
351 if (GetRxBuffData(i2sCfg, msgs, &rptrOffset) != HDF_SUCCESS) {
352 I2S_PRINT_LOG_ERR("%s: GetRxBuffData failed", __func__);
353 return HDF_FAILURE;
354 }
355
356 if (*msgs->pRlen == 0) {
357 I2S_PRINT_LOG_DBG("%s: not available data.", __func__);
358 return HDF_SUCCESS;
359 }
360
361 if (Hi35xxI2sRegWrite(rptrOffset, i2sCfg->regBase + RX_BUFF_RPTR) != HDF_SUCCESS) {
362 I2S_PRINT_LOG_ERR("%s: Hi35xxI2sRegWrite i2sCfg->regBase + RX_BUFF_RPTR failed", __func__);
363 return HDF_FAILURE;
364 }
365 return HDF_SUCCESS;
366 }
367
Hi35xxI2sWrite(struct I2sCntlr * cntlr,struct I2sMsg * msgs)368 static int32_t Hi35xxI2sWrite(struct I2sCntlr *cntlr, struct I2sMsg *msgs)
369 {
370 if (cntlr == NULL || cntlr->priv == NULL || msgs == NULL) {
371 I2S_PRINT_LOG_ERR("%s: input param is invalid", __func__);
372 return HDF_ERR_INVALID_PARAM;
373 }
374
375 struct I2sConfigInfo *i2sCfg = NULL;
376 i2sCfg = (struct I2sConfigInfo *)cntlr->priv;
377
378 I2S_PRINT_LOG_DBG("%s:len[0x%x], isplay[%d], txSize[0x%x]", __func__,
379 msgs->len, i2sCfg->isplay, i2sCfg->txSize);
380
381 if (i2sCfg->txVirData == NULL) {
382 I2S_PRINT_LOG_ERR("%s: txVirData NULL", __func__);
383 return HDF_FAILURE;
384 }
385
386 if (!i2sCfg->isplay) {
387 I2S_PRINT_LOG_ERR("%s: play is not set", __func__);
388 return HDF_FAILURE;
389 }
390
391 if (msgs->len >= i2sCfg->txSize) {
392 I2S_PRINT_LOG_ERR("%s: play data too big", __func__);
393 return HDF_FAILURE;
394 }
395 // play data set
396 CfgStartPlay(i2sCfg);
397
398 uint32_t offset = 0;
399 if (UpdateTxBuffData(i2sCfg, msgs, &offset) != HDF_SUCCESS) {
400 I2S_PRINT_LOG_ERR("%s:UpdateTxBuffData failed", __func__);
401 return HDF_FAILURE;
402 }
403
404 I2S_PRINT_LOG_DBG("%s: offset[0x%x]", __func__, offset);
405 if (*msgs->pRlen == 0) {
406 I2S_PRINT_LOG_DBG("%s: tx buff full, wait to write.", __func__);
407 return HDF_SUCCESS;
408 }
409
410 if (Hi35xxI2sRegWrite(offset, i2sCfg->regBase + TX_BUFF_WPTR) != HDF_SUCCESS) {
411 I2S_PRINT_LOG_ERR("%s: Hi35xxI2sRegWrite i2sCfg->regBase + TX_BUFF_WPTR failed", __func__);
412 return HDF_FAILURE;
413 }
414
415 return HDF_SUCCESS;
416 }
417
Hi35xxI2sTransfer(struct I2sCntlr * cntlr,struct I2sMsg * msgs)418 static int32_t Hi35xxI2sTransfer(struct I2sCntlr *cntlr, struct I2sMsg *msgs)
419 {
420 if (cntlr == NULL || cntlr->priv == NULL || msgs == NULL) {
421 I2S_PRINT_LOG_ERR("%s: input param is invalid", __func__);
422 return HDF_ERR_INVALID_PARAM;
423 }
424
425 struct I2sConfigInfo *i2sCfg = NULL;
426 i2sCfg = (struct I2sConfigInfo *)cntlr->priv;
427
428 if (msgs->rbuf != NULL) {
429 Hi35xxI2sRead(cntlr, msgs);
430 } else if (msgs->wbuf != NULL) {
431 Hi35xxI2sWrite(cntlr, msgs);
432 } else {
433 I2S_PRINT_LOG_ERR("%s: buf null", __func__);
434 return HDF_FAILURE;
435 }
436
437 return HDF_SUCCESS;
438 }
439
440 struct I2sCntlrMethod g_i2sCntlrMethod = {
441 .GetCfg = Hi35xxI2sGetCfg,
442 .SetCfg = Hi35xxI2sSetCfg,
443 .Transfer = Hi35xxI2sTransfer,
444 .Open = Hi35xxI2sOpen,
445 .Close = Hi35xxI2sClose,
446 .Enable = Hi35xxI2sEnable,
447 .Disable = Hi35xxI2sDisable,
448 .StartWrite = Hi35xxI2sStartWrite,
449 .StopWrite = Hi35xxI2sStopWrite,
450 .StartRead = Hi35xxI2sStartRead,
451 .StopRead = Hi35xxI2sStopRead,
452 };
453
I2sGetConfigInfoFromHcs(struct I2sCntlr * cntlr,const struct DeviceResourceNode * node)454 static int32_t I2sGetConfigInfoFromHcs(struct I2sCntlr *cntlr, const struct DeviceResourceNode *node)
455 {
456 struct DeviceResourceIface *iface = DeviceResourceGetIfaceInstance(HDF_CONFIG_SOURCE);
457
458 if (cntlr == NULL || node == NULL || iface == NULL || iface->GetUint32 == NULL) {
459 I2S_PRINT_LOG_ERR("%s: iface is invalid", __func__);
460 return HDF_FAILURE;
461 }
462 if (iface->GetUint32(node, "busNum", &cntlr->busNum, 0) != HDF_SUCCESS) {
463 I2S_PRINT_LOG_ERR("%s: read busNum fail", __func__);
464 return HDF_FAILURE;
465 }
466 if (iface->GetUint32(node, "irqNum", &cntlr->irqNum, 0) != HDF_SUCCESS) {
467 I2S_PRINT_LOG_ERR("%s: read irqNum fail", __func__);
468 return HDF_FAILURE;
469 }
470 return HDF_SUCCESS;
471 }
472
I2sGetRegCfgFromHcs(struct I2sConfigInfo * configInfo,const struct DeviceResourceNode * node)473 static int32_t I2sGetRegCfgFromHcs(struct I2sConfigInfo *configInfo, const struct DeviceResourceNode *node)
474 {
475 uint32_t tmp;
476 struct DeviceResourceIface *iface = DeviceResourceGetIfaceInstance(HDF_CONFIG_SOURCE);
477
478 if (configInfo == NULL || node == NULL || iface == NULL || iface->GetUint32 == NULL) {
479 I2S_PRINT_LOG_ERR("%s: face is invalid", __func__);
480 return HDF_FAILURE;
481 }
482 if (iface->GetUint32(node, "i2s_pad_enable", &tmp, 0) != HDF_SUCCESS) {
483 I2S_PRINT_LOG_ERR("%s: read i2s_pad_enable fail", __func__);
484 return HDF_FAILURE;
485 }
486 configInfo->i2sPadEnable = tmp;
487 if (iface->GetUint32(node, "audio_enable", &tmp, 0) != HDF_SUCCESS) {
488 I2S_PRINT_LOG_ERR("%s: read audio_enable fail", __func__);
489 return HDF_FAILURE;
490 }
491 configInfo->audioEnable = tmp;
492 if (iface->GetUint32(node, "PERI_CRG103", &configInfo->PERICRG103, 0) != HDF_SUCCESS) {
493 I2S_PRINT_LOG_ERR("%s: read PERI_CRG103 fail", __func__);
494 return HDF_FAILURE;
495 }
496 if (iface->GetUint32(node, "regBase", &tmp, 0) != HDF_SUCCESS) {
497 I2S_PRINT_LOG_ERR("%s: read regBase fail", __func__);
498 return HDF_FAILURE;
499 }
500 I2S_PRINT_LOG_DBG("%s: regBase[0x%x]", __func__, tmp);
501
502 configInfo->regBase = OsalIoRemap(tmp, I2S_AIAO_MAX_REG_SIZE);
503 I2S_PRINT_LOG_DBG("%s:regBase[0x%x][%px]", __func__, tmp, configInfo->regBase);
504 configInfo->codecAddr = OsalIoRemap(AUDIO_CODEC_BASE_ADDR, ACODEC_MAX_REG_SIZE);
505 I2S_PRINT_LOG_DBG("%s:codecAddr[0x%x][%px]", __func__, AUDIO_CODEC_BASE_ADDR, configInfo->codecAddr);
506 configInfo->crg103Addr = OsalIoRemap(PERI_CRG103, sizeof(unsigned int));
507 I2S_PRINT_LOG_DBG("%s:crg103Addr[0x%x][%px]", __func__, PERI_CRG103, configInfo->crg103Addr);
508 return HDF_SUCCESS;
509 }
510
PeriCrg103Set(struct I2sConfigInfo * configInfo)511 static int32_t PeriCrg103Set(struct I2sConfigInfo *configInfo)
512 {
513 if (configInfo == NULL) {
514 I2S_PRINT_LOG_ERR("%s: configInfo is null", __func__);
515 return HDF_FAILURE;
516 }
517
518 if (Hi35xxI2sRegWrite(configInfo->PERICRG103, configInfo->crg103Addr) != HDF_SUCCESS) {
519 I2S_PRINT_LOG_ERR("%s: Hi35xxI2sRegWrite configInfo->crg103Addr failed", __func__);
520 return HDF_FAILURE;
521 }
522
523 return HDF_SUCCESS;
524 }
525
I2sInit(struct I2sCntlr * cntlr,const struct HdfDeviceObject * device)526 static int32_t I2sInit(struct I2sCntlr *cntlr, const struct HdfDeviceObject *device)
527 {
528 int32_t ret;
529 struct I2sConfigInfo *configInfo = NULL;
530
531 if (device->property == NULL || cntlr == NULL) {
532 I2S_PRINT_LOG_ERR("%s: property is null", __func__);
533 return HDF_FAILURE;
534 }
535
536 configInfo = (struct I2sConfigInfo *)OsalMemCalloc(sizeof(*configInfo));
537 if (configInfo == NULL) {
538 I2S_PRINT_LOG_ERR("%s: OsalMemCalloc configInfo error", __func__);
539 return HDF_ERR_MALLOC_FAIL;
540 }
541
542 ret = I2sGetConfigInfoFromHcs(cntlr, device->property);
543 if (ret != HDF_SUCCESS) {
544 I2S_PRINT_LOG_ERR("%s: I2sGetConfigInfoFromHcs error", __func__);
545 OsalMemFree(configInfo);
546 return HDF_FAILURE;
547 }
548
549 ret = I2sGetRegCfgFromHcs(configInfo, device->property);
550 if (ret != HDF_SUCCESS) {
551 I2S_PRINT_LOG_ERR("%s: I2sGetRegCfgFromHcs error", __func__);
552 OsalMemFree(configInfo);
553 return HDF_FAILURE;
554 }
555 configInfo->isplay = false;
556 configInfo->rxVirData = NULL;
557 configInfo->txVirData = NULL;
558
559 // CLK RESET
560 (void)PeriCrg103Set(configInfo);
561 (void)AiaoInit(configInfo);
562 (void)CodecInit(configInfo);
563
564 cntlr->priv = configInfo;
565 cntlr->method = &g_i2sCntlrMethod;
566
567 return HDF_SUCCESS;
568 }
569
HdfI2sDeviceBind(struct HdfDeviceObject * device)570 static int32_t HdfI2sDeviceBind(struct HdfDeviceObject *device)
571 {
572 if (device == NULL) {
573 I2S_PRINT_LOG_ERR("%s: device NULL", __func__);
574 return HDF_ERR_INVALID_OBJECT;
575 }
576 return (I2sCntlrCreate(device) == NULL) ? HDF_FAILURE : HDF_SUCCESS;
577 }
578
HdfI2sDeviceInit(struct HdfDeviceObject * device)579 static int32_t HdfI2sDeviceInit(struct HdfDeviceObject *device)
580 {
581 struct I2sCntlr *cntlr = NULL;
582
583 if (device == NULL) {
584 I2S_PRINT_LOG_ERR("%s: device NULL", __func__);
585 return HDF_ERR_INVALID_OBJECT;
586 }
587
588 cntlr = I2sCntlrFromDevice(device);
589 if (cntlr == NULL) {
590 I2S_PRINT_LOG_ERR("%s: cntlr is null", __func__);
591 return HDF_FAILURE;
592 }
593
594 int32_t ret = I2sInit(cntlr, device);
595 if (ret != HDF_SUCCESS) {
596 I2S_PRINT_LOG_ERR("%s: I2sInit error", __func__);
597 return HDF_FAILURE;
598 }
599 return ret;
600 }
601
HdfI2sDeviceRelease(struct HdfDeviceObject * device)602 static void HdfI2sDeviceRelease(struct HdfDeviceObject *device)
603 {
604 struct I2sCntlr *cntlr = NULL;
605 if (device == NULL) {
606 I2S_PRINT_LOG_ERR("%s: device is NULL", __func__);
607 return;
608 }
609
610 cntlr = I2sCntlrFromDevice(device);
611 if (cntlr == NULL) {
612 I2S_PRINT_LOG_ERR("%s: cntlr is NULL", __func__);
613 return;
614 }
615
616 if (cntlr->priv != NULL) {
617 struct I2sConfigInfo *configInfo = cntlr->priv;
618 if (configInfo->regBase != 0) {
619 OsalIoUnmap((void *)configInfo->regBase);
620 }
621 if (configInfo->codecAddr != 0) {
622 OsalIoUnmap((void *)configInfo->codecAddr);
623 }
624 if (configInfo->crg103Addr != 0) {
625 OsalIoUnmap((void *)configInfo->crg103Addr);
626 }
627 OsalMemFree(cntlr->priv);
628 }
629
630 I2sCntlrDestroy(cntlr);
631 }
632
633 struct HdfDriverEntry g_hdfI2sDevice = {
634 .moduleVersion = 1,
635 .moduleName = "HDF_PLATFORM_I2S",
636 .Bind = HdfI2sDeviceBind,
637 .Init = HdfI2sDeviceInit,
638 .Release = HdfI2sDeviceRelease,
639 };
640
641 HDF_INIT(g_hdfI2sDevice);
642