18d6344f9Sopenharmony_ci/*
28d6344f9Sopenharmony_ci * Copyright (c) 2022 Huawei Device Co., Ltd.
38d6344f9Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
48d6344f9Sopenharmony_ci * you may not use this file except in compliance with the License.
58d6344f9Sopenharmony_ci * You may obtain a copy of the License at
68d6344f9Sopenharmony_ci *
78d6344f9Sopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
88d6344f9Sopenharmony_ci *
98d6344f9Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software
108d6344f9Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
118d6344f9Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
128d6344f9Sopenharmony_ci * See the License for the specific language governing permissions and
138d6344f9Sopenharmony_ci * limitations under the License.
148d6344f9Sopenharmony_ci */
158d6344f9Sopenharmony_ci
168d6344f9Sopenharmony_ci#include "alsa_snd_render.h"
178d6344f9Sopenharmony_ci#include "common.h"
188d6344f9Sopenharmony_ci
198d6344f9Sopenharmony_ci#define HDF_LOG_TAG HDF_AUDIO_HAL_RENDER
208d6344f9Sopenharmony_ci
218d6344f9Sopenharmony_citypedef struct _RENDER_DATA_ {
228d6344f9Sopenharmony_ci    struct AlsaMixerCtlElement ctrlLeftVolume;
238d6344f9Sopenharmony_ci    struct AlsaMixerCtlElement ctrlRightVolume;
248d6344f9Sopenharmony_ci    long tempVolume;
258d6344f9Sopenharmony_ci}RenderData;
268d6344f9Sopenharmony_ci
278d6344f9Sopenharmony_cistatic int32_t RenderInitImpl(struct AlsaRender *renderIns)
288d6344f9Sopenharmony_ci{
298d6344f9Sopenharmony_ci    if (renderIns->priData != NULL) {
308d6344f9Sopenharmony_ci        return HDF_SUCCESS;
318d6344f9Sopenharmony_ci    }
328d6344f9Sopenharmony_ci    CHECK_NULL_PTR_RETURN_DEFAULT(renderIns);
338d6344f9Sopenharmony_ci
348d6344f9Sopenharmony_ci    RenderData *priData = (RenderData *)OsalMemCalloc(sizeof(RenderData));
358d6344f9Sopenharmony_ci    if (priData == NULL) {
368d6344f9Sopenharmony_ci        AUDIO_FUNC_LOGE("Failed to allocate memory!");
378d6344f9Sopenharmony_ci        return HDF_FAILURE;
388d6344f9Sopenharmony_ci    }
398d6344f9Sopenharmony_ci
408d6344f9Sopenharmony_ci    SndElementItemInit(&priData->ctrlLeftVolume);
418d6344f9Sopenharmony_ci    SndElementItemInit(&priData->ctrlRightVolume);
428d6344f9Sopenharmony_ci    priData->ctrlLeftVolume.numid = SND_NUMID_DACL_PLAYBACK_VOL;
438d6344f9Sopenharmony_ci    priData->ctrlLeftVolume.name = SND_ELEM_DACL_PLAYBACK_VOL;
448d6344f9Sopenharmony_ci    priData->ctrlRightVolume.numid = SND_NUMID_DACR_PLAYBACK_VOL;
458d6344f9Sopenharmony_ci    priData->ctrlRightVolume.name = SND_ELEM_DACR_PLAYBACK_VOL;
468d6344f9Sopenharmony_ci    RenderSetPriData(renderIns, (RenderPriData)priData);
478d6344f9Sopenharmony_ci
488d6344f9Sopenharmony_ci    return HDF_SUCCESS;
498d6344f9Sopenharmony_ci}
508d6344f9Sopenharmony_ci
518d6344f9Sopenharmony_cistatic int32_t RenderSelectSceneImpl(struct AlsaRender *renderIns, enum AudioPortPin descPins,
528d6344f9Sopenharmony_ci    const struct PathDeviceInfo *deviceInfo)
538d6344f9Sopenharmony_ci{
548d6344f9Sopenharmony_ci    renderIns->descPins = descPins;
558d6344f9Sopenharmony_ci    return HDF_SUCCESS;
568d6344f9Sopenharmony_ci}
578d6344f9Sopenharmony_ci
588d6344f9Sopenharmony_cistatic int32_t RenderGetVolThresholdImpl(struct AlsaRender *renderIns, long *volMin, long *volMax)
598d6344f9Sopenharmony_ci{
608d6344f9Sopenharmony_ci    int32_t ret;
618d6344f9Sopenharmony_ci    long _volMin = 0;
628d6344f9Sopenharmony_ci    long _volMax = 0;
638d6344f9Sopenharmony_ci    struct AlsaSoundCard *cardIns = (struct AlsaSoundCard *)renderIns;
648d6344f9Sopenharmony_ci    RenderData *priData = RenderGetPriData(renderIns);
658d6344f9Sopenharmony_ci    CHECK_NULL_PTR_RETURN_DEFAULT(cardIns);
668d6344f9Sopenharmony_ci    CHECK_NULL_PTR_RETURN_DEFAULT(priData);
678d6344f9Sopenharmony_ci
688d6344f9Sopenharmony_ci    ret = SndElementReadRange(cardIns, &priData->ctrlLeftVolume, &_volMin, &_volMax);
698d6344f9Sopenharmony_ci    if (ret != HDF_SUCCESS) {
708d6344f9Sopenharmony_ci        AUDIO_FUNC_LOGE("SndElementReadRange fail!");
718d6344f9Sopenharmony_ci        return HDF_FAILURE;
728d6344f9Sopenharmony_ci    }
738d6344f9Sopenharmony_ci    *volMin = _volMin;
748d6344f9Sopenharmony_ci    *volMax = _volMax;
758d6344f9Sopenharmony_ci
768d6344f9Sopenharmony_ci    return HDF_SUCCESS;
778d6344f9Sopenharmony_ci}
788d6344f9Sopenharmony_ci
798d6344f9Sopenharmony_cistatic int32_t RenderGetVolumeImpl(struct AlsaRender *renderIns, long *volume)
808d6344f9Sopenharmony_ci{
818d6344f9Sopenharmony_ci    int32_t ret;
828d6344f9Sopenharmony_ci    long volLeft = 0;
838d6344f9Sopenharmony_ci    long volRight = 0;
848d6344f9Sopenharmony_ci    struct AlsaSoundCard *cardIns = (struct AlsaSoundCard *)renderIns;
858d6344f9Sopenharmony_ci    RenderData *priData = RenderGetPriData(renderIns);
868d6344f9Sopenharmony_ci    CHECK_NULL_PTR_RETURN_DEFAULT(cardIns);
878d6344f9Sopenharmony_ci    CHECK_NULL_PTR_RETURN_DEFAULT(priData);
888d6344f9Sopenharmony_ci
898d6344f9Sopenharmony_ci    ret = SndElementReadInt(cardIns, &priData->ctrlLeftVolume, &volLeft);
908d6344f9Sopenharmony_ci    if (ret != HDF_SUCCESS) {
918d6344f9Sopenharmony_ci        AUDIO_FUNC_LOGE("Read left volume fail!");
928d6344f9Sopenharmony_ci        return HDF_FAILURE;
938d6344f9Sopenharmony_ci    }
948d6344f9Sopenharmony_ci    ret = SndElementReadInt(cardIns, &priData->ctrlRightVolume, &volRight);
958d6344f9Sopenharmony_ci    if (ret != HDF_SUCCESS) {
968d6344f9Sopenharmony_ci        AUDIO_FUNC_LOGE("Read right volume fail!");
978d6344f9Sopenharmony_ci        return HDF_FAILURE;
988d6344f9Sopenharmony_ci    }
998d6344f9Sopenharmony_ci    *volume = (volLeft + volRight) >> 1;
1008d6344f9Sopenharmony_ci
1018d6344f9Sopenharmony_ci    return HDF_SUCCESS;
1028d6344f9Sopenharmony_ci}
1038d6344f9Sopenharmony_ci
1048d6344f9Sopenharmony_cistatic int32_t RenderSetVolumeImpl(struct AlsaRender *renderIns, long volume)
1058d6344f9Sopenharmony_ci{
1068d6344f9Sopenharmony_ci    int32_t ret;
1078d6344f9Sopenharmony_ci    struct AlsaSoundCard *cardIns = (struct AlsaSoundCard *)renderIns;
1088d6344f9Sopenharmony_ci    RenderData *priData = RenderGetPriData(renderIns);
1098d6344f9Sopenharmony_ci    CHECK_NULL_PTR_RETURN_DEFAULT(cardIns);
1108d6344f9Sopenharmony_ci    CHECK_NULL_PTR_RETURN_DEFAULT(priData);
1118d6344f9Sopenharmony_ci
1128d6344f9Sopenharmony_ci    ret = SndElementWriteInt(cardIns, &priData->ctrlLeftVolume, volume);
1138d6344f9Sopenharmony_ci    if (ret != HDF_SUCCESS) {
1148d6344f9Sopenharmony_ci        AUDIO_FUNC_LOGE("Write left volume fail!");
1158d6344f9Sopenharmony_ci        return HDF_FAILURE;
1168d6344f9Sopenharmony_ci    }
1178d6344f9Sopenharmony_ci    ret = SndElementWriteInt(cardIns, &priData->ctrlRightVolume, volume);
1188d6344f9Sopenharmony_ci    if (ret != HDF_SUCCESS) {
1198d6344f9Sopenharmony_ci        AUDIO_FUNC_LOGE("Write right volume fail!");
1208d6344f9Sopenharmony_ci        return HDF_FAILURE;
1218d6344f9Sopenharmony_ci    }
1228d6344f9Sopenharmony_ci
1238d6344f9Sopenharmony_ci    return HDF_SUCCESS;
1248d6344f9Sopenharmony_ci}
1258d6344f9Sopenharmony_ci
1268d6344f9Sopenharmony_cistatic bool RenderGetMuteImpl(struct AlsaRender *renderIns)
1278d6344f9Sopenharmony_ci{
1288d6344f9Sopenharmony_ci    return renderIns->muteState;
1298d6344f9Sopenharmony_ci}
1308d6344f9Sopenharmony_ci
1318d6344f9Sopenharmony_cistatic int32_t RenderSetMuteImpl(struct AlsaRender *renderIns, bool muteFlag)
1328d6344f9Sopenharmony_ci{
1338d6344f9Sopenharmony_ci    int32_t ret;
1348d6344f9Sopenharmony_ci    long vol, setVol;
1358d6344f9Sopenharmony_ci    RenderData *priData = RenderGetPriData(renderIns);
1368d6344f9Sopenharmony_ci    CHECK_NULL_PTR_RETURN_DEFAULT(renderIns);
1378d6344f9Sopenharmony_ci    CHECK_NULL_PTR_RETURN_DEFAULT(priData);
1388d6344f9Sopenharmony_ci
1398d6344f9Sopenharmony_ci    ret = renderIns->GetVolume(renderIns, &vol);
1408d6344f9Sopenharmony_ci    if (ret != HDF_SUCCESS) {
1418d6344f9Sopenharmony_ci        AUDIO_FUNC_LOGE("GetVolume failed!");
1428d6344f9Sopenharmony_ci        return HDF_FAILURE;
1438d6344f9Sopenharmony_ci    }
1448d6344f9Sopenharmony_ci
1458d6344f9Sopenharmony_ci    if (muteFlag) {
1468d6344f9Sopenharmony_ci        priData->tempVolume = vol;
1478d6344f9Sopenharmony_ci        setVol = 0;
1488d6344f9Sopenharmony_ci    } else {
1498d6344f9Sopenharmony_ci        setVol = priData->tempVolume;
1508d6344f9Sopenharmony_ci    }
1518d6344f9Sopenharmony_ci
1528d6344f9Sopenharmony_ci    renderIns->SetVolume(renderIns, setVol);
1538d6344f9Sopenharmony_ci    if (ret != HDF_SUCCESS) {
1548d6344f9Sopenharmony_ci        AUDIO_FUNC_LOGE("SetVolume failed!");
1558d6344f9Sopenharmony_ci        return HDF_FAILURE;
1568d6344f9Sopenharmony_ci    }
1578d6344f9Sopenharmony_ci    renderIns->muteState = muteFlag;
1588d6344f9Sopenharmony_ci
1598d6344f9Sopenharmony_ci    return HDF_SUCCESS;
1608d6344f9Sopenharmony_ci}
1618d6344f9Sopenharmony_ci
1628d6344f9Sopenharmony_cistatic int32_t RenderStartImpl(struct AlsaRender *renderIns)
1638d6344f9Sopenharmony_ci{
1648d6344f9Sopenharmony_ci    int32_t ret;
1658d6344f9Sopenharmony_ci    struct AlsaMixerCtlElement elem;
1668d6344f9Sopenharmony_ci    struct AlsaSoundCard *cardIns = (struct AlsaSoundCard *)renderIns;
1678d6344f9Sopenharmony_ci
1688d6344f9Sopenharmony_ci    SndElementItemInit(&elem);
1698d6344f9Sopenharmony_ci    elem.numid = SND_NUMID_PLAYBACK_PATH;
1708d6344f9Sopenharmony_ci    elem.name = SND_ELEM_PLAYBACK_PATH;
1718d6344f9Sopenharmony_ci    switch (renderIns->descPins) {
1728d6344f9Sopenharmony_ci        case PIN_OUT_SPEAKER:
1738d6344f9Sopenharmony_ci            elem.value = SND_OUT_CARD_SPK_HP;
1748d6344f9Sopenharmony_ci            break;
1758d6344f9Sopenharmony_ci        case PIN_OUT_HEADSET:
1768d6344f9Sopenharmony_ci            elem.value = SND_OUT_CARD_HP;
1778d6344f9Sopenharmony_ci            break;
1788d6344f9Sopenharmony_ci        default:
1798d6344f9Sopenharmony_ci            elem.value = SND_OUT_CARD_SPK_HP;
1808d6344f9Sopenharmony_ci    }
1818d6344f9Sopenharmony_ci
1828d6344f9Sopenharmony_ci    ret = SndElementWrite(cardIns, &elem);
1838d6344f9Sopenharmony_ci    if (ret != HDF_SUCCESS) {
1848d6344f9Sopenharmony_ci        AUDIO_FUNC_LOGE("write render fail!");
1858d6344f9Sopenharmony_ci        return HDF_FAILURE;
1868d6344f9Sopenharmony_ci    }
1878d6344f9Sopenharmony_ci
1888d6344f9Sopenharmony_ci    return HDF_SUCCESS;
1898d6344f9Sopenharmony_ci}
1908d6344f9Sopenharmony_ci
1918d6344f9Sopenharmony_cistatic int32_t RenderStopImpl(struct AlsaRender *renderIns)
1928d6344f9Sopenharmony_ci{
1938d6344f9Sopenharmony_ci    CHECK_NULL_PTR_RETURN_DEFAULT(renderIns);
1948d6344f9Sopenharmony_ci    int32_t ret;
1958d6344f9Sopenharmony_ci    struct AlsaMixerCtlElement elem;
1968d6344f9Sopenharmony_ci    struct AlsaSoundCard *cardIns = (struct AlsaSoundCard *)renderIns;
1978d6344f9Sopenharmony_ci    CHECK_NULL_PTR_RETURN_DEFAULT(cardIns);
1988d6344f9Sopenharmony_ci    CHECK_NULL_PTR_RETURN_DEFAULT(&renderIns->soundCard);
1998d6344f9Sopenharmony_ci
2008d6344f9Sopenharmony_ci    SndElementItemInit(&elem);
2018d6344f9Sopenharmony_ci    elem.numid = SND_NUMID_PLAYBACK_PATH;
2028d6344f9Sopenharmony_ci    elem.name = SND_ELEM_PLAYBACK_PATH;
2038d6344f9Sopenharmony_ci    elem.value = SND_OUT_CARD_OFF;
2048d6344f9Sopenharmony_ci    ret = SndElementWrite(cardIns, &elem);
2058d6344f9Sopenharmony_ci    if (ret != HDF_SUCCESS) {
2068d6344f9Sopenharmony_ci        AUDIO_FUNC_LOGE("write render fail!");
2078d6344f9Sopenharmony_ci        return HDF_FAILURE;
2088d6344f9Sopenharmony_ci    }
2098d6344f9Sopenharmony_ci
2108d6344f9Sopenharmony_ci    CHECK_NULL_PTR_RETURN_DEFAULT(renderIns->soundCard.pcmHandle);
2118d6344f9Sopenharmony_ci
2128d6344f9Sopenharmony_ci    snd_pcm_drain(renderIns->soundCard.pcmHandle);
2138d6344f9Sopenharmony_ci    return HDF_SUCCESS;
2148d6344f9Sopenharmony_ci}
2158d6344f9Sopenharmony_ci
2168d6344f9Sopenharmony_cistatic int32_t RenderGetGainThresholdImpl(struct AlsaRender *renderIns, float *gainMin, float *gainMax)
2178d6344f9Sopenharmony_ci{
2188d6344f9Sopenharmony_ci    AUDIO_FUNC_LOGI("Not support gain operation");
2198d6344f9Sopenharmony_ci    return HDF_SUCCESS;
2208d6344f9Sopenharmony_ci}
2218d6344f9Sopenharmony_ci
2228d6344f9Sopenharmony_cistatic int32_t RenderGetGainImpl(struct AlsaRender *renderIns, float *volume)
2238d6344f9Sopenharmony_ci{
2248d6344f9Sopenharmony_ci    AUDIO_FUNC_LOGI("Not support gain operation");
2258d6344f9Sopenharmony_ci    return HDF_SUCCESS;
2268d6344f9Sopenharmony_ci}
2278d6344f9Sopenharmony_ci
2288d6344f9Sopenharmony_cistatic int32_t RenderSetGainImpl(struct AlsaRender *renderIns, float volume)
2298d6344f9Sopenharmony_ci{
2308d6344f9Sopenharmony_ci    AUDIO_FUNC_LOGI("Not support gain operation");
2318d6344f9Sopenharmony_ci    return HDF_SUCCESS;
2328d6344f9Sopenharmony_ci}
2338d6344f9Sopenharmony_ci
2348d6344f9Sopenharmony_cistatic int32_t RenderGetChannelModeImpl(struct AlsaRender *renderIns, enum AudioChannelMode *mode)
2358d6344f9Sopenharmony_ci{
2368d6344f9Sopenharmony_ci    return HDF_SUCCESS;
2378d6344f9Sopenharmony_ci}
2388d6344f9Sopenharmony_ci
2398d6344f9Sopenharmony_cistatic int32_t RenderSetChannelModeImpl(struct AlsaRender *renderIns, enum AudioChannelMode mode)
2408d6344f9Sopenharmony_ci{
2418d6344f9Sopenharmony_ci    return HDF_SUCCESS;
2428d6344f9Sopenharmony_ci}
2438d6344f9Sopenharmony_ci
2448d6344f9Sopenharmony_ciint32_t RenderOverrideFunc(struct AlsaRender *renderIns)
2458d6344f9Sopenharmony_ci{
2468d6344f9Sopenharmony_ci    struct AlsaSoundCard *cardIns = (struct AlsaSoundCard *)renderIns;
2478d6344f9Sopenharmony_ci
2488d6344f9Sopenharmony_ci    if (cardIns->cardType == SND_CARD_PRIMARY) {
2498d6344f9Sopenharmony_ci        renderIns->Init = RenderInitImpl;
2508d6344f9Sopenharmony_ci        renderIns->SelectScene = RenderSelectSceneImpl;
2518d6344f9Sopenharmony_ci        renderIns->Start = RenderStartImpl;
2528d6344f9Sopenharmony_ci        renderIns->Stop = RenderStopImpl;
2538d6344f9Sopenharmony_ci        renderIns->GetVolThreshold = RenderGetVolThresholdImpl;
2548d6344f9Sopenharmony_ci        renderIns->GetVolume = RenderGetVolumeImpl;
2558d6344f9Sopenharmony_ci        renderIns->SetVolume = RenderSetVolumeImpl;
2568d6344f9Sopenharmony_ci        renderIns->GetGainThreshold = RenderGetGainThresholdImpl;
2578d6344f9Sopenharmony_ci        renderIns->GetGain = RenderGetGainImpl;
2588d6344f9Sopenharmony_ci        renderIns->SetGain = RenderSetGainImpl;
2598d6344f9Sopenharmony_ci        renderIns->GetMute = RenderGetMuteImpl;
2608d6344f9Sopenharmony_ci        renderIns->SetMute = RenderSetMuteImpl;
2618d6344f9Sopenharmony_ci        renderIns->GetChannelMode = RenderGetChannelModeImpl;
2628d6344f9Sopenharmony_ci        renderIns->SetChannelMode = RenderSetChannelModeImpl;
2638d6344f9Sopenharmony_ci    }
2648d6344f9Sopenharmony_ci
2658d6344f9Sopenharmony_ci    return HDF_SUCCESS;
2668d6344f9Sopenharmony_ci}
267