• 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 #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