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