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, ®CfgItem[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, ®CfgItem[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, ®CfgItem[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, ®CfgItem[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, ®CfgItem[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