1 /*
2 * Copyright (c) 2023 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_lib_common.h"
17
18 #define HDF_LOG_TAG HDF_AUDIO_HAL_LIB
19
AlsaControls(char * cardCtlName,const char * pathName,uint32_t * numId)20 static int32_t AlsaControls(char *cardCtlName, const char *pathName, uint32_t *numId)
21 {
22 int ret;
23 snd_hctl_t *handle = NULL;
24 snd_hctl_elem_t *elem = NULL;
25 snd_ctl_elem_id_t *id = NULL;
26 snd_ctl_elem_info_t *info = NULL;
27
28 if (cardCtlName == NULL || pathName == NULL || numId == NULL) {
29 AUDIO_FUNC_LOGE("The parameter is NULL!");
30 return HDF_FAILURE;
31 }
32
33 snd_ctl_elem_id_alloca(&id);
34 snd_ctl_elem_info_alloca(&info);
35 if (id == NULL || info == NULL) {
36 AUDIO_FUNC_LOGE("alloca failed!");
37 return HDF_FAILURE;
38 }
39 if ((ret = snd_hctl_open(&handle, cardCtlName, 0)) < 0) {
40 AUDIO_FUNC_LOGE("Control %{public}s open error: %{public}s", cardCtlName, snd_strerror(ret));
41 return ret;
42 }
43 if ((ret = snd_hctl_load(handle)) < 0) {
44 AUDIO_FUNC_LOGE("Control %{public}s local error: %{public}s\n", cardCtlName, snd_strerror(ret));
45 return ret;
46 }
47 /* Obtain the path information of the sound card in the control node */
48 for (elem = snd_hctl_first_elem(handle); elem != NULL; elem = snd_hctl_elem_next(elem)) {
49 if ((ret = snd_hctl_elem_info(elem, info)) < 0) {
50 AUDIO_FUNC_LOGE("Control %{public}s snd_hctl_elem_info error: %{public}s.", cardCtlName, snd_strerror(ret));
51 return ret;
52 }
53 if (snd_ctl_elem_info_is_inactive(info)) {
54 continue;
55 }
56 snd_hctl_elem_get_id(elem, id);
57 const char *name = snd_ctl_elem_id_get_name(id);
58 if (strncmp(name, pathName, strlen(pathName)) == 0) {
59 *numId = snd_ctl_elem_id_get_numid(id);
60 (void)snd_hctl_close(handle);
61 return ret;
62 }
63 }
64 AUDIO_FUNC_LOGE("The set ctlName was not found!");
65 (void)snd_hctl_close(handle);
66 return HDF_FAILURE;
67 }
68
AudioCtlElemWrite(const char * ctlName,uint32_t numId,uint32_t item)69 static int32_t AudioCtlElemWrite(const char *ctlName, uint32_t numId, uint32_t item)
70 {
71 int32_t ret;
72 snd_ctl_t *ctlHandle = NULL;
73 snd_ctl_elem_value_t *ctlElemValue = NULL;
74
75 if (ctlName == NULL) {
76 AUDIO_FUNC_LOGE("The parameter is NULL!");
77 return HDF_FAILURE;
78 }
79 ret = snd_ctl_elem_value_malloc(&ctlElemValue);
80 if (ret < 0) {
81 AUDIO_FUNC_LOGE("snd_ctl_elem_value_malloc error: %{public}s", snd_strerror(ret));
82 return HDF_FAILURE;
83 }
84
85 ret = snd_ctl_open(&ctlHandle, ctlName, 0);
86 if (ret < 0) {
87 AUDIO_FUNC_LOGE("snd_ctl_open error: %{public}s", snd_strerror(ret));
88 snd_ctl_elem_value_free(ctlElemValue);
89 return HDF_FAILURE;
90 }
91 snd_ctl_elem_value_set_numid(ctlElemValue, numId);
92 snd_ctl_elem_value_set_interface(ctlElemValue, SND_CTL_ELEM_IFACE_MIXER);
93 snd_ctl_elem_value_set_integer(ctlElemValue, 0, item); // 0 is index of the member
94 ret = snd_ctl_elem_write(ctlHandle, ctlElemValue);
95 if (ret < 0) {
96 AUDIO_FUNC_LOGE("snd_ctl_elem_write error: %{public}s", snd_strerror(ret));
97 }
98
99 snd_ctl_elem_value_free(ctlElemValue);
100 (void)snd_ctl_close(ctlHandle);
101 return ret;
102 }
103
EnableAudioRenderRoute(const struct AudioHwRenderParam * renderData)104 int32_t EnableAudioRenderRoute(const struct AudioHwRenderParam *renderData)
105 {
106 struct AudioCardInfo *cardIns = NULL;
107 uint32_t numId;
108 const char *pathName = NULL;
109 int32_t itemValue;
110 if (renderData == NULL) {
111 AUDIO_FUNC_LOGE("The parameter is NULL!");
112 return HDF_FAILURE;
113 }
114
115 const char *adapterName = renderData->renderMode.hwInfo.adapterName;
116 cardIns = AudioGetCardInstance(adapterName);
117 if (cardIns == NULL) {
118 AUDIO_FUNC_LOGE("AudioRenderGetCardIns failed.");
119 return HDF_FAILURE;
120 }
121
122 int32_t devCount = renderData->renderMode.hwInfo.pathSelect.deviceInfo.deviceNum;
123 if (devCount < 0 || devCount > PATHPLAN_COUNT - 1) {
124 AUDIO_FUNC_LOGE("devCount is error!");
125 return HDF_FAILURE;
126 }
127 for (int32_t i = 0; i < devCount; i++) {
128 pathName = renderData->renderMode.hwInfo.pathSelect.deviceInfo.deviceSwitchs[i].deviceSwitch;
129 itemValue = renderData->renderMode.hwInfo.pathSelect.deviceInfo.deviceSwitchs[i].value;
130 if (AlsaControls(cardIns->ctrlName, pathName, &numId) < 0) {
131 AUDIO_FUNC_LOGE("AlsaControls failed, pathName: %{public}s.", pathName);
132 return HDF_FAILURE;
133 }
134 if (AudioCtlElemWrite(cardIns->ctrlName, numId, itemValue) != HDF_SUCCESS) {
135 AUDIO_FUNC_LOGE("AudioCtlElemWrite failed.");
136 return HDF_FAILURE;
137 }
138 }
139
140 return HDF_SUCCESS;
141 }
142
EnableAudioCaptureRoute(const struct AudioHwCaptureParam * captureData)143 int32_t EnableAudioCaptureRoute(const struct AudioHwCaptureParam *captureData)
144 {
145 uint32_t numId;
146 int32_t itemValue;
147 struct AudioCardInfo *cardIns = NULL;
148 const char *capturePathName = NULL;
149
150 if (captureData == NULL) {
151 AUDIO_FUNC_LOGE("The parameter is NULL!");
152 return HDF_FAILURE;
153 }
154
155 const char *adapterName = captureData->captureMode.hwInfo.adapterName;
156 cardIns = AudioGetCardInstance(adapterName);
157 if (cardIns == NULL) {
158 AUDIO_FUNC_LOGE("AudioCaptureGetCardIns failed.");
159 return HDF_FAILURE;
160 }
161
162 int32_t devCount = captureData->captureMode.hwInfo.pathSelect.deviceInfo.deviceNum;
163 if (devCount < 0 || devCount > PATHPLAN_COUNT - 1) {
164 AUDIO_FUNC_LOGE("deviceIndex is error!");
165 return HDF_FAILURE;
166 }
167 for (int32_t i = 0; i < devCount; i++) {
168 capturePathName = captureData->captureMode.hwInfo.pathSelect.deviceInfo.deviceSwitchs[i].deviceSwitch;
169 itemValue = captureData->captureMode.hwInfo.pathSelect.deviceInfo.deviceSwitchs[i].value;
170 if (AlsaControls(cardIns->ctrlName, capturePathName, &numId) < 0) {
171 AUDIO_FUNC_LOGE("AlsaControls failed, pathName: %{public}s!", capturePathName);
172 return HDF_FAILURE;
173 }
174 if (AudioCtlElemWrite(cardIns->ctrlName, numId, itemValue) != HDF_SUCCESS) {
175 AUDIO_FUNC_LOGE("AudioCtlElemWrite failed!");
176 return HDF_FAILURE;
177 }
178 }
179
180 return HDF_SUCCESS;
181 }
182