1 /*
2 * Copyright (c) 2022 Unionman Technology 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 <linux/soundcard.h>
17 #include "sound/asound.h"
18
19 #include "hdf_log.h"
20 #include "tinyalsa/asoundlib.h"
21
22 #include "audio_interface_lib_capture.h"
23
24 #define HDF_LOG_TAG HDI_AUDIO_C_ALSA
25
26 // treat hats.
27 #define PLEASURE_HATS
28
29 #define SOUND_CARD_ID (0)
30 #define SOUND_DEV_ID (4)
31
32 struct AlsaCtx {
33 struct pcm *pcmHandler;
34 struct pcm_config config;
35 struct mixer *mixerHandler;
36
37 int initFlag;
38 int volume;
39 int volMin;
40 int volMax;
41 float gainMax;
42 float gainMin;
43 float gain;
44 bool mute;
45 };
46
47 static struct AlsaCtx s_alsaCtx = {.initFlag = 0};
48
MixerInit(struct mixer * mixer)49 static int32_t MixerInit(struct mixer *mixer)
50 {
51 int32_t ret = 0;
52
53 if (!mixer) {
54 HDF_LOGE("Error: mixer is NULL.");
55 return -1;
56 }
57
58 // config audio path
59 ret |= mixer_ctl_set_enum_by_string(
60 mixer_get_ctl_by_name(mixer, "TDMIN_LB SRC SEL"), "IN 1");
61 ret |= mixer_ctl_set_enum_by_string(
62 mixer_get_ctl_by_name(mixer, "TDMIN_B SRC SEL"), "IN 1");
63 ret |= mixer_ctl_set_enum_by_string(
64 mixer_get_ctl_by_name(mixer, "TODDR_B SRC SEL"), "IN 1");
65
66 return ret;
67 }
68
AlsaVolumeUpdate(struct AlsaCtx * aCtx)69 static int32_t AlsaVolumeUpdate(struct AlsaCtx *aCtx)
70 {
71 int32_t ret = 0;
72 int volumeSet = 0;
73
74 if (!aCtx->mixerHandler) {
75 return -1;
76 }
77
78 if (aCtx->mute) {
79 volumeSet = 0;
80 } else {
81 volumeSet = aCtx->volume * 1312U / (aCtx->volMax - aCtx->volMin);
82 }
83
84 ret = mixer_ctl_set_value(
85 mixer_get_ctl_by_name(aCtx->mixerHandler, "Linein Mic1 Volume"), 0,
86 volumeSet);
87
88 HDF_LOGV("Set Volume: volume=%{public}d, mute=%{public}d, "
89 "volumeSet=%{public}d, ret=%{public}d",
90 aCtx->volume, aCtx->mute, volumeSet, ret);
91
92 return ret;
93 }
94
ConvertFormatToAlsa(enum AudioFormat format)95 static enum pcm_format ConvertFormatToAlsa(enum AudioFormat format)
96 {
97 switch (format) {
98 case AUDIO_FORMAT_TYPE_PCM_8_BIT:
99 return PCM_FORMAT_S8;
100 case AUDIO_FORMAT_TYPE_PCM_16_BIT:
101 return PCM_FORMAT_S16_LE;
102 case AUDIO_FORMAT_TYPE_PCM_24_BIT:
103 return PCM_FORMAT_S24_LE;
104 case AUDIO_FORMAT_TYPE_PCM_32_BIT:
105 return PCM_FORMAT_S32_LE;
106 case AUDIO_FORMAT_TYPE_AAC_MAIN:
107 case AUDIO_FORMAT_TYPE_AAC_LC:
108 case AUDIO_FORMAT_TYPE_AAC_LD:
109 case AUDIO_FORMAT_TYPE_AAC_ELD:
110 case AUDIO_FORMAT_TYPE_AAC_HE_V1:
111 case AUDIO_FORMAT_TYPE_AAC_HE_V2:
112 case AUDIO_FORMAT_TYPE_G711A:
113 case AUDIO_FORMAT_TYPE_G711U:
114 case AUDIO_FORMAT_TYPE_G726:
115 default:
116 return PCM_FORMAT_INVALID;
117 }
118 }
119
AlsaCtxInstanceGet(void)120 static struct AlsaCtx *AlsaCtxInstanceGet(void)
121 {
122 if (!s_alsaCtx.initFlag) {
123 memset_s(&s_alsaCtx, sizeof(s_alsaCtx), 0, sizeof(s_alsaCtx));
124 s_alsaCtx.pcmHandler = NULL;
125 s_alsaCtx.volMin = 0;
126 s_alsaCtx.volMax = 100U;
127 s_alsaCtx.volume = s_alsaCtx.volMax;
128 s_alsaCtx.gainMin = 0.0;
129 s_alsaCtx.gainMax = 15.0f;
130 s_alsaCtx.gain = s_alsaCtx.gainMax;
131 s_alsaCtx.mute = false;
132 s_alsaCtx.mixerHandler = mixer_open(SOUND_CARD_ID);
133 MixerInit(s_alsaCtx.mixerHandler);
134 s_alsaCtx.initFlag = 1;
135
136 AlsaVolumeUpdate(&s_alsaCtx);
137 }
138
139 return &s_alsaCtx;
140 }
141
AlsaOpen(struct AlsaCtx * aCtx)142 static int AlsaOpen(struct AlsaCtx *aCtx)
143 {
144 int sound_card_id = SOUND_CARD_ID;
145 int sound_dev_id = SOUND_DEV_ID;
146
147 HDF_LOGI(
148 "%{public}s() rate=%{public}d, channels=%{public}d, format=%{public}d",
149 __func__, aCtx->config.rate, aCtx->config.channels,
150 aCtx->config.format);
151
152 if (aCtx->pcmHandler) {
153 HDF_LOGW("Alsa is opened already.");
154 return 0;
155 }
156
157 struct pcm_config config;
158 (void)memcpy_s(&config, sizeof(config), &aCtx->config, sizeof(config));
159 struct pcm *pcm = pcm_open(sound_card_id, sound_dev_id, PCM_IN, &config);
160 if (!pcm_is_ready(pcm)) {
161 HDF_LOGE("Error: %{public}s() Cannot open PCM_IN(card %{public}d, "
162 "device %{public}d): %{public}s",
163 __func__, sound_card_id, sound_dev_id, pcm_get_error(pcm));
164 pcm_close(pcm);
165
166 return -1;
167 }
168
169 aCtx->pcmHandler = pcm;
170
171 HDF_LOGI("Open Alsa PCM_IN Success.");
172
173 return 0;
174 }
175
AlsaClose(struct AlsaCtx * aCtx)176 static int AlsaClose(struct AlsaCtx *aCtx)
177 {
178 if (aCtx->pcmHandler) {
179 pcm_close(aCtx->pcmHandler);
180 aCtx->pcmHandler = NULL;
181 }
182
183 HDF_LOGI("Close Alsa Success.");
184
185 return 0;
186 }
187
CheckHwParam(struct AudioHwCaptureParam * handleData)188 static int CheckHwParam(struct AudioHwCaptureParam *handleData)
189 {
190 if (handleData == NULL) {
191 HDF_LOGE("Error: handleData is NULL!");
192 return -1;
193 }
194
195 if (handleData->frameCaptureMode.attrs.channelCount != 1U &&
196 handleData->frameCaptureMode.attrs.channelCount != 2U) {
197 HDF_LOGE("Error: Unsupported channel count: %{public}d",
198 handleData->frameCaptureMode.attrs.channelCount);
199 return -1;
200 }
201
202 if (handleData->frameCaptureMode.attrs.format == AUDIO_FORMAT_TYPE_PCM_8_BIT &&
203 handleData->frameCaptureMode.attrs.sampleRate == 8000U)
204 return -1;
205
206 if (handleData->frameCaptureMode.attrs.format == AUDIO_FORMAT_TYPE_PCM_32_BIT &&
207 handleData->frameCaptureMode.attrs.sampleRate == 11025U)
208 return -1;
209
210 return 0;
211 }
212
AlsaConfig(struct AlsaCtx * aCtx,struct AudioHwCaptureParam * handleData)213 static int AlsaConfig(struct AlsaCtx *aCtx, struct AudioHwCaptureParam *handleData)
214 {
215 struct pcm_config config;
216 enum pcm_format format;
217
218 if (CheckHwParam(handleData)) {
219 return -1;
220 }
221
222 format = ConvertFormatToAlsa(handleData->frameCaptureMode.attrs.format);
223 if (PCM_FORMAT_INVALID == format) {
224 HDF_LOGE("Error: Unsupported format: %{public}d", handleData->frameCaptureMode.attrs.format);
225 return -1;
226 }
227
228 memset_s(&config, sizeof(config), 0, sizeof(config));
229
230 config.channels = handleData->frameCaptureMode.attrs.channelCount;
231 config.rate = handleData->frameCaptureMode.attrs.sampleRate;
232 config.format = format;
233 config.period_count = handleData->frameCaptureMode.periodCount; // 4
234 config.period_size = handleData->frameCaptureMode.periodSize; // 1024
235
236 #ifdef PLEASURE_HATS
237 if (config.rate == 12000) {
238 config.rate = 8000;
239 } else if (config.rate == 24000) {
240 config.rate = 22050;
241 } else if (config.rate == 64000) {
242 config.rate = 48000;
243 } else if (config.rate == 96000) {
244 config.rate = 48000;
245 }
246
247 if (config.format == PCM_FORMAT_S24_LE) {
248 config.format = PCM_FORMAT_S16_LE;
249 }
250 #endif
251
252 HDF_LOGV("DUMP Alsa Config 1#: channels=%{public}d, rate=%{public}d, "
253 "format=%{public}d, period_count=%{public}d, period_size=%{public}d",
254 config.channels, config.rate, config.format, config.period_count,
255 config.period_size);
256
257 HDF_LOGV("DUMP Alsa OldConfig 1#: channels=%{public}d, rate=%{public}d, "
258 "format=%{public}d, period_count=%{public}d, period_size=%{public}d",
259 aCtx->config.channels, aCtx->config.rate, aCtx->config.format,
260 aCtx->config.period_count, aCtx->config.period_size);
261
262 if (aCtx->pcmHandler && !memcmp(&config, &aCtx->config, sizeof(config))) {
263 HDF_LOGW("Warn: Same Audio Hw config. No need to change.");
264 return 0;
265 }
266
267 (void)memcpy_s(&aCtx->config, sizeof(aCtx->config), &config, sizeof(config));
268
269 AlsaClose(aCtx);
270 if (AlsaOpen(aCtx) < 0) {
271 HDF_LOGE("Error: in %{public}s, AlsaOpen() failed.", __func__);
272 return -1;
273 }
274
275 HDF_LOGV("Config Alsa SUCCESS.");
276
277 return 0;
278 }
279
DoCtlCaptureSetPauseStu(const struct DevHandleCapture * handle,int cmdId,struct AudioHwCaptureParam * handleData)280 static int32_t DoCtlCaptureSetPauseStu(const struct DevHandleCapture *handle,
281 int cmdId,
282 struct AudioHwCaptureParam *handleData)
283 {
284 struct AlsaCtx *aCtx = (struct AlsaCtx *)handle->object;
285
286 if (!aCtx->pcmHandler) {
287 HDF_LOGE("Error: in %{public}s, Pcm is not opened!", __func__);
288 return HDF_FAILURE;
289 }
290
291 if (pcm_ioctl(aCtx->pcmHandler, SNDRV_PCM_IOCTL_PAUSE,
292 handleData->captureMode.ctlParam.pause ? 1 : 0) < 0) {
293 HDF_LOGE("Error: pcm_ioctl(SNDRV_PCM_IOCTL_PAUSE) failed: %{public}s\n",
294 pcm_get_error(aCtx->pcmHandler));
295 return HDF_FAILURE;
296 }
297
298 return HDF_SUCCESS;
299 }
300
DoCtlCaptureGetVolume(const struct DevHandleCapture * handle,int cmdId,struct AudioHwCaptureParam * handleData)301 static int32_t DoCtlCaptureGetVolume(const struct DevHandleCapture *handle,
302 int cmdId,
303 struct AudioHwCaptureParam *handleData)
304 {
305 struct AlsaCtx *aCtx = (struct AlsaCtx *)handle->object;
306
307 handleData->captureMode.ctlParam.volume = aCtx->volume;
308
309 return HDF_SUCCESS;
310 }
311
DoCtlCaptureSetVolume(const struct DevHandleCapture * handle,int cmdId,struct AudioHwCaptureParam * handleData)312 static int32_t DoCtlCaptureSetVolume(const struct DevHandleCapture *handle,
313 int cmdId,
314 struct AudioHwCaptureParam *handleData)
315 {
316 struct AlsaCtx *aCtx = (struct AlsaCtx *)handle->object;
317
318 HDF_LOGV("INFO: enter %{public}s(). volume=%{public}f", __func__,
319 handleData->captureMode.ctlParam.volume);
320
321 int volume = (int)handleData->captureMode.ctlParam.volume;
322
323 if (volume < aCtx->volMin || volume > aCtx->volMax) {
324 HDF_LOGE("Error: Invalid volume: %{public}d", volume);
325 return HDF_FAILURE;
326 }
327
328 aCtx->volume = volume;
329
330 return AlsaVolumeUpdate(aCtx);
331 }
332
DoCtlCaptureSetMuteStu(const struct DevHandleCapture * handle,int cmdId,struct AudioHwCaptureParam * handleData)333 static int32_t DoCtlCaptureSetMuteStu(const struct DevHandleCapture *handle,
334 int cmdId,
335 struct AudioHwCaptureParam *handleData)
336 {
337 struct AlsaCtx *aCtx = (struct AlsaCtx *)handle->object;
338
339 aCtx->mute = handleData->captureMode.ctlParam.mute;
340
341 return AlsaVolumeUpdate(aCtx);
342 }
343
DoCtlCaptureGetMuteStu(const struct DevHandleCapture * handle,int cmdId,struct AudioHwCaptureParam * handleData)344 static int32_t DoCtlCaptureGetMuteStu(const struct DevHandleCapture *handle,
345 int cmdId,
346 struct AudioHwCaptureParam *handleData)
347 {
348 struct AlsaCtx *aCtx = (struct AlsaCtx *)handle->object;
349
350 handleData->captureMode.ctlParam.mute = aCtx->mute;
351
352 return HDF_SUCCESS;
353 }
354
DoCtlCaptureSetGainStu(const struct DevHandleCapture * handle,int cmdId,struct AudioHwCaptureParam * handleData)355 static int32_t DoCtlCaptureSetGainStu(const struct DevHandleCapture *handle,
356 int cmdId,
357 struct AudioHwCaptureParam *handleData)
358 {
359 struct AlsaCtx *aCtx = (struct AlsaCtx *)handle->object;
360
361 float gain = handleData->captureMode.ctlParam.audioGain.gain;
362
363 if (gain < aCtx->gainMin || gain > aCtx->gainMax) {
364 HDF_LOGE("Error: Invalid gain: %{public}f", gain);
365 return HDF_FAILURE;
366 }
367
368 aCtx->gain = gain;
369
370 return HDF_SUCCESS;
371 }
372
DoCtlCaptureGetGainStu(const struct DevHandleCapture * handle,int cmdId,struct AudioHwCaptureParam * handleData)373 static int32_t DoCtlCaptureGetGainStu(const struct DevHandleCapture *handle,
374 int cmdId,
375 struct AudioHwCaptureParam *handleData)
376 {
377 struct AlsaCtx *aCtx = (struct AlsaCtx *)handle->object;
378
379 handleData->captureMode.ctlParam.audioGain.gain = aCtx->gain;
380
381 return HDF_SUCCESS;
382 }
383
DoCtlCaptureSceneSelect(const struct DevHandleCapture * handle,int cmdId,struct AudioHwCaptureParam * handleData)384 static int32_t DoCtlCaptureSceneSelect(const struct DevHandleCapture *handle,
385 int cmdId,
386 struct AudioHwCaptureParam *handleData)
387 {
388 return HDF_SUCCESS;
389 }
390
DoCtlCaptureGetGainThreshold(const struct DevHandleCapture * handle,int cmdId,struct AudioHwCaptureParam * handleData)391 static int32_t DoCtlCaptureGetGainThreshold(const struct DevHandleCapture *handle, int cmdId,
392 struct AudioHwCaptureParam *handleData)
393 {
394 struct AlsaCtx *aCtx = (struct AlsaCtx *)handle->object;
395
396 handleData->captureMode.ctlParam.audioGain.gainMax = aCtx->gainMax;
397 handleData->captureMode.ctlParam.audioGain.gainMin = aCtx->gainMin;
398
399 return HDF_SUCCESS;
400 }
401
DoCtlCaptureGetVolThreshold(const struct DevHandleCapture * handle,int cmdId,struct AudioHwCaptureParam * handleData)402 static int32_t DoCtlCaptureGetVolThreshold(const struct DevHandleCapture *handle, int cmdId,
403 struct AudioHwCaptureParam *handleData)
404 {
405 struct AlsaCtx *aCtx = (struct AlsaCtx *)handle->object;
406
407 handleData->captureMode.ctlParam.volThreshold.volMax = aCtx->volMax;
408 handleData->captureMode.ctlParam.volThreshold.volMin = aCtx->volMin;
409
410 return HDF_SUCCESS;
411 }
412
HandleCtlCaptureCmd(const struct DevHandleCapture * handle,int cmdId,struct AudioHwCaptureParam * handleData)413 static int32_t HandleCtlCaptureCmd(const struct DevHandleCapture *handle,
414 int cmdId,
415 struct AudioHwCaptureParam *handleData)
416 {
417 int32_t ret;
418
419 switch (cmdId) {
420 /* setPara: */
421 case AUDIODRV_CTL_IOCTL_ELEM_WRITE_CAPTURE:
422 ret = DoCtlCaptureSetVolume(handle, cmdId, handleData);
423 break;
424 case AUDIODRV_CTL_IOCTL_MUTE_WRITE_CAPTURE:
425 ret = DoCtlCaptureSetMuteStu(handle, cmdId, handleData);
426 break;
427 case AUDIODRV_CTL_IOCTL_MUTE_READ_CAPTURE:
428 ret = DoCtlCaptureGetMuteStu(handle, cmdId, handleData);
429 break;
430 /* getPara: */
431 case AUDIODRV_CTL_IOCTL_ELEM_READ_CAPTURE:
432 ret = DoCtlCaptureGetVolume(handle, cmdId, handleData);
433 break;
434 case AUDIODRV_CTL_IOCTL_GAIN_WRITE_CAPTURE:
435 ret = DoCtlCaptureSetGainStu(handle, cmdId, handleData);
436 break;
437 case AUDIODRV_CTL_IOCTL_GAIN_READ_CAPTURE:
438 ret = DoCtlCaptureGetGainStu(handle, cmdId, handleData);
439 break;
440 case AUDIODRV_CTL_IOCTL_SCENESELECT_CAPTURE:
441 ret = DoCtlCaptureSceneSelect(handle, cmdId, handleData);
442 break;
443 case AUDIODRV_CTL_IOCTL_GAINTHRESHOLD_CAPTURE:
444 ret = DoCtlCaptureGetGainThreshold(handle, cmdId, handleData);
445 break;
446 case AUDIODRV_CTL_IOCTL_VOL_THRESHOLD_CAPTURE:
447 ret = DoCtlCaptureGetVolThreshold(handle, cmdId, handleData);
448 break;
449 default:
450 HDF_LOGE("Error: Ctl Mode not support!");
451 ret = HDF_FAILURE;
452 break;
453 }
454
455 return ret;
456 }
457
DoOutputCaptureHwParams(const struct DevHandleCapture * handle,int cmdId,struct AudioHwCaptureParam * handleData)458 static int32_t DoOutputCaptureHwParams(const struct DevHandleCapture *handle,
459 int cmdId,
460 struct AudioHwCaptureParam *handleData)
461 {
462 struct AlsaCtx *aCtx = (struct AlsaCtx *)handle->object;
463
464 HDF_LOGV("INFO: enter %{public}s()", __func__);
465
466 if (AlsaConfig(aCtx, handleData) < 0) {
467 HDF_LOGE("Error: in %{public}s, AlsaConfig() failed.", __func__);
468 return HDF_FAILURE;
469 }
470
471 return HDF_SUCCESS;
472 }
473
DoOutputCaptureRead(const struct DevHandleCapture * handle,int cmdId,struct AudioHwCaptureParam * handleData)474 static int32_t DoOutputCaptureRead(const struct DevHandleCapture *handle,
475 int cmdId,
476 struct AudioHwCaptureParam *handleData)
477 {
478 struct AlsaCtx *aCtx = (struct AlsaCtx *)handle->object;
479
480 if (!aCtx->pcmHandler) {
481 HDF_LOGE("Error: in %{public}s, Pcm is not opened!", __func__);
482 return HDF_FAILURE;
483 }
484
485 uint32_t dataSize = 8192; // See to 'buffer_size' in audio_policy_config.xml
486
487 if (!handleData->frameCaptureMode.buffer) {
488 return HDF_FAILURE;
489 }
490
491 if (pcm_read(aCtx->pcmHandler, handleData->frameCaptureMode.buffer,
492 dataSize) < 0) {
493 HDF_LOGE("Error: pcm_read() failed: %{public}s\n",
494 pcm_get_error(aCtx->pcmHandler));
495 return HDF_FAILURE;
496 }
497
498 handleData->frameCaptureMode.bufferSize = dataSize;
499 handleData->frameCaptureMode.bufferFrameSize =
500 pcm_bytes_to_frames(aCtx->pcmHandler, dataSize);
501
502 return HDF_SUCCESS;
503 }
504
DoOutputCaptureStartPrepare(const struct DevHandleCapture * handle,int cmdId,struct AudioHwCaptureParam * handleData)505 static int32_t DoOutputCaptureStartPrepare(const struct DevHandleCapture *handle, int cmdId,
506 struct AudioHwCaptureParam *handleData)
507 {
508 struct AlsaCtx *aCtx = (struct AlsaCtx *)handle->object;
509
510 HDF_LOGV("INFO: enter %{public}s()", __func__);
511
512 AlsaOpen(aCtx);
513
514 return HDF_SUCCESS;
515 }
516
DoOutputCaptureOpen(const struct DevHandleCapture * handle,int cmdId,const struct AudioHwCaptureParam * handleData)517 static int32_t DoOutputCaptureOpen(const struct DevHandleCapture *handle,
518 int cmdId,
519 const struct AudioHwCaptureParam *handleData)
520 {
521 HDF_LOGV("INFO: enter %{public}s()", __func__);
522
523 return HDF_SUCCESS;
524 }
525
DoOutputCaptureClose(const struct DevHandleCapture * handle,int cmdId,const struct AudioHwCaptureParam * handleData)526 static int32_t DoOutputCaptureClose(const struct DevHandleCapture *handle, int cmdId,
527 const struct AudioHwCaptureParam *handleData)
528 {
529 struct AlsaCtx *aCtx = (struct AlsaCtx *)handle->object;
530
531 HDF_LOGV("INFO: enter %{public}s()", __func__);
532
533 if (!aCtx->pcmHandler) {
534 HDF_LOGE("Error: in %{public}s, Pcm is not opened!", __func__);
535 return HDF_FAILURE;
536 }
537
538 AlsaClose(aCtx);
539
540 return HDF_SUCCESS;
541 }
542
DoOutputCaptureStop(const struct DevHandleCapture * handle,int cmdId,struct AudioHwCaptureParam * handleData)543 static int32_t DoOutputCaptureStop(const struct DevHandleCapture *handle,
544 int cmdId,
545 struct AudioHwCaptureParam *handleData)
546 {
547 struct AlsaCtx *aCtx = (struct AlsaCtx *)handle->object;
548
549 HDF_LOGV("INFO: enter %{public}s()", __func__);
550
551 if (!aCtx->pcmHandler) {
552 HDF_LOGE("Error: in %{public}s, Pcm is not opened!", __func__);
553 return HDF_FAILURE;
554 }
555
556 AlsaClose(aCtx);
557
558 return HDF_SUCCESS;
559 }
560
DoOutputCaptureReqMmapBuffer(const struct DevHandleCapture * handle,int cmdId,struct AudioHwCaptureParam * handleData)561 static int32_t DoOutputCaptureReqMmapBuffer(const struct DevHandleCapture *handle, int cmdId,
562 struct AudioHwCaptureParam *handleData)
563 {
564 return HDF_SUCCESS;
565 }
566
DoOutputCaptureGetMmapPosition(const struct DevHandleCapture * handle,int cmdId,struct AudioHwCaptureParam * handleData)567 static int32_t DoOutputCaptureGetMmapPosition(const struct DevHandleCapture *handle, int cmdId,
568 struct AudioHwCaptureParam *handleData)
569 {
570 return HDF_SUCCESS;
571 }
572
HandleOutputCaptureCmd(const struct DevHandleCapture * handle,int cmdId,struct AudioHwCaptureParam * handleData)573 static int32_t HandleOutputCaptureCmd(const struct DevHandleCapture *handle,
574 int cmdId,
575 struct AudioHwCaptureParam *handleData)
576 {
577 int32_t ret;
578
579 switch (cmdId) {
580 case AUDIO_DRV_PCM_IOCTL_HW_PARAMS:
581 ret = DoOutputCaptureHwParams(handle, cmdId, handleData);
582 break;
583 case AUDIO_DRV_PCM_IOCTL_READ:
584 ret = DoOutputCaptureRead(handle, cmdId, handleData);
585 break;
586 case AUDIO_DRV_PCM_IOCTRL_START_CAPTURE:
587 case AUDIO_DRV_PCM_IOCTL_PREPARE_CAPTURE:
588 ret = DoOutputCaptureStartPrepare(handle, cmdId, handleData);
589 break;
590 case AUDIO_DRV_PCM_IOCTRL_CAPTURE_CLOSE:
591 ret = DoOutputCaptureClose(handle, cmdId, handleData);
592 break;
593 case AUDIO_DRV_PCM_IOCTRL_CAPTURE_OPEN:
594 ret = DoOutputCaptureOpen(handle, cmdId, handleData);
595 break;
596 case AUDIO_DRV_PCM_IOCTRL_STOP_CAPTURE:
597 ret = DoOutputCaptureStop(handle, cmdId, handleData);
598 break;
599 case AUDIODRV_CTL_IOCTL_PAUSE_WRITE_CAPTURE:
600 ret = DoCtlCaptureSetPauseStu(handle, cmdId, handleData);
601 break;
602 case AUDIO_DRV_PCM_IOCTL_MMAP_BUFFER_CAPTURE:
603 ret = DoOutputCaptureReqMmapBuffer(handle, cmdId, handleData);
604 break;
605 case AUDIO_DRV_PCM_IOCTL_MMAP_POSITION_CAPTURE:
606 ret = DoOutputCaptureGetMmapPosition(handle, cmdId, handleData);
607 break;
608 default:
609 HDF_LOGE("Output Mode not support!");
610 ret = HDF_FAILURE;
611 break;
612 }
613
614 return ret;
615 }
616
617 /************************************************************************************
618 Exported Interface
619 *************************************************************************************/
620
621 /* CreatCapture for Bind handle */
AudioBindServiceCapture(const char * name)622 struct DevHandleCapture *AudioBindServiceCapture(const char *name)
623 {
624 struct DevHandleCapture *handle = NULL;
625 if (!name) {
626 HDF_LOGE("service name NULL!");
627 return NULL;
628 }
629 handle =
630 (struct DevHandleCapture *)calloc(1, sizeof(struct DevHandleCapture));
631 if (handle == NULL) {
632 HDF_LOGE("Failed to OsalMemCalloc handle");
633 return NULL;
634 }
635
636 handle->object = AlsaCtxInstanceGet();
637
638 HDF_LOGV("BIND SERVICE SUCCESS: %{public}s, %{public}p", name, handle);
639
640 return handle;
641 }
642
AudioCloseServiceCapture(const struct DevHandleCapture * handle)643 void AudioCloseServiceCapture(const struct DevHandleCapture *handle)
644 {
645 if (!handle || !handle->object) {
646 HDF_LOGE("Capture handle or handle->object is NULL");
647 return;
648 }
649
650 free((void *)handle);
651
652 HDF_LOGV("CLOSE SERVICE SUCCESS: %{public}p", handle);
653
654 return;
655 }
656
AudioInterfaceLibModeCapture(const struct DevHandleCapture * handle,struct AudioHwCaptureParam * handleData,int cmdId)657 int32_t AudioInterfaceLibModeCapture(const struct DevHandleCapture *handle,
658 struct AudioHwCaptureParam *handleData,
659 int cmdId)
660 {
661 if (!handle || !handle->object || !handleData) {
662 HDF_LOGE("paras is NULL!");
663 return HDF_FAILURE;
664 }
665
666 switch (cmdId) {
667 case AUDIO_DRV_PCM_IOCTL_HW_PARAMS:
668 case AUDIO_DRV_PCM_IOCTL_READ:
669 case AUDIO_DRV_PCM_IOCTRL_START_CAPTURE:
670 case AUDIO_DRV_PCM_IOCTRL_STOP_CAPTURE:
671 case AUDIO_DRV_PCM_IOCTL_PREPARE_CAPTURE:
672 case AUDIODRV_CTL_IOCTL_PAUSE_WRITE_CAPTURE:
673 case AUDIO_DRV_PCM_IOCTL_MMAP_BUFFER_CAPTURE:
674 case AUDIO_DRV_PCM_IOCTL_MMAP_POSITION_CAPTURE:
675 case AUDIO_DRV_PCM_IOCTRL_CAPTURE_OPEN:
676 case AUDIO_DRV_PCM_IOCTRL_CAPTURE_CLOSE:
677 return HandleOutputCaptureCmd(handle, cmdId, handleData);
678 case AUDIODRV_CTL_IOCTL_ELEM_WRITE_CAPTURE:
679 case AUDIODRV_CTL_IOCTL_ELEM_READ_CAPTURE:
680 case AUDIODRV_CTL_IOCTL_MUTE_WRITE_CAPTURE:
681 case AUDIODRV_CTL_IOCTL_MUTE_READ_CAPTURE:
682 case AUDIODRV_CTL_IOCTL_GAIN_WRITE_CAPTURE:
683 case AUDIODRV_CTL_IOCTL_GAIN_READ_CAPTURE:
684 case AUDIODRV_CTL_IOCTL_SCENESELECT_CAPTURE:
685 case AUDIODRV_CTL_IOCTL_GAINTHRESHOLD_CAPTURE:
686 case AUDIODRV_CTL_IOCTL_VOL_THRESHOLD_CAPTURE:
687 return HandleCtlCaptureCmd(handle, cmdId, handleData);
688 default:
689 HDF_LOGE("Error: Mode Error!");
690 break;
691 }
692
693 return HDF_ERR_NOT_SUPPORT;
694 }
695