• 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 "hi3516_codec_impl.h"
11 #include "audio_control.h"
12 #include "audio_core.h"
13 #include "audio_driver_log.h"
14 #include "audio_platform_base.h"
15 #include "osal_io.h"
16 #include <asm/io.h>
17 
18 #define HDF_LOG_TAG hi3516_codec_impl
19 
20 static void *g_regAcodecBase = NULL; // CODEC Reg Base Addr
21 const int HALF_MINUTE = 30;
22 const int VOLUME_DB_MAX = 6;
23 const int VOLUME_DB_MIN = -121;
24 
CodecHalSysInit(struct CodecData * codeData)25 int32_t CodecHalSysInit(struct CodecData *codeData)
26 {
27     if (codeData == NULL) {
28         AUDIO_DEVICE_LOG_ERR("input invalid parameter.");
29         return HDF_ERR_INVALID_PARAM;
30     }
31     // ACODEC REMAP
32     if (g_regAcodecBase == NULL) {
33         g_regAcodecBase = (void *)(uintptr_t)(codeData->virtualAddress);
34         if (g_regAcodecBase == NULL) {
35             AUDIO_DEVICE_LOG_ERR("regAcodecBase is null.");
36             return HDF_FAILURE;
37         }
38     }
39     return HDF_SUCCESS;
40 }
41 
42 // Read contrl reg bits value
CodecRegBitsRead(struct AudioMixerControl * regAttr,uint32_t * regValue)43 int32_t CodecRegBitsRead(struct AudioMixerControl *regAttr, uint32_t *regValue)
44 {
45     if (g_regAcodecBase == NULL || regAttr == NULL ||
46         regAttr->reg < 0 || regValue == NULL) {
47         AUDIO_DEVICE_LOG_ERR("input invalid parameter.");
48         return HDF_ERR_INVALID_PARAM;
49     }
50     regAttr->value = SysReadl((uintptr_t)g_regAcodecBase + regAttr->reg);
51     *regValue = regAttr->value;
52     regAttr->value = (*regValue >> regAttr->shift) & regAttr->mask;
53     if (regAttr->value > regAttr->max || regAttr->value < regAttr->min) {
54         AUDIO_DEVICE_LOG_DEBUG("invalid bitsValue=0x%x", regAttr->value);
55         return HDF_FAILURE;
56     }
57     if (regAttr->invert) {
58         regAttr->value = regAttr->max - regAttr->value;
59     }
60     return HDF_SUCCESS;
61 }
62 
63 // Update contrl reg bits value
CodecRegBitsUpdate(struct AudioMixerControl regAttr)64 int32_t CodecRegBitsUpdate(struct AudioMixerControl regAttr)
65 {
66     int32_t ret;
67     uint32_t newValue, newMask, oldValue;
68     if (g_regAcodecBase == NULL || regAttr.reg < 0) {
69         AUDIO_DEVICE_LOG_ERR("input invalid parameter.");
70         return HDF_ERR_INVALID_PARAM;
71     }
72     if (regAttr.invert) {
73         regAttr.value = regAttr.max - regAttr.value;
74     }
75     newValue = regAttr.value << regAttr.shift;
76     newMask = regAttr.mask << regAttr.shift;
77     ret = CodecRegBitsRead(&regAttr, &oldValue);
78     if (ret != HDF_SUCCESS) {
79         ADM_LOG_ERR("CodecRegBitsRead failed, ret=%d.", ret);
80         return HDF_FAILURE;
81     }
82     regAttr.value = (oldValue & ~newMask) | (newValue & newMask);
83     SysWritel((uintptr_t)g_regAcodecBase + regAttr.reg, regAttr.value);
84     return HDF_SUCCESS;
85 }
86 
CodecRegDefaultInit(struct AudioRegCfgGroupNode ** regCfgGroup)87 int32_t CodecRegDefaultInit(struct AudioRegCfgGroupNode **regCfgGroup)
88 {
89     int32_t i;
90     struct AudioAddrConfig *regAttr = NULL;
91     if (g_regAcodecBase == NULL || regCfgGroup == NULL || regCfgGroup[AUDIO_INIT_GROUP] == NULL ||
92         regCfgGroup[AUDIO_INIT_GROUP]->addrCfgItem == NULL || regCfgGroup[AUDIO_INIT_GROUP]->itemNum <= 0) {
93         AUDIO_DEVICE_LOG_ERR("input invalid parameter.");
94         return HDF_FAILURE;
95     }
96     regAttr = regCfgGroup[AUDIO_INIT_GROUP]->addrCfgItem;
97 
98     for (i = 0; i < regCfgGroup[AUDIO_INIT_GROUP]->itemNum; i++) {
99         SysWritel((uintptr_t)g_regAcodecBase + regAttr[i].addr, regAttr[i].value);
100     }
101     AUDIO_DEVICE_LOG_DEBUG("success.");
102     return HDF_SUCCESS;
103 }
104 
CodecGetI2sFs(const unsigned int rate)105 static unsigned int CodecGetI2sFs(const unsigned int rate)
106 {
107     switch (rate) {
108         case AUDIO_SAMPLE_RATE_8000:
109         case AUDIO_SAMPLE_RATE_11025:
110         case AUDIO_SAMPLE_RATE_12000:
111             return ACODEC_I2S_FS_8000;
112         case AUDIO_SAMPLE_RATE_16000:
113         case AUDIO_SAMPLE_RATE_22050:
114         case AUDIO_SAMPLE_RATE_24000:
115             return ACODEC_I2S_FS_16000;
116         case AUDIO_SAMPLE_RATE_32000:
117         case AUDIO_SAMPLE_RATE_44100:
118         case AUDIO_SAMPLE_RATE_48000:
119             return ACODEC_I2S_FS_32000;
120         case AUDIO_SAMPLE_RATE_64000:
121         case AUDIO_SAMPLE_RATE_96000:
122             return ACODEC_I2S_FS_64000;
123         default:
124             AUDIO_DEVICE_LOG_DEBUG("unsupport samplerate %d\n", rate);
125             return ACODEC_I2S_FS_BUTT;
126     }
127 }
128 
CodecGetAdcModeSel(const unsigned int rate)129 static unsigned int CodecGetAdcModeSel(const unsigned int rate)
130 {
131     switch (rate) {
132         case AUDIO_SAMPLE_RATE_8000:
133         case AUDIO_SAMPLE_RATE_16000:
134         case AUDIO_SAMPLE_RATE_32000:
135         case AUDIO_SAMPLE_RATE_64000:
136             return ACODEC_ADC_MODESEL_4096;
137         case AUDIO_SAMPLE_RATE_11025:
138         case AUDIO_SAMPLE_RATE_12000:
139         case AUDIO_SAMPLE_RATE_22050:
140         case AUDIO_SAMPLE_RATE_24000:
141         case AUDIO_SAMPLE_RATE_44100:
142         case AUDIO_SAMPLE_RATE_48000:
143         case AUDIO_SAMPLE_RATE_96000:
144             return ACODEC_ADC_MODESEL_6144;
145         default:
146             AUDIO_DEVICE_LOG_DEBUG("unsupport samplerate %d.\n", rate);
147             return ACODEC_I2S_FS_BUTT;
148     }
149 }
150 
CodecGetI2s1DataWidth(unsigned int bitWidth,uint16_t * i2s1DataWidth)151 static int32_t CodecGetI2s1DataWidth(unsigned int bitWidth, uint16_t *i2s1DataWidth)
152 {
153     if (i2s1DataWidth == NULL) {
154         AUDIO_DEVICE_LOG_ERR("input param is NULL");
155         return HDF_FAILURE;
156     }
157     *i2s1DataWidth = AUDIO_CODEC_BIT_WIDTH_16;
158     switch (bitWidth) {
159         case BIT_WIDTH16:
160             *i2s1DataWidth = AUDIO_CODEC_BIT_WIDTH_16;
161             break;
162         case BIT_WIDTH18:
163             *i2s1DataWidth = AUDIO_CODEC_BIT_WIDTH_18;
164             break;
165         case BIT_WIDTH20:
166             *i2s1DataWidth = AUDIO_CODEC_BIT_WIDTH_20;
167             break;
168         case BIT_WIDTH24:
169             *i2s1DataWidth = AUDIO_CODEC_BIT_WIDTH_24;
170             break;
171         default:
172             AUDIO_DEVICE_LOG_ERR("unsupport sample bit width %d.\n", bitWidth);
173             return AUDIO_CODEC_BIT_WIDTH_BUTT;
174     }
175     return HDF_SUCCESS;
176 }
177 
CodecDaiParamsUpdate(struct AudioRegCfgGroupNode ** regCfgGroup,struct CodecDaiParamsVal codecDaiParamsVal)178 int32_t CodecDaiParamsUpdate(struct AudioRegCfgGroupNode **regCfgGroup,
179     struct CodecDaiParamsVal codecDaiParamsVal)
180 {
181     int32_t ret;
182     const int itemNum = 3; // current only 3 items
183     struct AudioMixerControl *regAttr = NULL;
184     uint16_t codecBitWidth;
185 
186     ret = (regCfgGroup == NULL
187         || regCfgGroup[AUDIO_DAI_PATAM_GROUP] == NULL
188         || regCfgGroup[AUDIO_DAI_PATAM_GROUP]->regCfgItem == NULL
189         || regCfgGroup[AUDIO_DAI_PATAM_GROUP]->itemNum < itemNum);
190     if (ret) {
191         AUDIO_DEVICE_LOG_ERR("input invalid parameter.");
192         return HDF_FAILURE;
193     }
194     regAttr = regCfgGroup[AUDIO_DAI_PATAM_GROUP]->regCfgItem;
195 
196     regAttr[0].value = CodecGetI2sFs(codecDaiParamsVal.frequencyVal);
197     ret = CodecRegBitsUpdate(regAttr[0]);               // i2s_frequency
198     if (ret != HDF_SUCCESS) {
199         AUDIO_DEVICE_LOG_ERR("set i2s_frequency failed.");
200         return HDF_FAILURE;
201     }
202     regAttr[1].value = CodecGetAdcModeSel(codecDaiParamsVal.frequencyVal);
203     ret = CodecRegBitsUpdate(regAttr[1]);           // adc_mode_sel
204     if (ret != HDF_SUCCESS) {
205         AUDIO_DEVICE_LOG_ERR("set adc_mode_sel failed.");
206         return HDF_FAILURE;
207     }
208 
209     ret = CodecGetI2s1DataWidth(codecDaiParamsVal.formatVal, &codecBitWidth);
210     if (ret != HDF_SUCCESS) {
211         AUDIO_DEVICE_LOG_ERR("I2s1DataWidthSel failed.");
212         return HDF_FAILURE;
213     }
214     regAttr[itemNum - 1].value = codecBitWidth;         // i2s_datawith
215     ret = CodecRegBitsUpdate(regAttr[itemNum - 1]);
216     if (ret != HDF_SUCCESS) {
217         AUDIO_DEVICE_LOG_ERR("set i2s_datawith failed.");
218         return HDF_FAILURE;
219     }
220     AUDIO_DEVICE_LOG_DEBUG("success.");
221     return HDF_SUCCESS;
222 }
223 
CodecSetAdcTuneEnable(struct AudioRegCfgGroupNode ** regCfgGroup)224 int32_t CodecSetAdcTuneEnable(struct AudioRegCfgGroupNode **regCfgGroup)
225 {
226     int32_t ret;
227     struct AudioMixerControl *regAttr = NULL;
228     const int itemNum = 1;
229     ret = (regCfgGroup == NULL || regCfgGroup[AUDIO_DAI_STARTUP_PATAM_GROUP] == NULL
230         || regCfgGroup[AUDIO_DAI_STARTUP_PATAM_GROUP]->regCfgItem == NULL
231         || regCfgGroup[AUDIO_DAI_STARTUP_PATAM_GROUP]->itemNum < itemNum);
232     if (ret) {
233         AUDIO_DEVICE_LOG_ERR("input invalid parameter.");
234         return HDF_FAILURE;
235     }
236     regAttr = regCfgGroup[AUDIO_DAI_STARTUP_PATAM_GROUP]->regCfgItem;
237     ret = CodecRegBitsUpdate(regAttr[0]);
238     if (ret != HDF_SUCCESS) {
239         AUDIO_DEVICE_LOG_ERR("set adc_tune_En09 failed.");
240         return HDF_FAILURE;
241     }
242     AUDIO_DEVICE_LOG_DEBUG("success.");
243     return HDF_SUCCESS;
244 }
245 
AudioCodecAiaoGetCtrlOps(const struct AudioKcontrol * kcontrol,struct AudioCtrlElemValue * elemValue)246 int32_t AudioCodecAiaoGetCtrlOps(const struct AudioKcontrol *kcontrol, struct AudioCtrlElemValue *elemValue)
247 {
248     uint32_t curValue;
249     uint32_t rcurValue;
250     void *codecVir = NULL;
251     struct AudioMixerControl *mixerCtrl = NULL;
252     if (kcontrol == NULL || kcontrol->privateValue <= 0 || elemValue == NULL) {
253         AUDIO_DEVICE_LOG_ERR("Audio input param is NULL.");
254         return HDF_ERR_INVALID_OBJECT;
255     }
256     mixerCtrl = (struct AudioMixerControl *)((volatile uintptr_t)kcontrol->privateValue);
257     if (mixerCtrl == NULL) {
258         AUDIO_DEVICE_LOG_ERR("mixerCtrl is NULL.");
259         return HDF_FAILURE;
260     }
261     codecVir = OsalIoRemap(AIAO_REG_BASE, AIAO_MAX_REG_SIZE);
262     if (codecVir == NULL) {
263         AUDIO_DEVICE_LOG_ERR("codecVir is NULL.");
264         return HDF_FAILURE;
265     }
266     curValue = OSAL_READL((void *)((uintptr_t)codecVir + mixerCtrl->reg));
267     rcurValue = OSAL_READL((void *)((uintptr_t)codecVir + mixerCtrl->rreg));
268     OsalIoUnmap(codecVir);
269 
270     if (AudioGetCtrlOpsReg(elemValue, mixerCtrl, curValue) != HDF_SUCCESS ||
271         AudioGetCtrlOpsRReg(elemValue, mixerCtrl, rcurValue) != HDF_SUCCESS) {
272         AUDIO_DEVICE_LOG_ERR("Audio codec get kcontrol reg and rreg failed.");
273         return HDF_FAILURE;
274     }
275 
276     return HDF_SUCCESS;
277 }
278 
AudioUpdateCodecAiaoRegBits(const struct AudioMixerControl * mixerControl,uint32_t value)279 static void AudioUpdateCodecAiaoRegBits(const struct AudioMixerControl *mixerControl, uint32_t value)
280 {
281     if (mixerControl == NULL) {
282         AUDIO_DEVICE_LOG_ERR("param mixerControl is null.");
283         return;
284     }
285 
286     uint32_t curValue;
287     void *codecVir = NULL;
288     uint32_t mixerControlMask;
289 
290     value = value << mixerControl->shift;
291     mixerControlMask = mixerControl->mask << mixerControl->shift;
292     codecVir = OsalIoRemap(AIAO_REG_BASE, AIAO_MAX_REG_SIZE);
293     if (codecVir == NULL) {
294         AUDIO_DEVICE_LOG_ERR("codecVir is NULL.");
295         return;
296     }
297 
298     curValue = OSAL_READL((void *)((uintptr_t)codecVir + mixerControl->reg));
299     curValue = (curValue & ~mixerControlMask) | (value & mixerControlMask);
300     OSAL_WRITEL(curValue, (void *)((uintptr_t)codecVir + mixerControl->reg));
301     OsalIoUnmap(codecVir);
302 }
303 
AudioCodecAiaoSetCtrlOps(const struct AudioKcontrol * kcontrol,const struct AudioCtrlElemValue * elemValue)304 int32_t AudioCodecAiaoSetCtrlOps(const struct AudioKcontrol *kcontrol, const struct AudioCtrlElemValue *elemValue)
305 {
306     uint32_t value;
307     uint32_t rvalue;
308     bool updateRReg = false;
309     struct AudioMixerControl *mixerCtrl = NULL;
310     if (kcontrol == NULL || (kcontrol->privateValue <= 0) || elemValue == NULL) {
311         AUDIO_DEVICE_LOG_ERR("Audio input param is NULL.");
312         return HDF_ERR_INVALID_OBJECT;
313     }
314 
315     mixerCtrl = (struct AudioMixerControl *)((volatile uintptr_t)kcontrol->privateValue);
316     if (AudioSetCtrlOpsReg(kcontrol, elemValue, mixerCtrl, &value) != HDF_SUCCESS) {
317         AUDIO_DEVICE_LOG_ERR("AudioSetCtrlOpsReg is failed.");
318         return HDF_ERR_INVALID_OBJECT;
319     }
320     AudioUpdateCodecAiaoRegBits(mixerCtrl, value);
321     if (AudioSetCtrlOpsRReg(elemValue, mixerCtrl, &rvalue, &updateRReg) != HDF_SUCCESS) {
322         AUDIO_DEVICE_LOG_ERR("AudioSetCtrlOpsRReg is failed.");
323         return HDF_ERR_INVALID_OBJECT;
324     }
325     if (updateRReg) {
326         AudioUpdateCodecAiaoRegBits(mixerCtrl, rvalue);
327     }
328 
329     return HDF_SUCCESS;
330 }
331