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_soundcard.h"
17 #include <ctype.h>
18 #include "cJSON.h"
19
20 #define HDF_LOG_TAG HDF_AUDIO_HAL_SND
21
22 #define ALSA_CARD_CONFIG_FILE HDF_CONFIG_DIR "/alsa_adapter.json"
23 #define ALSA_CONFIG_FILE_MAX (2 * 1024) // 2KB
24 #define SUPPORT_CAPTURE_OR_RENDER 1
25 #define SUPPORT_CAPTURE_AND_RENDER 2
26
27 /* Define structure description alsa_adapter.hson information */
28 struct AlsaAdapterCfgInfo {
29 char adapterName[MAX_CARD_NAME_LEN];
30 int32_t cardId;
31 char cardName[MAX_CARD_NAME_LEN];
32 };
33 struct AlsaAdapterList {
34 int32_t num;
35 struct AlsaAdapterCfgInfo list[AUDIO_MAX_CARD_NUM];
36 };
37 static struct AlsaAdapterList g_alsaAdapterList[SND_CARD_MAX];
38
39 struct AlsaDevInfo {
40 char cardId[MAX_CARD_NAME_LEN + 1];
41 char pcmInfoId[MAX_CARD_NAME_LEN + 1];
42 int32_t card;
43 int32_t device;
44 };
45 struct AlsaCardsList {
46 int32_t num;
47 struct AlsaDevInfo alsaDevIns[MAX_CARD_NUM];
48 };
49 static struct AlsaCardsList g_alsaCardsDevList;
50
51
CfgReadAdapterFile(const char * fpath)52 static char *CfgReadAdapterFile(const char *fpath)
53 {
54 int32_t jsonStrSize;
55 FILE *fp = NULL;
56 char *pJsonStr = NULL;
57 char pathBuf[PATH_MAX] = {0};
58
59 if (fpath == NULL) {
60 AUDIO_FUNC_LOGE("Parameter is null!!!");
61 return NULL;
62 }
63 if (realpath(fpath, pathBuf) == NULL) {
64 AUDIO_FUNC_LOGE("File path invalid!");
65 return NULL;
66 }
67
68 fp = fopen(pathBuf, "r");
69 if (fp == NULL) {
70 AUDIO_FUNC_LOGE("Can not open config file [ %{public}s ].", fpath);
71 return NULL;
72 }
73 if (fseek(fp, 0, SEEK_END) != 0) {
74 AUDIO_FUNC_LOGE("fseek configuration file error!");
75 (void)fclose(fp);
76 return NULL;
77 }
78 jsonStrSize = ftell(fp);
79 if (jsonStrSize <= 0) {
80 AUDIO_FUNC_LOGE("The configuration file size <= 0!");
81 (void)fclose(fp);
82 return NULL;
83 }
84 rewind(fp);
85 if (jsonStrSize > ALSA_CONFIG_FILE_MAX) {
86 AUDIO_FUNC_LOGE("The configuration file is too large to load!");
87 (void)fclose(fp);
88 return NULL;
89 }
90 pJsonStr = (char *)OsalMemCalloc((uint32_t)jsonStrSize + 1);
91 if (pJsonStr == NULL) {
92 AUDIO_FUNC_LOGE("OsalMemCalloc pJsonStr failed!");
93 (void)fclose(fp);
94 return NULL;
95 }
96 if (fread(pJsonStr, jsonStrSize, 1, fp) != 1) {
97 AUDIO_FUNC_LOGE("Read to config file failed!!!");
98 (void)fclose(fp);
99 AudioMemFree((void **)&pJsonStr);
100 return NULL;
101 }
102 (void)fclose(fp);
103
104 return pJsonStr;
105 }
106
CfgGetAdapterCount()107 static int32_t CfgGetAdapterCount()
108 {
109 int32_t num = 0;
110 for (enum SndCardType type = SND_CARD_PRIMARY; type < SND_CARD_MAX; ++type) {
111 num += g_alsaAdapterList[type].num;
112 }
113 return num;
114 }
115
CfgGetAdapterCardType(const char * adapterName)116 static enum SndCardType CfgGetAdapterCardType(const char* adapterName)
117 {
118 if (adapterName == NULL) {
119 return SND_CARD_UNKNOWN;
120 }
121
122 struct AlsaAdapterCfgInfo *info;
123 for (enum SndCardType type = SND_CARD_PRIMARY; type < SND_CARD_MAX; ++type) {
124 for (int32_t i = 0; i < g_alsaAdapterList[type].num; ++i) {
125 info = &g_alsaAdapterList[type].list[i];
126 if (strncmp(adapterName, info->adapterName, strlen(info->adapterName)) == 0) {
127 return type;
128 }
129 }
130 }
131 return SND_CARD_UNKNOWN;
132 }
133
CfgGetAdapterInfo(const char * adapterName)134 static struct AlsaAdapterCfgInfo *CfgGetAdapterInfo(const char* adapterName)
135 {
136 if (adapterName == NULL) {
137 return NULL;
138 }
139
140 struct AlsaAdapterCfgInfo *info;
141 for (enum SndCardType type = SND_CARD_PRIMARY; type < SND_CARD_MAX; ++type) {
142 for (int32_t i = 0; i < g_alsaAdapterList[type].num; ++i) {
143 info = &g_alsaAdapterList[type].list[i];
144 if (strncmp(adapterName, info->adapterName, strlen(info->adapterName)) == 0) {
145 return info;
146 }
147 }
148 }
149 return NULL;
150 }
151
CfgDumpAdapterInfo(struct AlsaAdapterCfgInfo * info)152 static int32_t CfgDumpAdapterInfo(struct AlsaAdapterCfgInfo *info)
153 {
154 int32_t ret, idx;
155 enum SndCardType cardType = SND_CARD_UNKNOWN;
156 CHECK_NULL_PTR_RETURN_DEFAULT(info);
157
158 if (strcmp(info->adapterName, PRIMARY) == 0) {
159 cardType = SND_CARD_PRIMARY;
160 } else if (strcmp(info->adapterName, HDMI) == 0) {
161 cardType = SND_CARD_HDMI;
162 } else if (strcmp(info->adapterName, USB) == 0) {
163 cardType = SND_CARD_USB;
164 } else if (strcmp(info->adapterName, A2DP) == 0) {
165 cardType = SND_CARD_BT;
166 }
167
168 if (cardType == SND_CARD_UNKNOWN) {
169 AUDIO_FUNC_LOGE("Error: %{public}s is unspupported adapter name", info->adapterName);
170 }
171
172 idx = g_alsaAdapterList[cardType].num;
173 ret = memcpy_s((void*)&g_alsaAdapterList[cardType].list[idx], sizeof(struct AlsaAdapterCfgInfo),
174 (void*)info, sizeof(struct AlsaAdapterCfgInfo));
175 if (ret != EOK) {
176 AUDIO_FUNC_LOGE("memcpy_s g_alsaAdapterList fail!");
177 return HDF_FAILURE;
178 }
179 g_alsaAdapterList[cardType].num++;
180
181 AUDIO_FUNC_LOGI("cardId:%{public}d: adapterName:%{public}s, cardName:%{public}s",
182 g_alsaAdapterList[cardType].list[idx].cardId,
183 g_alsaAdapterList[cardType].list[idx].adapterName,
184 g_alsaAdapterList[cardType].list[idx].cardName);
185 return HDF_SUCCESS;
186 }
187
CfgSaveAdapterStruct(cJSON * adapter,struct AlsaAdapterCfgInfo * info)188 static int32_t CfgSaveAdapterStruct(cJSON *adapter, struct AlsaAdapterCfgInfo *info)
189 {
190 int32_t ret;
191 cJSON *item;
192 CHECK_NULL_PTR_RETURN_DEFAULT(adapter);
193 CHECK_NULL_PTR_RETURN_DEFAULT(info);
194
195 item = cJSON_GetObjectItem(adapter, "name");
196 if (item == NULL || item->valuestring == NULL) {
197 AUDIO_FUNC_LOGE("adapter name is null!");
198 return HDF_FAILURE;
199 }
200 ret = memcpy_s(info->adapterName, MAX_CARD_NAME_LEN - 1, item->valuestring, MAX_CARD_NAME_LEN - 1);
201 if (ret != EOK) {
202 AUDIO_FUNC_LOGE("memcpy_s adapterName fail!");
203 return HDF_FAILURE;
204 }
205
206 item = cJSON_GetObjectItem(adapter, "cardId");
207 if (item == NULL) {
208 AUDIO_FUNC_LOGE("cardId not set!");
209 return HDF_FAILURE;
210 }
211 info->cardId = item->valuedouble;
212
213 item = cJSON_GetObjectItem(adapter, "cardName");
214 if (item == NULL || item->valuestring == NULL) {
215 AUDIO_FUNC_LOGE("cardName is null!");
216 return HDF_FAILURE;
217 }
218 ret = memcpy_s(info->cardName, MAX_CARD_NAME_LEN - 1, item->valuestring, MAX_CARD_NAME_LEN - 1);
219 if (ret != EOK) {
220 AUDIO_FUNC_LOGE("memcpy_s cardName fail!");
221 return HDF_FAILURE;
222 }
223
224 return HDF_SUCCESS;
225 }
226
CfgParseAdapterItems(cJSON * adapterObj)227 static int32_t CfgParseAdapterItems(cJSON *adapterObj)
228 {
229 int32_t ret, adapterNum;
230 cJSON *adapterItems = NULL;
231
232 adapterItems = cJSON_GetObjectItem(adapterObj, "adapters");
233 if (adapterItems == NULL) {
234 AUDIO_FUNC_LOGE("Get adapterItems from json failed!\n");
235 return HDF_FAILURE;
236 }
237 adapterNum = cJSON_GetArraySize(adapterItems);
238 if (adapterNum <= 0) {
239 AUDIO_FUNC_LOGE("Get adapter number failed!");
240 return HDF_FAILURE;
241 } else if (adapterNum > MAX_CARD_NUM) {
242 AUDIO_FUNC_LOGE("Read adapters number is %{public}d over max num %{public}d!", adapterNum, MAX_CARD_NUM);
243 return HDF_FAILURE;
244 }
245
246 for (int32_t i = 0; i < adapterNum; ++i) {
247 cJSON *adapter;
248 struct AlsaAdapterCfgInfo info;
249 adapter = cJSON_GetArrayItem(adapterItems, i);
250 if (adapter == NULL) {
251 AUDIO_FUNC_LOGE("Get adapter item from array failed!");
252 }
253
254 ret = CfgSaveAdapterStruct(adapter, &info);
255 if (ret != HDF_SUCCESS) {
256 AUDIO_FUNC_LOGE("CfgSaveAdapterStruct failed!");
257 return HDF_FAILURE;
258 }
259
260 ret = CfgDumpAdapterInfo(&info);
261 if (ret != HDF_SUCCESS) {
262 AUDIO_FUNC_LOGE("CfgDumpAdapterInfo failed!");
263 return HDF_FAILURE;
264 }
265 }
266
267 return HDF_SUCCESS;
268 }
269
CfgSaveAdapterFromFile(void)270 int32_t CfgSaveAdapterFromFile(void)
271 {
272 int32_t ret;
273 cJSON *adapterObj = NULL;
274 char *configBuf = NULL;
275
276 configBuf = CfgReadAdapterFile(ALSA_CARD_CONFIG_FILE);
277 if (configBuf == NULL) {
278 AUDIO_FUNC_LOGE("CfgReadAdapterFile failed!");
279 return HDF_FAILURE;
280 }
281 adapterObj = cJSON_Parse(configBuf);
282 if (adapterObj == NULL) {
283 AUDIO_FUNC_LOGE("Parse json file failed!");
284 AudioMemFree((void **)&configBuf);
285 return HDF_FAILURE;
286 }
287 AudioMemFree((void **)&configBuf);
288
289 ret = CfgParseAdapterItems(adapterObj);
290 if (ret != HDF_SUCCESS) {
291 cJSON_Delete(adapterObj);
292 AUDIO_FUNC_LOGE("Parse adapter items failed!");
293 return HDF_FAILURE;
294 }
295
296 cJSON_Delete(adapterObj);
297 return HDF_SUCCESS;
298 }
299
DevGetInfoByCardId(int32_t cardId)300 static struct AlsaDevInfo *DevGetInfoByCardId(int32_t cardId)
301 {
302 struct AlsaDevInfo *info = NULL;
303 int num = g_alsaCardsDevList.num;
304 for (int i = 0; i < num; ++i) {
305 info = &g_alsaCardsDevList.alsaDevIns[i];
306 if (info->card == cardId) {
307 return info;
308 }
309 }
310 return NULL;
311 }
312
DevGetInfoByPcmInfoId(const char * name)313 static struct AlsaDevInfo *DevGetInfoByPcmInfoId(const char * name)
314 {
315 struct AlsaDevInfo *info = NULL;
316 int num = g_alsaCardsDevList.num;
317 for (int i = 0; i < num; ++i) {
318 info = &g_alsaCardsDevList.alsaDevIns[i];
319 if (strcmp(name, info->pcmInfoId) == 0) {
320 return info;
321 }
322 }
323
324 return NULL;
325 }
326
DevSaveCardPcmInfo(snd_ctl_t * handle,snd_pcm_stream_t stream,int card,const char * deviceName)327 static int32_t DevSaveCardPcmInfo(snd_ctl_t *handle, snd_pcm_stream_t stream, int card, const char *deviceName)
328 {
329 int32_t ret;
330 int pcmDev = -1;
331 snd_ctl_card_info_t *info = NULL;
332 snd_pcm_info_t *pcminfo = NULL;
333 snd_ctl_card_info_alloca(&info);
334 snd_pcm_info_alloca(&pcminfo);
335
336 if (snd_ctl_card_info(handle, info) != 0) {
337 AUDIO_FUNC_LOGE("snd_ctl_card_info failed.");
338 return HDF_FAILURE;
339 }
340 if (snd_ctl_pcm_next_device(handle, &pcmDev) < 0 || pcmDev < 0) {
341 AUDIO_FUNC_LOGE("No pcm device found");
342 return HDF_FAILURE;
343 }
344 while (pcmDev >= 0) {
345 snd_pcm_info_set_device(pcminfo, pcmDev);
346 snd_pcm_info_set_subdevice(pcminfo, 0);
347 snd_pcm_info_set_stream(pcminfo, stream);
348 ret = snd_ctl_pcm_info(handle, pcminfo);
349 if (ret < 0) {
350 if (ret != -ENOENT) {
351 AUDIO_FUNC_LOGE("control digital audio info (%{public}d)", pcmDev);
352 }
353 } else {
354 struct AlsaDevInfo *devInfo = &g_alsaCardsDevList.alsaDevIns[g_alsaCardsDevList.num];
355 const char *cardId = snd_ctl_card_info_get_id(info);
356 const char *pcmInfoId = snd_pcm_info_get_id(pcminfo);
357 AUDIO_FUNC_LOGD("alsa cardName: %{public}s, pcmInfoId %{public}s", cardId, pcmInfoId);
358 devInfo->card = card;
359 devInfo->device = pcmDev;
360 if (strncpy_s(devInfo->cardId, MAX_CARD_NAME_LEN + 1, cardId, strlen(cardId)) != 0) {
361 AUDIO_FUNC_LOGE("strncpy_s failed!");
362 return HDF_FAILURE;
363 }
364 if (strncpy_s(devInfo->pcmInfoId, MAX_CARD_NAME_LEN + 1, pcmInfoId, strlen(pcmInfoId)) != 0) {
365 AUDIO_FUNC_LOGE("strncpy_s failed!");
366 return HDF_FAILURE;
367 }
368 g_alsaCardsDevList.num++;
369 }
370
371 if (snd_ctl_pcm_next_device(handle, &pcmDev) < 0) {
372 AUDIO_FUNC_LOGE("snd_ctl_pcm_next_device error!");
373 return HDF_FAILURE;
374 }
375 AUDIO_FUNC_LOGD("soundcard pcm device number: %{public}d.", pcmDev);
376 }
377 return HDF_SUCCESS;
378 }
379
DevSaveDriverInfo(snd_pcm_stream_t stream)380 static int32_t DevSaveDriverInfo(snd_pcm_stream_t stream)
381 {
382 int32_t ret;
383 snd_ctl_t *handle;
384 int card = -1;
385 char deviceName[MAX_CARD_NAME_LEN] = {0};
386
387 ret = snd_card_next(&card);
388 if (ret < 0 || card < 0) {
389 AUDIO_FUNC_LOGE("No soundcards found: %{public}s.", snd_strerror(ret));
390 return HDF_FAILURE;
391 }
392
393 while (card >= 0) {
394 (void)memset_s(deviceName, MAX_CARD_NAME_LEN, 0, MAX_CARD_NAME_LEN);
395 ret = snprintf_s(deviceName, MAX_CARD_NAME_LEN, MAX_CARD_NAME_LEN - 1, "hw:%d", card);
396 if (ret < 0) {
397 AUDIO_FUNC_LOGE("snprintf_s failed");
398 snd_ctl_close(handle);
399 return HDF_FAILURE;
400 }
401
402 ret = snd_ctl_open(&handle, deviceName, 0);
403 if (ret != 0) {
404 AUDIO_FUNC_LOGE("snd_ctl_open failed.");
405 return HDF_FAILURE;
406 }
407
408 ret = DevSaveCardPcmInfo(handle, stream, card, deviceName);
409 if (ret != HDF_SUCCESS) {
410 AUDIO_FUNC_LOGE("save alsa sound cards %{public}s pcm info failed!", deviceName);
411 }
412
413 ret = snd_ctl_close(handle);
414 if (ret < 0) {
415 AUDIO_FUNC_LOGE("snd_ctl_close error: %{public}s.", snd_strerror(ret));
416 return HDF_FAILURE;
417 }
418
419 ret = snd_card_next(&card);
420 if (ret < 0) {
421 AUDIO_FUNC_LOGE("snd_card_next error: %{public}s", snd_strerror(ret));
422 return HDF_FAILURE;
423 }
424 }
425
426 return HDF_SUCCESS;
427 }
428
SndSaveCardListInfo(snd_pcm_stream_t stream)429 int32_t SndSaveCardListInfo(snd_pcm_stream_t stream)
430 {
431 int32_t ret;
432
433 (void)memset_s(&g_alsaAdapterList, sizeof(struct AlsaAdapterList) * SND_CARD_MAX,
434 0, sizeof(struct AlsaAdapterList) * SND_CARD_MAX);
435 (void)memset_s(&g_alsaCardsDevList, sizeof(struct AlsaCardsList),
436 0, sizeof(struct AlsaCardsList));
437
438 /* Parse sound card from configuration file */
439 ret = CfgSaveAdapterFromFile();
440 if (ret != HDF_SUCCESS) {
441 AUDIO_FUNC_LOGE("parse config file failed! ret = %{public}d", ret);
442 return HDF_FAILURE;
443 }
444
445 /* Read sound card list from alsa hardware */
446 ret = DevSaveDriverInfo(stream);
447 if (ret != HDF_SUCCESS) {
448 AUDIO_FUNC_LOGE("failed to save alsa sound cards driver info");
449 return HDF_FAILURE;
450 }
451
452 /* if the alsa hardware include usb then add to adapter list */
453 struct AlsaDevInfo *devInfo = DevGetInfoByPcmInfoId(USB);
454 if (devInfo != NULL) {
455 g_alsaAdapterList[SND_CARD_USB].num = 1;
456 ret = memcpy_s((void*)&g_alsaAdapterList[SND_CARD_USB].list[0].adapterName, MAX_CARD_NAME_LEN,
457 USB, sizeof(USB));
458 if (ret != EOK) {
459 AUDIO_FUNC_LOGE("memcpy_s adapterName fail!");
460 return HDF_FAILURE;
461 }
462 }
463
464 return HDF_SUCCESS;
465 }
466
SndMatchSelAdapter(struct AlsaSoundCard * cardIns,const char * adapterName)467 int32_t SndMatchSelAdapter(struct AlsaSoundCard *cardIns, const char *adapterName)
468 {
469 int32_t ret;
470 enum SndCardType cardType;
471 struct AlsaAdapterCfgInfo *info = NULL;
472 struct AlsaDevInfo *devInfo = NULL;
473 CHECK_NULL_PTR_RETURN_DEFAULT(cardIns);
474 CHECK_NULL_PTR_RETURN_DEFAULT(adapterName);
475
476 cardType = CfgGetAdapterCardType(adapterName);
477 if (cardType == SND_CARD_UNKNOWN) {
478 AUDIO_FUNC_LOGE("unknow card type error.");
479 return HDF_FAILURE;
480 }
481 cardIns->cardType = cardType;
482
483 info = CfgGetAdapterInfo(adapterName);
484 if (info == NULL) {
485 AUDIO_FUNC_LOGE("adapter %{public}s is not exits.", cardIns->adapterName);
486 return HDF_FAILURE;
487 }
488
489 devInfo = DevGetInfoByCardId(info->cardId);
490 if (devInfo == NULL) {
491 AUDIO_FUNC_LOGE("adapter %{public}s cant not find sound card device.", cardIns->adapterName);
492 return HDF_FAILURE;
493 }
494
495 ret = snprintf_s(cardIns->devName, MAX_CARD_NAME_LEN, MAX_CARD_NAME_LEN - 1,
496 "hw:%d,%d", devInfo->card, devInfo->device);
497 if (ret < 0) {
498 AUDIO_FUNC_LOGE("%{public}s snprintf_s devName failed", cardIns->adapterName);
499 return HDF_FAILURE;
500 }
501 ret = snprintf_s(cardIns->ctrlName, MAX_CARD_NAME_LEN, MAX_CARD_NAME_LEN - 1, "hw:%d", devInfo->card);
502 if (ret < 0) {
503 AUDIO_FUNC_LOGE("%{public}s snprintf_s ctrlName failed", cardIns->adapterName);
504 return HDF_FAILURE;
505 }
506 ret = snprintf_s(cardIns->alsaCardId, MAX_CARD_NAME_LEN, MAX_CARD_NAME_LEN - 1, "%s", devInfo->cardId);
507 if (ret < 0) {
508 AUDIO_FUNC_LOGE("%{public}s snprintf_s alsaCardId failed", cardIns->adapterName);
509 return HDF_FAILURE;
510 }
511
512 return HDF_SUCCESS;
513 }
514
SndConverAlsaPcmFormat(const struct AudioPcmHwParams * hwParams,snd_pcm_format_t * alsaPcmFormat)515 int32_t SndConverAlsaPcmFormat(const struct AudioPcmHwParams *hwParams, snd_pcm_format_t *alsaPcmFormat)
516 {
517 CHECK_NULL_PTR_RETURN_DEFAULT(hwParams);
518 CHECK_NULL_PTR_RETURN_DEFAULT(alsaPcmFormat);
519 enum AudioFormat audioFormat = hwParams->format;
520 bool isBigEndian = hwParams->isBigEndian;
521
522 /** Little Endian */
523 if (!isBigEndian) {
524 switch (audioFormat) {
525 case AUDIO_FORMAT_TYPE_PCM_8_BIT:
526 *alsaPcmFormat = SND_PCM_FORMAT_S8; /** Signed 8 bit */
527 break;
528 case AUDIO_FORMAT_TYPE_PCM_16_BIT:
529 *alsaPcmFormat = SND_PCM_FORMAT_S16_LE; /** Signed 16 bit Little Endian */
530 break;
531 case AUDIO_FORMAT_TYPE_PCM_24_BIT:
532 *alsaPcmFormat = SND_PCM_FORMAT_S24_LE; /** Signed 24 bit Little Endian */
533 break;
534 case AUDIO_FORMAT_TYPE_PCM_32_BIT:
535 *alsaPcmFormat = SND_PCM_FORMAT_S32_LE; /** Signed 32 bit Little Endian */
536 break;
537 default:
538 AUDIO_FUNC_LOGE("not support format %{public}d", audioFormat);
539 return HDF_ERR_NOT_SUPPORT;
540 }
541 } else { /** Big Endian */
542 switch (audioFormat) {
543 case AUDIO_FORMAT_TYPE_PCM_8_BIT:
544 *alsaPcmFormat = SND_PCM_FORMAT_S8; /** Signed 8 bit */
545 break;
546 case AUDIO_FORMAT_TYPE_PCM_16_BIT:
547 *alsaPcmFormat = SND_PCM_FORMAT_S16_BE; /** Signed 16 bit Big Endian */
548 break;
549 case AUDIO_FORMAT_TYPE_PCM_24_BIT:
550 *alsaPcmFormat = SND_PCM_FORMAT_S24_BE; /** Signed 24 bit Big Endian */
551 break;
552 case AUDIO_FORMAT_TYPE_PCM_32_BIT:
553 *alsaPcmFormat = SND_PCM_FORMAT_S32_BE; /** Signed 32 bit Big Endian */
554 break;
555 default:
556 AUDIO_FUNC_LOGE("not support format %{public}d", audioFormat);
557 return HDF_ERR_NOT_SUPPORT;
558 }
559 }
560
561 return HDF_SUCCESS;
562 }
563
SndPcmPrepare(struct AlsaSoundCard * cardIns)564 int32_t SndPcmPrepare(struct AlsaSoundCard *cardIns)
565 {
566 int32_t ret;
567 ret = snd_pcm_prepare(cardIns->pcmHandle);
568 if (ret < 0) {
569 AUDIO_FUNC_LOGE("snd_pcm_prepare fail: %{public}s", snd_strerror(ret));
570 return HDF_FAILURE;
571 }
572 return HDF_SUCCESS;
573 }
574
SndisBusy(struct AlsaSoundCard * cardIns)575 bool SndisBusy(struct AlsaSoundCard *cardIns)
576 {
577 return (cardIns->pcmHandle == NULL) ? false : true;
578 }
579
SndOpenMixer(struct AlsaSoundCard * cardIns)580 int32_t SndOpenMixer(struct AlsaSoundCard *cardIns)
581 {
582 int32_t ret;
583
584 if (strlen(cardIns->ctrlName) == 0) {
585 AUDIO_FUNC_LOGE("The soundcard ctrname is null.");
586 return HDF_FAILURE;
587 }
588
589 ret = snd_mixer_open(&cardIns->mixerHandle, 0);
590 if (ret < 0) {
591 AUDIO_FUNC_LOGE("Failed to open mixer: %{public}s.", snd_strerror(ret));
592 return HDF_FAILURE;
593 }
594
595 ret = snd_mixer_attach(cardIns->mixerHandle, cardIns->ctrlName);
596 if (ret < 0) {
597 AUDIO_FUNC_LOGE("Failed to attach mixer: %{public}s.", snd_strerror(ret));
598 ret = snd_mixer_close(cardIns->mixerHandle);
599 if (ret < 0) {
600 AUDIO_FUNC_LOGE("mixer close error: %{public}s.", snd_strerror(ret));
601 }
602 cardIns->mixerHandle = NULL;
603 return HDF_FAILURE;
604 }
605
606 ret = snd_mixer_selem_register(cardIns->mixerHandle, NULL, NULL);
607 if (ret < 0) {
608 AUDIO_FUNC_LOGE("Failed to register mixer element: %{public}s.", snd_strerror(ret));
609 ret = snd_mixer_close(cardIns->mixerHandle);
610 if (ret < 0) {
611 AUDIO_FUNC_LOGE("mixer close error: %{public}s.", snd_strerror(ret));
612 }
613 cardIns->mixerHandle = NULL;
614 return HDF_FAILURE;
615 }
616
617 ret = snd_mixer_load(cardIns->mixerHandle);
618 if (ret < 0) {
619 AUDIO_FUNC_LOGE("Failed to load mixer element: %{public}s.", snd_strerror(ret));
620 ret = snd_mixer_close(cardIns->mixerHandle);
621 if (ret < 0) {
622 AUDIO_FUNC_LOGE("mixer close error: %{public}s.", snd_strerror(ret));
623 }
624 cardIns->mixerHandle = NULL;
625 return HDF_FAILURE;
626 }
627 return HDF_SUCCESS;
628 }
629
SndGetRunState(struct AlsaSoundCard * cardIns)630 snd_pcm_state_t SndGetRunState(struct AlsaSoundCard * cardIns)
631 {
632 return snd_pcm_state(cardIns->pcmHandle);
633 }
634
SndCloseHandle(struct AlsaSoundCard * cardIns)635 void SndCloseHandle(struct AlsaSoundCard *cardIns)
636 {
637 int32_t ret;
638 if (cardIns->cardStatus > 0) {
639 cardIns->cardStatus -= 1;
640 }
641 if (cardIns->cardStatus == 0) {
642 if (cardIns->pcmHandle != NULL) {
643 ret = snd_pcm_close(cardIns->pcmHandle);
644 if (ret < 0) {
645 AUDIO_FUNC_LOGE("snd_pcm_close fail: %{public}s", snd_strerror(ret));
646 }
647 cardIns->pcmHandle = NULL;
648 }
649 if (cardIns->mixerHandle != NULL) {
650 ret = snd_mixer_close(cardIns->mixerHandle);
651 if (ret < 0) {
652 AUDIO_FUNC_LOGE("mixer close error: %{public}s.", snd_strerror(ret));
653 }
654 cardIns->mixerHandle = NULL;
655 }
656 (void)memset_s(cardIns, sizeof(struct AlsaSoundCard), 0, sizeof(struct AlsaSoundCard));
657 }
658 }
659
AudioInitPortOut(struct AudioPort * audioPort)660 static void AudioInitPortOut(struct AudioPort *audioPort)
661 {
662 audioPort->dir = PORT_OUT;
663 audioPort->portId = 0;
664 audioPort->portName = strdup("AOP");
665 }
666
AudioInitPortIn(struct AudioPort * audioPort)667 static void AudioInitPortIn(struct AudioPort *audioPort)
668 {
669 audioPort->dir = PORT_IN;
670 audioPort->portId = 0;
671 audioPort->portName = strdup("AIP");
672 }
673
AudioInitPortOutAndIn(struct AudioPort * audioPort)674 static void AudioInitPortOutAndIn(struct AudioPort *audioPort)
675 {
676 audioPort->dir = PORT_OUT_IN;
677 audioPort->portId = 0;
678 audioPort->portName = strdup("AIOP");
679 }
680
AudioInitPorts(struct AudioAdapterDescriptor * desc,enum SndCardType type)681 static int32_t AudioInitPorts(struct AudioAdapterDescriptor *desc, enum SndCardType type)
682 {
683 uint8_t portNum;
684 CHECK_NULL_PTR_RETURN_DEFAULT(desc);
685
686 switch (type) {
687 case SND_CARD_PRIMARY:
688 portNum = PORT_OUT_IN;
689 break;
690 case SND_CARD_HDMI:
691 portNum = PORT_OUT;
692 break;
693 case SND_CARD_USB:
694 portNum = PORT_IN;
695 break;
696 default:
697 AUDIO_FUNC_LOGE("Unknown sound card type does not support this sound card temporarily!");
698 return HDF_FAILURE;
699 }
700
701 #ifndef AUDIO_HDI_SERVICE_MODE
702 desc->portNum = portNum;
703 #else
704 desc->portsLen = portNum;
705 #endif
706
707 desc->ports = (struct AudioPort *)OsalMemCalloc(sizeof(struct AudioPort) * portNum);
708 if (desc->ports == NULL) {
709 AUDIO_FUNC_LOGE("OsalMemCalloc failed!");
710 return HDF_ERR_MALLOC_FAIL;
711 }
712
713 if (type == SND_CARD_PRIMARY) {
714 AudioInitPortOut(&desc->ports[0]);
715 AudioInitPortIn(&desc->ports[SUPPORT_CAPTURE_OR_RENDER]);
716 AudioInitPortOutAndIn(&desc->ports[SUPPORT_CAPTURE_AND_RENDER]);
717 } else if (type == SND_CARD_HDMI) {
718 AudioInitPortOut(&desc->ports[0]);
719 } else if (type == SND_CARD_USB) {
720 AudioInitPortOut(&desc->ports[0]);
721 AudioInitPortIn(&desc->ports[SUPPORT_CAPTURE_OR_RENDER]);
722 } else {
723 AUDIO_FUNC_LOGE("adapter list not support sound card type %{public}d", type);
724 return HDF_FAILURE;
725 }
726
727 return HDF_SUCCESS;
728 }
729
AudioGetAllCardInfo(struct AudioAdapterDescriptor ** descs,int32_t * sndCardNum)730 int32_t AudioGetAllCardInfo(struct AudioAdapterDescriptor **descs, int32_t *sndCardNum)
731 {
732 int32_t ret, idx;
733 int32_t adapterNum;
734 CHECK_NULL_PTR_RETURN_DEFAULT(descs);
735 CHECK_NULL_PTR_RETURN_DEFAULT(sndCardNum);
736
737 ret = SndSaveCardListInfo(SND_PCM_STREAM_PLAYBACK);
738 if (ret != HDF_SUCCESS) {
739 return HDF_FAILURE;
740 }
741
742 adapterNum = CfgGetAdapterCount();
743 if (*descs == NULL) {
744 AUDIO_FUNC_LOGW("*descs is null, need memcalloc.");
745 *descs = (struct AudioAdapterDescriptor *)OsalMemCalloc(sizeof(struct AudioAdapterDescriptor) * adapterNum);
746 if (*descs == NULL) {
747 AUDIO_FUNC_LOGE("OsalMemCalloc descs is NULL");
748 return HDF_ERR_MALLOC_FAIL;
749 }
750 }
751 *sndCardNum = adapterNum;
752
753 idx = 0;
754 for (enum SndCardType type = SND_CARD_PRIMARY; type < SND_CARD_MAX; ++type) {
755 for (int32_t i = 0; i < g_alsaAdapterList[type].num; ++i) {
756 (*descs)[idx].adapterName = strdup(g_alsaAdapterList[type].list[i].adapterName);
757 AudioInitPorts(&(*descs)[idx], type);
758 AUDIO_FUNC_LOGI("adapter name : %{public}s", (*descs)[idx].adapterName);
759 idx++;
760 }
761 }
762
763 return HDF_SUCCESS;
764 }
765
HdfIoServiceBindName(const char * serviceName)766 struct HdfIoService *HdfIoServiceBindName(const char *serviceName)
767 {
768 (void)serviceName;
769 /* Nothing to do */
770 static struct HdfIoService hdfIoService;
771 return &hdfIoService;
772 }
773
AudioBindService(const char * name)774 struct DevHandle *AudioBindService(const char *name)
775 {
776 struct DevHandle *handle = NULL;
777
778 if (name == NULL) {
779 AUDIO_FUNC_LOGE("service name NULL!");
780 return NULL;
781 }
782
783 handle = (struct DevHandle *)OsalMemCalloc(sizeof(struct DevHandle));
784 if (handle == NULL) {
785 AUDIO_FUNC_LOGE("OsalMemCalloc handle failed!!!");
786 return NULL;
787 }
788
789 AUDIO_FUNC_LOGI("BIND SERVICE SUCCESS!");
790 return handle;
791 }
792
AudioCloseService(const struct DevHandle * handle)793 void AudioCloseService(const struct DevHandle *handle)
794 {
795 if (handle != NULL) {
796 AudioMemFree((void **)&handle);
797 }
798 }
799
SndElementItemInit(struct AlsaMixerCtlElement * m)800 void SndElementItemInit(struct AlsaMixerCtlElement *m)
801 {
802 m->iface = IFACE_MIXER;
803 m->index = -1;
804 m->device = -1;
805 m->subdevice = -1;
806 }
807
ConvertIfaceType(enum SndIfaceType iface)808 static snd_ctl_elem_iface_t ConvertIfaceType(enum SndIfaceType iface)
809 {
810 snd_ctl_elem_iface_t snd_iface;
811 switch (iface) {
812 case IFACE_CARD:
813 snd_iface = SND_CTL_ELEM_IFACE_CARD;
814 break;
815 case IFACE_MIXER:
816 snd_iface = SND_CTL_ELEM_IFACE_MIXER;
817 break;
818 case IFACE_PCM:
819 snd_iface = SND_CTL_ELEM_IFACE_PCM;
820 break;
821 case IFACE_RAWMIDI:
822 snd_iface = SND_CTL_ELEM_IFACE_RAWMIDI;
823 break;
824 case IFACE_TIMER:
825 snd_iface = SND_CTL_ELEM_IFACE_TIMER;
826 break;
827 case IFACE_SEQUENCER:
828 snd_iface = SND_CTL_ELEM_IFACE_SEQUENCER;
829 break;
830 default:
831 snd_iface = SND_CTL_ELEM_IFACE_MIXER;
832 break;
833 }
834 return snd_iface;
835 }
836
SetElementInfo(snd_ctl_t * alsaHandle,const struct AlsaMixerCtlElement * ctlElem,snd_ctl_elem_info_t * info,snd_ctl_elem_id_t * id)837 static int32_t SetElementInfo(snd_ctl_t *alsaHandle, const struct AlsaMixerCtlElement *ctlElem,
838 snd_ctl_elem_info_t *info, snd_ctl_elem_id_t *id)
839 {
840 int32_t ret;
841 snd_ctl_elem_iface_t ifaceType;
842 CHECK_NULL_PTR_RETURN_DEFAULT(alsaHandle);
843 CHECK_NULL_PTR_RETURN_DEFAULT(ctlElem);
844 CHECK_NULL_PTR_RETURN_DEFAULT(info);
845 CHECK_NULL_PTR_RETURN_DEFAULT(id);
846
847 if (ctlElem->numid >= 0) {
848 snd_ctl_elem_id_set_numid(id, ctlElem->numid);
849 }
850 if (ctlElem->index >= 0) {
851 snd_ctl_elem_id_set_index(id, ctlElem->index);
852 }
853 if (ctlElem->device >= 0) {
854 snd_ctl_elem_id_set_device(id, ctlElem->device);
855 }
856 if (ctlElem->subdevice >= 0) {
857 snd_ctl_elem_id_set_subdevice(id, ctlElem->subdevice);
858 }
859
860 ifaceType = ConvertIfaceType(ctlElem->iface);
861 snd_ctl_elem_id_set_interface(id, ifaceType);
862 if (ctlElem->name) {
863 snd_ctl_elem_id_set_name(id, ctlElem->name);
864 }
865 snd_ctl_elem_info_set_id(info, id);
866 ret = snd_ctl_elem_info(alsaHandle, info);
867 if (ret < 0) {
868 AUDIO_FUNC_LOGE("Cannot find the given element from elem_value\n");
869 return HDF_FAILURE;
870 }
871 snd_ctl_elem_info_get_id(info, id);
872
873 return HDF_SUCCESS;
874 }
875
SndElementReadInt(struct AlsaSoundCard * cardIns,const struct AlsaMixerCtlElement * ctlElem,long * value)876 int32_t SndElementReadInt(struct AlsaSoundCard *cardIns,
877 const struct AlsaMixerCtlElement *ctlElem, long *value)
878 {
879 int ret;
880 snd_ctl_t *alsaHandle = NULL;
881 snd_ctl_elem_id_t *elem_id;
882 snd_ctl_elem_info_t *elem_info;
883 snd_ctl_elem_value_t *elem_value;
884 snd_ctl_elem_type_t type;
885
886 CHECK_NULL_PTR_RETURN_DEFAULT(cardIns);
887 CHECK_NULL_PTR_RETURN_DEFAULT(ctlElem);
888
889 ret = snd_ctl_open(&alsaHandle, cardIns->ctrlName, 0);
890 if (ret < 0) {
891 AUDIO_FUNC_LOGE("snd_ctl_open error: %{public}s", snd_strerror(ret));
892 return HDF_FAILURE;
893 }
894
895 snd_ctl_elem_id_alloca(&elem_id);
896 snd_ctl_elem_info_alloca(&elem_info);
897 snd_ctl_elem_value_alloca(&elem_value);
898 ret = SetElementInfo(alsaHandle, ctlElem, elem_info, elem_id);
899 if (ret != HDF_SUCCESS) {
900 AUDIO_FUNC_LOGE("Set element %{public}s elem_info failed!\n", ctlElem->name);
901 return HDF_FAILURE;
902 }
903 snd_ctl_elem_value_set_id(elem_value, elem_id);
904
905 if (!snd_ctl_elem_info_is_readable(elem_info)) {
906 AUDIO_FUNC_LOGE("Element read enable\n");
907 return HDF_FAILURE;
908 }
909 ret = snd_ctl_elem_read(alsaHandle, elem_value);
910 if (ret < 0) {
911 AUDIO_FUNC_LOGE("Cannot read the given element from elem_value \n");
912 return HDF_FAILURE;
913 }
914
915 type = snd_ctl_elem_info_get_type(elem_info);
916 if (type == SND_CTL_ELEM_TYPE_INTEGER) {
917 *value = snd_ctl_elem_value_get_integer(elem_value, 0);
918 } else if (type == SND_CTL_ELEM_TYPE_INTEGER64) {
919 *value = (long)snd_ctl_elem_value_get_integer64(elem_value, 0);
920 } else {
921 AUDIO_FUNC_LOGE("Element type is not interger\n");
922 return HDF_FAILURE;
923 }
924
925 return HDF_SUCCESS;
926 }
927
SndElementReadEnum(struct AlsaSoundCard * cardIns,const struct AlsaMixerCtlElement * ctlElem,unsigned int * item)928 int32_t SndElementReadEnum(
929 struct AlsaSoundCard *cardIns, const struct AlsaMixerCtlElement *ctlElem, unsigned int *item)
930 {
931 int ret;
932 snd_ctl_t *alsaHandle = NULL;
933 snd_ctl_elem_id_t *elem_id;
934 snd_ctl_elem_info_t *elem_info;
935 snd_ctl_elem_value_t *elem_value;
936 snd_ctl_elem_type_t type;
937
938 CHECK_NULL_PTR_RETURN_DEFAULT(cardIns);
939 CHECK_NULL_PTR_RETURN_DEFAULT(ctlElem);
940
941 ret = snd_ctl_open(&alsaHandle, cardIns->ctrlName, 0);
942 if (ret < 0) {
943 AUDIO_FUNC_LOGE("snd_ctl_open error: %{public}s", snd_strerror(ret));
944 return HDF_FAILURE;
945 }
946
947 snd_ctl_elem_id_alloca(&elem_id);
948 snd_ctl_elem_info_alloca(&elem_info);
949 snd_ctl_elem_value_alloca(&elem_value);
950 ret = SetElementInfo(alsaHandle, ctlElem, elem_info, elem_id);
951 if (ret != HDF_SUCCESS) {
952 AUDIO_FUNC_LOGE("Set element %{public}s elem_info failed!\n", ctlElem->name);
953 return HDF_FAILURE;
954 }
955 snd_ctl_elem_value_set_id(elem_value, elem_id);
956
957 if (!snd_ctl_elem_info_is_readable(elem_info)) {
958 AUDIO_FUNC_LOGE("Element read enable\n");
959 return HDF_FAILURE;
960 }
961 ret = snd_ctl_elem_read(alsaHandle, elem_value);
962 if (ret < 0) {
963 AUDIO_FUNC_LOGE("Cannot read the given element from elem_value \n");
964 return HDF_FAILURE;
965 }
966
967 type = snd_ctl_elem_info_get_type(elem_info);
968 if (type == SND_CTL_ELEM_TYPE_ENUMERATED) {
969 *item = snd_ctl_elem_value_get_enumerated(elem_value, 0);
970 } else {
971 AUDIO_FUNC_LOGE("Element type is not enumerated\n");
972 return HDF_FAILURE;
973 }
974
975 return HDF_SUCCESS;
976 }
977
SndElementReadRange(struct AlsaSoundCard * cardIns,const struct AlsaMixerCtlElement * ctlElem,long * mix,long * max)978 int32_t SndElementReadRange(
979 struct AlsaSoundCard * cardIns, const struct AlsaMixerCtlElement * ctlElem, long * mix, long * max)
980 {
981 int ret;
982 snd_ctl_t *alsaHandle = NULL;
983 snd_ctl_elem_id_t *elem_id;
984 snd_ctl_elem_info_t *elem_info;
985 snd_ctl_elem_value_t *elem_value;
986 snd_ctl_elem_type_t type;
987
988 CHECK_NULL_PTR_RETURN_DEFAULT(cardIns);
989 CHECK_NULL_PTR_RETURN_DEFAULT(ctlElem);
990
991 ret = snd_ctl_open(&alsaHandle, cardIns->ctrlName, 0);
992 if (ret < 0) {
993 AUDIO_FUNC_LOGE("snd_ctl_open error: %{public}s", snd_strerror(ret));
994 return HDF_FAILURE;
995 }
996
997 snd_ctl_elem_id_alloca(&elem_id);
998 snd_ctl_elem_info_alloca(&elem_info);
999 snd_ctl_elem_value_alloca(&elem_value);
1000 ret = SetElementInfo(alsaHandle, ctlElem, elem_info, elem_id);
1001 if (ret != HDF_SUCCESS) {
1002 AUDIO_FUNC_LOGE("Set element %{public}s elem_info failed!\n", ctlElem->name);
1003 return HDF_FAILURE;
1004 }
1005 snd_ctl_elem_value_set_id(elem_value, elem_id);
1006
1007 if (!snd_ctl_elem_info_is_readable(elem_info)) {
1008 AUDIO_FUNC_LOGE("Element read enable\n");
1009 return HDF_FAILURE;
1010 }
1011 ret = snd_ctl_elem_read(alsaHandle, elem_value);
1012 if (ret < 0) {
1013 AUDIO_FUNC_LOGE("Cannot read the given element from elem_value \n");
1014 return HDF_FAILURE;
1015 }
1016
1017 type = snd_ctl_elem_info_get_type(elem_info);
1018 if (type == SND_CTL_ELEM_TYPE_INTEGER) {
1019 *mix = snd_ctl_elem_info_get_min(elem_info);
1020 *max = snd_ctl_elem_info_get_max(elem_info);
1021 } else if (type == SND_CTL_ELEM_TYPE_INTEGER64) {
1022 *mix = (long)snd_ctl_elem_info_get_min64(elem_info);
1023 *max = (long)snd_ctl_elem_info_get_max64(elem_info);
1024 } else {
1025 AUDIO_FUNC_LOGE("Element value is not integer type!\n");
1026 return HDF_FAILURE;
1027 }
1028
1029 return HDF_SUCCESS;
1030 }
1031
SndElementReadSwitch(struct AlsaSoundCard * cardIns,const struct AlsaMixerCtlElement * ctlElem,bool * on)1032 int32_t SndElementReadSwitch(
1033 struct AlsaSoundCard *cardIns, const struct AlsaMixerCtlElement *ctlElem, bool *on)
1034 {
1035 int ret;
1036 snd_ctl_t *alsaHandle = NULL;
1037 snd_ctl_elem_id_t *elem_id;
1038 snd_ctl_elem_info_t *elem_info;
1039 snd_ctl_elem_value_t *elem_value;
1040 snd_ctl_elem_type_t type;
1041
1042 CHECK_NULL_PTR_RETURN_DEFAULT(cardIns);
1043 CHECK_NULL_PTR_RETURN_DEFAULT(ctlElem);
1044
1045 ret = snd_ctl_open(&alsaHandle, cardIns->ctrlName, 0);
1046 if (ret < 0) {
1047 AUDIO_FUNC_LOGE("snd_ctl_open error: %{public}s", snd_strerror(ret));
1048 return HDF_FAILURE;
1049 }
1050
1051 snd_ctl_elem_id_alloca(&elem_id);
1052 snd_ctl_elem_info_alloca(&elem_info);
1053 snd_ctl_elem_value_alloca(&elem_value);
1054 ret = SetElementInfo(alsaHandle, ctlElem, elem_info, elem_id);
1055 if (ret != HDF_SUCCESS) {
1056 AUDIO_FUNC_LOGE("Set element %{public}s elem_info failed!\n", ctlElem->name);
1057 return HDF_FAILURE;
1058 }
1059 snd_ctl_elem_value_set_id(elem_value, elem_id);
1060
1061 if (!snd_ctl_elem_info_is_readable(elem_info)) {
1062 AUDIO_FUNC_LOGE("Element read enable\n");
1063 return HDF_FAILURE;
1064 }
1065 ret = snd_ctl_elem_read(alsaHandle, elem_value);
1066 if (ret < 0) {
1067 AUDIO_FUNC_LOGE("Cannot read the given element from elem_value \n");
1068 return HDF_FAILURE;
1069 }
1070
1071 type = snd_ctl_elem_info_get_type(elem_info);
1072 if (type == SND_CTL_ELEM_TYPE_BOOLEAN) {
1073 ret = snd_ctl_elem_value_get_boolean(elem_value, 0);
1074 *on = (ret > 0) ? true : false;
1075 } else {
1076 AUDIO_FUNC_LOGE("Element type is not boolean\n");
1077 return HDF_FAILURE;
1078 }
1079
1080 return HDF_SUCCESS;
1081 }
1082
SndElementWriteInt(struct AlsaSoundCard * cardIns,const struct AlsaMixerCtlElement * ctlElem,long value)1083 int32_t SndElementWriteInt(
1084 struct AlsaSoundCard *cardIns, const struct AlsaMixerCtlElement *ctlElem, long value)
1085 {
1086 int ret;
1087 snd_ctl_t *alsaHandle = NULL;
1088 snd_ctl_elem_id_t *elem_id;
1089 snd_ctl_elem_info_t *elem_info;
1090 snd_ctl_elem_value_t *elem_value;
1091 snd_ctl_elem_type_t type;
1092
1093 CHECK_NULL_PTR_RETURN_DEFAULT(cardIns);
1094 CHECK_NULL_PTR_RETURN_DEFAULT(ctlElem);
1095
1096 ret = snd_ctl_open(&alsaHandle, cardIns->ctrlName, 0);
1097 if (ret < 0) {
1098 AUDIO_FUNC_LOGE("snd_ctl_open error: %{public}s", snd_strerror(ret));
1099 return HDF_FAILURE;
1100 }
1101
1102 snd_ctl_elem_id_alloca(&elem_id);
1103 snd_ctl_elem_info_alloca(&elem_info);
1104 snd_ctl_elem_value_alloca(&elem_value);
1105 ret = SetElementInfo(alsaHandle, ctlElem, elem_info, elem_id);
1106 if (ret != HDF_SUCCESS) {
1107 AUDIO_FUNC_LOGE("Set element %{public}s elem_info failed!\n", ctlElem->name);
1108 return HDF_FAILURE;
1109 }
1110
1111 if (!snd_ctl_elem_info_is_writable(elem_info)) {
1112 AUDIO_FUNC_LOGE("Element write enable\n");
1113 return HDF_FAILURE;
1114 }
1115
1116 snd_ctl_elem_value_set_id(elem_value, elem_id);
1117 type = snd_ctl_elem_info_get_type(elem_info);
1118 if (type == SND_CTL_ELEM_TYPE_INTEGER) {
1119 snd_ctl_elem_value_set_integer(elem_value, 0, value);
1120 } else if (type == SND_CTL_ELEM_TYPE_INTEGER64) {
1121 snd_ctl_elem_value_set_integer64(elem_value, 0, (long long)value);
1122 } else {
1123 AUDIO_FUNC_LOGE("Element value is not integer type!\n");
1124 return HDF_FAILURE;
1125 }
1126
1127 ret = snd_ctl_elem_write(alsaHandle, elem_value);
1128 if (ret < 0) {
1129 AUDIO_FUNC_LOGE("snd_ctl_elem_write failed!\n");
1130 return HDF_FAILURE;
1131 }
1132
1133 return HDF_SUCCESS;
1134 }
1135
SndElementWriteEnum(struct AlsaSoundCard * cardIns,const struct AlsaMixerCtlElement * ctlElem,unsigned int item)1136 int32_t SndElementWriteEnum(
1137 struct AlsaSoundCard *cardIns, const struct AlsaMixerCtlElement *ctlElem, unsigned int item)
1138 {
1139 int ret;
1140 snd_ctl_t *alsaHandle = NULL;
1141 snd_ctl_elem_id_t *elem_id;
1142 snd_ctl_elem_info_t *elem_info;
1143 snd_ctl_elem_value_t *elem_value;
1144 snd_ctl_elem_type_t type;
1145
1146 CHECK_NULL_PTR_RETURN_DEFAULT(cardIns);
1147 CHECK_NULL_PTR_RETURN_DEFAULT(ctlElem);
1148
1149 ret = snd_ctl_open(&alsaHandle, cardIns->ctrlName, 0);
1150 if (ret < 0) {
1151 AUDIO_FUNC_LOGE("snd_ctl_open error: %{public}s", snd_strerror(ret));
1152 return HDF_FAILURE;
1153 }
1154
1155 snd_ctl_elem_id_alloca(&elem_id);
1156 snd_ctl_elem_info_alloca(&elem_info);
1157 snd_ctl_elem_value_alloca(&elem_value);
1158 ret = SetElementInfo(alsaHandle, ctlElem, elem_info, elem_id);
1159 if (ret != HDF_SUCCESS) {
1160 AUDIO_FUNC_LOGE("Set element %{public}s elem_info failed!\n", ctlElem->name);
1161 return HDF_FAILURE;
1162 }
1163
1164 if (!snd_ctl_elem_info_is_writable(elem_info)) {
1165 AUDIO_FUNC_LOGE("Element write enable\n");
1166 return HDF_FAILURE;
1167 }
1168
1169 snd_ctl_elem_value_set_id(elem_value, elem_id);
1170 type = snd_ctl_elem_info_get_type(elem_info);
1171 if (type == SND_CTL_ELEM_TYPE_ENUMERATED) {
1172 snd_ctl_elem_value_set_enumerated(elem_value, 0, item);
1173 } else {
1174 AUDIO_FUNC_LOGE("Element value is not enum type!\n");
1175 return HDF_FAILURE;
1176 }
1177
1178 ret = snd_ctl_elem_write(alsaHandle, elem_value);
1179 if (ret < 0) {
1180 AUDIO_FUNC_LOGE("snd_ctl_elem_write failed!\n");
1181 return HDF_FAILURE;
1182 }
1183
1184 return HDF_SUCCESS;
1185 }
1186
SndElementWriteSwitch(struct AlsaSoundCard * cardIns,const struct AlsaMixerCtlElement * ctlElem,bool on)1187 int32_t SndElementWriteSwitch(
1188 struct AlsaSoundCard *cardIns, const struct AlsaMixerCtlElement *ctlElem, bool on)
1189 {
1190 int ret;
1191 int value;
1192 snd_ctl_t *alsaHandle = NULL;
1193 snd_ctl_elem_id_t *elem_id;
1194 snd_ctl_elem_info_t *elem_info;
1195 snd_ctl_elem_value_t *elem_value;
1196 snd_ctl_elem_type_t type;
1197
1198 CHECK_NULL_PTR_RETURN_DEFAULT(cardIns);
1199 CHECK_NULL_PTR_RETURN_DEFAULT(ctlElem);
1200
1201 ret = snd_ctl_open(&alsaHandle, cardIns->ctrlName, 0);
1202 if (ret < 0) {
1203 AUDIO_FUNC_LOGE("snd_ctl_open error: %{public}s", snd_strerror(ret));
1204 return HDF_FAILURE;
1205 }
1206
1207 snd_ctl_elem_id_alloca(&elem_id);
1208 snd_ctl_elem_info_alloca(&elem_info);
1209 snd_ctl_elem_value_alloca(&elem_value);
1210 ret = SetElementInfo(alsaHandle, ctlElem, elem_info, elem_id);
1211 if (ret != HDF_SUCCESS) {
1212 AUDIO_FUNC_LOGE("Set element %{public}s elem_info failed!\n", ctlElem->name);
1213 return HDF_FAILURE;
1214 }
1215
1216 if (!snd_ctl_elem_info_is_writable(elem_info)) {
1217 AUDIO_FUNC_LOGE("Element write enable\n");
1218 return HDF_FAILURE;
1219 }
1220
1221 snd_ctl_elem_value_set_id(elem_value, elem_id);
1222 type = snd_ctl_elem_info_get_type(elem_info);
1223 if (type == SND_CTL_ELEM_TYPE_BOOLEAN) {
1224 value = on ? 1 : 0;
1225 snd_ctl_elem_value_set_boolean(elem_value, 0, value);
1226 } else {
1227 AUDIO_FUNC_LOGE("Element value is not boolean type!\n");
1228 return HDF_FAILURE;
1229 }
1230
1231 ret = snd_ctl_elem_write(alsaHandle, elem_value);
1232 if (ret < 0) {
1233 AUDIO_FUNC_LOGE("snd_ctl_elem_write failed!\n");
1234 return HDF_FAILURE;
1235 }
1236
1237 return HDF_SUCCESS;
1238 }
1239
SndElementWrite(struct AlsaSoundCard * cardIns,const struct AlsaMixerCtlElement * ctlElem)1240 int32_t SndElementWrite(
1241 struct AlsaSoundCard *cardIns, const struct AlsaMixerCtlElement *ctlElem)
1242 {
1243 int ret;
1244 snd_ctl_t *alsaHandle = NULL;
1245 snd_ctl_elem_id_t *elem_id;
1246 snd_ctl_elem_info_t *elem_info;
1247 snd_ctl_elem_value_t *elem_value;
1248
1249 CHECK_NULL_PTR_RETURN_DEFAULT(cardIns);
1250 CHECK_NULL_PTR_RETURN_DEFAULT(ctlElem);
1251
1252 ret = snd_ctl_open(&alsaHandle, cardIns->ctrlName, 0);
1253 if (ret < 0) {
1254 AUDIO_FUNC_LOGE("snd_ctl_open error: %{public}s", snd_strerror(ret));
1255 return HDF_FAILURE;
1256 }
1257
1258 snd_ctl_elem_id_alloca(&elem_id);
1259 snd_ctl_elem_info_alloca(&elem_info);
1260 snd_ctl_elem_value_alloca(&elem_value);
1261 ret = SetElementInfo(alsaHandle, ctlElem, elem_info, elem_id);
1262 if (ret != HDF_SUCCESS) {
1263 AUDIO_FUNC_LOGE("Set element %{public}s elem_info failed!\n", ctlElem->name);
1264 return HDF_FAILURE;
1265 }
1266
1267 if (!snd_ctl_elem_info_is_writable(elem_info)) {
1268 AUDIO_FUNC_LOGE("Element write enable\n");
1269 return HDF_FAILURE;
1270 }
1271
1272 snd_ctl_elem_value_set_id(elem_value, elem_id);
1273 ret = snd_ctl_ascii_value_parse(alsaHandle, elem_value, elem_info, ctlElem->value);
1274 if (ret < 0) {
1275 AUDIO_FUNC_LOGE("Control parse error: %s\n", snd_strerror(ret));
1276 return HDF_FAILURE;
1277 }
1278 ret = snd_ctl_elem_write(alsaHandle, elem_value);
1279 if (ret < 0) {
1280 AUDIO_FUNC_LOGE("Control element write error: %s\n", snd_strerror(ret));
1281 return HDF_FAILURE;
1282 }
1283
1284 return HDF_SUCCESS;
1285 }
1286
SndElementGroupWrite(struct AlsaSoundCard * cardIns,const struct AlsaMixerCtlElement * elemGroup,int32_t groupSize)1287 int32_t SndElementGroupWrite(
1288 struct AlsaSoundCard *cardIns, const struct AlsaMixerCtlElement* elemGroup, int32_t groupSize)
1289 {
1290 int err;
1291 CHECK_NULL_PTR_RETURN_DEFAULT(cardIns);
1292
1293 for (int i = 0; i < groupSize; ++i) {
1294 err = SndElementWrite(cardIns, &elemGroup[i]);
1295 if (err < 0) {
1296 AUDIO_FUNC_LOGE("Cant't set element %{public}s", elemGroup[i].name);
1297 }
1298 }
1299
1300 return HDF_SUCCESS;
1301 }
1302
SndTraversalMixerElement(struct AlsaSoundCard * cardIns,bool (* callback)(void * data,snd_ctl_elem_id_t * elem_id),void * data)1303 int32_t SndTraversalMixerElement(struct AlsaSoundCard *cardIns,
1304 bool (*callback)(void *data, snd_ctl_elem_id_t *elem_id), void *data)
1305 {
1306 int ret;
1307 snd_hctl_t *handle;
1308 snd_hctl_elem_t *elem;
1309 snd_ctl_elem_id_t *elem_id;
1310 snd_ctl_elem_info_t *elem_info;
1311 CHECK_NULL_PTR_RETURN_DEFAULT(cardIns);
1312 CHECK_NULL_PTR_RETURN_DEFAULT(callback);
1313
1314 ret = snd_hctl_open(&handle, cardIns->ctrlName, 0);
1315 if (ret < 0) {
1316 AUDIO_FUNC_LOGE("Control %{public}s open error: %{public}s",
1317 cardIns->ctrlName, snd_strerror(ret));
1318 return HDF_FAILURE;
1319 }
1320 ret = snd_hctl_load(handle);
1321 if (ret < 0) {
1322 AUDIO_FUNC_LOGE("Control %{public}s local error: %{public}s\n",
1323 cardIns->ctrlName, snd_strerror(ret));
1324 return HDF_FAILURE;
1325 }
1326
1327 snd_ctl_elem_id_alloca(&elem_id);
1328 snd_ctl_elem_info_alloca(&elem_info);
1329 for (elem = snd_hctl_first_elem(handle); elem; elem = snd_hctl_elem_next(elem)) {
1330 ret = snd_hctl_elem_info(elem, elem_info);
1331 if (ret < 0) {
1332 AUDIO_FUNC_LOGE("Control %{public}s snd_hctl_elem_info error: %{public}s\n",
1333 cardIns->ctrlName, snd_strerror(ret));
1334 return HDF_FAILURE;
1335 }
1336 if (snd_ctl_elem_info_is_inactive(elem_info)) {
1337 continue;
1338 }
1339 snd_hctl_elem_get_id(elem, elem_id);
1340 if (callback(data, elem_id)) {
1341 (void)snd_hctl_close(handle);
1342 return HDF_SUCCESS;
1343 }
1344 }
1345 (void)snd_hctl_close(handle);
1346 return HDF_FAILURE;
1347 }
1348