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 "audio_core.h"
10 #include "audio_driver_log.h"
11 #include "audio_sapm.h"
12 #include "devmgr_service_clnt.h"
13 #include "osal_io.h"
14 
15 #define HDF_LOG_TAG HDF_AUDIO_KADM
16 
17 #define CHANNEL_MAX_NUM 2
18 #define CHANNEL_MIN_NUM 1
19 #define AUDIO_DAI_LINK_COMPLETE 1
20 #define AUDIO_DAI_LINK_UNCOMPLETE 0
21 
22 typedef enum {
23     AUDIO_CTL_ELEM_TYPE_NONE = 0, /**< Invalid type */
24     AUDIO_CTL_ELEM_TYPE_BOOLEAN,
25     AUDIO_CTL_ELEM_TYPE_INTEGER,
26     AUDIO_CTL_ELEM_TYPE_ENUMERATED,
27     AUDIO_CTL_ELEM_TYPE_BYTES,
28     AUDIO_CTL_ELEM_TYPE_LAST = AUDIO_CTL_ELEM_TYPE_BYTES
29 } AudioCtlElemValueType;
30 
31 AUDIO_LIST_HEAD(daiController);
32 AUDIO_LIST_HEAD(platformController);
33 AUDIO_LIST_HEAD(codecController);
34 AUDIO_LIST_HEAD(dspController);
35 
AudioSocRegisterPlatform(struct HdfDeviceObject * device,struct PlatformData * platformData)36 int32_t AudioSocRegisterPlatform(struct HdfDeviceObject *device, struct PlatformData *platformData)
37 {
38     struct PlatformDevice *platformDevice = NULL;
39 
40     if (device == NULL) {
41         ADM_LOG_ERR("Input params check error: device is NULL.");
42         return HDF_ERR_INVALID_OBJECT;
43     }
44     if (platformData == NULL) {
45         ADM_LOG_ERR("Input params check error: platformData is NULL.");
46         return HDF_ERR_INVALID_OBJECT;
47     }
48 
49     platformDevice = (struct PlatformDevice *)OsalMemCalloc(sizeof(*platformDevice));
50     if (platformDevice == NULL) {
51         ADM_LOG_ERR("Malloc platformDevice device fail!");
52         return HDF_ERR_MALLOC_FAIL;
53     }
54 
55     platformDevice->devPlatformName = platformData->drvPlatformName;
56     platformDevice->devData = platformData;
57     platformDevice->device = device;
58     DListInsertHead(&platformDevice->list, &platformController);
59 
60     ADM_LOG_INFO("Register [%s] success.", platformDevice->devPlatformName);
61     return HDF_SUCCESS;
62 }
63 
AudioSocRegisterDai(struct HdfDeviceObject * device,struct DaiData * daiData)64 int32_t AudioSocRegisterDai(struct HdfDeviceObject *device, struct DaiData *daiData)
65 {
66     struct DaiDevice *dai = NULL;
67 
68     if (device == NULL) {
69         ADM_LOG_ERR("Input params check error: device is NULL");
70         return HDF_ERR_INVALID_OBJECT;
71     }
72     if (daiData == NULL) {
73         ADM_LOG_ERR("Input params check error: daiData is NULL");
74         return HDF_ERR_INVALID_OBJECT;
75     }
76 
77     dai = (struct DaiDevice *)OsalMemCalloc(sizeof(*dai));
78     if (dai == NULL) {
79         ADM_LOG_ERR("Malloc dai device fail!");
80         return HDF_ERR_MALLOC_FAIL;
81     }
82 
83     dai->devDaiName = daiData->drvDaiName;
84     dai->devData = daiData;
85     dai->device = device;
86     DListInsertHead(&dai->list, &daiController);
87     ADM_LOG_INFO("Register [%s] success.", dai->devDaiName);
88 
89     return HDF_SUCCESS;
90 }
91 
AudioRegisterCodec(struct HdfDeviceObject * device,struct CodecData * codecData,struct DaiData * daiData)92 int32_t AudioRegisterCodec(struct HdfDeviceObject *device, struct CodecData *codecData, struct DaiData *daiData)
93 {
94     struct CodecDevice *codec = NULL;
95     int32_t ret;
96 
97     if (device == NULL) {
98         ADM_LOG_ERR("Input params check error: device is NULL.");
99         return HDF_ERR_INVALID_OBJECT;
100     }
101     if (codecData == NULL) {
102         ADM_LOG_ERR("Input params check error: codecData is NULL.");
103         return HDF_ERR_INVALID_OBJECT;
104     }
105     if (daiData == NULL) {
106         ADM_LOG_ERR("Input params check error: daiData is NULL.");
107         return HDF_ERR_INVALID_OBJECT;
108     }
109 
110     codec = (struct CodecDevice *)OsalMemCalloc(sizeof(*codec));
111     if (codec == NULL) {
112         ADM_LOG_ERR("Malloc codec device fail!");
113         return HDF_ERR_MALLOC_FAIL;
114     }
115 
116     codec->devCodecName = codecData->drvCodecName;
117     codec->devData = codecData;
118     codec->device = device;
119 
120     ret = AudioSocRegisterDai(device, daiData);
121     if (ret != HDF_SUCCESS) {
122         OsalIoUnmap((void *)((uintptr_t)(codec->devData->virtualAddress)));
123         OsalMemFree(codec);
124         ADM_LOG_ERR("Register dai device fail ret=%d", ret);
125         return HDF_ERR_IO;
126     }
127     DListInsertHead(&codec->list, &codecController);
128     ADM_LOG_INFO("Register [%s] success.", codec->devCodecName);
129 
130     return HDF_SUCCESS;
131 }
132 
AudioRegisterDsp(struct HdfDeviceObject * device,struct DspData * dspData,struct DaiData * DaiData)133 int32_t AudioRegisterDsp(struct HdfDeviceObject *device, struct DspData *dspData, struct DaiData *DaiData)
134 {
135     struct DspDevice *dspDev = NULL;
136     int32_t ret;
137 
138     if (device == NULL) {
139         ADM_LOG_ERR("Input params check error: device is NULL.");
140         return HDF_ERR_INVALID_OBJECT;
141     }
142     if (dspData == NULL) {
143         ADM_LOG_ERR("Input params check error: dspData is NULL.");
144         return HDF_ERR_INVALID_OBJECT;
145     }
146     if (DaiData == NULL) {
147         ADM_LOG_ERR("Input params check error: daiData is NULL.");
148         return HDF_ERR_INVALID_OBJECT;
149     }
150 
151     dspDev = (struct DspDevice *)OsalMemCalloc(sizeof(*dspDev));
152     if (dspDev == NULL) {
153         ADM_LOG_ERR("Malloc codec device fail!");
154         return HDF_ERR_MALLOC_FAIL;
155     }
156 
157     dspDev->devDspName = dspData->drvDspName;
158     dspDev->devData = dspData;
159     dspDev->device = device;
160 
161     ret = AudioSocRegisterDai(device, DaiData);
162     if (ret != HDF_SUCCESS) {
163         OsalMemFree(dspDev);
164         ADM_LOG_ERR("Register dai device fail ret=%d", ret);
165         return HDF_ERR_IO;
166     }
167     DListInsertHead(&dspDev->list, &dspController);
168     ADM_LOG_INFO("Register [%s] success.", dspDev->devDspName);
169 
170     return HDF_SUCCESS;
171 }
172 
AudioSeekPlatformDevice(struct AudioRuntimeDeivces * rtd,const struct AudioConfigData * configData)173 static int32_t AudioSeekPlatformDevice(struct AudioRuntimeDeivces *rtd, const struct AudioConfigData *configData)
174 {
175     struct PlatformDevice *platform = NULL;
176     if (rtd == NULL || configData == NULL) {
177         ADM_LOG_ERR("Input params check error");
178         return HDF_ERR_INVALID_OBJECT;
179     }
180     if (configData->platformName == NULL) {
181         ADM_LOG_ERR("Input devicesName check error: configData->platformName is NULL.");
182         return HDF_ERR_INVALID_OBJECT;
183     }
184 
185     ADM_LOG_DEBUG("Seek platformName[%s]", configData->platformName);
186     DLIST_FOR_EACH_ENTRY(platform, &platformController, struct PlatformDevice, list) {
187         if (platform->devPlatformName != NULL &&
188             strcmp(platform->devPlatformName, configData->platformName) == 0) {
189             rtd->platform = platform;
190             break;
191         }
192     }
193 
194     return HDF_SUCCESS;
195 }
196 
AudioSeekCpuDaiDevice(struct AudioRuntimeDeivces * rtd,const struct AudioConfigData * configData)197 static int32_t AudioSeekCpuDaiDevice(struct AudioRuntimeDeivces *rtd, const struct AudioConfigData *configData)
198 {
199     struct DaiDevice *cpuDai = NULL;
200     if (rtd == NULL || configData == NULL) {
201         ADM_LOG_ERR("Input params check error");
202         return HDF_ERR_INVALID_OBJECT;
203     }
204     if (configData->cpuDaiName == NULL) {
205         ADM_LOG_ERR("Input cpuDaiName check error: configData->cpuDaiName is NULL.");
206         return HDF_ERR_INVALID_OBJECT;
207     }
208     if (DListIsEmpty(&daiController)) {
209         ADM_LOG_ERR("daiController is empty.");
210         return HDF_FAILURE;
211     }
212     ADM_LOG_DEBUG("Seek cpuDaiName[%s]", configData->cpuDaiName);
213     DLIST_FOR_EACH_ENTRY(cpuDai, &daiController, struct DaiDevice, list) {
214         if (cpuDai == NULL) {
215             return HDF_ERR_INVALID_OBJECT;
216         }
217         if (cpuDai->devDaiName != NULL &&
218             strcmp(cpuDai->devDaiName, configData->cpuDaiName) == 0) {
219             rtd->cpuDai = cpuDai;
220             break;
221         }
222     }
223 
224     return HDF_SUCCESS;
225 }
226 
AudioSeekCodecDevice(struct AudioRuntimeDeivces * rtd,const struct AudioConfigData * configData)227 static int32_t AudioSeekCodecDevice(struct AudioRuntimeDeivces *rtd, const struct AudioConfigData *configData)
228 {
229     struct CodecDevice *codec = NULL;
230     struct DaiDevice *codecDai = NULL;
231 
232     if ((rtd == NULL) || (configData == NULL)) {
233         ADM_LOG_ERR("Input params check error");
234         return HDF_ERR_INVALID_OBJECT;
235     }
236     if (configData->codecName == NULL) {
237         ADM_LOG_ERR("Input devicesName check error: configData->codecName is NULL.");
238         return HDF_ERR_INVALID_OBJECT;
239     }
240     if (configData->codecDaiName == NULL) {
241         ADM_LOG_ERR("Input devicesName check error: configData->codecDaiName is NULL.");
242         return HDF_ERR_INVALID_OBJECT;
243     }
244     ADM_LOG_DEBUG ("Seek codecName[%s] codecDaiName[%s]", configData->codecName, configData->codecDaiName);
245     DLIST_FOR_EACH_ENTRY(codec, &codecController, struct CodecDevice, list) {
246         if (codec->devCodecName != NULL && strcmp(codec->devCodecName, configData->codecName) == 0) {
247             rtd->codec = codec;
248             DLIST_FOR_EACH_ENTRY(codecDai, &daiController, struct DaiDevice, list) {
249                 if (codecDai == NULL) {
250                     return HDF_ERR_INVALID_OBJECT;
251                 }
252                 if (codecDai->device != NULL && codec->device == codecDai->device &&
253                     codecDai->devDaiName != NULL && strcmp(codecDai->devDaiName, configData->codecDaiName) == 0) {
254                     rtd->codecDai = codecDai;
255                     break;
256                 }
257             }
258             break;
259         }
260     }
261     return HDF_SUCCESS;
262 }
263 
AudioSeekDspDevice(struct AudioRuntimeDeivces * rtd,const struct AudioConfigData * configData)264 static int32_t AudioSeekDspDevice(struct AudioRuntimeDeivces *rtd, const struct AudioConfigData *configData)
265 {
266     struct DspDevice *dsp = NULL;
267     struct DaiDevice *dspDai = NULL;
268 
269     if ((rtd == NULL) || (configData == NULL)) {
270         ADM_LOG_ERR("Input params check error");
271         return HDF_ERR_INVALID_OBJECT;
272     }
273     if (configData->dspName == NULL) {
274         ADM_LOG_ERR("Input devicesName check error: configData->dspName is NULL.");
275         return HDF_ERR_INVALID_OBJECT;
276     }
277     if (configData->dspDaiName == NULL) {
278         ADM_LOG_ERR("Input devicesName check error: configData->dspDaiName is NULL.");
279         return HDF_ERR_INVALID_OBJECT;
280     }
281     ADM_LOG_DEBUG("Seek dspName[%s] dspDaiName[%s]", configData->dspName, configData->dspDaiName);
282     DLIST_FOR_EACH_ENTRY(dsp, &dspController, struct DspDevice, list) {
283         if (dsp == NULL) {
284             return HDF_ERR_INVALID_OBJECT;
285         }
286         if (dsp->devDspName != NULL && strcmp(dsp->devDspName, configData->dspName) == 0) {
287             rtd->dsp = dsp;
288             DLIST_FOR_EACH_ENTRY(dspDai, &daiController, struct DaiDevice, list) {
289                 if (dspDai == NULL) {
290                     return HDF_ERR_INVALID_OBJECT;
291                 }
292                 if (dspDai->device != NULL && dsp->device == dspDai->device &&
293                     dspDai->devDaiName != NULL && strcmp(dspDai->devDaiName, configData->dspDaiName) == 0) {
294                     rtd->dspDai = dspDai;
295                     break;
296                 }
297             }
298             break;
299         }
300     }
301 
302     return HDF_SUCCESS;
303 }
304 
AudioBindDaiLink(struct AudioCard * audioCard,const struct AudioConfigData * configData)305 int32_t AudioBindDaiLink(struct AudioCard *audioCard, const struct AudioConfigData *configData)
306 {
307     if (audioCard == NULL) {
308         ADM_LOG_ERR("Input params check error: audioCard is NULL.");
309         return HDF_ERR_INVALID_OBJECT;
310     }
311     if (configData == NULL) {
312         ADM_LOG_ERR("Input params check error: configData is NULL.");
313         return HDF_ERR_INVALID_OBJECT;
314     }
315 
316     audioCard->rtd = (struct AudioRuntimeDeivces *)OsalMemCalloc(sizeof(struct AudioRuntimeDeivces));
317     if (audioCard->rtd == NULL) {
318         ADM_LOG_ERR("Malloc audioCard->rtd fail!");
319         return HDF_ERR_MALLOC_FAIL;
320     }
321 
322     audioCard->rtd->complete = AUDIO_DAI_LINK_UNCOMPLETE;
323     if (AudioSeekPlatformDevice(audioCard->rtd, configData) == HDF_SUCCESS) {
324         ADM_LOG_INFO("PLATFORM [%s] is registered!", configData->platformName);
325     }
326     if (AudioSeekCpuDaiDevice(audioCard->rtd, configData) == HDF_SUCCESS) {
327         ADM_LOG_INFO("CPUDAI [%s] is registered!", configData->cpuDaiName);
328     }
329     if (AudioSeekCodecDevice(audioCard->rtd, configData) == HDF_SUCCESS) {
330         ADM_LOG_INFO("CODEC [%s] is registered!", configData->codecName);
331         ADM_LOG_INFO("CODECDAI [%s] is registered!", configData->codecDaiName);
332     }
333     if (AudioSeekDspDevice(audioCard->rtd, configData) == HDF_SUCCESS) {
334         ADM_LOG_INFO("DSP [%s] is registered!", configData->dspName);
335         ADM_LOG_INFO("DSPDAI [%s] is registered!", configData->dspDaiName);
336     }
337     audioCard->rtd->complete = AUDIO_DAI_LINK_COMPLETE;
338     ADM_LOG_DEBUG("All devices register complete!");
339 
340     return HDF_SUCCESS;
341 }
342 
AudioDaiReadReg(const struct DaiDevice * dai,uint32_t reg,uint32_t * val)343 int32_t AudioDaiReadReg(const struct DaiDevice *dai, uint32_t reg, uint32_t *val)
344 {
345     int32_t ret;
346 
347     if (dai == NULL || dai->devData == NULL || dai->devData->Read == NULL || val == NULL) {
348         ADM_LOG_ERR("Input param is NULL.");
349         return HDF_ERR_INVALID_OBJECT;
350     }
351 
352     ret = dai->devData->Read(dai, reg, val);
353     if (ret != HDF_SUCCESS) {
354         ADM_LOG_ERR("dai device read fail.");
355         return HDF_FAILURE;
356     }
357     return HDF_SUCCESS;
358 }
359 
AudioDaiWriteReg(const struct DaiDevice * dai,uint32_t reg,uint32_t val)360 int32_t AudioDaiWriteReg(const struct DaiDevice *dai, uint32_t reg, uint32_t val)
361 {
362     int32_t ret;
363     if (dai == NULL || dai->devData == NULL || dai->devData->Write == NULL) {
364         ADM_LOG_ERR("Input param codec is NULL.");
365         return HDF_ERR_INVALID_OBJECT;
366     }
367 
368     ret = dai->devData->Write(dai, reg, val);
369     if (ret != HDF_SUCCESS) {
370         ADM_LOG_ERR("dai device write fail.");
371         return HDF_FAILURE;
372     }
373     return HDF_SUCCESS;
374 }
375 
AudioCodecReadReg(const struct CodecDevice * codec,uint32_t reg,uint32_t * val)376 int32_t AudioCodecReadReg(const struct CodecDevice *codec, uint32_t reg, uint32_t *val)
377 {
378     int32_t ret;
379 
380     if (codec == NULL || codec->devData == NULL || codec->devData->Read == NULL || val == NULL) {
381         ADM_LOG_ERR("Input param codec is NULL.");
382         return HDF_ERR_INVALID_OBJECT;
383     }
384 
385     ret = codec->devData->Read(codec, reg, val);
386     if (ret != HDF_SUCCESS) {
387         ADM_LOG_ERR("Codec device read fail.");
388         return HDF_FAILURE;
389     }
390     return HDF_SUCCESS;
391 }
392 
AudioCodecWriteReg(const struct CodecDevice * codec,uint32_t reg,uint32_t val)393 int32_t AudioCodecWriteReg(const struct CodecDevice *codec, uint32_t reg, uint32_t val)
394 {
395     int32_t ret;
396 
397     if (codec == NULL || codec->devData == NULL || codec->devData->Write == NULL) {
398         ADM_LOG_ERR("Input param codec is NULL.");
399         return HDF_ERR_INVALID_OBJECT;
400     }
401 
402     ret = codec->devData->Write(codec, reg, val);
403     if (ret != HDF_SUCCESS) {
404         ADM_LOG_ERR("Codec device write fail.");
405         return HDF_FAILURE;
406     }
407     return HDF_SUCCESS;
408 }
409 
AudioUpdateCodecRegBits(struct CodecDevice * codec,uint32_t reg,const uint32_t mask,const uint32_t shift,uint32_t value)410 int32_t AudioUpdateCodecRegBits(struct CodecDevice *codec, uint32_t reg,
411     const uint32_t mask, const uint32_t shift, uint32_t value)
412 {
413     int32_t ret;
414     uint32_t curValue = 0;
415     uint32_t controlMask;
416     uint32_t tempVal;
417     if (codec == NULL || codec->devData == NULL) {
418         ADM_LOG_ERR("Invalid input param.");
419         return HDF_ERR_INVALID_OBJECT;
420     }
421 
422     value = value << shift;
423     controlMask = mask << shift;
424 
425     OsalMutexLock(&codec->devData->mutex);
426     ret = AudioCodecReadReg(codec, reg, &curValue);
427     if (ret != HDF_SUCCESS) {
428         OsalMutexUnlock(&codec->devData->mutex);
429         ADM_LOG_ERR("Read reg fail ret=%d.", ret);
430         return HDF_FAILURE;
431     }
432 
433     tempVal = curValue & controlMask;
434     if (tempVal == value) {
435         OsalMutexUnlock(&codec->devData->mutex);
436         ADM_LOG_DEBUG("Success.");
437         return HDF_SUCCESS;
438     }
439     curValue = (curValue & ~controlMask) | (value & controlMask);
440     ret = AudioCodecWriteReg(codec, reg, curValue);
441     if (ret != HDF_SUCCESS) {
442         OsalMutexUnlock(&codec->devData->mutex);
443         ADM_LOG_ERR("Write reg fail ret=%d", ret);
444         return HDF_FAILURE;
445     }
446     OsalMutexUnlock(&codec->devData->mutex);
447 
448     ADM_LOG_DEBUG("Success.");
449     return HDF_SUCCESS;
450 }
451 
AudioUpdateDaiRegBits(const struct DaiDevice * dai,uint32_t reg,const uint32_t mask,const uint32_t shift,uint32_t value)452 int32_t AudioUpdateDaiRegBits(const struct DaiDevice *dai, uint32_t reg,
453     const uint32_t mask, const uint32_t shift, uint32_t value)
454 {
455     int32_t ret;
456     uint32_t curValue = 0;
457     uint32_t mixerControlMask;
458     uint32_t tempVal;
459     struct DaiData *data = NULL;
460 
461     if (dai == NULL || dai->devData == NULL) {
462         ADM_LOG_ERR("Invalid input param.");
463         return HDF_ERR_INVALID_OBJECT;
464     }
465     data = dai->devData;
466     value = value << shift;
467     mixerControlMask = mask << shift;
468 
469     OsalMutexLock(&data->mutex);
470     ret = AudioDaiReadReg(dai, reg, &curValue);
471     if (ret != HDF_SUCCESS) {
472         OsalMutexUnlock(&data->mutex);
473         ADM_LOG_ERR("Read reg fail ret=%d.", ret);
474         return HDF_FAILURE;
475     }
476 
477     tempVal = curValue & mixerControlMask;
478     if (tempVal == value) {
479         OsalMutexUnlock(&data->mutex);
480         ADM_LOG_DEBUG("Success.");
481         return HDF_SUCCESS;
482     }
483     curValue = (curValue & ~mixerControlMask) | (value & mixerControlMask);
484     ret = AudioDaiWriteReg(dai, reg, curValue);
485     if (ret != HDF_SUCCESS) {
486         OsalMutexUnlock(&data->mutex);
487         ADM_LOG_ERR("Write reg fail ret=%d", ret);
488         return HDF_FAILURE;
489     }
490     OsalMutexUnlock(&data->mutex);
491 
492     ADM_LOG_DEBUG("Success.");
493     return HDF_SUCCESS;
494 }
495 
AudioCodecRegUpdate(struct CodecDevice * codec,struct AudioMixerControl * mixerCtrl)496 int32_t AudioCodecRegUpdate(struct CodecDevice *codec, struct AudioMixerControl *mixerCtrl)
497 {
498     uint32_t mixerValue;
499     if (codec == NULL || mixerCtrl == NULL) {
500         ADM_LOG_ERR("AudioKcontrolGetCodec is fail.");
501         return HDF_ERR_INVALID_OBJECT;
502     }
503 
504     mixerValue = mixerCtrl->value;
505     if (mixerValue < mixerCtrl->min || mixerValue > mixerCtrl->max) {
506         ADM_LOG_ERR("Audio codec invalid value=%u", mixerValue);
507         return HDF_ERR_INVALID_OBJECT;
508     }
509 
510     if (mixerCtrl->invert) {
511         mixerValue = mixerCtrl->max - mixerCtrl->value;
512     }
513     if (AudioUpdateCodecRegBits(codec, mixerCtrl->reg, mixerCtrl->mask, mixerCtrl->shift, mixerValue) != HDF_SUCCESS) {
514         ADM_LOG_ERR("Audio codec stereo update reg bits fail.");
515         return HDF_FAILURE;
516     }
517 
518     if (mixerCtrl->reg != mixerCtrl->rreg || mixerCtrl->shift != mixerCtrl->rshift) {
519         if (AudioUpdateCodecRegBits(codec, mixerCtrl->rreg, mixerCtrl->mask,
520             mixerCtrl->rshift, mixerValue) != HDF_SUCCESS) {
521             ADM_LOG_ERR("Audio codec stereo update reg bits fail.");
522             return HDF_FAILURE;
523         }
524     }
525 
526     return HDF_SUCCESS;
527 }
528 
AudioCodecMuxRegUpdate(struct CodecDevice * codec,struct AudioEnumKcontrol * enumCtrl,const uint32_t * value)529 int32_t AudioCodecMuxRegUpdate(struct CodecDevice *codec, struct AudioEnumKcontrol *enumCtrl, const uint32_t *value)
530 {
531     uint32_t val[2];
532     int32_t ret;
533 
534     if (codec == NULL || enumCtrl == NULL || value == NULL) {
535         ADM_LOG_ERR("input para is null.");
536         return HDF_ERR_INVALID_OBJECT;
537     }
538 
539     if (enumCtrl->values != NULL) {
540         val[0] = enumCtrl->values[value[0]];
541         val[1] = enumCtrl->values[value[1]];
542     } else {
543         val[0] = value[0];
544         val[1] = value[1];
545     }
546 
547     if (val[0] > enumCtrl->max) {
548         ADM_LOG_ERR("Audio invalid value=%u", val[0]);
549         return HDF_ERR_INVALID_OBJECT;
550     }
551     ret = AudioUpdateCodecRegBits(codec, enumCtrl->reg, enumCtrl->mask, enumCtrl->shiftLeft, val[0]);
552     if (ret != HDF_SUCCESS) {
553         ADM_LOG_ERR("update left reg bits fail!");
554         return ret;
555     }
556 
557     if (enumCtrl->reg != enumCtrl->reg2 || enumCtrl->shiftLeft != enumCtrl->shiftRight) {
558         if (val[1] > enumCtrl->max) {
559             ADM_LOG_ERR("Audio invalid value=%u", val[1]);
560             return HDF_ERR_INVALID_OBJECT;
561         }
562         ret = AudioUpdateCodecRegBits(codec, enumCtrl->reg2, enumCtrl->mask, enumCtrl->shiftRight, val[1]);
563         if (ret != HDF_SUCCESS) {
564             ADM_LOG_ERR("update right reg bits fail!");
565             return ret;
566         }
567     }
568     return HDF_SUCCESS;
569 }
570 
AudioDaiRegUpdate(const struct DaiDevice * dai,struct AudioMixerControl * mixerCtrl)571 int32_t AudioDaiRegUpdate(const struct DaiDevice *dai, struct AudioMixerControl *mixerCtrl)
572 {
573     uint32_t value;
574 
575     if (dai == NULL || mixerCtrl == NULL) {
576         ADM_LOG_ERR("AudioKcontrolGetCodec is fail.");
577         return HDF_ERR_INVALID_OBJECT;
578     }
579 
580     value = mixerCtrl->value;
581     if (value < mixerCtrl->min || value > mixerCtrl->max) {
582         ADM_LOG_ERR("Audio dai invalid value=%u", value);
583         return HDF_ERR_INVALID_OBJECT;
584     }
585 
586     if (mixerCtrl->invert) {
587         value = mixerCtrl->max - mixerCtrl->value;
588     }
589 
590     if (AudioUpdateDaiRegBits(dai, mixerCtrl->reg, mixerCtrl->mask, mixerCtrl->shift, value) != HDF_SUCCESS) {
591         ADM_LOG_ERR("Audio codec stereo update reg bits fail.");
592         return HDF_FAILURE;
593     }
594 
595     if (mixerCtrl->reg != mixerCtrl->rreg || mixerCtrl->shift != mixerCtrl->rshift) {
596         if (AudioUpdateDaiRegBits(dai, mixerCtrl->rreg, mixerCtrl->mask,
597             mixerCtrl->rshift, value) != HDF_SUCCESS) {
598             ADM_LOG_ERR("Audio codec stereo update reg bits fail.");
599             return HDF_FAILURE;
600         }
601     }
602 
603     return HDF_SUCCESS;
604 }
605 
AudioKcontrolGetCodec(const struct AudioKcontrol * kcontrol)606 struct CodecDevice *AudioKcontrolGetCodec(const struct AudioKcontrol *kcontrol)
607 {
608     struct AudioCard *audioCard = NULL;
609     if (kcontrol == NULL || kcontrol->pri == NULL) {
610         ADM_LOG_ERR("Get Codec input param kcontrol is NULL.");
611         return NULL;
612     }
613 
614     audioCard = (struct AudioCard *)((volatile uintptr_t)(kcontrol->pri));
615     if (audioCard->rtd == NULL) {
616         ADM_LOG_ERR("Get audio card or rtd fail.");
617         return NULL;
618     }
619 
620     return audioCard->rtd->codec;
621 }
622 
AudioKcontrolGetCpuDai(const struct AudioKcontrol * kcontrol)623 struct DaiDevice *AudioKcontrolGetCpuDai(const struct AudioKcontrol *kcontrol)
624 {
625     struct AudioCard *audioCard = NULL;
626     if (kcontrol == NULL || kcontrol->pri == NULL) {
627         ADM_LOG_ERR("Get CpuDai input param kcontrol is NULL.");
628         return NULL;
629     }
630 
631     audioCard = (struct AudioCard *)((volatile uintptr_t)(kcontrol->pri));
632     if (audioCard->rtd == NULL) {
633         ADM_LOG_ERR("Get audio card or rtd fail.");
634         return NULL;
635     }
636 
637     return audioCard->rtd->cpuDai;
638 }
639 
AudioAddControl(const struct AudioCard * audioCard,const struct AudioKcontrol * ctrl)640 struct AudioKcontrol *AudioAddControl(const struct AudioCard *audioCard, const struct AudioKcontrol *ctrl)
641 {
642     struct AudioKcontrol *control = NULL;
643 
644     if ((audioCard == NULL) || (ctrl == NULL)) {
645         ADM_LOG_ERR("Input params check error");
646         return NULL;
647     }
648 
649     control = (struct AudioKcontrol *)OsalMemCalloc(sizeof(*control));
650     if (control == NULL) {
651         ADM_LOG_ERR("Malloc control fail!");
652         return NULL;
653     }
654     DListHeadInit(&control->list);
655     control->name = ctrl->name;
656     control->iface = ctrl->iface;
657     control->Info = ctrl->Info;
658     control->Get = ctrl->Get;
659     control->Set = ctrl->Set;
660     control->pri = (void *)audioCard;
661     control->privateValue = ctrl->privateValue;
662 
663     return control;
664 }
665 
AudioAddControls(struct AudioCard * audioCard,const struct AudioKcontrol * controls,int32_t controlMaxNum)666 int32_t AudioAddControls(struct AudioCard *audioCard, const struct AudioKcontrol *controls, int32_t controlMaxNum)
667 {
668     struct AudioKcontrol *control = NULL;
669     int32_t i;
670     ADM_LOG_DEBUG("Entry.");
671 
672     if (audioCard == NULL) {
673         ADM_LOG_ERR("Input params check error: audioCard is NULL.");
674         return HDF_ERR_INVALID_OBJECT;
675     }
676     if (controls == NULL) {
677         ADM_LOG_ERR("Input params check error: controls is NULL.");
678         return HDF_FAILURE;
679     }
680     if (controlMaxNum <= 0) {
681         ADM_LOG_ERR("Input params check error: controlMaxNum=%d.", controlMaxNum);
682         return HDF_FAILURE;
683     }
684 
685     for (i = 0; i < controlMaxNum; i++) {
686         control = AudioAddControl(audioCard, &controls[i]);
687         if (control == NULL) {
688             ADM_LOG_ERR("Add control fail!");
689             return HDF_FAILURE;
690         }
691         DListInsertHead(&control->list, &audioCard->controls);
692     }
693     ADM_LOG_DEBUG("Success.");
694     return HDF_SUCCESS;
695 }
696 
AudioInfoCtrlOps(const struct AudioKcontrol * kcontrol,struct AudioCtrlElemInfo * elemInfo)697 int32_t AudioInfoCtrlOps(const struct AudioKcontrol *kcontrol, struct AudioCtrlElemInfo *elemInfo)
698 {
699     struct AudioMixerControl *mixerCtrl = NULL;
700 
701     if (kcontrol == NULL || kcontrol->privateValue <= 0 || elemInfo == NULL) {
702         ADM_LOG_ERR("Input param kcontrol is NULL.");
703         return HDF_ERR_INVALID_OBJECT;
704     }
705 
706     mixerCtrl = (struct AudioMixerControl *)((volatile uintptr_t)(kcontrol->privateValue));
707     if (mixerCtrl->reg != mixerCtrl->rreg || mixerCtrl->shift != mixerCtrl->rshift) {
708         /* stereo */
709         elemInfo->count = CHANNEL_MAX_NUM;
710     } else {
711         elemInfo->count = CHANNEL_MIN_NUM;
712     }
713     elemInfo->type = AUDIO_CTL_ELEM_TYPE_INTEGER;
714     elemInfo->min = mixerCtrl->min;
715     elemInfo->max = mixerCtrl->max;
716 
717     return HDF_SUCCESS;
718 }
719 
AudioInfoEnumCtrlOps(const struct AudioKcontrol * kcontrol,struct AudioCtrlElemInfo * elemInfo)720 int32_t AudioInfoEnumCtrlOps(const struct AudioKcontrol *kcontrol, struct AudioCtrlElemInfo *elemInfo)
721 {
722     struct AudioEnumKcontrol *enumCtrl = NULL;
723 
724     if (kcontrol == NULL || kcontrol->privateValue <= 0 || elemInfo == NULL) {
725         ADM_LOG_ERR("Input param kcontrol is NULL.");
726         return HDF_ERR_INVALID_OBJECT;
727     }
728 
729     enumCtrl = (struct AudioEnumKcontrol *)((volatile uintptr_t)(kcontrol->privateValue));
730     if (enumCtrl->reg != enumCtrl->reg2 || enumCtrl->shiftLeft != enumCtrl->shiftRight) {
731         /* stereo */
732         elemInfo->count = CHANNEL_MAX_NUM;
733     } else {
734         elemInfo->count = CHANNEL_MIN_NUM;
735     }
736     elemInfo->type = AUDIO_CTL_ELEM_TYPE_ENUMERATED;
737     elemInfo->min = 0;
738     elemInfo->max = enumCtrl->max;
739 
740     return HDF_SUCCESS;
741 }
742 
AudioGetCtrlOpsRReg(struct AudioCtrlElemValue * elemValue,const struct AudioMixerControl * mixerCtrl,uint32_t rcurValue)743 int32_t AudioGetCtrlOpsRReg(struct AudioCtrlElemValue *elemValue,
744     const struct AudioMixerControl *mixerCtrl, uint32_t rcurValue)
745 {
746     if (elemValue == NULL || mixerCtrl == NULL) {
747         ADM_LOG_ERR("Audio input param is NULL.");
748         return HDF_ERR_INVALID_OBJECT;
749     }
750 
751     if (mixerCtrl->reg != mixerCtrl->rreg || mixerCtrl->shift != mixerCtrl->rshift) {
752         if (mixerCtrl->reg == mixerCtrl->rreg) {
753             rcurValue = (rcurValue >> mixerCtrl->rshift) & mixerCtrl->mask;
754         } else {
755             rcurValue = (rcurValue >> mixerCtrl->shift) & mixerCtrl->mask;
756         }
757         if (rcurValue > mixerCtrl->max || rcurValue < mixerCtrl->min) {
758             ADM_LOG_ERR("Audio invalid rcurValue=%u", rcurValue);
759             return HDF_FAILURE;
760         }
761         if (mixerCtrl->invert) {
762             rcurValue = mixerCtrl->max - rcurValue;
763         }
764         elemValue->value[1] = rcurValue;
765     }
766 
767     return HDF_SUCCESS;
768 }
769 
AudioGetCtrlOpsReg(struct AudioCtrlElemValue * elemValue,const struct AudioMixerControl * mixerCtrl,uint32_t curValue)770 int32_t AudioGetCtrlOpsReg(struct AudioCtrlElemValue *elemValue,
771     const struct AudioMixerControl *mixerCtrl, uint32_t curValue)
772 {
773     if (elemValue == NULL || mixerCtrl == NULL) {
774         ADM_LOG_ERR("Audio input param is NULL.");
775         return HDF_ERR_INVALID_OBJECT;
776     }
777 
778     curValue = (curValue >> mixerCtrl->shift) & mixerCtrl->mask;
779     if (curValue > mixerCtrl->max || curValue < mixerCtrl->min) {
780         ADM_LOG_ERR("Audio invalid curValue=%u", curValue);
781         return HDF_FAILURE;
782     }
783     if (mixerCtrl->invert) {
784         curValue = mixerCtrl->max - curValue;
785     }
786     elemValue->value[0] = curValue;
787 
788     return HDF_SUCCESS;
789 }
790 
AudioGetEnumCtrlOpsReg(struct AudioCtrlElemValue * elemValue,const struct AudioEnumKcontrol * enumCtrl,uint32_t curValue)791 static int32_t AudioGetEnumCtrlOpsReg(struct AudioCtrlElemValue *elemValue,
792     const struct AudioEnumKcontrol *enumCtrl, uint32_t curValue)
793 {
794     if (elemValue == NULL || enumCtrl == NULL) {
795         ADM_LOG_ERR("Audio input param is NULL.");
796         return HDF_ERR_INVALID_OBJECT;
797     }
798 
799     curValue = (curValue >> enumCtrl->shiftLeft) & enumCtrl->mask;
800     if (curValue > enumCtrl->max) {
801         ADM_LOG_ERR("Audio invalid curValue=%u", curValue);
802         return HDF_FAILURE;
803     }
804 
805     elemValue->value[0] = curValue;
806 
807     return HDF_SUCCESS;
808 }
809 
AudioGetEnumCtrlOpsRReg(struct AudioCtrlElemValue * elemValue,const struct AudioEnumKcontrol * enumCtrl,uint32_t rcurValue)810 static int32_t AudioGetEnumCtrlOpsRReg(struct AudioCtrlElemValue *elemValue,
811     const struct AudioEnumKcontrol *enumCtrl, uint32_t rcurValue)
812 {
813     if (elemValue == NULL || enumCtrl == NULL) {
814         ADM_LOG_ERR("Audio input param is NULL.");
815         return HDF_ERR_INVALID_OBJECT;
816     }
817 
818     if (enumCtrl->reg != enumCtrl->reg2 || enumCtrl->shiftLeft != enumCtrl->shiftRight) {
819         rcurValue = (rcurValue >> enumCtrl->shiftLeft) & enumCtrl->mask;
820 
821         if (rcurValue > enumCtrl->max) {
822             ADM_LOG_ERR("Audio invalid rcurValue=%u", rcurValue);
823             return HDF_FAILURE;
824         }
825 
826         elemValue->value[1] = rcurValue;
827     }
828 
829     return HDF_SUCCESS;
830 }
831 
AudioCodecGetCtrlOps(const struct AudioKcontrol * kcontrol,struct AudioCtrlElemValue * elemValue)832 int32_t AudioCodecGetCtrlOps(const struct AudioKcontrol *kcontrol, struct AudioCtrlElemValue *elemValue)
833 {
834     uint32_t curValue = 0;
835     uint32_t rcurValue = 0;
836     struct AudioMixerControl *mixerCtrl = NULL;
837     struct CodecDevice *codec = NULL;
838     if (kcontrol == NULL || kcontrol->privateValue <= 0 || elemValue == NULL) {
839         ADM_LOG_ERR("Audio input param is NULL.");
840         return HDF_ERR_INVALID_OBJECT;
841     }
842     mixerCtrl = (struct AudioMixerControl *)((volatile uintptr_t)kcontrol->privateValue);
843     codec = AudioKcontrolGetCodec(kcontrol);
844     if (codec == NULL) {
845         ADM_LOG_ERR("mixerCtrl and codec is NULL.");
846         return HDF_FAILURE;
847     }
848     if (AudioCodecReadReg(codec, mixerCtrl->reg, &curValue) != HDF_SUCCESS ||
849         AudioCodecReadReg(codec, mixerCtrl->rreg, &rcurValue) != HDF_SUCCESS) {
850         ADM_LOG_ERR("Read Codec Reg fail.");
851         return HDF_FAILURE;
852     }
853     if (AudioGetCtrlOpsReg(elemValue, mixerCtrl, curValue) != HDF_SUCCESS ||
854         AudioGetCtrlOpsRReg(elemValue, mixerCtrl, rcurValue) != HDF_SUCCESS) {
855         ADM_LOG_ERR("Audio codec get kcontrol reg and rreg fail.");
856         return HDF_FAILURE;
857     }
858 
859     return HDF_SUCCESS;
860 }
861 
AudioCodecGetEnumCtrlOps(const struct AudioKcontrol * kcontrol,struct AudioCtrlElemValue * elemValue)862 int32_t AudioCodecGetEnumCtrlOps(const struct AudioKcontrol *kcontrol, struct AudioCtrlElemValue *elemValue)
863 {
864     uint32_t curValue = 0;
865     uint32_t rcurValue = 0;
866     struct AudioEnumKcontrol *enumCtrl = NULL;
867     struct CodecDevice *codec = NULL;
868     if (kcontrol == NULL || kcontrol->privateValue <= 0 || elemValue == NULL) {
869         ADM_LOG_ERR("Audio input param is NULL.");
870         return HDF_ERR_INVALID_OBJECT;
871     }
872     enumCtrl = (struct AudioEnumKcontrol *)((volatile uintptr_t)kcontrol->privateValue);
873     codec = AudioKcontrolGetCodec(kcontrol);
874     if (codec == NULL) {
875         ADM_LOG_ERR("mixerCtrl and codec is NULL.");
876         return HDF_FAILURE;
877     }
878     if (AudioCodecReadReg(codec, enumCtrl->reg, &curValue) != HDF_SUCCESS ||
879         AudioCodecReadReg(codec, enumCtrl->reg2, &rcurValue) != HDF_SUCCESS) {
880         ADM_LOG_ERR("Read Reg fail.");
881         return HDF_FAILURE;
882     }
883 
884     if (AudioGetEnumCtrlOpsReg(elemValue, enumCtrl, curValue) != HDF_SUCCESS ||
885         AudioGetEnumCtrlOpsRReg(elemValue, enumCtrl, rcurValue) != HDF_SUCCESS) {
886         ADM_LOG_ERR("Audio codec get kcontrol reg and rreg fail.");
887         return HDF_FAILURE;
888     }
889 
890     return HDF_SUCCESS;
891 }
892 
AudioSetCtrlOpsReg(const struct AudioKcontrol * kcontrol,const struct AudioCtrlElemValue * elemValue,const struct AudioMixerControl * mixerCtrl,uint32_t * value)893 int32_t AudioSetCtrlOpsReg(const struct AudioKcontrol *kcontrol, const struct AudioCtrlElemValue *elemValue,
894     const struct AudioMixerControl *mixerCtrl, uint32_t *value)
895 {
896     uint32_t val;
897 
898     if (kcontrol == NULL || (kcontrol->privateValue <= 0) || elemValue == NULL ||
899         mixerCtrl == NULL || value == NULL) {
900         ADM_LOG_ERR("Audio input param is NULL.");
901         return HDF_ERR_INVALID_OBJECT;
902     }
903 
904     val = elemValue->value[0];
905     if (val < mixerCtrl->min || val > mixerCtrl->max) {
906         ADM_LOG_ERR("Audio invalid value=%u", val);
907         return HDF_ERR_INVALID_OBJECT;
908     }
909     *value = mixerCtrl->invert == 0 ? val : mixerCtrl->max - val;
910 
911     return HDF_SUCCESS;
912 }
913 
AudioSetCtrlOpsRReg(const struct AudioCtrlElemValue * elemValue,struct AudioMixerControl * mixerCtrl,uint32_t * rvalue,bool * updateRReg)914 int32_t AudioSetCtrlOpsRReg(const struct AudioCtrlElemValue *elemValue,
915     struct AudioMixerControl *mixerCtrl, uint32_t *rvalue, bool *updateRReg)
916 {
917     uint32_t val;
918 
919     if (elemValue == NULL || mixerCtrl == NULL || rvalue == NULL || updateRReg == NULL) {
920         ADM_LOG_ERR("Audio input param is NULL.");
921         return HDF_ERR_INVALID_OBJECT;
922     }
923 
924     if (mixerCtrl->reg != mixerCtrl->rreg || mixerCtrl->shift != mixerCtrl->rshift) {
925         val = elemValue->value[1];
926         if (val < mixerCtrl->min || val > mixerCtrl->max) {
927             ADM_LOG_ERR("Audio invalid fail.");
928             return HDF_FAILURE;
929         }
930 
931         if (mixerCtrl->reg == mixerCtrl->rreg) {
932             mixerCtrl->shift = mixerCtrl->rshift;
933         }
934         *rvalue = mixerCtrl->invert == 0 ? val : mixerCtrl->max - val;
935         *updateRReg = true;
936     }
937 
938     return HDF_SUCCESS;
939 }
940 
AudioCodecSetCtrlOps(const struct AudioKcontrol * kcontrol,const struct AudioCtrlElemValue * elemValue)941 int32_t AudioCodecSetCtrlOps(const struct AudioKcontrol *kcontrol, const struct AudioCtrlElemValue *elemValue)
942 {
943     uint32_t value = 0;
944     uint32_t rvalue = 0;
945     bool updateRReg = false;
946     struct CodecDevice *codec = NULL;
947     struct AudioMixerControl *mixerCtrl = NULL;
948 
949     if (kcontrol == NULL || (kcontrol->privateValue <= 0) || elemValue == NULL) {
950         ADM_LOG_ERR("Audio codec set control register input param is NULL.");
951         return HDF_ERR_INVALID_OBJECT;
952     }
953 
954     codec = AudioKcontrolGetCodec(kcontrol);
955     if (codec == NULL) {
956         ADM_LOG_ERR("AudioKcontrolGetCodec is fail.");
957         return HDF_ERR_INVALID_OBJECT;
958     }
959 
960     mixerCtrl = (struct AudioMixerControl *)((volatile uintptr_t)kcontrol->privateValue);
961     if (AudioSetCtrlOpsReg(kcontrol, elemValue, mixerCtrl, &value) != HDF_SUCCESS) {
962         ADM_LOG_ERR("AudioSetCtrlOpsReg is fail.");
963         return HDF_ERR_INVALID_OBJECT;
964     }
965 
966     if (AudioUpdateCodecRegBits(codec, mixerCtrl->reg, mixerCtrl->mask, mixerCtrl->shift, value) != HDF_SUCCESS) {
967         ADM_LOG_ERR("Audio codec stereo update reg bits fail.");
968         return HDF_FAILURE;
969     }
970 
971     if (AudioSetCtrlOpsRReg(elemValue, mixerCtrl, &rvalue, &updateRReg) != HDF_SUCCESS) {
972         ADM_LOG_ERR("AudioSetCtrlOpsRReg is fail.");
973         return HDF_ERR_INVALID_OBJECT;
974     }
975 
976     if (updateRReg) {
977         if (AudioUpdateCodecRegBits(codec, mixerCtrl->rreg, mixerCtrl->mask,
978             mixerCtrl->rshift, rvalue) != HDF_SUCCESS) {
979             ADM_LOG_ERR("Audio codec stereo update reg bits fail.");
980             return HDF_FAILURE;
981         }
982     }
983 
984     return HDF_SUCCESS;
985 }
986 
AudioCodecSetEnumRegUpdate(struct CodecDevice * codec,const struct AudioEnumKcontrol * enumCtrl,const uint32_t * value)987 static int32_t AudioCodecSetEnumRegUpdate(struct CodecDevice *codec, const struct AudioEnumKcontrol *enumCtrl,
988     const uint32_t *value)
989 {
990     uint32_t setVal[2];
991     int32_t ret;
992 
993     if (codec == NULL || enumCtrl == NULL || value == NULL) {
994         ADM_LOG_ERR("Audio input param is NULL.");
995         return HDF_ERR_INVALID_OBJECT;
996     }
997 
998     if (enumCtrl->values != NULL) {
999         setVal[0] = enumCtrl->values[value[0]];
1000         setVal[1] = enumCtrl->values[value[1]];
1001     } else {
1002         setVal[0] = value[0];
1003         setVal[1] = value[1];
1004     }
1005 
1006     if (setVal[0] > enumCtrl->max) {
1007         ADM_LOG_ERR("Audio invalid value=%u", setVal[0]);
1008         return HDF_ERR_INVALID_OBJECT;
1009     }
1010     ret = AudioUpdateCodecRegBits(codec, enumCtrl->reg, enumCtrl->mask, enumCtrl->shiftLeft, setVal[0]);
1011     if (ret != HDF_SUCCESS) {
1012         ADM_LOG_ERR("Audio codec stereo update reg bits fail.");
1013         return HDF_FAILURE;
1014     }
1015 
1016     if (enumCtrl->reg != enumCtrl->reg2 || enumCtrl->shiftLeft != enumCtrl->shiftRight) {
1017         if (setVal[1] > enumCtrl->max) {
1018             ADM_LOG_ERR("Audio invalid value=%u", setVal[1]);
1019             return HDF_ERR_INVALID_OBJECT;
1020         }
1021         ret = AudioUpdateCodecRegBits(codec, enumCtrl->reg2, enumCtrl->mask, enumCtrl->shiftRight, setVal[1]);
1022         if (ret != HDF_SUCCESS) {
1023             ADM_LOG_ERR("Audio codec stereo update reg bits fail.");
1024             return HDF_FAILURE;
1025         }
1026     }
1027 
1028     return HDF_SUCCESS;
1029 }
1030 
AudioCodecSetEnumCtrlOps(const struct AudioKcontrol * kcontrol,const struct AudioCtrlElemValue * elemValue)1031 int32_t AudioCodecSetEnumCtrlOps(const struct AudioKcontrol *kcontrol, const struct AudioCtrlElemValue *elemValue)
1032 {
1033     struct CodecDevice *codec = NULL;
1034     struct AudioEnumKcontrol *enumCtrl = NULL;
1035     int32_t ret;
1036     if (kcontrol == NULL || (kcontrol->privateValue <= 0) || elemValue == NULL) {
1037         ADM_LOG_ERR("Audio input param is NULL.");
1038         return HDF_ERR_INVALID_OBJECT;
1039     }
1040     codec = AudioKcontrolGetCodec(kcontrol);
1041     if (codec == NULL) {
1042         ADM_LOG_ERR("AudioKcontrolGetCodec is fail.");
1043         return HDF_ERR_INVALID_OBJECT;
1044     }
1045     enumCtrl = (struct AudioEnumKcontrol *)((volatile uintptr_t)kcontrol->privateValue);
1046     ret = AudioCodecSetEnumRegUpdate(codec, enumCtrl, (uint32_t *)elemValue->value);
1047     if (ret != HDF_SUCCESS) {
1048         ADM_LOG_ERR("AudioCodecSetEnumRegUpdate fail.");
1049         return HDF_FAILURE;
1050     }
1051     return HDF_SUCCESS;
1052 }
1053 
AudioCpuDaiSetCtrlOps(const struct AudioKcontrol * kcontrol,const struct AudioCtrlElemValue * elemValue)1054 int32_t AudioCpuDaiSetCtrlOps(const struct AudioKcontrol *kcontrol, const struct AudioCtrlElemValue *elemValue)
1055 {
1056     uint32_t value;
1057     uint32_t rvalue;
1058     bool updateRReg = false;
1059     struct DaiDevice *dai = NULL;
1060     struct AudioMixerControl *mixerCtrl = NULL;
1061     if (kcontrol == NULL || (kcontrol->privateValue <= 0) || elemValue == NULL) {
1062         ADM_LOG_ERR("Audio cpu dai set control register input param is NULL.");
1063         return HDF_ERR_INVALID_OBJECT;
1064     }
1065 
1066     mixerCtrl = (struct AudioMixerControl *)((volatile uintptr_t)kcontrol->privateValue);
1067     if (AudioSetCtrlOpsReg(kcontrol, elemValue, mixerCtrl, &value) != HDF_SUCCESS) {
1068         ADM_LOG_ERR("AudioSetCtrlOpsReg is fail.");
1069         return HDF_ERR_INVALID_OBJECT;
1070     }
1071     dai = AudioKcontrolGetCpuDai(kcontrol);
1072     if (dai == NULL) {
1073         ADM_LOG_ERR("AudioKcontrolGetCodec is fail.");
1074         return HDF_ERR_INVALID_OBJECT;
1075     }
1076     if (AudioUpdateDaiRegBits(dai, mixerCtrl->reg, mixerCtrl->mask, mixerCtrl->shift, value) != HDF_SUCCESS) {
1077         ADM_LOG_ERR("Audio codec stereo update reg bits fail.");
1078         return HDF_FAILURE;
1079     }
1080 
1081     if (AudioSetCtrlOpsRReg(elemValue, mixerCtrl, &rvalue, &updateRReg) != HDF_SUCCESS) {
1082         ADM_LOG_ERR("AudioSetCtrlOpsRReg is fail.");
1083         return HDF_ERR_INVALID_OBJECT;
1084     }
1085 
1086     if (updateRReg) {
1087         if (AudioUpdateDaiRegBits(dai, mixerCtrl->rreg, mixerCtrl->mask, mixerCtrl->rshift, rvalue) != HDF_SUCCESS) {
1088             ADM_LOG_ERR("Audio codec stereo update reg bits fail.");
1089             return HDF_FAILURE;
1090         }
1091     }
1092     return HDF_SUCCESS;
1093 }
1094 
AudioCpuDaiGetCtrlOps(const struct AudioKcontrol * kcontrol,struct AudioCtrlElemValue * elemValue)1095 int32_t AudioCpuDaiGetCtrlOps(const struct AudioKcontrol *kcontrol, struct AudioCtrlElemValue *elemValue)
1096 {
1097     uint32_t curValue = 0;
1098     uint32_t rcurValue = 0;
1099     struct AudioMixerControl *mixerCtrl = NULL;
1100     struct DaiDevice *dai = NULL;
1101     if (kcontrol == NULL || kcontrol->privateValue <= 0 || elemValue == NULL) {
1102         ADM_LOG_ERR("Audio input param is NULL.");
1103         return HDF_ERR_INVALID_OBJECT;
1104     }
1105     mixerCtrl = (struct AudioMixerControl *)((volatile uintptr_t)kcontrol->privateValue);
1106     dai = AudioKcontrolGetCpuDai(kcontrol);
1107     if (dai == NULL) {
1108         ADM_LOG_ERR("mixerCtrl and codec is NULL.");
1109         return HDF_FAILURE;
1110     }
1111     if (AudioDaiReadReg(dai, mixerCtrl->reg, &curValue) != HDF_SUCCESS ||
1112         AudioDaiReadReg(dai, mixerCtrl->rreg, &rcurValue) != HDF_SUCCESS) {
1113         ADM_LOG_ERR("Read dai Reg fail.");
1114         return HDF_FAILURE;
1115     }
1116     if (AudioGetCtrlOpsReg(elemValue, mixerCtrl, curValue) != HDF_SUCCESS ||
1117         AudioGetCtrlOpsRReg(elemValue, mixerCtrl, rcurValue) != HDF_SUCCESS) {
1118         ADM_LOG_ERR("Audio dai get kcontrol reg and rreg fail.");
1119         return HDF_FAILURE;
1120     }
1121 
1122     return HDF_SUCCESS;
1123 }
1124 
1125