• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2022 Huawei Device Co., Ltd.
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License
6  * as published by the Free Software Foundation; either version 2
7  * of the License, or (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
17  */
18 
19 #include "hi3516_aiao_impl.h"
20 #include "audio_host.h"
21 #include "audio_control.h"
22 #include "audio_dai_if.h"
23 #include "audio_dai_base.h"
24 #include "audio_driver_log.h"
25 #include "osal_io.h"
26 
27 #define HDF_LOG_TAG HDF_AUDIO_DRIVER
28 
29 /* Hi35xx IO register address */
30 #define HI35XX_I2C_REG_BASE_ADDR  (0x114F0000)
31 #define HI35XX_I2S_REG_BASE_ADDR  (0x112F0000)
32 #define CODEC_REG_BASE            (0x113C0000)
33 #define CODEC_MAX_REG_SIZE        (0x1000)
34 
35 #define I2S_IOCFG2_BASE1 0x0020
36 #define I2S_IOCFG2_BASE2 0x0024
37 #define I2S_IOCFG2_BASE3 0x0028
38 #define I2S_IOCFG2_BASE4 0x002C
39 #define I2S_IOCFG2_BASE5 0x0030
40 
41 #define I2S_IOCFG2_BASE1_VAL 0x663
42 #define I2S_IOCFG2_BASE2_VAL 0x673
43 #define I2S_IOCFG2_BASE3_VAL 0x573
44 #define I2S_IOCFG2_BASE4_VAL 0x473
45 #define I2S_IOCFG2_BASE5_VAL 0x433
46 
47 void *g_regCodecBase = NULL;
48 void *g_regDaiBase = NULL;
49 
50 /* i2c6 init */
I2c6PinInit(void)51 static int I2c6PinInit(void)
52 {
53     char *regI2cBase = (void *)OsalIoRemap(HI35XX_I2C_REG_BASE_ADDR, 0x1000);
54     if (regI2cBase == NULL) {
55         AUDIO_DRIVER_LOG_ERR("regI2cBase is null.");
56         return HDF_FAILURE;
57     }
58     SysWritel((uintptr_t)regI2cBase + 0x0048, 0x0473); // I2C6_SCL
59     SysWritel((uintptr_t)regI2cBase + 0x004C, 0x0473); // I2C6_SDA
60     if (regI2cBase != NULL) {
61         OsalIoUnmap(regI2cBase);
62     }
63     AUDIO_DRIVER_LOG_DEBUG("success!");
64     return HDF_SUCCESS;
65 }
66 
67 /* i2s0 pin init */
I2s0PinMux(const char * regI2sBase)68 static void I2s0PinMux(const char *regI2sBase)
69 {
70     SysWritel((uintptr_t)regI2sBase + I2S_IOCFG2_BASE1, I2S_IOCFG2_BASE1_VAL);
71     SysWritel((uintptr_t)regI2sBase + I2S_IOCFG2_BASE2, I2S_IOCFG2_BASE2_VAL);
72     SysWritel((uintptr_t)regI2sBase + I2S_IOCFG2_BASE3, I2S_IOCFG2_BASE3_VAL);
73     SysWritel((uintptr_t)regI2sBase + I2S_IOCFG2_BASE4, I2S_IOCFG2_BASE4_VAL);
74     SysWritel((uintptr_t)regI2sBase + I2S_IOCFG2_BASE5, I2S_IOCFG2_BASE5_VAL);
75 }
76 
77 /* i2s init */
I2sPinInit(void)78 static int I2sPinInit(void)
79 {
80     char *regI2sBase = (void *)OsalIoRemap(HI35XX_I2S_REG_BASE_ADDR, 0x1000);
81     if (regI2sBase == NULL) {
82         AUDIO_DRIVER_LOG_ERR("regI2sBase is null.");
83         return HDF_FAILURE;
84     }
85     I2s0PinMux(regI2sBase);
86     if (regI2sBase != NULL) {
87         OsalIoUnmap(regI2sBase);
88     }
89     AUDIO_DRIVER_LOG_DEBUG("success!");
90     return HDF_SUCCESS;
91 }
92 
Hi3516DaiDeviceInit(struct AudioCard * audioCard,const struct DaiDevice * dai)93 int32_t Hi3516DaiDeviceInit(struct AudioCard *audioCard, const struct DaiDevice *dai)
94 {
95     if (dai == NULL || dai->devData == NULL) {
96         AUDIO_DRIVER_LOG_ERR("dai is nullptr.");
97         return HDF_FAILURE;
98     }
99     struct DaiData *data = dai->devData;
100     struct AudioRegCfgData *regConfig = dai->devData->regConfig;
101     if (regConfig == NULL) {
102         AUDIO_DRIVER_LOG_ERR("regConfig is nullptr.");
103         return HDF_FAILURE;
104     }
105 
106     if (g_regCodecBase == NULL) {
107         g_regCodecBase = OsalIoRemap(CODEC_REG_BASE, CODEC_MAX_REG_SIZE);
108         if (g_regCodecBase == NULL) {
109             AUDIO_DRIVER_LOG_ERR("OsalIoRemap fail.");
110             return HDF_FAILURE;
111         }
112     }
113 
114     if (g_regDaiBase == NULL) {
115         g_regDaiBase = OsalIoRemap(regConfig->audioIdInfo.chipIdRegister,
116             regConfig->audioIdInfo.chipIdSize);
117         if (g_regDaiBase == NULL) {
118             AUDIO_DRIVER_LOG_ERR("OsalIoRemap fail.");
119             return HDF_FAILURE;
120         }
121     }
122 
123     data->regVirtualAddr = (uintptr_t)g_regCodecBase;
124 
125     if (DaiSetConfigInfoOfControls(data) != HDF_SUCCESS) {
126         AUDIO_DRIVER_LOG_ERR("set config info fail.");
127         return HDF_FAILURE;
128     }
129 
130     int ret = AudioAddControls(audioCard, data->controls, data->numControls);
131     if (ret != HDF_SUCCESS) {
132         AUDIO_DRIVER_LOG_ERR("add controls failed.");
133         return HDF_FAILURE;
134     }
135 
136     if (data->daiInitFlag == true) {
137         AUDIO_DRIVER_LOG_DEBUG("dai init complete!");
138         return HDF_SUCCESS;
139     }
140 
141     if (I2c6PinInit() != HDF_SUCCESS) {
142         AUDIO_DRIVER_LOG_ERR("I2c6PinInit fail.");
143         return HDF_FAILURE;
144     }
145 
146     data->daiInitFlag = true;
147 
148     return HDF_SUCCESS;
149 }
150 
Hi3516DaiTrigger(const struct AudioCard * card,int cmd,const struct DaiDevice * device)151 int32_t Hi3516DaiTrigger(const struct AudioCard *card, int cmd, const struct DaiDevice *device)
152 {
153     (void)card;
154     (void)device;
155     (void)cmd;
156 
157     return HDF_SUCCESS;
158 }
159 
Hi3516DaiStartup(const struct AudioCard * card,const struct DaiDevice * device)160 int32_t Hi3516DaiStartup(const struct AudioCard *card, const struct DaiDevice *device)
161 {
162     struct AudioMixerControl *regCfgItem = NULL;
163     (void)card;
164 
165     if (device == NULL || device->devData == NULL || device->devData->regConfig == NULL ||
166         device->devData->regConfig->audioRegParams[AUDIO_DAI_STARTUP_PATAM_GROUP] == NULL ||
167         device->devData->regConfig->audioRegParams[AUDIO_DAI_STARTUP_PATAM_GROUP]->regCfgItem == NULL) {
168         AUDIO_DRIVER_LOG_ERR("input para is nullptr.");
169         return HDF_FAILURE;
170     }
171     regCfgItem = device->devData->regConfig->audioRegParams[AUDIO_DAI_STARTUP_PATAM_GROUP]->regCfgItem;
172     int itemNum = device->devData->regConfig->audioRegParams[AUDIO_DAI_STARTUP_PATAM_GROUP]->itemNum;
173 
174     device->devData->regVirtualAddr = (uintptr_t)g_regDaiBase;
175     for (int i = 0; i < itemNum; i++) {
176         int ret = AudioDaiRegUpdate(device, &regCfgItem[i]);
177         if (ret != HDF_SUCCESS) {
178             AUDIO_DRIVER_LOG_ERR("set frequency fail.");
179             return HDF_FAILURE;
180         }
181     }
182     device->devData->regVirtualAddr = (uintptr_t)g_regCodecBase;
183 
184     if (I2sPinInit() != HDF_SUCCESS) {
185         AUDIO_DRIVER_LOG_ERR("I2sPinInit fail.");
186     }
187 
188     return HDF_SUCCESS;
189 }
190 
SetIISRate(const struct DaiDevice * device,struct AudioMixerControl * regCfgItem,uint32_t itemNum)191 static int32_t SetIISRate(const struct DaiDevice *device, struct AudioMixerControl *regCfgItem, uint32_t itemNum)
192 {
193     const uint32_t shiftMax = 4;
194     uint32_t mclkSel;
195     uint32_t shift = 0;
196     uint32_t bclkRegVal;
197 
198     if (device == NULL || device->devData == NULL || regCfgItem == NULL) {
199         AUDIO_DRIVER_LOG_ERR("input para is nullptr.");
200         return HDF_FAILURE;
201     }
202     uint32_t rate = device->devData->pcmInfo.rate;
203     uint32_t bitWidth = device->devData->pcmInfo.bitWidth;
204 
205     if (device->devData->pcmInfo.streamType == AUDIO_CAPTURE_STREAM) {
206         shift = shiftMax;
207     }
208 
209     (void)memset_s(&mclkSel, sizeof(uint32_t), 0, sizeof(uint32_t));
210     if (AiaoGetMclk(rate, &mclkSel) != HDF_SUCCESS) {
211         return HDF_FAILURE;
212     }
213 
214     if (itemNum <= shift + 1) {
215         return HDF_FAILURE;
216     }
217 
218     regCfgItem[0 + shift].value = mclkSel;
219     if (AudioDaiRegUpdate(device, &regCfgItem[0 + shift]) != HDF_SUCCESS) {
220         AUDIO_DRIVER_LOG_ERR("set frequency fail.");
221         return HDF_FAILURE;
222     }
223 
224     (void)memset_s(&bclkRegVal, sizeof(uint32_t), 0, sizeof(uint32_t));
225     if (AiaoSetSysCtlRegValue(mclkSel, bitWidth, rate, &bclkRegVal) != HDF_SUCCESS) {
226         return HDF_FAILURE;
227     }
228 
229     regCfgItem[1 + shift].value = bclkRegVal;
230     if (AudioDaiRegUpdate(device, &regCfgItem[1 + shift]) != HDF_SUCCESS) {
231         AUDIO_DRIVER_LOG_ERR("set frequency fail.");
232         return HDF_FAILURE;
233     }
234     return HDF_SUCCESS;
235 }
236 
DaiParamsUpdate(const struct DaiDevice * device)237 static int32_t DaiParamsUpdate(const struct DaiDevice *device)
238 {
239     uint32_t value;
240     struct AudioMixerControl *regCfgItem = NULL;
241     const uint32_t shiftMax = 4;
242     uint32_t shift = 0;
243     const uint32_t index2 = 2;
244     const uint32_t index3 = 3;
245     uint32_t itemNum;
246 
247     if (device == NULL || device->devData == NULL || device->devData->regConfig == NULL ||
248         device->devData->regConfig->audioRegParams[AUDIO_DAI_PATAM_GROUP] == NULL ||
249         device->devData->regConfig->audioRegParams[AUDIO_DAI_PATAM_GROUP]->regCfgItem == NULL) {
250         AUDIO_DRIVER_LOG_ERR("input para is nullptr.");
251         return HDF_FAILURE;
252     }
253     regCfgItem = device->devData->regConfig->audioRegParams[AUDIO_DAI_PATAM_GROUP]->regCfgItem;
254     itemNum = device->devData->regConfig->audioRegParams[AUDIO_DAI_PATAM_GROUP]->itemNum;
255 
256     if (device->devData->pcmInfo.streamType == AUDIO_CAPTURE_STREAM) {
257         shift = shiftMax;
258     }
259 
260     if (SetIISRate(device, regCfgItem, itemNum) != HDF_SUCCESS) {
261         AUDIO_DRIVER_LOG_ERR("set Rate fail.");
262         return HDF_FAILURE;
263     }
264 
265     uint32_t bitWidth = device->devData->pcmInfo.bitWidth;
266 
267     if (bitWidth == BIT_WIDTH16) {
268         value = 0x1;
269     } else if (bitWidth == BIT_WIDTH24) {
270         value = 0x2; /* 2: 24bit */
271     } else {
272         AUDIO_DEVICE_LOG_ERR(" invalued bitWidth: %d.", bitWidth);
273         return HDF_FAILURE;
274     }
275 
276     regCfgItem[index2 + shift].value = value;
277     if (AudioDaiRegUpdate(device, &regCfgItem[index2 + shift]) != HDF_SUCCESS) {
278         AUDIO_DRIVER_LOG_ERR("set bitWidth fail.");
279         return HDF_FAILURE;
280     }
281 
282     value = device->devData->pcmInfo.channels - 1;
283     regCfgItem[index3 + shift].value = value;
284     if (AudioDaiRegUpdate(device, &regCfgItem[index3 + shift]) != HDF_SUCCESS) {
285         AUDIO_DRIVER_LOG_ERR("set channels fail.");
286         return HDF_FAILURE;
287     }
288     return HDF_SUCCESS;
289 }
290 
Hi3516DaiHwParams(const struct AudioCard * card,const struct AudioPcmHwParams * param)291 int32_t Hi3516DaiHwParams(const struct AudioCard *card, const struct AudioPcmHwParams *param)
292 {
293     uint32_t bitWidth;
294 
295     if (card == NULL || card->rtd == NULL || card->rtd->cpuDai == NULL ||
296         param == NULL || param->cardServiceName == NULL) {
297         AUDIO_DRIVER_LOG_ERR("input para is nullptr.");
298         return HDF_FAILURE;
299     }
300     struct DaiDevice *device = card->rtd->cpuDai;
301 
302     if (DaiCheckSampleRate(param->rate) != HDF_SUCCESS) {
303         return HDF_ERR_NOT_SUPPORT;
304     }
305 
306     struct DaiData *data = DaiDataFromCard(card);
307     if (data == NULL) {
308         AUDIO_DRIVER_LOG_ERR("platformHost is nullptr.");
309         return HDF_FAILURE;
310     }
311 
312     data->pcmInfo.channels = param->channels;
313 
314     if (AudioFormatToBitWidth(param->format, &bitWidth) != HDF_SUCCESS) {
315         return HDF_FAILURE;
316     }
317 
318     data->pcmInfo.bitWidth = bitWidth;
319     data->pcmInfo.rate = param->rate;
320     data->pcmInfo.streamType = param->streamType;
321     data->regVirtualAddr = (uintptr_t)g_regDaiBase;
322 
323     if (DaiParamsUpdate(device) != HDF_SUCCESS) {
324         AUDIO_DRIVER_LOG_ERR("DaiParamsUpdate:  fail.");
325         return HDF_FAILURE;
326     }
327     data->regVirtualAddr = (uintptr_t)g_regCodecBase;
328     return HDF_SUCCESS;
329 }
330