* Copyright (c) 2021 Huawei Device Co., Ltd.
*
* HDF is dual licensed: you can use it either under the terms of
* the GPL, or the BSD license, at your option.
* See the LICENSE file in the root of this repository for complete details.
*/
#include "audio_sapm.h"
#include "audio_driver_log.h"
#include "osal_io.h"
#include "osal_time.h"
#include "osal_timer.h"
#define HDF_LOG_TAG HDF_AUDIO_SAPM
#define SAPM_POLL_TIME 10000
#define SAPM_SLEEP_TIME (3 * 60000)
#define SAPM_POWER_DOWN 0
#define SAPM_POWER_UP 1
#define CONNECT_CODEC_PIN 1
#define UNCONNECT_CODEC_PIN 0
#define EXIST_EXTERNAL_WIDGET 1
#define UNEXIST_EXTERNAL_WIDGET 1
#define CONNECT_SINK_AND_SOURCE 1
#define UNCONNECT_SINK_AND_SOURCE 0
static void AudioSapmTimerCallback(uintptr_t para);
static int32_t AudioSapmRefreshTime(struct AudioCard *audioCard, bool bRefresh);
static int32_t g_audioSapmPowerUpSeq[] = {
[AUDIO_SAPM_PRE] = 0,
[AUDIO_SAPM_SUPPLY] = 1,
[AUDIO_SAPM_MICBIAS] = 2,
[AUDIO_SAPM_AIF_IN] = 3,
[AUDIO_SAPM_AIF_OUT] = 3,
[AUDIO_SAPM_MIC] = 4,
[AUDIO_SAPM_MUX] = 5,
[AUDIO_SAPM_VIRT_MUX] = 5,
[AUDIO_SAPM_VALUE_MUX] = 5,
[AUDIO_SAPM_DAC] = 6,
[AUDIO_SAPM_MIXER] = 7,
[AUDIO_SAPM_MIXER_NAMED_CTRL] = 7,
[AUDIO_SAPM_PGA] = 8,
[AUDIO_SAPM_ADC] = 9,
[AUDIO_SAPM_OUT_DRV] = 10,
[AUDIO_SAPM_HP] = 10,
[AUDIO_SAPM_SPK] = 10,
[AUDIO_SAPM_POST] = 11,
};
static int32_t g_audioSapmPowerDownSeq[] = {
[AUDIO_SAPM_PRE] = 0,
[AUDIO_SAPM_ADC] = 1,
[AUDIO_SAPM_HP] = 2,
[AUDIO_SAPM_SPK] = 2,
[AUDIO_SAPM_OUT_DRV] = 2,
[AUDIO_SAPM_PGA] = 4,
[AUDIO_SAPM_MIXER_NAMED_CTRL] = 5,
[AUDIO_SAPM_MIXER] = 5,
[AUDIO_SAPM_DAC] = 6,
[AUDIO_SAPM_MIC] = 7,
[AUDIO_SAPM_MICBIAS] = 8,
[AUDIO_SAPM_MUX] = 9,
[AUDIO_SAPM_VIRT_MUX] = 9,
[AUDIO_SAPM_VALUE_MUX] = 9,
[AUDIO_SAPM_AIF_IN] = 10,
[AUDIO_SAPM_AIF_OUT] = 10,
[AUDIO_SAPM_SUPPLY] = 11,
[AUDIO_SAPM_POST] = 12,
};
OSAL_DECLARE_TIMER(g_sleepTimer);
static int32_t ConnectedInputEndPoint(const struct AudioSapmComponent *sapmComponent)
{
struct AudioSapmpath *path = NULL;
int32_t count = 0;
const int32_t endPointVal = 1;
if (sapmComponent == NULL) {
ADM_LOG_ERR("input param sapmComponent is NULL.");
return HDF_FAILURE;
}
switch (sapmComponent->sapmType) {
case AUDIO_SAPM_DAC:
case AUDIO_SAPM_AIF_IN:
case AUDIO_SAPM_INPUT:
case AUDIO_SAPM_MIC:
case AUDIO_SAPM_LINE:
return endPointVal;
default:
break;
}
DLIST_FOR_EACH_ENTRY(path, &sapmComponent->sources, struct AudioSapmpath, listSink) {
if ((path->source != NULL) && (path->connect == CONNECT_SINK_AND_SOURCE)) {
count += ConnectedInputEndPoint(path->source);
}
}
return count;
}
static int32_t ConnectedOutputEndPoint(const struct AudioSapmComponent *sapmComponent)
{
struct AudioSapmpath *path = NULL;
int32_t count = 0;
const int32_t endPointVal = 1;
if (sapmComponent == NULL) {
ADM_LOG_ERR("input param sapmComponent is NULL.");
return HDF_FAILURE;
}
switch (sapmComponent->sapmType) {
case AUDIO_SAPM_ADC:
case AUDIO_SAPM_AIF_OUT:
case AUDIO_SAPM_OUTPUT:
case AUDIO_SAPM_HP:
case AUDIO_SAPM_SPK:
case AUDIO_SAPM_LINE:
return endPointVal;
default:
break;
}
DLIST_FOR_EACH_ENTRY(path, &sapmComponent->sinks, struct AudioSapmpath, listSource) {
if ((path->sink != NULL) && (path->connect == CONNECT_SINK_AND_SOURCE)) {
count += ConnectedOutputEndPoint(path->sink);
}
}
return count;
}
static int32_t AudioSapmGenericCheckPower(const struct AudioSapmComponent *sapmComponent)
{
int32_t input;
int32_t output;
if (sapmComponent == NULL) {
ADM_LOG_ERR("input param cpt is NULL.");
return HDF_FAILURE;
}
input = ConnectedInputEndPoint(sapmComponent);
if (input == HDF_FAILURE) {
ADM_LOG_ERR("input endpoint fail!");
return HDF_FAILURE;
}
output = ConnectedOutputEndPoint(sapmComponent);
if (output == HDF_FAILURE) {
ADM_LOG_ERR("output endpoint fail!");
return HDF_FAILURE;
}
if ((input == 0) || (output == 0)) {
ADM_LOG_DEBUG("component is not in a complete path.");
return SAPM_POWER_DOWN;
}
return SAPM_POWER_UP;
}
static int32_t AudioSapmAdcPowerClock(struct AudioSapmComponent *sapmComponent)
{
(void)sapmComponent;
ADM_LOG_INFO("Adc standby mode entry!");
return HDF_SUCCESS;
}
static int32_t AudioSapmDacPowerClock(struct AudioSapmComponent *sapmComponent)
{
(void)sapmComponent;
ADM_LOG_INFO("Dac standby mode entry!");
return HDF_SUCCESS;
}
static int32_t AudioSapmAdcCheckPower(const struct AudioSapmComponent *sapmComponent)
{
int32_t input;
if (sapmComponent == NULL) {
ADM_LOG_ERR("input param sapmComponent is NULL.");
return HDF_FAILURE;
}
if (sapmComponent->active == 0) {
input = AudioSapmGenericCheckPower(sapmComponent);
} else {
input = ConnectedInputEndPoint(sapmComponent);
}
if (input == HDF_FAILURE) {
ADM_LOG_ERR("input endpoint fail!");
return HDF_FAILURE;
}
return input;
}
static int AudioSapmDacCheckPower(const struct AudioSapmComponent *sapmComponent)
{
int32_t output;
if (sapmComponent == NULL) {
ADM_LOG_ERR("input sapmComponent cpt is NULL.");
return HDF_FAILURE;
}
if (sapmComponent->active == 0) {
output = AudioSapmGenericCheckPower(sapmComponent);
} else {
output = ConnectedOutputEndPoint(sapmComponent);
}
if (output == HDF_FAILURE) {
ADM_LOG_ERR("output endpoint fail!");
return HDF_FAILURE;
}
return output;
}
static void AudioSampCheckPowerCallback(struct AudioSapmComponent *sapmComponent)
{
if (sapmComponent == NULL) {
ADM_LOG_ERR("input param cpt is NULL.");
return;
}
switch (sapmComponent->sapmType) {
case AUDIO_SAPM_ANALOG_SWITCH:
case AUDIO_SAPM_MIXER:
case AUDIO_SAPM_MIXER_NAMED_CTRL:
sapmComponent->PowerCheck = AudioSapmGenericCheckPower;
break;
case AUDIO_SAPM_MUX:
case AUDIO_SAPM_VIRT_MUX:
case AUDIO_SAPM_VALUE_MUX:
sapmComponent->PowerCheck = AudioSapmGenericCheckPower;
break;
case AUDIO_SAPM_ADC:
case AUDIO_SAPM_AIF_OUT:
sapmComponent->PowerCheck = AudioSapmAdcCheckPower;
break;
case AUDIO_SAPM_DAC:
case AUDIO_SAPM_AIF_IN:
sapmComponent->PowerCheck = AudioSapmDacCheckPower;
break;
case AUDIO_SAPM_PGA:
case AUDIO_SAPM_OUT_DRV:
case AUDIO_SAPM_INPUT:
case AUDIO_SAPM_OUTPUT:
case AUDIO_SAPM_MICBIAS:
case AUDIO_SAPM_SPK:
case AUDIO_SAPM_HP:
case AUDIO_SAPM_MIC:
case AUDIO_SAPM_LINE:
sapmComponent->PowerCheck = AudioSapmGenericCheckPower;
break;
default:
sapmComponent->PowerCheck = AudioSapmGenericCheckPower;
break;
}
return;
}
static void AudioSampPowerClockCallback(struct AudioSapmComponent *sapmComponent)
{
if (sapmComponent == NULL) {
ADM_LOG_ERR("input param cpt is NULL.");
return;
}
switch (sapmComponent->sapmType) {
case AUDIO_SAPM_ANALOG_SWITCH:
case AUDIO_SAPM_MIXER:
case AUDIO_SAPM_MIXER_NAMED_CTRL:
sapmComponent->PowerClockOp = NULL;
break;
case AUDIO_SAPM_MUX:
case AUDIO_SAPM_VIRT_MUX:
case AUDIO_SAPM_VALUE_MUX:
sapmComponent->PowerClockOp = NULL;
break;
case AUDIO_SAPM_ADC:
case AUDIO_SAPM_AIF_OUT:
sapmComponent->PowerClockOp = AudioSapmAdcPowerClock;
break;
case AUDIO_SAPM_DAC:
case AUDIO_SAPM_AIF_IN:
sapmComponent->PowerClockOp = AudioSapmDacPowerClock;
break;
case AUDIO_SAPM_PGA:
case AUDIO_SAPM_OUT_DRV:
case AUDIO_SAPM_INPUT:
case AUDIO_SAPM_OUTPUT:
case AUDIO_SAPM_MICBIAS:
case AUDIO_SAPM_SPK:
case AUDIO_SAPM_HP:
case AUDIO_SAPM_MIC:
case AUDIO_SAPM_LINE:
sapmComponent->PowerClockOp = NULL;
break;
default:
sapmComponent->PowerClockOp = NULL;
break;
}
return;
}
int32_t AudioSapmNewComponent(struct AudioCard *audioCard, const struct AudioSapmComponent *component)
{
struct AudioSapmComponent *sapmComponent = NULL;
if ((audioCard == NULL || audioCard->rtd == NULL)) {
ADM_LOG_ERR("input params check error: audioCard is NULL.");
return HDF_FAILURE;
}
if (component == NULL) {
ADM_LOG_ERR("input params check error: component is NULL.");
return HDF_FAILURE;
}
if (component->componentName == NULL) {
ADM_LOG_ERR("component->componentName is NULL");
return HDF_FAILURE;
}
sapmComponent = (struct AudioSapmComponent *)OsalMemCalloc(sizeof(struct AudioSapmComponent));
if (sapmComponent == NULL) {
ADM_LOG_ERR("malloc cpt fail!");
return HDF_FAILURE;
}
if (memcpy_s(sapmComponent, sizeof(struct AudioSapmComponent),
component, sizeof(struct AudioSapmComponent)) != EOK) {
ADM_LOG_ERR("memcpy cpt fail!");
OsalMemFree(sapmComponent);
return HDF_FAILURE;
}
sapmComponent->componentName = (char *)OsalMemCalloc(strlen(component->componentName) + 1);
if (sapmComponent->componentName == NULL) {
ADM_LOG_ERR("malloc cpt->componentName fail!");
OsalMemFree(sapmComponent);
return HDF_FAILURE;
}
if (memcpy_s(sapmComponent->componentName, strlen(component->componentName) + 1,
component->componentName, strlen(component->componentName) + 1) != EOK) {
ADM_LOG_ERR("memcpy cpt->componentName fail!");
OsalMemFree(sapmComponent->componentName);
OsalMemFree(sapmComponent);
return HDF_FAILURE;
}
sapmComponent->codec = audioCard->rtd->codec;
sapmComponent->kcontrolsNum = component->kcontrolsNum;
sapmComponent->active = 0;
AudioSampCheckPowerCallback(sapmComponent);
AudioSampPowerClockCallback(sapmComponent);
DListHeadInit(&sapmComponent->sources);
DListHeadInit(&sapmComponent->sinks);
DListHeadInit(&sapmComponent->list);
DListHeadInit(&sapmComponent->dirty);
DListInsertHead(&sapmComponent->list, &audioCard->components);
sapmComponent->connected = CONNECT_CODEC_PIN;
return HDF_SUCCESS;
}
int32_t AudioSapmNewComponents(struct AudioCard *audioCard,
const struct AudioSapmComponent *component, int32_t cptMaxNum)
{
int32_t i;
int32_t ret;
if (audioCard == NULL) {
ADM_LOG_ERR("input params check error: audioCard is NULL.");
return HDF_FAILURE;
}
if (component == NULL) {
ADM_LOG_ERR("input params check error: component is NULL.");
return HDF_FAILURE;
}
for (i = 0; i < cptMaxNum; i++) {
ret = AudioSapmNewComponent(audioCard, component);
if (ret != HDF_SUCCESS) {
ADM_LOG_ERR("AudioSapmNewComponent fail!");
return HDF_FAILURE;
}
component++;
}
return HDF_SUCCESS;
}
static void MuxSetPathStatus(const struct AudioSapmComponent *sapmComponent, struct AudioSapmpath *path,
const struct AudioEnumKcontrol *enumKtl, int32_t i)
{
int32_t ret;
uint32_t val = 0;
int32_t item;
const uint32_t reg = 0;
uint32_t shift;
if ((sapmComponent == NULL || sapmComponent->codec == NULL)) {
ADM_LOG_ERR("input MuxSet params check error: sapmComponent is NULL.");
return;
}
if ((path == NULL || path->name == NULL)) {
ADM_LOG_ERR("input MuxSet params check error: path is NULL.");
return;
}
if ((enumKtl == NULL || enumKtl->texts == NULL)) {
ADM_LOG_ERR("input MuxSet params check error: enumKtl is NULL.");
return;
}
shift = enumKtl->shiftLeft;
ret = AudioCodecReadReg(sapmComponent->codec, reg, &val);
if (ret != HDF_SUCCESS) {
ADM_LOG_ERR("MuxSet read reg fail!");
return;
}
item = val >> shift;
path->connect = UNCONNECT_SINK_AND_SOURCE;
for (i = 0; i < enumKtl->max; i++) {
if (enumKtl->texts[i] == NULL) {
ADM_LOG_ERR("enumKtl->texts[%d] is NULL", i);
continue;
}
if ((strcmp(path->name, enumKtl->texts[i]) == 0) && item == i) {
path->connect = CONNECT_SINK_AND_SOURCE;
}
}
return;
}
static void MuxValueSetPathStatus(const struct AudioSapmComponent *sapmComponent, struct AudioSapmpath *path,
const struct AudioEnumKcontrol *enumKtl, int32_t i)
{
int32_t ret;
uint32_t val = 0;
uint32_t item;
const uint32_t reg = 0;
uint32_t shift;
if ((sapmComponent == NULL || sapmComponent->codec == NULL)) {
ADM_LOG_ERR("input muxValueSet params check error: cpt is NULL.");
return;
}
if ((path == NULL || path->name == NULL)) {
ADM_LOG_ERR("input muxValueSet params check error: path is NULL.");
return;
}
if ((enumKtl == NULL || enumKtl->texts == NULL)) {
ADM_LOG_ERR("input muxValueSet params check error: enumKtl is NULL.");
return;
}
shift = enumKtl->shiftLeft;
ret = AudioCodecReadReg(sapmComponent->codec, reg, &val);
if (ret != HDF_SUCCESS) {
ADM_LOG_ERR("muxValueSet read reg fail!");
return;
}
val = val >> shift;
for (item = 0; item < enumKtl->max; item++) {
if (val == enumKtl->values[item]) {
break;
}
}
path->connect = UNCONNECT_SINK_AND_SOURCE;
for (i = 0; i < enumKtl->max; i++) {
if (enumKtl->texts[i] == NULL) {
continue;
}
if ((strcmp(path->name, enumKtl->texts[i]) == 0) && item == i) {
path->connect = CONNECT_SINK_AND_SOURCE;
}
}
return;
}
static void MixerSetPathStatus(const struct AudioSapmComponent *sapmComponent, struct AudioSapmpath *path,
const struct AudioMixerControl *mixerCtrl)
{
int32_t ret;
uint32_t reg;
uint32_t mask;
uint32_t shift;
uint32_t invert;
uint32_t curValue = 0;
if (sapmComponent == NULL) {
ADM_LOG_ERR("input params check error: sapmComponent is NULL.");
return;
}
if (path == NULL) {
ADM_LOG_ERR("input params check error: path is NULL.");
return;
}
if (mixerCtrl == NULL) {
ADM_LOG_ERR("input params check error: mixerCtrl is NULL.");
return;
}
reg = mixerCtrl->reg;
shift = mixerCtrl->shift;
mask = mixerCtrl->mask;
invert = mixerCtrl->invert;
if (sapmComponent->codec != NULL) {
ret = AudioCodecReadReg(sapmComponent->codec, reg, &curValue);
if (ret != HDF_SUCCESS) {
ADM_LOG_ERR("read reg fail!");
return;
}
} else {
ADM_LOG_ERR("codec is null!");
return;
}
curValue = (curValue >> shift) & mask;
if ((invert && !curValue) || (!invert && curValue)) {
path->connect = CONNECT_SINK_AND_SOURCE;
} else {
path->connect = UNCONNECT_SINK_AND_SOURCE;
}
return;
}
static int32_t AudioSapmSetPathStatus(const struct AudioSapmComponent *sapmComponent,
struct AudioSapmpath *path, int32_t i)
{
if ((sapmComponent == NULL) || (path == NULL)) {
ADM_LOG_ERR("input params check error: sapmComponent=%p, path=%p.", sapmComponent, path);
return HDF_FAILURE;
}
switch (sapmComponent->sapmType) {
case AUDIO_SAPM_MIXER:
case AUDIO_SAPM_ANALOG_SWITCH:
case AUDIO_SAPM_MIXER_NAMED_CTRL:
MixerSetPathStatus(sapmComponent, path,
(struct AudioMixerControl *)((volatile uintptr_t)sapmComponent->kcontrolNews[i].privateValue));
break;
case AUDIO_SAPM_MUX:
MuxSetPathStatus(sapmComponent, path,
(struct AudioEnumKcontrol *)((volatile uintptr_t)sapmComponent->kcontrolNews[i].privateValue), i);
break;
case AUDIO_SAPM_VALUE_MUX:
MuxValueSetPathStatus(sapmComponent, path,
(struct AudioEnumKcontrol *)((volatile uintptr_t)sapmComponent->kcontrolNews[i].privateValue), i);
break;
default:
path->connect = CONNECT_SINK_AND_SOURCE;
break;
}
return HDF_SUCCESS;
}
static int32_t AudioSapmConnectMixer(struct AudioCard *audioCard,
struct AudioSapmComponent *source, struct AudioSapmComponent *sink,
struct AudioSapmpath *path, const char *controlName)
{
int i = 0;
if ((audioCard == NULL) || (source == NULL) || (sink == NULL) ||
(path == NULL) || (controlName == NULL)) {
ADM_LOG_ERR("input params check error: audioCard=%p, source=%p, sink=%p, path=%p, controlName=%p.",
audioCard, source, sink, path, controlName);
return HDF_FAILURE;
}
for (i = 0; i < sink->kcontrolsNum; i++) {
if (sink->kcontrolNews[i].name == NULL) {
continue;
}
if (strcmp(controlName, sink->kcontrolNews[i].name) == 0) {
path->name = (char *)OsalMemCalloc(strlen(sink->kcontrolNews[i].name) + 1);
if (path->name == NULL) {
ADM_LOG_ERR("malloc path->name fail!");
return HDF_FAILURE;
}
if (memcpy_s(path->name, strlen(sink->kcontrolNews[i].name) + 1, sink->kcontrolNews[i].name,
strlen(sink->kcontrolNews[i].name) + 1) != EOK) {
OsalMemFree(path->name);
ADM_LOG_ERR("memcpy cpt->componentName fail!");
return HDF_FAILURE;
}
DListInsertHead(&path->list, &audioCard->paths);
DListInsertHead(&path->listSink, &sink->sources);
DListInsertHead(&path->listSource, &source->sinks);
AudioSapmSetPathStatus(sink, path, i);
return HDF_SUCCESS;
}
}
return HDF_FAILURE;
}
static int32_t AudioSampStaticOrDynamicPath(struct AudioCard *audioCard,
struct AudioSapmComponent *source, struct AudioSapmComponent *sink,
struct AudioSapmpath *path, const struct AudioSapmRoute *route)
{
int32_t ret;
if ((audioCard == NULL) || (source == NULL) || (sink == NULL) || (path == NULL) || (route == NULL)) {
ADM_LOG_ERR("input params check error: audioCard=%p, source=%p, sink=%p, path=%p, route=%p.",
audioCard, source, sink, path, route);
return HDF_FAILURE;
}
if (route->control == NULL) {
DListInsertHead(&path->list, &audioCard->paths);
DListInsertHead(&path->listSink, &sink->sources);
DListInsertHead(&path->listSource, &source->sinks);
path->connect = CONNECT_SINK_AND_SOURCE;
return HDF_SUCCESS;
}
switch (sink->sapmType) {
case AUDIO_SAPM_MUX:
case AUDIO_SAPM_VIRT_MUX:
case AUDIO_SAPM_VALUE_MUX:
break;
case AUDIO_SAPM_ANALOG_SWITCH:
case AUDIO_SAPM_MIXER:
case AUDIO_SAPM_MIXER_NAMED_CTRL:
case AUDIO_SAPM_PGA:
case AUDIO_SAPM_SPK:
ret = AudioSapmConnectMixer(audioCard, source, sink, path, route->control);
if (ret != HDF_SUCCESS) {
ADM_LOG_ERR("connect mixer fail!");
return HDF_FAILURE;
}
break;
case AUDIO_SAPM_HP:
case AUDIO_SAPM_MIC:
case AUDIO_SAPM_LINE:
DListInsertHead(&path->list, &audioCard->paths);
DListInsertHead(&path->listSink, &sink->sources);
DListInsertHead(&path->listSource, &source->sinks);
path->connect = CONNECT_SINK_AND_SOURCE;
break;
default:
DListInsertHead(&path->list, &audioCard->paths);
DListInsertHead(&path->listSink, &sink->sources);
DListInsertHead(&path->listSource, &source->sinks);
path->connect = CONNECT_SINK_AND_SOURCE;
break;
}
return HDF_SUCCESS;
}
static void AudioSampExtComponentsCheck(struct AudioSapmComponent *cptSource, struct AudioSapmComponent *cptSink)
{
if ((cptSource == NULL) || (cptSink == NULL)) {
ADM_LOG_ERR("input params check error: cptSource=%p, cptSink=%p.", cptSource, cptSink);
return;
}
if (cptSink->sapmType == AUDIO_SAPM_INPUT) {
if (cptSource->sapmType == AUDIO_SAPM_MICBIAS || cptSource->sapmType == AUDIO_SAPM_MIC ||
cptSource->sapmType == AUDIO_SAPM_LINE || cptSource->sapmType == AUDIO_SAPM_OUTPUT) {
cptSink->external = EXIST_EXTERNAL_WIDGET;
}
}
if (cptSource->sapmType == AUDIO_SAPM_OUTPUT) {
if (cptSink->sapmType == AUDIO_SAPM_SPK || cptSink->sapmType == AUDIO_SAPM_HP ||
cptSink->sapmType == AUDIO_SAPM_LINE || cptSink->sapmType == AUDIO_SAPM_INPUT) {
cptSource->external = EXIST_EXTERNAL_WIDGET;
}
}
return;
}
static int32_t AudioSapmAddRoute(struct AudioCard *audioCard, const struct AudioSapmRoute *route)
{
struct AudioSapmpath *path = NULL;
struct AudioSapmComponent *cptSource = NULL;
struct AudioSapmComponent *cptSink = NULL;
struct AudioSapmComponent *sapmComponent = NULL;
int32_t ret;
if (audioCard == NULL) {
ADM_LOG_ERR("input params check error: audioCard is NULL.");
return HDF_FAILURE;
}
if (route == NULL || route->source == NULL || route->sink == NULL) {
ADM_LOG_ERR("input params check error: route is NULL.");
return HDF_FAILURE;
}
DLIST_FOR_EACH_ENTRY(sapmComponent, &audioCard->components, struct AudioSapmComponent, list) {
if (sapmComponent->componentName == NULL) {
continue;
}
if ((cptSource == NULL) && (strcmp(sapmComponent->componentName, route->source) == 0)) {
cptSource = sapmComponent;
continue;
}
if ((cptSink == NULL) && (strcmp(sapmComponent->componentName, route->sink) == 0)) {
cptSink = sapmComponent;
}
if ((cptSource != NULL) && (cptSink != NULL)) {
break;
}
}
if ((cptSource == NULL) || (cptSink == NULL)) {
ADM_LOG_ERR("find component fail!");
return HDF_FAILURE;
}
path = (struct AudioSapmpath *)OsalMemCalloc(sizeof(struct AudioSapmpath));
if (path == NULL) {
ADM_LOG_ERR("malloc path fail!");
return HDF_FAILURE;
}
path->source = cptSource;
path->sink = cptSink;
DListHeadInit(&path->list);
DListHeadInit(&path->listSink);
DListHeadInit(&path->listSource);
AudioSampExtComponentsCheck(cptSource, cptSink);
ret = AudioSampStaticOrDynamicPath(audioCard, cptSource, cptSink, path, route);
if (ret != HDF_SUCCESS) {
OsalMemFree(path);
ADM_LOG_ERR("static or dynamic path fail!");
return HDF_FAILURE;
}
return HDF_SUCCESS;
}
int32_t AudioSapmAddRoutes(struct AudioCard *audioCard, const struct AudioSapmRoute *route, int32_t routeMaxNum)
{
int32_t i;
int32_t ret;
if (audioCard == NULL) {
ADM_LOG_ERR("input params check error: audioCard is NULL.");
return HDF_FAILURE;
}
if (route == NULL) {
ADM_LOG_ERR("input params check error: route is NULL.");
return HDF_FAILURE;
}
for (i = 0; i < routeMaxNum; i++) {
ret = AudioSapmAddRoute(audioCard, route);
if (ret != HDF_SUCCESS) {
ADM_LOG_ERR("AudioSapmAddRoute failed!");
return HDF_FAILURE;
}
route++;
}
return HDF_SUCCESS;
}
int32_t AudioSapmNewMixerControls(const struct AudioSapmComponent *sapmComponent, struct AudioCard *audioCard)
{
struct AudioSapmpath *path = NULL;
int32_t i;
if (sapmComponent == NULL || sapmComponent->kcontrols == NULL) {
ADM_LOG_ERR("input params check error: sapmComponent is NULL.");
return HDF_FAILURE;
}
if (audioCard == NULL) {
ADM_LOG_ERR("input params check error: audioCard is NULL.");
return HDF_FAILURE;
}
for (i = 0; i < sapmComponent->kcontrolsNum; i++) {
DLIST_FOR_EACH_ENTRY(path, &sapmComponent->sources, struct AudioSapmpath, listSink) {
if (path->name == NULL || sapmComponent->kcontrolNews == NULL
|| sapmComponent->kcontrolNews[i].name == NULL) {
continue;
}
if (strcmp(path->name, sapmComponent->kcontrolNews[i].name) != 0) {
continue;
}
path->kcontrol = AudioAddControl(audioCard, &sapmComponent->kcontrolNews[i]);
if (path->kcontrol == NULL) {
ADM_LOG_ERR("add control fail!");
return HDF_FAILURE;
}
sapmComponent->kcontrols[i] = path->kcontrol;
DListInsertHead(&sapmComponent->kcontrols[i]->list, &audioCard->controls);
}
}
return HDF_SUCCESS;
}
int AudioSapmNewMuxControls(struct AudioSapmComponent *sapmComponent, struct AudioCard *audioCard)
{
struct AudioKcontrol *kctrl = NULL;
if (sapmComponent == NULL || sapmComponent->kcontrolNews == NULL || audioCard == NULL) {
ADM_LOG_ERR("input param is NULL.");
return HDF_FAILURE;
}
if (sapmComponent->kcontrolsNum != 1) {
ADM_LOG_ERR("incorrect number of controls.");
return HDF_FAILURE;
}
kctrl = AudioAddControl(audioCard, &sapmComponent->kcontrolNews[0]);
if (kctrl == NULL) {
ADM_LOG_ERR("add control fail!");
return HDF_FAILURE;
}
if (sapmComponent->kcontrols == NULL) {
OsalMemFree(kctrl);
kctrl = NULL;
ADM_LOG_ERR("sapmComponent->kcontrols is NULL!");
return HDF_FAILURE;
}
sapmComponent->kcontrols[0] = kctrl;
DListInsertHead(&sapmComponent->kcontrols[0]->list, &audioCard->controls);
return HDF_SUCCESS;
}
static void AudioSapmPowerSeqInsert(struct AudioSapmComponent *newSapmComponent,
struct DListHead *list, int8_t isPowerUp)
{
struct AudioSapmComponent *sapmComponent = NULL;
int32_t *seq = {0};
if (newSapmComponent == NULL || list == NULL || newSapmComponent->componentName == NULL) {
ADM_LOG_ERR("input param newCpt is NULL.");
return;
}
if (isPowerUp) {
seq = g_audioSapmPowerUpSeq;
} else {
seq = g_audioSapmPowerDownSeq;
}
DLIST_FOR_EACH_ENTRY(sapmComponent, list, struct AudioSapmComponent, powerList) {
if ((seq[newSapmComponent->sapmType] - seq[sapmComponent->sapmType]) < 0) {
DListInsertTail(&newSapmComponent->powerList, &sapmComponent->powerList);
return;
}
}
DListInsertTail(&newSapmComponent->powerList, list);
ADM_LOG_DEBUG("[%s] success.", newSapmComponent->componentName);
return;
}
static void AudioSapmSetPower(struct AudioCard *audioCard, struct AudioSapmComponent *sapmComponent,
uint8_t power, struct DListHead *upList, struct DListHead *downList)
{
struct AudioSapmpath *path = NULL;
if (sapmComponent == NULL) {
ADM_LOG_ERR("input param sapmComponent is NULL.");
return;
}
DLIST_FOR_EACH_ENTRY(path, &sapmComponent->sources, struct AudioSapmpath, listSink) {
if (path->source != NULL) {
if ((path->source->power != power) && path->connect) {
if (DListIsEmpty(&path->source->dirty)) {
DListInsertTail(&path->source->dirty, &audioCard->sapmDirty);
}
}
}
}
DLIST_FOR_EACH_ENTRY(path, &sapmComponent->sinks, struct AudioSapmpath, listSource) {
if (path->sink != NULL) {
if ((path->sink->power != power) && path->connect) {
if (DListIsEmpty(&path->sink->dirty)) {
DListInsertTail(&path->sink->dirty, &audioCard->sapmDirty);
}
}
}
}
if (power) {
AudioSapmPowerSeqInsert(sapmComponent, upList, power);
} else {
AudioSapmPowerSeqInsert(sapmComponent, downList, power);
}
return;
}
static void AudioSapmPowerUpSeqRun(const struct DListHead *list)
{
uint32_t val;
struct AudioMixerControl mixerControl;
struct AudioSapmComponent *sapmComponent = NULL;
if (list == NULL) {
ADM_LOG_ERR("input param list is NULL.");
return;
}
DLIST_FOR_EACH_ENTRY(sapmComponent, list, struct AudioSapmComponent, powerList) {
if ((sapmComponent->reg >= 0) && (sapmComponent->power == SAPM_POWER_DOWN)) {
val = SAPM_POWER_UP;
sapmComponent->power = SAPM_POWER_UP;
mixerControl.reg = sapmComponent->reg;
mixerControl.mask = sapmComponent->mask;
mixerControl.shift = sapmComponent->shift;
if (sapmComponent->invert) {
val = !val;
}
if (sapmComponent->codec != NULL) {
AudioUpdateCodecRegBits(sapmComponent->codec, mixerControl.reg, mixerControl.mask,
mixerControl.shift, val);
ADM_LOG_DEBUG("Sapm Codec Power Up.");
}
}
}
return;
}
static void AudioSapmPowerDownSeqRun(const struct DListHead *list)
{
uint32_t val;
struct AudioMixerControl mixerControl;
struct AudioSapmComponent *sapmComponent = NULL;
ADM_LOG_DEBUG("entry!");
if (list == NULL) {
ADM_LOG_ERR("input param list is NULL.");
return;
}
DLIST_FOR_EACH_ENTRY(sapmComponent, list, struct AudioSapmComponent, powerList) {
if ((sapmComponent->reg >= 0) && (sapmComponent->power == SAPM_POWER_UP)) {
val = SAPM_POWER_DOWN;
sapmComponent->power = SAPM_POWER_DOWN;
mixerControl.mask = sapmComponent->mask;
mixerControl.reg = sapmComponent->reg;
mixerControl.shift = sapmComponent->shift;
if (sapmComponent->invert) {
val = !val;
}
if (sapmComponent->codec != NULL) {
AudioUpdateCodecRegBits(sapmComponent->codec, mixerControl.reg, mixerControl.mask,
mixerControl.shift, val);
ADM_LOG_DEBUG("Sapm Codec Power Down.");
}
}
}
return;
}
static void AudioSapmPowerComponents(struct AudioCard *audioCard)
{
int32_t ret;
struct AudioSapmComponent *sapmComponent = NULL;
struct DListHead upList;
struct DListHead downList;
ADM_LOG_DEBUG("entry!");
if (audioCard == NULL) {
ADM_LOG_ERR("input param audioCard is NULL.");
return;
}
DListHeadInit(&upList);
DListHeadInit(&downList);
DLIST_FOR_EACH_ENTRY(sapmComponent, &audioCard->sapmDirty, struct AudioSapmComponent, dirty) {
sapmComponent->newPower = sapmComponent->PowerCheck(sapmComponent);
if (sapmComponent->newPower == sapmComponent->power) {
continue;
}
if (audioCard->sapmStandbyState && sapmComponent->PowerClockOp != NULL) {
ret = sapmComponent->PowerClockOp(sapmComponent);
if (ret != HDF_SUCCESS) {
continue;
}
}
AudioSapmSetPower(audioCard, sapmComponent, sapmComponent->newPower, &upList, &downList);
}
DLIST_FOR_EACH_ENTRY(sapmComponent, &audioCard->components, struct AudioSapmComponent, list) {
DListRemove(&sapmComponent->dirty);
DListHeadInit(&sapmComponent->dirty);
}
AudioSapmPowerDownSeqRun(&downList);
AudioSapmPowerUpSeqRun(&upList);
}
static void ReadInitComponentPowerStatus(struct AudioSapmComponent *sapmComponent)
{
int32_t ret;
uint32_t regVal = 0;
if (sapmComponent == NULL || sapmComponent->codec == NULL) {
ADM_LOG_ERR("input param sapmComponent is NULL.");
return;
}
if (sapmComponent->reg >= 0) {
ret = AudioCodecReadReg(sapmComponent->codec, sapmComponent->reg, ®Val);
if (ret != HDF_SUCCESS) {
ADM_LOG_ERR("read reg fail!");
return;
}
regVal &= 1 << sapmComponent->shift;
if (sapmComponent->invert) {
regVal = !regVal;
}
if (regVal) {
sapmComponent->power = SAPM_POWER_UP;
} else {
sapmComponent->power = SAPM_POWER_DOWN;
}
}
return;
}
int32_t AudioSapmSleep(struct AudioCard *audioCard)
{
if (audioCard == NULL) {
ADM_LOG_ERR("input param audioCard is NULL.");
return HDF_ERR_INVALID_OBJECT;
}
if (g_sleepTimer.realTimer != NULL) {
OsalTimerDelete(&g_sleepTimer);
}
OsalTimerCreate(&g_sleepTimer, SAPM_POLL_TIME, AudioSapmTimerCallback, (uintptr_t)audioCard);
OsalTimerStartLoop(&g_sleepTimer);
if (AudioSapmRefreshTime(audioCard, true) != HDF_SUCCESS) {
ADM_LOG_ERR("AudioSapmRefreshTime failed.");
return HDF_FAILURE;
}
audioCard->sapmStandbyState = false;
audioCard->sapmSleepState = false;
return HDF_SUCCESS;
}
int32_t AudioSapmNewControls(struct AudioCard *audioCard)
{
struct AudioSapmComponent *sapmComponent = NULL;
int ret = HDF_SUCCESS;
if (audioCard == NULL) {
ADM_LOG_ERR("input param audioCard is NULL.");
return HDF_ERR_INVALID_OBJECT;
}
DLIST_FOR_EACH_ENTRY(sapmComponent, &audioCard->components, struct AudioSapmComponent, list) {
if (sapmComponent->newCpt) {
continue;
}
if (sapmComponent->kcontrolsNum > 0) {
sapmComponent->kcontrols = OsalMemCalloc(sizeof(struct AudioKcontrol*) * sapmComponent->kcontrolsNum);
if (sapmComponent->kcontrols == NULL) {
ADM_LOG_ERR("malloc kcontrols fail!");
return HDF_FAILURE;
}
}
switch (sapmComponent->sapmType) {
case AUDIO_SAPM_ANALOG_SWITCH:
case AUDIO_SAPM_MIXER:
case AUDIO_SAPM_MIXER_NAMED_CTRL:
case AUDIO_SAPM_SPK:
case AUDIO_SAPM_PGA:
ret = AudioSapmNewMixerControls(sapmComponent, audioCard);
break;
case AUDIO_SAPM_MUX:
case AUDIO_SAPM_VIRT_MUX:
case AUDIO_SAPM_VALUE_MUX:
ret = AudioSapmNewMuxControls(sapmComponent, audioCard);
break;
default:
ret = HDF_SUCCESS;
break;
}
if (ret != HDF_SUCCESS) {
OsalMemFree(sapmComponent->kcontrols);
ADM_LOG_ERR("sapm new mixer or mux controls fail!");
return HDF_FAILURE;
}
ReadInitComponentPowerStatus(sapmComponent);
sapmComponent->newCpt = 1;
DListInsertTail(&sapmComponent->dirty, &audioCard->sapmDirty);
}
AudioSapmPowerComponents(audioCard);
return HDF_SUCCESS;
}
static int32_t MixerUpdatePowerStatus(const struct AudioKcontrol *kcontrol, uint32_t pathStatus)
{
struct AudioCard *audioCard = NULL;
struct AudioSapmpath *path = NULL;
if (kcontrol == NULL || kcontrol->pri == NULL) {
ADM_LOG_ERR("input param kcontrol is NULL.");
return HDF_ERR_INVALID_OBJECT;
}
audioCard = (struct AudioCard *)((volatile uintptr_t)(kcontrol->pri));
DLIST_FOR_EACH_ENTRY(path, &audioCard->paths, struct AudioSapmpath, list) {
if (path->kcontrol != kcontrol) {
continue;
}
if (path->sink == NULL || path->source == NULL) {
ADM_LOG_ERR("get path sink or source fail!");
return HDF_FAILURE;
}
if (path->sink->sapmType != AUDIO_SAPM_MIXER &&
path->sink->sapmType != AUDIO_SAPM_MIXER_NAMED_CTRL &&
path->sink->sapmType != AUDIO_SAPM_PGA &&
path->sink->sapmType != AUDIO_SAPM_SPK &&
path->sink->sapmType != AUDIO_SAPM_ANALOG_SWITCH) {
ADM_LOG_DEBUG("no mixer device.");
return HDF_DEV_ERR_NO_DEVICE;
}
path->connect = pathStatus;
DListInsertTail(&path->source->dirty, &audioCard->sapmDirty);
DListInsertTail(&path->sink->dirty, &audioCard->sapmDirty);
break;
}
AudioSapmPowerComponents(audioCard);
return HDF_SUCCESS;
}
int32_t AudioCodecSapmGetCtrlOps(const struct AudioKcontrol *kcontrol, struct AudioCtrlElemValue *elemValue)
{
if (AudioCodecGetCtrlOps(kcontrol, elemValue) != HDF_SUCCESS) {
ADM_LOG_ERR("Audio codec sapm get control switch is fail!");
return HDF_FAILURE;
}
return HDF_SUCCESS;
}
static int32_t AudioSapmSetCtrlOps(const struct AudioKcontrol *kcontrol, const struct AudioCtrlElemValue *elemValue,
uint32_t *value, uint32_t *pathStatus)
{
struct AudioMixerControl *mixerCtrl = NULL;
int iFlag = (kcontrol == NULL) || (kcontrol->privateValue <= 0) || (elemValue == NULL)
|| (value == NULL) || (pathStatus == NULL);
if (iFlag) {
ADM_LOG_ERR("input params invalid.");
return HDF_ERR_INVALID_OBJECT;
}
mixerCtrl = (struct AudioMixerControl *)((volatile uintptr_t)kcontrol->privateValue);
*value = elemValue->value[0];
if (*value < mixerCtrl->min || *value > mixerCtrl->max) {
ADM_LOG_ERR("value is invalid.");
return HDF_ERR_INVALID_OBJECT;
}
if (mixerCtrl->invert) {
*value = mixerCtrl->max - *value;
}
if (*value) {
*pathStatus = CONNECT_SINK_AND_SOURCE;
} else {
*pathStatus = UNCONNECT_SINK_AND_SOURCE;
}
return HDF_SUCCESS;
}
int32_t AudioCodecSapmSetCtrlOps(const struct AudioKcontrol *kcontrol, const struct AudioCtrlElemValue *elemValue)
{
uint32_t curValue = 0;
uint32_t value;
uint32_t pathStatus = 0;
struct CodecDevice *codec = NULL;
struct AudioMixerControl *mixerCtrl = NULL;
struct AudioCard *audioCard = NULL;
if ((kcontrol == NULL) || (kcontrol->privateValue <= 0) || (kcontrol->pri == NULL)) {
ADM_LOG_ERR("input params: kcontrol is NULL.");
return HDF_ERR_INVALID_OBJECT;
}
if (elemValue == NULL) {
ADM_LOG_ERR("input params: elemValue is NULL.");
return HDF_ERR_INVALID_OBJECT;
}
audioCard = (struct AudioCard *)((volatile uintptr_t)(kcontrol->pri));
mixerCtrl = (struct AudioMixerControl *)((volatile uintptr_t)kcontrol->privateValue);
if (AudioSapmSetCtrlOps(kcontrol, elemValue, &value, &pathStatus) != HDF_SUCCESS) {
ADM_LOG_ERR("Audio sapm put control switch fail!");
}
codec = AudioKcontrolGetCodec(kcontrol);
if (AudioCodecReadReg(codec, mixerCtrl->reg, &curValue) != HDF_SUCCESS) {
ADM_LOG_ERR("Device read register is failure!");
return HDF_FAILURE;
}
curValue &= mixerCtrl->mask << mixerCtrl->shift;
value = (value & mixerCtrl->mask) << mixerCtrl->shift;
if (curValue != value || audioCard->sapmSleepState == true) {
if (MixerUpdatePowerStatus(kcontrol, pathStatus) != HDF_SUCCESS) {
ADM_LOG_ERR("update power status is failure!");
return HDF_FAILURE;
}
if (AudioUpdateCodecRegBits(codec, mixerCtrl->reg, mixerCtrl->mask, mixerCtrl->shift,
elemValue->value[0]) != HDF_SUCCESS) {
ADM_LOG_ERR("update reg bits fail!");
return HDF_FAILURE;
}
}
return HDF_SUCCESS;
}
static int32_t AudioSapmRefreshTime(struct AudioCard *audioCard, bool bRefresh)
{
if (audioCard == NULL) {
ADM_LOG_ERR("input params is NULL.");
return HDF_ERR_INVALID_OBJECT;
}
if (bRefresh) {
audioCard->time = OsalGetSysTimeMs();
}
return HDF_SUCCESS;
}
static int32_t AudioSapmCheckTime(struct AudioCard *audioCard, bool *timeoutStatus)
{
int ret;
uint64_t diffTime;
if (audioCard == NULL || timeoutStatus == NULL) {
ADM_LOG_ERR("input params is NULL.");
return HDF_ERR_INVALID_OBJECT;
}
ret = AudioSapmRefreshTime(audioCard, false);
if (ret != HDF_SUCCESS) {
ADM_LOG_ERR("AudioSapmRefreshTime failed.");
return HDF_FAILURE;
}
diffTime = OsalGetSysTimeMs() - audioCard->time;
if (diffTime > SAPM_SLEEP_TIME) {
*timeoutStatus = true;
} else {
*timeoutStatus = false;
}
return HDF_SUCCESS;
}
int32_t AudioSampPowerUp(const struct AudioCard *card)
{
struct DListHead upList;
struct AudioSapmComponent *sapmComponent = NULL;
if (card == NULL) {
ADM_LOG_ERR("input params is null.");
return HDF_ERR_INVALID_OBJECT;
}
DListHeadInit(&upList);
DLIST_FOR_EACH_ENTRY(sapmComponent, &card->components, struct AudioSapmComponent, list) {
if (sapmComponent == NULL) {
break;
}
if (sapmComponent->power == SAPM_POWER_DOWN) {
AudioSapmPowerSeqInsert(sapmComponent, &upList, SAPM_POWER_UP);
}
}
AudioSapmPowerUpSeqRun(&upList);
return HDF_SUCCESS;
}
int32_t AudioSampSetPowerMonitor(struct AudioCard *card, bool powerMonitorState)
{
if (card == NULL) {
ADM_LOG_ERR("input params is null.");
return HDF_ERR_INVALID_OBJECT;
}
card->sapmMonitorState = powerMonitorState;
if (powerMonitorState == false) {
card->sapmSleepState = false;
card->sapmStandbyState = false;
card->sapmStandbyStartTimeFlag = false;
card->sapmSleepStartTimeFlag = false;
}
return HDF_SUCCESS;
}
static void AudioSapmEnterSleep(const uintptr_t para)
{
struct DListHead downList;
struct AudioCard *audioCard = (struct AudioCard *)para;
struct AudioSapmComponent *sapmComponent = NULL;
ADM_LOG_INFO("entry!");
DListHeadInit(&downList);
if (audioCard == NULL) {
ADM_LOG_ERR("audioCard is null.");
return;
}
DLIST_FOR_EACH_ENTRY(sapmComponent, &audioCard->components, struct AudioSapmComponent, list) {
if (sapmComponent == NULL) {
break;
}
if (sapmComponent->power == SAPM_POWER_UP) {
AudioSapmPowerSeqInsert(sapmComponent, &downList, SAPM_POWER_DOWN);
}
}
AudioSapmPowerDownSeqRun(&downList);
audioCard->sapmSleepState = true;
}
static bool AudioSapmEnterStandby(struct AudioCard *audioCard)
{
bool timeoutStatus;
struct AudioSapmComponent *sapmComponent = NULL;
if (audioCard == NULL) {
return false;
}
if (audioCard->sapmStandbyStartTimeFlag == false) {
if (AudioSapmRefreshTime(audioCard, true) != HDF_SUCCESS) {
ADM_LOG_ERR("AudioSapmRefreshTime failed.");
return false;
}
audioCard->sapmStandbyStartTimeFlag = true;
}
if (audioCard->standbyMode != AUDIO_SAPM_TURN_STANDBY_NOW) {
if (AudioSapmCheckTime(audioCard, &timeoutStatus) != HDF_SUCCESS) {
ADM_LOG_ERR("AudioSapmCheckTime failed.");
return false;
}
if (!timeoutStatus) {
return false;
}
}
if (audioCard->sapmStandbyState == false) {
DLIST_FOR_EACH_ENTRY(sapmComponent, &audioCard->components, struct AudioSapmComponent, list) {
if (sapmComponent->PowerClockOp != NULL) {
sapmComponent->PowerClockOp(sapmComponent);
}
}
audioCard->sapmStandbyState = true;
}
return true;
}
static void AudioSapmTimerCallback(uintptr_t para)
{
struct AudioCard *audioCard = (struct AudioCard *)para;
bool timeoutStatus;
bool standbyEntry;
#ifndef __LITEOS__
ADM_LOG_DEBUG("entry!");
#endif
if (audioCard == NULL) {
return;
}
if (audioCard->sapmSleepState == true) {
return;
}
if (audioCard->sapmMonitorState == false) {
return;
}
standbyEntry = AudioSapmEnterStandby(audioCard);
if (!standbyEntry) {
return;
}
if (audioCard->sapmSleepStartTimeFlag == false) {
if (AudioSapmRefreshTime(audioCard, true) != HDF_SUCCESS) {
ADM_LOG_ERR("AudioSapmRefreshTime failed.");
return;
}
audioCard->sapmSleepStartTimeFlag = true;
}
if (AudioSapmCheckTime(audioCard, &timeoutStatus) != HDF_SUCCESS) {
ADM_LOG_ERR("AudioSapmCheckTime failed.");
return;
}
if (!timeoutStatus) {
return;
}
AudioSapmEnterSleep(para);
}