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