1/*
2 * Copyright (c) 2022 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 *     http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16#include "alsa_snd_capture.h"
17#include "common.h"
18
19#define HDF_LOG_TAG HDF_AUDIO_HAL_CAPTURE
20
21typedef struct _CAPTURE_DATA_ {
22    struct AlsaMixerCtlElement ctrlLeftVolume;
23    struct AlsaMixerCtlElement ctrlRightVolume;
24    long tempVolume;
25}CaptureData;
26
27static int32_t CaptureInitImpl(struct AlsaCapture* captureIns)
28{
29    if (captureIns->priData != NULL) {
30        return HDF_SUCCESS;
31    }
32    CHECK_NULL_PTR_RETURN_DEFAULT(captureIns);
33
34    CaptureData *priData = (CaptureData *)OsalMemCalloc(sizeof(CaptureData));
35    if (priData == NULL) {
36        AUDIO_FUNC_LOGE("Failed to allocate memory!");
37        return HDF_FAILURE;
38    }
39
40    SndElementItemInit(&priData->ctrlLeftVolume);
41    SndElementItemInit(&priData->ctrlRightVolume);
42    priData->ctrlLeftVolume.numid = SND_NUMID_DACL_CAPTURE_VOL;
43    priData->ctrlLeftVolume.name = SND_ELEM_DACL_CAPTURE_VOL;
44    priData->ctrlRightVolume.numid = SND_NUMID_DACR_CAPTURE_VOL;
45    priData->ctrlRightVolume.name = SND_ELEM_DACR_CAPTURE_VOL;
46    CaptureSetPriData(captureIns, (CapturePriData)priData);
47
48    return HDF_SUCCESS;
49}
50
51static int32_t CaptureSelectSceneImpl(struct AlsaCapture *captureIns, enum AudioPortPin descPins,
52    const struct PathDeviceInfo *deviceInfo)
53{
54    captureIns->descPins = descPins;
55    return HDF_SUCCESS;
56}
57
58static int32_t CaptureGetVolThresholdImpl(struct AlsaCapture *captureIns, long *volMin, long *volMax)
59{
60    int32_t ret;
61    long _volMin = 0;
62    long _volMax = 0;
63    struct AlsaSoundCard *cardIns = (struct AlsaSoundCard *)captureIns;
64    CaptureData *priData = CaptureGetPriData(captureIns);
65    CHECK_NULL_PTR_RETURN_DEFAULT(cardIns);
66    CHECK_NULL_PTR_RETURN_DEFAULT(priData);
67
68    ret = SndElementReadRange(cardIns, &priData->ctrlLeftVolume, &_volMin, &_volMax);
69    if (ret != HDF_SUCCESS) {
70        AUDIO_FUNC_LOGE("SndElementReadRange fail!");
71        return HDF_FAILURE;
72    }
73    *volMin = _volMin;
74    *volMax = _volMax;
75
76    return HDF_SUCCESS;
77}
78
79static int32_t CaptureGetVolumeImpl(struct AlsaCapture *captureIns, long *volume)
80{
81    int32_t ret;
82    long volLeft = 0;
83    long volRight = 0;
84    struct AlsaSoundCard *cardIns = (struct AlsaSoundCard *)captureIns;
85    CaptureData *priData = CaptureGetPriData(captureIns);
86    CHECK_NULL_PTR_RETURN_DEFAULT(cardIns);
87    CHECK_NULL_PTR_RETURN_DEFAULT(priData);
88
89    ret = SndElementReadInt(cardIns, &priData->ctrlLeftVolume, &volLeft);
90    if (ret != HDF_SUCCESS) {
91        AUDIO_FUNC_LOGE("Read left volume fail!");
92        return HDF_FAILURE;
93    }
94    ret = SndElementReadInt(cardIns, &priData->ctrlRightVolume, &volRight);
95    if (ret != HDF_SUCCESS) {
96        AUDIO_FUNC_LOGE("Read right volume fail!");
97        return HDF_FAILURE;
98    }
99    *volume = (volLeft + volRight) >> 1;
100
101    return HDF_SUCCESS;
102}
103
104static int32_t CaptureSetVolumeImpl(struct AlsaCapture *captureIns, long volume)
105{
106    int32_t ret;
107    struct AlsaSoundCard *cardIns = (struct AlsaSoundCard *)captureIns;
108    CaptureData *priData = CaptureGetPriData(captureIns);
109    CHECK_NULL_PTR_RETURN_DEFAULT(cardIns);
110    CHECK_NULL_PTR_RETURN_DEFAULT(priData);
111    ret = SndElementWriteInt(cardIns, &priData->ctrlLeftVolume, volume);
112    if (ret != HDF_SUCCESS) {
113        AUDIO_FUNC_LOGE("Write left volume fail!");
114        return HDF_FAILURE;
115    }
116    ret = SndElementWriteInt(cardIns, &priData->ctrlRightVolume, volume);
117    if (ret != HDF_SUCCESS) {
118        AUDIO_FUNC_LOGE("Write right volume fail!");
119        return HDF_FAILURE;
120    }
121
122    return HDF_SUCCESS;
123}
124
125static int32_t CaptureSetMuteImpl(struct AlsaCapture *captureIns, bool muteFlag)
126{
127    int32_t ret;
128    long vol, setVol;
129    CaptureData *priData = CaptureGetPriData(captureIns);
130    CHECK_NULL_PTR_RETURN_DEFAULT(captureIns);
131    CHECK_NULL_PTR_RETURN_DEFAULT(priData);
132    ret = captureIns->GetVolume(captureIns, &vol);
133    if (ret != HDF_SUCCESS) {
134        AUDIO_FUNC_LOGE("GetVolume failed!");
135        return HDF_FAILURE;
136    }
137
138    if (muteFlag) {
139        priData->tempVolume = vol;
140        setVol = 0;
141    } else {
142        setVol = priData->tempVolume;
143    }
144    captureIns->SetVolume(captureIns, setVol);
145    if (ret != HDF_SUCCESS) {
146        AUDIO_FUNC_LOGE("SetVolume failed!");
147        return HDF_FAILURE;
148    }
149    captureIns->muteState = muteFlag;
150    return HDF_SUCCESS;
151}
152
153static int32_t CaptureStartImpl(struct AlsaCapture *captureIns)
154{
155    struct AlsaMixerCtlElement mixerItem;
156    CHECK_NULL_PTR_RETURN_DEFAULT(captureIns);
157
158    SndElementItemInit(&mixerItem);
159    mixerItem.numid = SND_NUMID_CAPUTRE_MIC_PATH;
160    mixerItem.name = SND_ELEM_CAPUTRE_MIC_PATH;
161    mixerItem.value = SND_IN_CARD_MAIN_MIC;
162    SndElementWrite(&captureIns->soundCard, &mixerItem);
163
164    return HDF_SUCCESS;
165}
166
167static int32_t CaptureStopImpl(struct AlsaCapture *captureIns)
168{
169    struct AlsaMixerCtlElement mixerItem;
170    CHECK_NULL_PTR_RETURN_DEFAULT(captureIns);
171    CHECK_NULL_PTR_RETURN_DEFAULT(&captureIns->soundCard);
172
173    SndElementItemInit(&mixerItem);
174    mixerItem.numid = SND_NUMID_CAPUTRE_MIC_PATH;
175    mixerItem.name = SND_ELEM_CAPUTRE_MIC_PATH;
176    mixerItem.value = SND_IN_CARD_MIC_OFF;
177    SndElementWrite(&captureIns->soundCard, &mixerItem);
178    CHECK_NULL_PTR_RETURN_DEFAULT(captureIns->soundCard.pcmHandle);
179    snd_pcm_drop(captureIns->soundCard.pcmHandle);
180    return HDF_SUCCESS;
181}
182
183static int32_t CaptureGetGainThresholdImpl(struct AlsaCapture *captureIns, float *gainMin, float *gainMax)
184{
185    AUDIO_FUNC_LOGE("8541e not support gain operation");
186    return HDF_SUCCESS;
187}
188
189static int32_t CaptureGetGainImpl(struct AlsaCapture *captureIns, float *volume)
190{
191    AUDIO_FUNC_LOGE("8541e not support gain operation");
192    return HDF_SUCCESS;
193}
194
195static int32_t CaptureSetGainImpl(struct AlsaCapture *captureIns, float volume)
196{
197    AUDIO_FUNC_LOGE("8541e not support gain operation");
198    return HDF_SUCCESS;
199}
200
201static bool CaptureGetMuteImpl(struct AlsaCapture *captureIns)
202{
203    return captureIns->muteState;
204}
205
206int32_t CaptureOverrideFunc(struct AlsaCapture *captureIns)
207{
208    if (captureIns == NULL) {
209        return HDF_FAILURE;
210    }
211    struct AlsaSoundCard *cardIns = (struct AlsaSoundCard *)captureIns;
212
213    if (cardIns->cardType == SND_CARD_PRIMARY) {
214        captureIns->Init = CaptureInitImpl;
215        captureIns->SelectScene = CaptureSelectSceneImpl;
216        captureIns->Start = CaptureStartImpl;
217        captureIns->Stop = CaptureStopImpl;
218        captureIns->GetVolThreshold = CaptureGetVolThresholdImpl;
219        captureIns->GetVolume = CaptureGetVolumeImpl;
220        captureIns->SetVolume = CaptureSetVolumeImpl;
221        captureIns->GetGainThreshold = CaptureGetGainThresholdImpl;
222        captureIns->GetGain = CaptureGetGainImpl;
223        captureIns->SetGain = CaptureSetGainImpl;
224        captureIns->GetMute = CaptureGetMuteImpl;
225        captureIns->SetMute = CaptureSetMuteImpl;
226    }
227
228    return HDF_SUCCESS;
229}